diff --git a/.DS_Store.REMOVED.git-id.REMOVED.git-id b/.DS_Store.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index c0afee48..00000000 --- a/.DS_Store.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -07fd5f30875d2bc15afcc83055ee4000a0b7acd2 \ No newline at end of file diff --git a/._.DS_Store.REMOVED.git-id.REMOVED.git-id b/._.DS_Store.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 95175ab4..00000000 --- a/._.DS_Store.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -301d01b13096dca1cd26a9b8830a99612aa2553b \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..5ecfcdaa --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.csv +/.project diff --git a/.gitignore.REMOVED.git-id.REMOVED.git-id b/.gitignore.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 49ab68a1..00000000 --- a/.gitignore.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3c234b962282580cddee0b6d5f8eb4fae2feee8d \ No newline at end of file diff --git a/AVR Code/.vs/USB_BULK_TEST/v14/.atsuo b/AVR Code/.vs/USB_BULK_TEST/v14/.atsuo new file mode 100644 index 00000000..b0425510 Binary files /dev/null and b/AVR Code/.vs/USB_BULK_TEST/v14/.atsuo differ diff --git a/AVR Code/.vs/USB_BULK_TEST/v14/.atsuo.REMOVED.git-id b/AVR Code/.vs/USB_BULK_TEST/v14/.atsuo.REMOVED.git-id deleted file mode 100644 index d5b314c8..00000000 --- a/AVR Code/.vs/USB_BULK_TEST/v14/.atsuo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b0425510fe37aefb3e097ee1d324ce58289db692 \ No newline at end of file diff --git a/AVR Code/PRODUCTION/EEPROM.eep.REMOVED.git-id b/AVR Code/PRODUCTION/EEPROM.eep.REMOVED.git-id deleted file mode 100644 index 93704c5b..00000000 --- a/AVR Code/PRODUCTION/EEPROM.eep.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -18628c0284cf09b51812cf534acccabbe149f9a7 \ No newline at end of file diff --git a/AVR Code/PRODUCTION/FLASH.hex.REMOVED.git-id b/AVR Code/PRODUCTION/FLASH.hex.REMOVED.git-id deleted file mode 100644 index fc103313..00000000 --- a/AVR Code/PRODUCTION/FLASH.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5f1f7084dc45171b5b705dd350003ec686cd9673 \ No newline at end of file diff --git a/AVR Code/PRODUCTION/USER_SIGNATURES.hex.REMOVED.git-id b/AVR Code/PRODUCTION/USER_SIGNATURES.hex.REMOVED.git-id deleted file mode 100644 index 1f07f264..00000000 --- a/AVR Code/PRODUCTION/USER_SIGNATURES.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -81817d5221b066f2b509d433e8993e91a8b58386 \ No newline at end of file diff --git a/AVR Code/PRODUCTION/labrador-ba94.elf.REMOVED.git-id b/AVR Code/PRODUCTION/labrador-ba94.elf.REMOVED.git-id deleted file mode 100644 index faa464b1..00000000 --- a/AVR Code/PRODUCTION/labrador-ba94.elf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -13a8f78b24a1efe08d7e032557c1e4705ee3cede \ No newline at end of file diff --git a/AVR Code/PRODUCTION/labrador.elf.REMOVED.git-id b/AVR Code/PRODUCTION/labrador.elf.REMOVED.git-id deleted file mode 100644 index 37fa2544..00000000 --- a/AVR Code/PRODUCTION/labrador.elf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6045df59563c016446f7f75c6ab08fefad8be790 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST.atsln b/AVR Code/USB_BULK_TEST.atsln new file mode 100644 index 00000000..39d696da --- /dev/null +++ b/AVR Code/USB_BULK_TEST.atsln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Atmel Studio Solution File, Format Version 11.00 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "USB_BULK_TEST", "USB_BULK_TEST\USB_BULK_TEST.cproj", "{BD2AA8D9-491B-4ECD-9255-825EAABC7BA4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|AVR = Debug|AVR + Release|AVR = Release|AVR + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BD2AA8D9-491B-4ECD-9255-825EAABC7BA4}.Debug|AVR.ActiveCfg = Debug|AVR + {BD2AA8D9-491B-4ECD-9255-825EAABC7BA4}.Debug|AVR.Build.0 = Debug|AVR + {BD2AA8D9-491B-4ECD-9255-825EAABC7BA4}.Release|AVR.ActiveCfg = Release|AVR + {BD2AA8D9-491B-4ECD-9255-825EAABC7BA4}.Release|AVR.Build.0 = Release|AVR + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/AVR Code/USB_BULK_TEST.atsln.REMOVED.git-id b/AVR Code/USB_BULK_TEST.atsln.REMOVED.git-id deleted file mode 100644 index 1e669861..00000000 --- a/AVR Code/USB_BULK_TEST.atsln.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -39d696da99993e89d69ed499ff1514c0556104ce \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST.atsuo b/AVR Code/USB_BULK_TEST.atsuo new file mode 100644 index 00000000..d20afbd3 Binary files /dev/null and b/AVR Code/USB_BULK_TEST.atsuo differ diff --git a/AVR Code/USB_BULK_TEST.atsuo.REMOVED.git-id b/AVR Code/USB_BULK_TEST.atsuo.REMOVED.git-id deleted file mode 100644 index a031f993..00000000 --- a/AVR Code/USB_BULK_TEST.atsuo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d20afbd372a73154b5b74452dced748255ec0578 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/Makefile.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/Makefile.REMOVED.git-id deleted file mode 100644 index 0015dfb8..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/Makefile.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5d9342282bd9e5cec14a00dafa34e65566dc75ac \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.eep.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.eep.REMOVED.git-id deleted file mode 100644 index bd662121..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.eep.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7c166a13c19d7811fbf00e7e334ad40eebfcbe2f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.elf.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.elf.REMOVED.git-id deleted file mode 100644 index e16e4a8d..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.elf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b32256faf53600ebdbacbf778dd4e755479c7b3a \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.hex.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.hex.REMOVED.git-id deleted file mode 100644 index 2085bbb2..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -728e9e5182f1248d37038474b5ef358f03e0a546 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.lss.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.lss.REMOVED.git-id deleted file mode 100644 index bfbb5507..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.lss.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8e4d695e19a7cdfd133c4cb5fcf596214dd4fdca \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.map.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.map.REMOVED.git-id deleted file mode 100644 index 1371f591..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.map.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -620b84bbb4a02f9e1b0fa4d5dac1f2f17a245932 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.srec.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.srec.REMOVED.git-id deleted file mode 100644 index d65d6cdb..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/USB_BULK_TEST.srec.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c7bf90f8efb130b20ca372c7084ccf3915d91c8b \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/makedep.mk.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/makedep.mk.REMOVED.git-id deleted file mode 100644 index 933cec14..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/makedep.mk.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -39b6d418feb9451846091d4f8b02f6178b662787 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/boards/user_board/init.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/boards/user_board/init.d.REMOVED.git-id deleted file mode 100644 index ef880328..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/boards/user_board/init.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -72fbb82ce899ecad41ea37b50a819b78b770f2b7 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/boards/user_board/init.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/boards/user_board/init.o.REMOVED.git-id deleted file mode 100644 index 40705846..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/boards/user_board/init.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -106c90d2b446ea3de5a2aee9695225011d7cf748 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/clock/xmega/sysclk.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/clock/xmega/sysclk.d.REMOVED.git-id deleted file mode 100644 index 0db57f92..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/clock/xmega/sysclk.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -35c4a6114f3c290992adedd53336a50f9efcc07f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/clock/xmega/sysclk.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/clock/xmega/sysclk.o.REMOVED.git-id deleted file mode 100644 index e39d2e04..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/clock/xmega/sysclk.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a634afecc1826672afd7af866395930f8817767a \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/ioport/xmega/ioport_compat.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/ioport/xmega/ioport_compat.d.REMOVED.git-id deleted file mode 100644 index b4ce3e97..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/ioport/xmega/ioport_compat.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1d491823486282983c2b92e7ef9e078815c716fa \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/ioport/xmega/ioport_compat.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/ioport/xmega/ioport_compat.o.REMOVED.git-id deleted file mode 100644 index f18fcc1e..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/ioport/xmega/ioport_compat.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c8ca9c133746a4917c48bab12e52d4a1b84af99d \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/sleepmgr/xmega/sleepmgr.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/sleepmgr/xmega/sleepmgr.d.REMOVED.git-id deleted file mode 100644 index 4e7a0338..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/sleepmgr/xmega/sleepmgr.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -37537db1ec527dd9a123a966a0566fdfb61e3af2 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/sleepmgr/xmega/sleepmgr.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/sleepmgr/xmega/sleepmgr.o.REMOVED.git-id deleted file mode 100644 index 302f9a75..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/sleepmgr/xmega/sleepmgr.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -67b1d35612797655dc0064b66805ac82e44c6769 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.d.REMOVED.git-id deleted file mode 100644 index 22bd9599..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5c4260aaa0a3c3306e4bc5698404578231239c88 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.o.REMOVED.git-id deleted file mode 100644 index 0c30e57f..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a8f9116279c3229297d8b012dc38ca1fa3583396 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/udi_vendor.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/udi_vendor.d.REMOVED.git-id deleted file mode 100644 index b4d0b248..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/udi_vendor.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -db3dd5ec2c5ff9b5e199751b90feb91577d00b11 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/udi_vendor.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/udi_vendor.o.REMOVED.git-id deleted file mode 100644 index b483d4a2..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/udi_vendor.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -29a1b7abf2baf31b14db89d0f828f3e3da89786f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.d.REMOVED.git-id deleted file mode 100644 index 980f2301..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -94cc3abb6ddb957afcb7e6b81990adcecbda0090 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.o.REMOVED.git-id deleted file mode 100644 index 61cbc58c..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ad7b70be963700678586e89d9baa4701680ee6d1 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/udc/udc.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/udc/udc.d.REMOVED.git-id deleted file mode 100644 index 7384c559..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/udc/udc.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ed7f4d2d45a89f270dc9d0aaffd0a75e8fb2090d \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/udc/udc.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/udc/udc.o.REMOVED.git-id deleted file mode 100644 index f1f829c7..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/common/services/usb/udc/udc.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -92ada3896e0c9de0fa0cf921fbb5c4165204855b \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/cpu/ccp.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/cpu/ccp.d.REMOVED.git-id deleted file mode 100644 index c70bbd21..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/cpu/ccp.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9eed18c8185f635ec502905bee11ad12eb105a02 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/cpu/ccp.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/cpu/ccp.o.REMOVED.git-id deleted file mode 100644 index beee8639..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/cpu/ccp.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fd457ecf9238b3ac1068e0c00b5b245843fa4d7e \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/nvm/nvm.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/nvm/nvm.d.REMOVED.git-id deleted file mode 100644 index 0cced544..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/nvm/nvm.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7efcb915d6cf7f829757ac7b0ab0c5cc21597e71 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/nvm/nvm.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/nvm/nvm.o.REMOVED.git-id deleted file mode 100644 index 7ce57de7..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/nvm/nvm.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1a78298dc01d42dc58f7307c77d81f294f4a5145 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/nvm/nvm_asm.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/nvm/nvm_asm.d.REMOVED.git-id deleted file mode 100644 index 9e08b412..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/nvm/nvm_asm.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f222d9bd3f855a764a788c74efa9ac2cc1a27ef2 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/nvm/nvm_asm.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/nvm/nvm_asm.o.REMOVED.git-id deleted file mode 100644 index bb74f8f2..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/nvm/nvm_asm.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f3db8dacf8f538915f10b968296d76b1332e0e5e \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/usb/usb_device.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/usb/usb_device.d.REMOVED.git-id deleted file mode 100644 index cd25aa15..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/usb/usb_device.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -75c961d1aea87e51d5c99e624a25a0235986f34e \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/usb/usb_device.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/usb/usb_device.o.REMOVED.git-id deleted file mode 100644 index 941c78b8..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/ASF/xmega/drivers/usb/usb_device.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -91eaced37dea3f9ac59df57d58ab2908eef8f9d8 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/main.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/main.d.REMOVED.git-id deleted file mode 100644 index 8423483f..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/main.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3639cd654ea38e37377dbc81928b7f05d9216fa1 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/main.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/main.o.REMOVED.git-id deleted file mode 100644 index 6bcc4585..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/main.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b7ad4d7b5b09b6912c087929dbe8db05116670b8 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_adc.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_adc.d.REMOVED.git-id deleted file mode 100644 index d0b7aad2..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_adc.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d08a1c880873ec3b5fa541c0b3466acef46d5044 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_adc.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_adc.o.REMOVED.git-id deleted file mode 100644 index 62c9d0dd..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_adc.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ff8f06d883ba5bc77c2ce555406a58755a66c439 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_calibration.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_calibration.d.REMOVED.git-id deleted file mode 100644 index 29ddb797..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_calibration.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -039191a18d85f2d70c16b9028a87eb7f8f30d581 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_calibration.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_calibration.o.REMOVED.git-id deleted file mode 100644 index 10a96eee..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_calibration.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3cde6c7b1491f21ca8360fbb38d2452b3356fbd2 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_dac.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_dac.d.REMOVED.git-id deleted file mode 100644 index 16863e56..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_dac.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bb5ffab188c34a323ab96531806e6f36a706d136 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_dac.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_dac.o.REMOVED.git-id deleted file mode 100644 index bdee88e6..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_dac.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -349444cadd03a4f09868d01b5de9c8ae3059802f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_dig.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_dig.d.REMOVED.git-id deleted file mode 100644 index 3308c0d5..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_dig.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4b21c82a3e6ad5103ca9d8c4149d529aa993fe8a \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_dig.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_dig.o.REMOVED.git-id deleted file mode 100644 index 8dac18c5..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_dig.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b795b5c9f284f51d3c3017c7a63c5602daac0a1e \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_dma.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_dma.d.REMOVED.git-id deleted file mode 100644 index bd91a5f1..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_dma.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8a50f8ad90c2036f98e82aa782133b1b2ad0c036 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_dma.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_dma.o.REMOVED.git-id deleted file mode 100644 index 48f0f843..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_dma.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7f6d2cde9ffb4bdb92262847aa3b79098a0af4d8 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_eeprom.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_eeprom.d.REMOVED.git-id deleted file mode 100644 index 24a9ad0d..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_eeprom.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -287cf5d9efef1dbb7d415cefeb99d0e5644dd92f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_eeprom.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_eeprom.o.REMOVED.git-id deleted file mode 100644 index babbfdcd..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_eeprom.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -82c983dfd5c509530561c2243b26d887bfe69368 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_timer.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_timer.d.REMOVED.git-id deleted file mode 100644 index e215d95b..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_timer.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4882e9999d78dadae5e743313359febd8406e18f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_timer.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_timer.o.REMOVED.git-id deleted file mode 100644 index 9ffdda82..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_timer.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b81730484a5a8d482abe13b74fa81294b1fa8e62 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_uart.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_uart.d.REMOVED.git-id deleted file mode 100644 index f8f4fc12..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_uart.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aee87ec58561da038369a2e7bbabf2cc40d723f8 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Debug/src/tiny_uart.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Debug/src/tiny_uart.o.REMOVED.git-id deleted file mode 100644 index a4df1b7d..00000000 --- a/AVR Code/USB_BULK_TEST/Debug/src/tiny_uart.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aba99b4cd260dc07166e879897f840366a15badb \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/Makefile.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/Makefile.REMOVED.git-id deleted file mode 100644 index 9360a732..00000000 --- a/AVR Code/USB_BULK_TEST/Release/Makefile.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6cc08fb8d835e5eb776bfd1851c9b1e1245a58a2 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.eep.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.eep.REMOVED.git-id deleted file mode 100644 index bd662121..00000000 --- a/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.eep.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7c166a13c19d7811fbf00e7e334ad40eebfcbe2f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.elf.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.elf.REMOVED.git-id deleted file mode 100644 index ff002924..00000000 --- a/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.elf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9f89cf82ce049475369780f2a0cdc02be513c2d5 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.hex.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.hex.REMOVED.git-id deleted file mode 100644 index 42c42b45..00000000 --- a/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -879125a9685d89a7f05bd38994079919338f49b6 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.lss.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.lss.REMOVED.git-id deleted file mode 100644 index ef852a03..00000000 --- a/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.lss.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b406b76b903a439b21fce909991ba737bda29cfc \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.map.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.map.REMOVED.git-id deleted file mode 100644 index 0a80c0ad..00000000 --- a/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.map.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0fec8ec9acb97731a04a8baa7901c4c0c8ca84c8 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.srec.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.srec.REMOVED.git-id deleted file mode 100644 index 9af282c3..00000000 --- a/AVR Code/USB_BULK_TEST/Release/USB_BULK_TEST.srec.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f2c7a9e7828b9e65490e84fdcd77a805711b35f7 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/makedep.mk.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/makedep.mk.REMOVED.git-id deleted file mode 100644 index 933cec14..00000000 --- a/AVR Code/USB_BULK_TEST/Release/makedep.mk.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -39b6d418feb9451846091d4f8b02f6178b662787 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/boards/user_board/init.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/boards/user_board/init.d.REMOVED.git-id deleted file mode 100644 index ef880328..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/boards/user_board/init.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -72fbb82ce899ecad41ea37b50a819b78b770f2b7 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/boards/user_board/init.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/boards/user_board/init.o.REMOVED.git-id deleted file mode 100644 index b0045558..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/boards/user_board/init.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -904c1b6e11e9f116a364b731be8b410c7856a501 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/clock/xmega/sysclk.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/clock/xmega/sysclk.d.REMOVED.git-id deleted file mode 100644 index 0db57f92..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/clock/xmega/sysclk.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -35c4a6114f3c290992adedd53336a50f9efcc07f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/clock/xmega/sysclk.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/clock/xmega/sysclk.o.REMOVED.git-id deleted file mode 100644 index b75aeaaa..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/clock/xmega/sysclk.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0b7967a50932626d89f597638c94a816e7f4c127 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/ioport/xmega/ioport_compat.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/ioport/xmega/ioport_compat.d.REMOVED.git-id deleted file mode 100644 index b4ce3e97..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/ioport/xmega/ioport_compat.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1d491823486282983c2b92e7ef9e078815c716fa \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/ioport/xmega/ioport_compat.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/ioport/xmega/ioport_compat.o.REMOVED.git-id deleted file mode 100644 index b3fd54e0..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/ioport/xmega/ioport_compat.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ab55998976e607fdbda8724521b9b5d456ddddc8 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/sleepmgr/xmega/sleepmgr.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/sleepmgr/xmega/sleepmgr.d.REMOVED.git-id deleted file mode 100644 index 4e7a0338..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/sleepmgr/xmega/sleepmgr.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -37537db1ec527dd9a123a966a0566fdfb61e3af2 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/sleepmgr/xmega/sleepmgr.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/sleepmgr/xmega/sleepmgr.o.REMOVED.git-id deleted file mode 100644 index 9dd0a346..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/sleepmgr/xmega/sleepmgr.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -83b8226444b433f0a7a6815c351e0a92133015bf \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.d.REMOVED.git-id deleted file mode 100644 index 22bd9599..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5c4260aaa0a3c3306e4bc5698404578231239c88 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.o.REMOVED.git-id deleted file mode 100644 index 16bd0182..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d0b23ad47eb219e319a766a123413fb04dd902ed \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/udi_vendor.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/udi_vendor.d.REMOVED.git-id deleted file mode 100644 index b4d0b248..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/udi_vendor.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -db3dd5ec2c5ff9b5e199751b90feb91577d00b11 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/udi_vendor.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/udi_vendor.o.REMOVED.git-id deleted file mode 100644 index 0e505b52..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/udi_vendor.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -80e4467cac19d50a8a8ae90b01e08786e93fd6b0 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.d.REMOVED.git-id deleted file mode 100644 index 980f2301..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -94cc3abb6ddb957afcb7e6b81990adcecbda0090 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.o.REMOVED.git-id deleted file mode 100644 index c15b2c3e..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c48edfecfcd7085d51768de1a167caf4060367d5 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/udc/udc.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/udc/udc.d.REMOVED.git-id deleted file mode 100644 index 7384c559..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/udc/udc.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ed7f4d2d45a89f270dc9d0aaffd0a75e8fb2090d \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/udc/udc.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/udc/udc.o.REMOVED.git-id deleted file mode 100644 index eebfee2f..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/common/services/usb/udc/udc.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8954d0cefbff2cd0892b4e4301a5f8f2169d1f4f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/cpu/ccp.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/cpu/ccp.d.REMOVED.git-id deleted file mode 100644 index c70bbd21..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/cpu/ccp.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9eed18c8185f635ec502905bee11ad12eb105a02 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/cpu/ccp.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/cpu/ccp.o.REMOVED.git-id deleted file mode 100644 index 69651235..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/cpu/ccp.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -34a0448329bf456d5a69b62e952372ad2753d907 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/nvm/nvm.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/nvm/nvm.d.REMOVED.git-id deleted file mode 100644 index 0cced544..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/nvm/nvm.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7efcb915d6cf7f829757ac7b0ab0c5cc21597e71 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/nvm/nvm.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/nvm/nvm.o.REMOVED.git-id deleted file mode 100644 index 18ebd9f6..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/nvm/nvm.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -80c6b3b9275c7220f0520e5f52dee1fd13b32a75 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/nvm/nvm_asm.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/nvm/nvm_asm.d.REMOVED.git-id deleted file mode 100644 index 9e08b412..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/nvm/nvm_asm.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f222d9bd3f855a764a788c74efa9ac2cc1a27ef2 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/nvm/nvm_asm.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/nvm/nvm_asm.o.REMOVED.git-id deleted file mode 100644 index 66128843..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/nvm/nvm_asm.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -33efe4841140e2530d145e3fde7113ad9ad7ce78 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/usb/usb_device.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/usb/usb_device.d.REMOVED.git-id deleted file mode 100644 index cd25aa15..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/usb/usb_device.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -75c961d1aea87e51d5c99e624a25a0235986f34e \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/usb/usb_device.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/usb/usb_device.o.REMOVED.git-id deleted file mode 100644 index a643d895..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/ASF/xmega/drivers/usb/usb_device.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d76c48c10c1c1bd2b19e7703cdcf4980734d7a31 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/main.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/main.d.REMOVED.git-id deleted file mode 100644 index 8423483f..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/main.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3639cd654ea38e37377dbc81928b7f05d9216fa1 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/main.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/main.o.REMOVED.git-id deleted file mode 100644 index 5f33dbb8..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/main.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b5ba5743bf2540bd9cdf6ed001dd3019eaf8359f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_adc.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_adc.d.REMOVED.git-id deleted file mode 100644 index d0b7aad2..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_adc.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d08a1c880873ec3b5fa541c0b3466acef46d5044 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_adc.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_adc.o.REMOVED.git-id deleted file mode 100644 index f278269f..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_adc.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5239cd1fd850fc8a6327ebda1a2dee46fd18975a \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_calibration.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_calibration.d.REMOVED.git-id deleted file mode 100644 index 29ddb797..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_calibration.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -039191a18d85f2d70c16b9028a87eb7f8f30d581 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_calibration.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_calibration.o.REMOVED.git-id deleted file mode 100644 index 2f4b5f99..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_calibration.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9f652f5c817f655f59165abd62e6c26537fe8ced \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_dac.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_dac.d.REMOVED.git-id deleted file mode 100644 index 16863e56..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_dac.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bb5ffab188c34a323ab96531806e6f36a706d136 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_dac.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_dac.o.REMOVED.git-id deleted file mode 100644 index e816e23e..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_dac.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6dd71268fb79a36cb4eebacdefed1263e1be67c0 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_dig.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_dig.d.REMOVED.git-id deleted file mode 100644 index 3308c0d5..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_dig.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4b21c82a3e6ad5103ca9d8c4149d529aa993fe8a \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_dig.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_dig.o.REMOVED.git-id deleted file mode 100644 index 4a18f78c..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_dig.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -06501cb01524911283dc083e386b8643c8d3e888 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_dma.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_dma.d.REMOVED.git-id deleted file mode 100644 index bd91a5f1..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_dma.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8a50f8ad90c2036f98e82aa782133b1b2ad0c036 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_dma.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_dma.o.REMOVED.git-id deleted file mode 100644 index ea9b1877..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_dma.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fdbd27679843541577b42a06247a4da86d163398 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_eeprom.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_eeprom.d.REMOVED.git-id deleted file mode 100644 index 24a9ad0d..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_eeprom.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -287cf5d9efef1dbb7d415cefeb99d0e5644dd92f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_eeprom.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_eeprom.o.REMOVED.git-id deleted file mode 100644 index e476e53c..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_eeprom.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -edaabceaf58b981d808753b9651f0d8ef73a7e57 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_timer.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_timer.d.REMOVED.git-id deleted file mode 100644 index e215d95b..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_timer.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4882e9999d78dadae5e743313359febd8406e18f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_timer.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_timer.o.REMOVED.git-id deleted file mode 100644 index a0652b10..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_timer.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6f1d433f15b166a9f29457c53e8e8f80240820fa \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_uart.d.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_uart.d.REMOVED.git-id deleted file mode 100644 index f8f4fc12..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_uart.d.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aee87ec58561da038369a2e7bbabf2cc40d723f8 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/Release/src/tiny_uart.o.REMOVED.git-id b/AVR Code/USB_BULK_TEST/Release/src/tiny_uart.o.REMOVED.git-id deleted file mode 100644 index 262fb629..00000000 --- a/AVR Code/USB_BULK_TEST/Release/src/tiny_uart.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1dc4f7c23a085ecf71dfc00bfecf9d8dbbd50adb \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/USB_BULK_TEST.componentinfo.xml b/AVR Code/USB_BULK_TEST/USB_BULK_TEST.componentinfo.xml new file mode 100644 index 00000000..958c6281 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/USB_BULK_TEST.componentinfo.xml @@ -0,0 +1,86 @@ + + + + + + + Device + Startup + + + Atmel + 1.0.0 + C:/Program Files (x86)\Atmel\Studio\7.0\Packs + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.0.39\include + + include + C + + + include + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.0.39\include\avr\iox32a4u.h + + header + C + KyiKDrCTHLqSzerM5JnazQ== + + include/avr/iox32a4u.h + + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.0.39\templates\main.c + template + source + C Exe + GD1k8YYhulqRs6FD1B2Hog== + + templates/main.c + Main file (.c) + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.0.39\templates\main.cpp + template + source + C Exe + YXFphlh0CtZJU+ebktABgQ== + + templates/main.cpp + Main file (.cpp) + + + + C:/Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\XMEGAA_DFP\1.0.39\gcc\dev\atxmega32a4u + + libraryPrefix + GCC + + + gcc/dev/atxmega32a4u + + + + + XMEGAA_DFP + C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/XMEGAA_DFP/1.0.39/Atmel.XMEGAA_DFP.pdsc + 1.0.39 + true + ATxmega32A4U + + + + Resolved + Fixed + true + + + \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/USB_BULK_TEST.componentinfo.xml.REMOVED.git-id b/AVR Code/USB_BULK_TEST/USB_BULK_TEST.componentinfo.xml.REMOVED.git-id deleted file mode 100644 index 7b52dce9..00000000 --- a/AVR Code/USB_BULK_TEST/USB_BULK_TEST.componentinfo.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -958c62813dfddca94844c415ca12b0fdd460e317 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/USB_BULK_TEST.cproj b/AVR Code/USB_BULK_TEST/USB_BULK_TEST.cproj new file mode 100644 index 00000000..7f53efbd --- /dev/null +++ b/AVR Code/USB_BULK_TEST/USB_BULK_TEST.cproj @@ -0,0 +1,594 @@ + + + + 2.0 + 7.0 + com.Atmel.AVRGCC8.C + {bd2aa8d9-491b-4ecd-9255-825eaabc7ba4} + atxmega32a4u + xmegaau + Executable + C + $(MSBuildProjectName) + .elf + $(MSBuildProjectDirectory)\$(Configuration) + USB_BULK_TEST + USB_BULK_TEST + USB_BULK_TEST + Native + true + false + true + true + 0x20000000 + + true + exception_table + 2 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + com.atmel.avrdbg.tool.atmelice + + + + 4000000 + 7500000 + + PDI + + com.atmel.avrdbg.tool.atmelice + J41800006314 + Atmel-ICE + + PDI + + + + + PDI + + com.atmel.avrdbg.tool.simulator + + + Simulator + + J41800006314 + 0x1E9541 + 4000000 + + + + + -mmcu=atxmega32a4u -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.39\gcc\dev\atxmega32a4u" + True + True + True + True + True + False + + + NDEBUG + BOARD=USER_BOARD + + + + + ../common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained + ../common/services/usb/class/vendor/device/example + ../src/ASF/common/services/usb/udc + ../src/ASF/xmega/drivers/nvm + ../src/ASF/common/services/sleepmgr + ../src/ASF/common/services/clock + ../src/ASF/xmega/drivers/sleep + ../src/ASF/xmega/drivers/usb + ../src/ASF/xmega/drivers/cpu + ../src/ASF/common/services/usb/class/vendor + ../src/ASF/common/services/usb/class/vendor/device + ../src/ASF/common/services/usb + ../common/applications/user_application/user_board/config + ../src/ASF/xmega/utils + ../src/config + ../src/ASF/common/boards + ../src/ASF/xmega/utils/preprocessor + ../src/ASF/common/utils + ../src + ../src/ASF/common/boards/user_board + ../src/ASF/common/services/ioport + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.39\include + + + Optimize for size (-Os) + -fdata-sections + True + True + True + -std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax + + + libm + + + -Wl,--relax + -mrelax -DBOARD=USER_BOARD + + + ../common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained + ../common/services/usb/class/vendor/device/example + ../src/ASF/common/services/usb/udc + ../src/ASF/xmega/drivers/nvm + ../src/ASF/common/services/sleepmgr + ../src/ASF/common/services/clock + ../src/ASF/xmega/drivers/sleep + ../src/ASF/xmega/drivers/usb + ../src/ASF/xmega/drivers/cpu + ../src/ASF/common/services/usb/class/vendor + ../src/ASF/common/services/usb/class/vendor/device + ../src/ASF/common/services/usb + ../common/applications/user_application/user_board/config + ../src/ASF/xmega/utils + ../src/config + ../src/ASF/common/boards + ../src/ASF/xmega/utils/preprocessor + ../src/ASF/common/utils + ../src + ../src/ASF/common/boards/user_board + ../src/ASF/common/services/ioport + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.39\include + + + + + + + + + -mmcu=atxmega32a4u -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.39\gcc\dev\atxmega32a4u" + True + True + True + True + True + False + + + DEBUG + BOARD=USER_BOARD + + + + + ../common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained + ../common/services/usb/class/vendor/device/example + ../src/ASF/common/services/usb/udc + ../src/ASF/xmega/drivers/nvm + ../src/ASF/common/services/sleepmgr + ../src/ASF/common/services/clock + ../src/ASF/xmega/drivers/sleep + ../src/ASF/xmega/drivers/usb + ../src/ASF/xmega/drivers/cpu + ../src/ASF/common/services/usb/class/vendor + ../src/ASF/common/services/usb/class/vendor/device + ../src/ASF/common/services/usb + ../common/applications/user_application/user_board/config + ../src/ASF/xmega/utils + ../src/config + ../src/ASF/common/boards + ../src/ASF/xmega/utils/preprocessor + ../src/ASF/common/utils + ../src + ../src/ASF/common/boards/user_board + ../src/ASF/common/services/ioport + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.39\include + + + Optimize (-O1) + -fdata-sections + True + True + Maximum (-g3) + True + -std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax + + + libm + + + -Wl,--relax + -mrelax -DBOARD=USER_BOARD + + + ../common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained + ../common/services/usb/class/vendor/device/example + ../src/ASF/common/services/usb/udc + ../src/ASF/xmega/drivers/nvm + ../src/ASF/common/services/sleepmgr + ../src/ASF/common/services/clock + ../src/ASF/xmega/drivers/sleep + ../src/ASF/xmega/drivers/usb + ../src/ASF/xmega/drivers/cpu + ../src/ASF/common/services/usb/class/vendor + ../src/ASF/common/services/usb/class/vendor/device + ../src/ASF/common/services/usb + ../common/applications/user_application/user_board/config + ../src/ASF/xmega/utils + ../src/config + ../src/ASF/common/boards + ../src/ASF/xmega/utils/preprocessor + ../src/ASF/common/utils + ../src + ../src/ASF/common/boards/user_board + ../src/ASF/common/services/ioport + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.39\include + + + Default (-Wa,-g) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + + \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/USB_BULK_TEST.cproj.REMOVED.git-id b/AVR Code/USB_BULK_TEST/USB_BULK_TEST.cproj.REMOVED.git-id deleted file mode 100644 index 5f4fdb37..00000000 --- a/AVR Code/USB_BULK_TEST/USB_BULK_TEST.cproj.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7f53efbdce024f6fdff72d3aab71b56e7ac9f5df \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/USB_BULK_TEST_6_2.cproj.REMOVED.git-id b/AVR Code/USB_BULK_TEST/USB_BULK_TEST_6_2.cproj.REMOVED.git-id deleted file mode 100644 index ff4ec4a9..00000000 --- a/AVR Code/USB_BULK_TEST/USB_BULK_TEST_6_2.cproj.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -66ffcb4ccf5a4f2e63134282d64a4e2da1d0a35e \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/boards/board.h b/AVR Code/USB_BULK_TEST/src/ASF/common/boards/board.h new file mode 100644 index 00000000..63d76ae9 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/boards/board.h @@ -0,0 +1,398 @@ +/** + * \file + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/** + * \defgroup group_common_boards Generic board support + * + * The generic board support module includes board-specific definitions + * and function prototypes, such as the board initialization function. + * + * \{ + */ + +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! \name Base Boards + */ +//! @{ +#define EVK1100 1 //!< AT32UC3A EVK1100 board. +#define EVK1101 2 //!< AT32UC3B EVK1101 board. +#define UC3C_EK 3 //!< AT32UC3C UC3C-EK board. +#define EVK1104 4 //!< AT32UC3A3 EVK1104 board. +#define EVK1105 5 //!< AT32UC3A EVK1105 board. +#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board. +#define UC3L_EK 7 //!< AT32UC3L-EK board. +#define XPLAIN 8 //!< ATxmega128A1 Xplain board. +#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board. +#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board. +#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board. +#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board. +#define STK600_RCUC3D 16 //!< STK600 RCUC3D board. +#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board. +#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board. +#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board. +#define XMEGA_A1U_XPLAINED_PRO 20 //!< ATxmega128A1U XMEGA-A1U Xplained Pro board. +#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board. +#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board. +#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board. +#define STK600_RC044X 24 //!< STK600 with RC044X routing card board. +#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board. +#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board. +#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board. +#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board. +#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board. +#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards. +#define RZ600 31 //!< AT32UC3A RZ600 MCU board. +#define SAM3S_EK 32 //!< SAM3S-EK board. +#define SAM3U_EK 33 //!< SAM3U-EK board. +#define SAM3X_EK 34 //!< SAM3X-EK board. +#define SAM3N_EK 35 //!< SAM3N-EK board. +#define SAM3S_EK2 36 //!< SAM3S-EK2 board. +#define SAM4S_EK 37 //!< SAM4S-EK board. +#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board. +#define STK600_MEGA 39 //!< STK600 MEGA board. +#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board. +#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board. +#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board. +#define ARDUINO_DUE_X 43 //!< Arduino Due/X board. +#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board. +#define SAM4L_EK 45 //!< SAM4L-EK board. +#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board. +#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board. +#define STK600_RC032X 48 //!< STK600 with RC032X routing card board. +#define SAM4S_EK2 49 //!< SAM4S-EK2 board. +#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board. +#define SAM4E_EK 51 //!< SAM4E-EK board. +#define ATMEGA256RFR2_XPLAINED_PRO 52 //!< ATmega256RFR2 Xplained Pro board. +#define SAM4S_XPLAINED_PRO 53 //!< SAM4S Xplained Pro board. +#define SAM4L_XPLAINED_PRO 54 //!< SAM4L Xplained Pro board. +#define ATMEGA256RFR2_ZIGBIT 55 //!< ATmega256RFR2 zigbit. +#define XMEGA_RF233_ZIGBIT 56 //!< ATxmega256A3U with AT86RF233 Zigbit. +#define XMEGA_RF212B_ZIGBIT 57 //!< ATxmega256A3U with AT86RF212B Zigbit. +#define SAM4S_WPIR_RD 58 //!< SAM4S-WPIR-RD board. +#define SAMD20_XPLAINED_PRO 59 //!< SAM D20 Xplained Pro board. +#define SAM4L8_XPLAINED_PRO 60 //!< SAM4L8 Xplained Pro board. +#define SAM4N_XPLAINED_PRO 61 //!< SAM4N Xplained Pro board. +#define XMEGA_A3_REB_CBB 62 //!< XMEGA REB Controller Base board. +#define ATMEGARFX_RCB 63 //!< RFR2 & RFA1 RCB. +#define SAM4C_EK 64 //!< SAM4C-EK board. +#define RCB256RFR2_XPRO 65 //!< RFR2 RCB Xplained Pro board. +#define SAMG53_XPLAINED_PRO 66 //!< SAMG53 Xplained Pro board. +#define SAM4CP16BMB 67 //!< SAM4CP16BMB board. +#define SAM4E_XPLAINED_PRO 68 //!< SAM4E Xplained Pro board. +#define SAMD21_XPLAINED_PRO 69 //!< SAM D21 Xplained Pro board. +#define SAMR21_XPLAINED_PRO 70 //!< SAM R21 Xplained Pro board. +#define SAM4CMP_DB 71 //!< SAM4CMP demo board. +#define SAM4CMS_DB 72 //!< SAM4CMS demo board. +#define ATPL230AMB 73 //!< ATPL230AMB board. +#define SAMD11_XPLAINED_PRO 74 //!< SAM D11 Xplained Pro board. +#define SAMG55_XPLAINED_PRO 75 //!< SAMG55 Xplained Pro board. +#define SAML21_XPLAINED_PRO 76 //!< SAM L21 Xplained Pro board. +#define SAMD10_XPLAINED_MINI 77 //!< SAM D10 Xplained Mini board. +#define SAMW25_XPLAINED_PRO 79 //!< SAMW25 Xplained Pro board. +#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices. +#define AVR_SIMULATOR_UC3 98 //!< Simulator for the AVR UC3 device family. +#define USER_BOARD 99 //!< User-reserved board (if any). +#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader). +//! @} + +/*! \name Extension Boards + */ +//! @{ +#define EXT1102 1 //!< AT32UC3B EXT1102 board +#define MC300 2 //!< AT32UC3 MC300 board +#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1 +#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2 +#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board +#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board +#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A" +#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF230B 9 //!< AT86RF230B RF board in RZ600 +#define RZ600_AT86RF212 10 //!< AT86RF212 RF board in RZ600 +#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard +#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board +#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any). +//! @} + +#if BOARD == EVK1100 +# include "evk1100/evk1100.h" +#elif BOARD == EVK1101 +# include "evk1101/evk1101.h" +#elif BOARD == UC3C_EK +# include "uc3c_ek/uc3c_ek.h" +#elif BOARD == EVK1104 +# include "evk1104/evk1104.h" +#elif BOARD == EVK1105 +# include "evk1105/evk1105.h" +#elif BOARD == STK600_RCUC3L0 +# include "stk600/rcuc3l0/stk600_rcuc3l0.h" +#elif BOARD == UC3L_EK +# include "uc3l_ek/uc3l_ek.h" +#elif BOARD == STK600_RCUC3L4 +# include "stk600/rcuc3l4/stk600_rcuc3l4.h" +#elif BOARD == XPLAIN +# include "xplain/xplain.h" +#elif BOARD == STK600_MEGA + /*No header-file to include*/ +#elif BOARD == STK600_MEGA_RF +# include "stk600.h" +#elif BOARD == ATMEGA256RFR2_XPLAINED_PRO +# include "atmega256rfr2_xplained_pro/atmega256rfr2_xplained_pro.h" +#elif BOARD == ATMEGA256RFR2_ZIGBIT +# include "atmega256rfr2_zigbit/atmega256rfr2_zigbit.h" +#elif BOARD == STK600_RC032X +# include "stk600/rc032x/stk600_rc032x.h" +#elif BOARD == STK600_RC044X +# include "stk600/rc044x/stk600_rc044x.h" +#elif BOARD == STK600_RC064X +# include "stk600/rc064x/stk600_rc064x.h" +#elif BOARD == STK600_RC100X +# include "stk600/rc100x/stk600_rc100x.h" +#elif BOARD == UC3_A3_XPLAINED +# include "uc3_a3_xplained/uc3_a3_xplained.h" +#elif BOARD == UC3_L0_XPLAINED +# include "uc3_l0_xplained/uc3_l0_xplained.h" +#elif BOARD == STK600_RCUC3B0 +# include "stk600/rcuc3b0/stk600_rcuc3b0.h" +#elif BOARD == STK600_RCUC3D +# include "stk600/rcuc3d/stk600_rcuc3d.h" +#elif BOARD == STK600_RCUC3C0 +# include "stk600/rcuc3c0/stk600_rcuc3c0.h" +#elif BOARD == SAMG53_XPLAINED_PRO +# include "samg53_xplained_pro/samg53_xplained_pro.h" +#elif BOARD == SAMG55_XPLAINED_PRO +# include "samg55_xplained_pro/samg55_xplained_pro.h" +#elif BOARD == XMEGA_B1_XPLAINED +# include "xmega_b1_xplained/xmega_b1_xplained.h" +#elif BOARD == STK600_RC064X_LCDX +# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h" +#elif BOARD == STK600_RC100X_LCDX +# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h" +#elif BOARD == XMEGA_A1_XPLAINED +# include "xmega_a1_xplained/xmega_a1_xplained.h" +#elif BOARD == XMEGA_A1U_XPLAINED_PRO +# include "xmega_a1u_xplained_pro/xmega_a1u_xplained_pro.h" +#elif BOARD == UC3_L0_XPLAINED_BC +# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h" +#elif BOARD == SAM3S_EK +# include "sam3s_ek/sam3s_ek.h" +# include "system_sam3s.h" +#elif BOARD == SAM3S_EK2 +# include "sam3s_ek2/sam3s_ek2.h" +# include "system_sam3sd8.h" +#elif BOARD == SAM3U_EK +# include "sam3u_ek/sam3u_ek.h" +# include "system_sam3u.h" +#elif BOARD == SAM3X_EK +# include "sam3x_ek/sam3x_ek.h" +# include "system_sam3x.h" +#elif BOARD == SAM3N_EK +# include "sam3n_ek/sam3n_ek.h" +# include "system_sam3n.h" +#elif BOARD == SAM4S_EK +# include "sam4s_ek/sam4s_ek.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_WPIR_RD +# include "sam4s_wpir_rd/sam4s_wpir_rd.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_XPLAINED +# include "sam4s_xplained/sam4s_xplained.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_EK2 +# include "sam4s_ek2/sam4s_ek2.h" +# include "system_sam4s.h" +#elif BOARD == MEGA_1284P_XPLAINED + /*No header-file to include*/ +#elif BOARD == ARDUINO_DUE_X +# include "arduino_due_x/arduino_due_x.h" +# include "system_sam3x.h" +#elif BOARD == SAM4L_EK +# include "sam4l_ek/sam4l_ek.h" +#elif BOARD == SAM4E_EK +# include "sam4e_ek/sam4e_ek.h" +#elif BOARD == SAMD20_XPLAINED_PRO +# include "samd20_xplained_pro/samd20_xplained_pro.h" +#elif BOARD == SAMD21_XPLAINED_PRO +# include "samd21_xplained_pro/samd21_xplained_pro.h" +#elif BOARD == SAMR21_XPLAINED_PRO +# include "samr21_xplained_pro/samr21_xplained_pro.h" +#elif BOARD == SAMD11_XPLAINED_PRO +# include "samd11_xplained_pro/samd11_xplained_pro.h" +#elif BOARD == SAML21_XPLAINED_PRO +# include "saml21_xplained_pro/saml21_xplained_pro.h" +#elif BOARD == SAMD10_XPLAINED_MINI +# include "samd10_xplained_mini/samd10_xplained_mini.h" +#elif BOARD == SAM4N_XPLAINED_PRO +# include "sam4n_xplained_pro/sam4n_xplained_pro.h" +#elif BOARD == SAMW25_XPLAINED_PRO +# include "samw25_xplained_pro/samw25_xplained_pro.h" +#elif BOARD == MEGA1284P_XPLAINED_BC +# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h" +#elif BOARD == UC3_L0_QT600 +# include "uc3_l0_qt600/uc3_l0_qt600.h" +#elif BOARD == XMEGA_A3BU_XPLAINED +# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h" +#elif BOARD == XMEGA_E5_XPLAINED +# include "xmega_e5_xplained/xmega_e5_xplained.h" +#elif BOARD == UC3B_BOARD_CONTROLLER +# include "uc3b_board_controller/uc3b_board_controller.h" +#elif BOARD == RZ600 +# include "rz600/rz600.h" +#elif BOARD == STK600_RCUC3A0 +# include "stk600/rcuc3a0/stk600_rcuc3a0.h" +#elif BOARD == ATXMEGA128A1_QT600 +# include "atxmega128a1_qt600/atxmega128a1_qt600.h" +#elif BOARD == STK600_RCUC3L3 +# include "stk600/rcuc3l3/stk600_rcuc3l3.h" +#elif BOARD == SAM4S_XPLAINED_PRO +# include "sam4s_xplained_pro/sam4s_xplained_pro.h" +#elif BOARD == SAM4L_XPLAINED_PRO +# include "sam4l_xplained_pro/sam4l_xplained_pro.h" +#elif BOARD == SAM4L8_XPLAINED_PRO +# include "sam4l8_xplained_pro/sam4l8_xplained_pro.h" +#elif BOARD == SAM4C_EK +# include "sam4c_ek/sam4c_ek.h" +#elif BOARD == SAM4CMP_DB +# include "sam4cmp_db/sam4cmp_db.h" +#elif BOARD == SAM4CMS_DB +# include "sam4cms_db/sam4cms_db.h" +#elif BOARD == SAM4CP16BMB +# include "sam4cp16bmb/sam4cp16bmb.h" +#elif BOARD == ATPL230AMB +# include "atpl230amb/atpl230amb.h" +#elif BOARD == SIMULATOR_XMEGA_A1 +# include "simulator/xmega_a1/simulator_xmega_a1.h" +#elif BOARD == XMEGA_C3_XPLAINED +# include "xmega_c3_xplained/xmega_c3_xplained.h" +#elif BOARD == XMEGA_RF233_ZIGBIT +# include "xmega_rf233_zigbit/xmega_rf233_zigbit.h" +#elif BOARD == XMEGA_A3_REB_CBB +# include "xmega_a3_reb_cbb/xmega_a3_reb_cbb.h" +#elif BOARD == ATMEGARFX_RCB +# include "atmegarfx_rcb/atmegarfx_rcb.h" +#elif BOARD == RCB256RFR2_XPRO +# include "atmega256rfr2_rcb_xpro/atmega256rfr2_rcb_xpro.h" +#elif BOARD == XMEGA_RF212B_ZIGBIT +# include "xmega_rf212b_zigbit/xmega_rf212b_zigbit.h" +#elif BOARD == SAM4E_XPLAINED_PRO +# include "sam4e_xplained_pro/sam4e_xplained_pro.h" +#elif BOARD == AVR_SIMULATOR_UC3 +# include "avr_simulator_uc3/avr_simulator_uc3.h" +#elif BOARD == USER_BOARD + // User-reserved area: #include the header file of your board here (if any). +# include "user_board.h" +#elif BOARD == DUMMY_BOARD +# include "dummy/dummy_board.h" +#else +# error No known Atmel board defined +#endif + +#if (defined EXT_BOARD) +# if EXT_BOARD == MC300 +# include "mc300/mc300.h" +# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \ + (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD) +# include "sensors_xplained/sensors_xplained.h" +# elif EXT_BOARD == RZ600_AT86RF231 +# include "at86rf231/at86rf231.h" +# elif EXT_BOARD == RZ600_AT86RF230B +# include "at86rf230b/at86rf230b.h" +# elif EXT_BOARD == RZ600_AT86RF212 +# include "at86rf212/at86rf212.h" +# elif EXT_BOARD == SECURITY_XPLAINED +# include "security_xplained.h" +# elif EXT_BOARD == USER_EXT_BOARD + // User-reserved area: #include the header file of your extension board here + // (if any). +# endif +#endif + + +#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); + +#endif // #ifdef __AVR32_ABI_COMPILER__ +#else +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * \} + */ + +#endif // _BOARD_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/boards/board.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/boards/board.h.REMOVED.git-id deleted file mode 100644 index aaab3c0a..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/boards/board.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -63d76ae9f8ad6b36a18af2d915996af68ca6c094 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/boards/user_board/init.c b/AVR Code/USB_BULK_TEST/src/ASF/common/boards/user_board/init.c new file mode 100644 index 00000000..32fba369 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/boards/user_board/init.c @@ -0,0 +1,21 @@ +/** + * \file + * + * \brief User board initialization template + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include +#include +#include + +void board_init(void) +{ + /* This function is meant to contain board-specific initialization code + * for, e.g., the I/O pins. The initialization can rely on application- + * specific board configuration, found in conf_board.h. + */ +} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/boards/user_board/init.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/boards/user_board/init.c.REMOVED.git-id deleted file mode 100644 index bddbbdfa..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/boards/user_board/init.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -32fba3695e759c0557b46daf5a77a051f57b20cc \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/boards/user_board/user_board.h b/AVR Code/USB_BULK_TEST/src/ASF/common/boards/user_board/user_board.h new file mode 100644 index 00000000..39980a7d --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/boards/user_board/user_board.h @@ -0,0 +1,40 @@ +/** + * \file + * + * \brief User board definition template + * + */ + + /* This file is intended to contain definitions and configuration details for + * features and devices that are available on the board, e.g., frequency and + * startup time for an external crystal, external memory devices, LED and USART + * pins. + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef USER_BOARD_H +#define USER_BOARD_H + +#include + +// External oscillator settings. +// Uncomment and set correct values if external oscillator is used. + +// External oscillator frequency +//#define BOARD_XOSC_HZ 8000000 + +// External oscillator type. +//!< External clock signal +//#define BOARD_XOSC_TYPE XOSC_TYPE_EXTERNAL +//!< 32.768 kHz resonator on TOSC +//#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ +//!< 0.4 to 16 MHz resonator on XTALS +//#define BOARD_XOSC_TYPE XOSC_TYPE_XTAL + +// External oscillator startup time +//#define BOARD_XOSC_STARTUP_US 500000 + + +#endif // USER_BOARD_H diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/boards/user_board/user_board.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/boards/user_board/user_board.h.REMOVED.git-id deleted file mode 100644 index a605e78a..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/boards/user_board/user_board.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -39980a7d2e46bb1a0c9e0a93930f392bd83c5677 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/components/display/st7565r/st7565r.c b/AVR Code/USB_BULK_TEST/src/ASF/common/components/display/st7565r/st7565r.c new file mode 100644 index 00000000..cb51cfb8 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/components/display/st7565r/st7565r.c @@ -0,0 +1,125 @@ +/** + * \file + * + * \brief ST7565R display controller driver. + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#include "st7565r.h" + +/** + * \internal + * \brief Initialize the hardware interface + * + * Depending on what interface used for interfacing the LCD controller this + * function will initialize the necessary hardware. + */ +static void st7565r_interface_init(void) +{ +#ifdef ST7565R_SERIAL_INTERFACE + spi_flags_t spi_flags = SPI_MODE_3; + board_spi_select_id_t spi_select_id = 0; +#endif + +#if defined(ST7565R_USART_SPI_INTERFACE) + struct usart_spi_device device = { + .id = ST7565R_CS_PIN, + }; + usart_spi_init(ST7565R_USART_SPI); + usart_spi_setup_device(ST7565R_USART_SPI, &device, spi_flags, + ST7565R_CLOCK_SPEED, spi_select_id); +#elif defined(ST7565R_SPI_INTERFACE) + struct spi_device device = { + .id = ST7565R_CS_PIN, + }; + spi_master_init(ST7565R_SPI); + spi_master_setup_device(ST7565R_SPI, &device, spi_flags, + ST7565R_CLOCK_SPEED, spi_select_id); +#endif +} + +/** + * \brief Initialize the LCD controller + * + * Call this function to initialize the hardware interface and the LCD + * controller. When initialization is done the display is turned on and ready + * to receive data. + */ +void st7565r_init(void) +{ + // Do a hard reset of the LCD display controller + st7565r_hard_reset(); + + // Initialize the interface + st7565r_interface_init(); + + // Set the A0 pin to the default state (command) + ioport_set_pin_low(ST7565R_A0_PIN); + + // The column address is set to increasing + st7565r_write_command(ST7565R_CMD_ADC_NORMAL); + + // Non-inverted display + st7565r_display_invert_disable(); + + // The common mode scan direction is reversed COM31->COM0 + st7565r_write_command(ST7565R_CMD_REVERSE_SCAN_DIRECTION); + + // Set the voltage bias ratio to 1/6 + st7565r_write_command(ST7565R_CMD_LCD_BIAS_1_DIV_6_DUTY33); + + // Set booster circuit, voltage regulator and voltage follower all to on + st7565r_write_command(ST7565R_CMD_POWER_CTRL_ALL_ON); + + // Set the booster ratio to 2X,3X,4X + st7565r_write_command(ST7565R_CMD_BOOSTER_RATIO_SET); + st7565r_write_command(ST7565R_CMD_BOOSTER_RATIO_2X_3X_4X); + + // Set voltage resistor ratio to 1 + st7565r_write_command(ST7565R_CMD_VOLTAGE_RESISTOR_RATIO_1); + + /* Set contrast to min value, no need to check return value as the contrast + is set to the defined min*/ + st7565r_set_contrast(ST7565R_DISPLAY_CONTRAST_MIN); + + // Turn on the display + st7565r_display_on(); +} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/components/display/st7565r/st7565r.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/components/display/st7565r/st7565r.c.REMOVED.git-id deleted file mode 100644 index 0e1ab871..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/components/display/st7565r/st7565r.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cb51cfb8d9d84ce3e4eea63f12065af87db702a4 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/components/display/st7565r/st7565r.h b/AVR Code/USB_BULK_TEST/src/ASF/common/components/display/st7565r/st7565r.h new file mode 100644 index 00000000..436d354a --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/components/display/st7565r/st7565r.h @@ -0,0 +1,463 @@ +/** + * \file + * + * \brief ST7565R display controller driver. + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef ST7565R_H_INCLUDED +#define ST7565R_H_INCLUDED + +#include +#include +#include +#include +#include + +// controller and LCD configuration file +#include "conf_st7565r.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup st7565r_lcd_controller_group ST7565R LCD Controller Low-level\ + * driver + * + * This is a low level driver for the ST7565R LCD controller. It provides basic + * functions for initializing and writing to the LCD controller. In addition to + * hardware control and use of the LCD controller internal functions . + * + * Before writing data to the display call \ref st7565r_init() which will set up + * the physical interface and the LCD. A file named \ref conf_st7565r.h is needed + * to define which interface to use. For more information see the Interface + * selection section. In addition one also need to define the pins + * \ref ST7565R_A0_PIN, \ref ST7565R_CS_PIN and \ref ST7565R_RESET_PIN and the + * display \ref ST7565R_CLOCK_SPEED. + * + * \warning This driver is not reentrant and can not be used in interrupt\ + * service routines without extra care. + * + * As a safety feature one also need to set the max and min contrast levels that + * the \ref st7565r_set_contrast using the defines + * \ref ST7565R_DISPLAY_CONTRAST_MAX and \ref ST7565R_DISPLAY_CONTRAST_MIN to + * protect the display from too high voltage, please see the + * \ref st7565r_set_contrast function for more details. + * + * An example \ref conf_st7565r.h file could look like + * \code + // interface selection + #define ST7565R_USART_SPI_INTERFACE + #define ST7565R_USART_SPI &USARTD0 + + // minimum clock period is 50ns@3.3V -> max frequency is 20MHz + #define ST7565R_CLOCK_SPEED 1000000 + + #define ST7565R_DISPLAY_CONTRAST_MAX 40 + #define ST7565R_DISPLAY_CONTRAST_MIN 30 + + #define ST7565R_A0_PIN NHD_C12832A1Z_REGISTER_SELECT + #define ST7565R_CS_PIN NHD_C12832A1Z_CSN + #define ST7565R_RESET_PIN NHD_C12832A1Z_RESETN +\endcode + * + * \section dependencies Dependencies + * This driver depends on the following modules: + * - \ref ioport_group for IO port control. + * - \ref sysclk_group for getting system clock speeds for init functions. + * - \ref usart_spi_group or \ref spi_group for communication with the LCD + * controller + * @{ + */ + +//! \name Command defines +//@{ +#define ST7565R_CMD_DISPLAY_ON 0xAF +#define ST7565R_CMD_DISPLAY_OFF 0xAE +#define ST7565R_CMD_START_LINE_SET(line) (0x40 | (line)) +#define ST7565R_CMD_PAGE_ADDRESS_SET(page) (0xB0 | (page)) +#define ST7565R_CMD_COLUMN_ADDRESS_SET_MSB(column) (0x10 | (column)) +#define ST7565R_CMD_COLUMN_ADDRESS_SET_LSB(column) (0x00 | (column)) +#define ST7565R_CMD_ADC_NORMAL 0xA0 +#define ST7565R_CMD_ADC_REVERSE 0xA1 +#define ST7565R_CMD_DISPLAY_NORMAL 0xA6 +#define ST7565R_CMD_DISPLAY_REVERSE 0xA7 +#define ST7565R_CMD_DISPLAY_ALL_POINTS_OFF 0xA4 +#define ST7565R_CMD_DISPLAY_ALL_POINTS_ON 0xA5 +#define ST7565R_CMD_LCD_BIAS_1_DIV_5_DUTY33 0xA1 +#define ST7565R_CMD_LCD_BIAS_1_DIV_6_DUTY33 0xA2 +#define ST7565R_CMD_NORMAL_SCAN_DIRECTION 0xC0 +#define ST7565R_CMD_REVERSE_SCAN_DIRECTION 0xC8 +#define ST7565R_CMD_VOLTAGE_RESISTOR_RATIO_0 0x20 +#define ST7565R_CMD_VOLTAGE_RESISTOR_RATIO_1 0x21 +#define ST7565R_CMD_VOLTAGE_RESISTOR_RATIO_2 0x22 +#define ST7565R_CMD_VOLTAGE_RESISTOR_RATIO_3 0x23 +#define ST7565R_CMD_VOLTAGE_RESISTOR_RATIO_4 0x24 +#define ST7565R_CMD_VOLTAGE_RESISTOR_RATIO_5 0x25 +#define ST7565R_CMD_VOLTAGE_RESISTOR_RATIO_6 0x26 +#define ST7565R_CMD_VOLTAGE_RESISTOR_RATIO_7 0x27 +#define ST7565R_CMD_POWER_CTRL_ALL_ON 0x2F +#define ST7565R_CMD_SLEEP_MODE 0xAC +#define ST7565R_CMD_NORMAL_MODE 0xAD +#define ST7565R_CMD_RESET 0xE2 +#define ST7565R_CMD_NOP 0xE3 +#define ST7565R_CMD_ELECTRONIC_VOLUME_MODE_SET 0x81 +#define ST7565R_CMD_ELECTRONIC_VOLUME(volume) (0x3F & (~volume)) +#define ST7565R_CMD_BOOSTER_RATIO_SET 0xF8 +#define ST7565R_CMD_BOOSTER_RATIO_2X_3X_4X 0x00 +#define ST7565R_CMD_BOOSTER_RATIO_5X 0x01 +#define ST7565R_CMD_BOOSTER_RATIO_6X 0x03 +#define ST7565R_CMD_STATUS_READ 0x00 +#define ST7565R_CMD_END 0xEE +#define ST7565R_CMD_READ_MODIFY_WRITE 0xE0 +//@} + +/** + * \name Interface selection + * + * The LCD controller support both serial and parallel mode, that means there + * is a number of possible ways of interfacing the controller using different + * AVR peripherals. The different interfaces can be selected using different + * defines. This driver supports the serial communication mode using an + * USART in Master SPI mode by defining \ref ST7565R_USART_SPI_INTERFACE, and a + * normal SPI in Master Mode by defining \ref ST7565R_SPI_INTERFACE. + * + * \note The current driver only support serial mode. + */ +//@{ +#if defined(__DOXYGEN__) +//! \brief Select the a USART SPI interface. +# define ST7565R_USART_SPI_INTERFACE +//! \brief Select the normal SPI peripheral interface. +# define ST7565R_SPI_INTERFACE +#endif + +#if defined(ST7565R_USART_SPI_INTERFACE) +# include +#elif defined(ST7565R_SPI_INTERFACE) +# include +#else +#error "Interface not supported by the driver" +#endif +//@} + +#if defined(ST7565R_USART_SPI_INTERFACE) || defined(ST7565R_SPI_INTERFACE) +// +# define ST7565R_SERIAL_INTERFACE +#endif + +//! \name LCD controller write and read functions +//@{ +/** + * \brief Writes a command to the display controller + * + * This functions pull pin A0 low before writing to the controller. Different + * data write function is called based on the selected interface. + * + * \param command the command to write + */ +static inline void st7565r_write_command(uint8_t command) +{ +#if defined(ST7565R_USART_SPI_INTERFACE) + struct usart_spi_device device = {.id = ST7565R_CS_PIN}; + usart_spi_select_device(ST7565R_USART_SPI, &device); + ioport_set_pin_low(ST7565R_A0_PIN); + usart_spi_transmit(ST7565R_USART_SPI, command); + usart_spi_deselect_device(ST7565R_USART_SPI, &device); +#elif defined(ST7565R_SPI_INTERFACE) + struct spi_device device = {.id = ST7565R_CS_PIN}; + spi_select_device(ST7565R_SPI, &device); + ioport_set_pin_low(ST7565R_A0_PIN); + spi_write_single(ST7565R_SPI, command); + spi_deselect_device(ST7565R_SPI, &device); +#endif +} + +/** + * \brief Write data to the display controller + * + * This functions sets the pin A0 before writing to the controller. Different + * data write function is called based on the selected interface. + * + * \param data the data to write + */ +static inline void st7565r_write_data(uint8_t data) +{ +#if defined(ST7565R_USART_SPI_INTERFACE) + struct usart_spi_device device = {.id = ST7565R_CS_PIN}; + usart_spi_select_device(ST7565R_USART_SPI, &device); + ioport_set_pin_high(ST7565R_A0_PIN); + usart_spi_transmit(ST7565R_USART_SPI, data); + ioport_set_pin_low(ST7565R_A0_PIN); + usart_spi_deselect_device(ST7565R_USART_SPI, &device); +#elif defined(ST7565R_SPI_INTERFACE) + struct spi_device device = {.id = ST7565R_CS_PIN}; + spi_select_device(ST7565R_SPI, &device); + ioport_set_pin_high(ST7565R_A0_PIN); + spi_write_single(ST7565R_SPI, data); + ioport_set_pin_low(ST7565R_A0_PIN); + spi_deselect_device(ST7565R_SPI, &device); +#endif +} + +/** + * \brief Read data from the controller + * + * \note The controller does not support read in serial mode. + * + * \retval 8 bit data read from the controller + */ +static inline uint8_t st7565r_read_data(void) +{ + return 0; +} + +/** + * \brief Read status from the controller + * + * \note The controller does not support read in serial mode. + * + * \retval 8 bit status read from the controller + */ +static inline uint8_t st7565r_get_status(void) +{ + return 0; +} +//@} + +//! \name LCD Controller reset +//@{ +/** + * \brief Perform a soft reset of the LCD controller + * + * This functions will reset the LCD controller by sending the reset command. + * \note this functions should not be confused with the \ref st7565r_hard_reset() + * function, this command will not control the RST pin. + */ +static inline void st7565r_soft_reset(void) +{ + st7565r_write_command(ST7565R_CMD_RESET); +} + +/** + * \brief Perform a hard reset of the LCD controller + * + * This functions will reset the LCD controller by setting the reset pin low. + * \note this functions should not be confused with the \ref st7565r_soft_reset() + * function, this command will control the RST pin. + */ +static inline void st7565r_hard_reset(void) +{ + ioport_set_pin_low(ST7565R_RESET_PIN); + delay_us(10); + ioport_set_pin_high(ST7565R_RESET_PIN); + delay_us(10); +} +//@} + +//! \name Sleep control +//@{ +/** + * \brief Enable the LCD sleep mode + */ +static inline void st7565r_sleep_enable(void) +{ + st7565r_write_command(ST7565R_CMD_SLEEP_MODE); +} + +/** + * \brief Disable the LCD sleep mode + */ +static inline void st7565r_sleep_disable(void) +{ + st7565r_write_command(ST7565R_CMD_NORMAL_MODE); +} +//@} + +//! \name Address setup for the LCD +//@{ +/** + * \brief Set current page in display RAM + * + * This command is usually followed by the configuration of the column address + * because this scheme will provide access to all locations in the display + * RAM. + * + * \param address the page address + */ +static inline void st7565r_set_page_address(uint8_t address) +{ + // Make sure that the address is 4 bits (only 8 pages) + address &= 0x0F; + st7565r_write_command(ST7565R_CMD_PAGE_ADDRESS_SET(address)); +} + +/** + * \brief Set current column in display RAM + * + * \param address the column address + */ +static inline void st7565r_set_column_address(uint8_t address) +{ + // Make sure the address is 7 bits + address &= 0x7F; + st7565r_write_command(ST7565R_CMD_COLUMN_ADDRESS_SET_MSB(address >> 4)); + st7565r_write_command(ST7565R_CMD_COLUMN_ADDRESS_SET_LSB(address & 0x0F)); +} + +/** + * \brief Set the display start draw line address + * + * This function will set which line should be the start draw line for the LCD. + */ +static inline void st7565r_set_display_start_line_address(uint8_t address) +{ + // Make sure address is 6 bits + address &= 0x3F; + st7565r_write_command(ST7565R_CMD_START_LINE_SET(address)); +} +//@} + +//! \name Display hardware control +//@{ +/** + * \brief Turn the LCD display on + * + * This function will turn on the LCD. + */ +static inline void st7565r_display_on(void) +{ + st7565r_write_command(ST7565R_CMD_DISPLAY_ON); +} + +/** + * \brief Turn the LCD display off + * + * This function will turn off the LCD. + */ +static inline void st7565r_display_off(void) +{ + st7565r_write_command(ST7565R_CMD_DISPLAY_OFF); +} + +/** + * \brief Sets all LCD pixels on + * + * This function can be used to test the LCD by setting all pixels on, this will + * not affect the current LCD RAM. + * + * \param pixels_on if true all the LCD pixels are turned on, false the display + * is back in normal mode displaying what is in the display + * RAM. + */ +static inline void st7565r_set_all_pixels(bool pixels_on) +{ + if (pixels_on) { + st7565r_write_command(ST7565R_CMD_DISPLAY_ALL_POINTS_ON); + } else { + st7565r_write_command(ST7565R_CMD_DISPLAY_ALL_POINTS_OFF); + } +} + +/** + * \brief Set the LCD contrast level + * + * \warning This will set the voltage for the LCD, settings this value too high + * may result in damage to the LCD. Hence the limit for these settings must be + * defined in the \ref conf_st7565r.h file. + * + * Contrast values outside the max and min values will be clipped to the defined + * \ref ST7565R_DISPLAY_CONTRAST_MAX and \ref ST7565R_DISPLAY_CONTRAST_MIN. + * + * \param contrast a number between 0 and 63 where the max values is given by + * the LCD. + * + * \retval contrast the contrast value written to the LCD controller + */ +static inline uint8_t st7565r_set_contrast(uint8_t contrast) +{ + if (contrast < ST7565R_DISPLAY_CONTRAST_MIN) { + contrast = ST7565R_DISPLAY_CONTRAST_MIN; + } + if (contrast > ST7565R_DISPLAY_CONTRAST_MAX) { + contrast = ST7565R_DISPLAY_CONTRAST_MAX; + } + st7565r_write_command(ST7565R_CMD_ELECTRONIC_VOLUME_MODE_SET); + st7565r_write_command(ST7565R_CMD_ELECTRONIC_VOLUME(contrast)); + return contrast; +} + +/** + * \brief Invert all pixels on the device + * + * This function will invert all pixels on the LCD + * + */ +static inline void st7565r_display_invert_enable(void) +{ + st7565r_write_command(ST7565R_CMD_DISPLAY_REVERSE); +} + +/** + * \brief Disable invert of all pixels on the device + * + * This function will disable invert on all pixels on the LCD + * + */ +static inline void st7565r_display_invert_disable(void) +{ + st7565r_write_command(ST7565R_CMD_DISPLAY_NORMAL); +} +//@} + +//! \name Initialization +//@{ +void st7565r_init(void); +//@} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* ST7565R_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/components/display/st7565r/st7565r.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/components/display/st7565r/st7565r.h.REMOVED.git-id deleted file mode 100644 index 057974ae..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/components/display/st7565r/st7565r.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -436d354a6809406213467b7c79eaf4f7138f5e02 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/genclk.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/genclk.h new file mode 100644 index 00000000..f910d8bb --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/genclk.h @@ -0,0 +1,191 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef CLK_GENCLK_H_INCLUDED +#define CLK_GENCLK_H_INCLUDED + +#include "parts.h" + +#if SAM3S +# include "sam3s/genclk.h" +#elif SAM3U +# include "sam3u/genclk.h" +#elif SAM3N +# include "sam3n/genclk.h" +#elif SAM3XA +# include "sam3x/genclk.h" +#elif SAM4S +# include "sam4s/genclk.h" +#elif SAM4L +# include "sam4l/genclk.h" +#elif SAM4E +# include "sam4e/genclk.h" +#elif SAM4N +# include "sam4n/genclk.h" +#elif SAM4C +# include "sam4c/genclk.h" +#elif SAM4CM +# include "sam4cm/genclk.h" +#elif SAM4CP +# include "sam4cp/genclk.h" +#elif SAMG +# include "samg/genclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/genclk.h" +#elif UC3A3 +# include "uc3a3_a4/genclk.h" +#elif UC3B +# include "uc3b0_b1/genclk.h" +#elif UC3C +# include "uc3c/genclk.h" +#elif UC3D +# include "uc3d/genclk.h" +#elif UC3L +# include "uc3l/genclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup genclk_group Generic Clock Management + * + * Generic clocks are configurable clocks which run outside the system + * clock domain. They are often connected to peripherals which have an + * asynchronous component running independently of the bus clock, e.g. + * USB controllers, low-power timers and RTCs, etc. + * + * Note that not all platforms have support for generic clocks; on such + * platforms, this API will not be available. + * + * @{ + */ + +/** + * \def GENCLK_DIV_MAX + * \brief Maximum divider supported by the generic clock implementation + */ +/** + * \enum genclk_source + * \brief Generic clock source ID + * + * Each generic clock may be generated from a different clock source. + * These are the available alternatives provided by the chip. + */ + +//! \name Generic clock configuration +//@{ +/** + * \struct genclk_config + * \brief Hardware representation of a set of generic clock parameters + */ +/** + * \fn void genclk_config_defaults(struct genclk_config *cfg, + * unsigned int id) + * \brief Initialize \a cfg to the default configuration for the clock + * identified by \a id. + */ +/** + * \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id) + * \brief Read the currently active configuration of the clock + * identified by \a id into \a cfg. + */ +/** + * \fn void genclk_config_write(const struct genclk_config *cfg, + * unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id. + */ +/** + * \fn void genclk_config_set_source(struct genclk_config *cfg, + * enum genclk_source src) + * \brief Select a new source clock \a src in configuration \a cfg. + */ +/** + * \fn void genclk_config_set_divider(struct genclk_config *cfg, + * unsigned int divider) + * \brief Set a new \a divider in configuration \a cfg. + */ +/** + * \fn void genclk_enable_source(enum genclk_source src) + * \brief Enable the source clock \a src used by a generic clock. + */ + //@} + +//! \name Enabling and disabling Generic Clocks +//@{ +/** + * \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id and enable it. + */ +/** + * \fn void genclk_disable(unsigned int id) + * \brief Disable the generic clock identified by \a id. + */ +//@} + +/** + * \brief Enable the configuration defined by \a src and \a divider + * for the generic clock identified by \a id. + * + * \param id The ID of the generic clock. + * \param src The source clock of the generic clock. + * \param divider The divider used to generate the generic clock. + */ +static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider) +{ + struct genclk_config gcfg; + + genclk_config_defaults(&gcfg, id); + genclk_enable_source(src); + genclk_config_set_source(&gcfg, src); + genclk_config_set_divider(&gcfg, divider); + genclk_enable(&gcfg, id); +} + +//! @} + +#endif /* CLK_GENCLK_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/genclk.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/genclk.h.REMOVED.git-id deleted file mode 100644 index cb24b607..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/genclk.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f910d8bb324a902e904e49c5de6cea41d018bb34 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/osc.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/osc.h new file mode 100644 index 00000000..678f4200 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/osc.h @@ -0,0 +1,177 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef OSC_H_INCLUDED +#define OSC_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/osc.h" +#elif SAM3XA +# include "sam3x/osc.h" +#elif SAM3U +# include "sam3u/osc.h" +#elif SAM3N +# include "sam3n/osc.h" +#elif SAM4S +# include "sam4s/osc.h" +#elif SAM4E +# include "sam4e/osc.h" +#elif SAM4C +# include "sam4c/osc.h" +#elif SAM4CM +# include "sam4cm/osc.h" +#elif SAM4CP +# include "sam4cp/osc.h" +#elif SAM4L +# include "sam4l/osc.h" +#elif SAM4N +# include "sam4n/osc.h" +#elif SAMG +# include "samg/osc.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/osc.h" +#elif UC3A3 +# include "uc3a3_a4/osc.h" +#elif UC3B +# include "uc3b0_b1/osc.h" +#elif UC3C +# include "uc3c/osc.h" +#elif UC3D +# include "uc3d/osc.h" +#elif UC3L +# include "uc3l/osc.h" +#elif XMEGA +# include "xmega/osc.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup osc_group Oscillator Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip oscillators. Internal RC-oscillators, + * external crystal oscillators and external clock generators are + * supported by this module. What all of these have in common is that + * they swing at a fixed, nominal frequency which is normally not + * adjustable. + * + * \par Example: Enabling an oscillator + * + * The following example demonstrates how to enable the external + * oscillator on XMEGA A and wait for it to be ready to use. The + * oscillator identifiers are platform-specific, so while the same + * procedure is used on all platforms, the parameter to osc_enable() + * will be different from device to device. + * \code + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); \endcode + * + * \section osc_group_board Board-specific Definitions + * If external oscillators are used, the board code must provide the + * following definitions for each of those: + * - \b BOARD__HZ: The nominal frequency of the oscillator. + * - \b BOARD__STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD__TYPE: The type of oscillator connected, i.e. + * whether it's a crystal or external clock, and sometimes what kind + * of crystal it is. The meaning of this value is platform-specific. + * + * @{ + */ + +//! \name Oscillator Management +//@{ +/** + * \fn void osc_enable(uint8_t id) + * \brief Enable oscillator \a id + * + * The startup time and mode value is automatically determined based on + * definitions in the board code. + */ +/** + * \fn void osc_disable(uint8_t id) + * \brief Disable oscillator \a id + */ +/** + * \fn osc_is_ready(uint8_t id) + * \brief Determine whether oscillator \a id is ready. + * \retval true Oscillator \a id is running and ready to use as a clock + * source. + * \retval false Oscillator \a id is not running. + */ +/** + * \fn uint32_t osc_get_rate(uint8_t id) + * \brief Return the frequency of oscillator \a id in Hz + */ + +#ifndef __ASSEMBLY__ + +/** + * \brief Wait until the oscillator identified by \a id is ready + * + * This function will busy-wait for the oscillator identified by \a id + * to become stable and ready to use as a clock source. + * + * \param id A number identifying the oscillator to wait for. + */ +static inline void osc_wait_ready(uint8_t id) +{ + while (!osc_is_ready(id)) { + /* Do nothing */ + } +} + +#endif /* __ASSEMBLY__ */ + +//@} + +//! @} + +#endif /* OSC_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/osc.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/osc.h.REMOVED.git-id deleted file mode 100644 index a161affa..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/osc.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -678f4200c1d15181908876e0ac021d00958ad33f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/pll.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/pll.h new file mode 100644 index 00000000..ce88b96b --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/pll.h @@ -0,0 +1,333 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef CLK_PLL_H_INCLUDED +#define CLK_PLL_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/pll.h" +#elif SAM3XA +# include "sam3x/pll.h" +#elif SAM3U +# include "sam3u/pll.h" +#elif SAM3N +# include "sam3n/pll.h" +#elif SAM4S +# include "sam4s/pll.h" +#elif SAM4E +# include "sam4e/pll.h" +#elif SAM4C +# include "sam4c/pll.h" +#elif SAM4CM +# include "sam4cm/pll.h" +#elif SAM4CP +# include "sam4cp/pll.h" +#elif SAM4L +# include "sam4l/pll.h" +#elif SAM4N +# include "sam4n/pll.h" +#elif SAMG +# include "samg/pll.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/pll.h" +#elif UC3A3 +# include "uc3a3_a4/pll.h" +#elif UC3B +# include "uc3b0_b1/pll.h" +#elif UC3C +# include "uc3c/pll.h" +#elif UC3D +# include "uc3d/pll.h" +#elif (UC3L0128 || UC3L0256 || UC3L3_L4) +# include "uc3l/pll.h" +#elif XMEGA +# include "xmega/pll.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup pll_group PLL Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip PLLs. A PLL will take an input signal + * (the \em source), optionally divide the frequency by a configurable + * \em divider, and then multiply the frequency by a configurable \em + * multiplier. + * + * Some devices don't support input dividers; specifying any other + * divisor than 1 on these devices will result in an assertion failure. + * Other devices may have various restrictions to the frequency range of + * the input and output signals. + * + * \par Example: Setting up PLL0 with default parameters + * + * The following example shows how to configure and enable PLL0 using + * the default parameters specified using the configuration symbols + * listed above. + * \code + pll_enable_config_defaults(0); \endcode + * + * To configure, enable PLL0 using the default parameters and to disable + * a specific feature like Wide Bandwidth Mode (a UC3A3-specific + * PLL option.), you can use this initialization process. + * \code + struct pll_config pllcfg; + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); \endcode + * + * When the last function call returns, PLL0 is ready to be used as the + * main system clock source. + * + * \section pll_group_config Configuration Symbols + * + * Each PLL has a set of default parameters determined by the following + * configuration symbols in the application's configuration file: + * - \b CONFIG_PLLn_SOURCE: The default clock source connected to the + * input of PLL \a n. Must be one of the values defined by the + * #pll_source enum. + * - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL + * \a n. + * - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n. + * + * These configuration symbols determine the result of calling + * pll_config_defaults() and pll_get_default_rate(). + * + * @{ + */ + +//! \name Chip-specific PLL characteristics +//@{ +/** + * \def PLL_MAX_STARTUP_CYCLES + * \brief Maximum PLL startup time in number of slow clock cycles + */ +/** + * \def NR_PLLS + * \brief Number of on-chip PLLs + */ + +/** + * \def PLL_MIN_HZ + * \brief Minimum frequency that the PLL can generate + */ +/** + * \def PLL_MAX_HZ + * \brief Maximum frequency that the PLL can generate + */ +/** + * \def PLL_NR_OPTIONS + * \brief Number of PLL option bits + */ +//@} + +/** + * \enum pll_source + * \brief PLL clock source + */ + +//! \name PLL configuration +//@{ + +/** + * \struct pll_config + * \brief Hardware-specific representation of PLL configuration. + * + * This structure contains one or more device-specific values + * representing the current PLL configuration. The contents of this + * structure is typically different from platform to platform, and the + * user should not access any fields except through the PLL + * configuration API. + */ + +/** + * \fn void pll_config_init(struct pll_config *cfg, + * enum pll_source src, unsigned int div, unsigned int mul) + * \brief Initialize PLL configuration from standard parameters. + * + * \note This function may be defined inline because it is assumed to be + * called very few times, and usually with constant parameters. Inlining + * it will in such cases reduce the code size significantly. + * + * \param cfg The PLL configuration to be initialized. + * \param src The oscillator to be used as input to the PLL. + * \param div PLL input divider. + * \param mul PLL loop divider (i.e. multiplier). + * + * \return A configuration which will make the PLL run at + * (\a mul / \a div) times the frequency of \a src + */ +/** + * \def pll_config_defaults(cfg, pll_id) + * \brief Initialize PLL configuration using default parameters. + * + * After this function returns, \a cfg will contain a configuration + * which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV) + * times the frequency of CONFIG_PLLx_SOURCE. + * + * \param cfg The PLL configuration to be initialized. + * \param pll_id Use defaults for this PLL. + */ +/** + * \def pll_get_default_rate(pll_id) + * \brief Get the default rate in Hz of \a pll_id + */ +/** + * \fn void pll_config_set_option(struct pll_config *cfg, + * unsigned int option) + * \brief Set the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be set. + */ +/** + * \fn void pll_config_clear_option(struct pll_config *cfg, + * unsigned int option) + * \brief Clear the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be cleared. + */ +/** + * \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id) + * \brief Read the currently active configuration of \a pll_id. + * + * \param cfg The configuration object into which to store the currently + * active configuration. + * \param pll_id The ID of the PLL to be accessed. + */ +/** + * \fn void pll_config_write(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg on \a pll_id + * + * \param cfg The configuration object representing the PLL + * configuration to be activated. + * \param pll_id The ID of the PLL to be updated. + */ + +//@} + +//! \name Interaction with the PLL hardware +//@{ +/** + * \fn void pll_enable(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg and enable PLL \a pll_id. + * + * \param cfg The PLL configuration to be activated. + * \param pll_id The ID of the PLL to be enabled. + */ +/** + * \fn void pll_disable(unsigned int pll_id) + * \brief Disable the PLL identified by \a pll_id. + * + * After this function is called, the PLL identified by \a pll_id will + * be disabled. The PLL configuration stored in hardware may be affected + * by this, so if the caller needs to restore the same configuration + * later, it should either do a pll_config_read() before disabling the + * PLL, or remember the last configuration written to the PLL. + * + * \param pll_id The ID of the PLL to be disabled. + */ +/** + * \fn bool pll_is_locked(unsigned int pll_id) + * \brief Determine whether the PLL is locked or not. + * + * \param pll_id The ID of the PLL to check. + * + * \retval true The PLL is locked and ready to use as a clock source + * \retval false The PLL is not yet locked, or has not been enabled. + */ +/** + * \fn void pll_enable_source(enum pll_source src) + * \brief Enable the source of the pll. + * The source is enabled, if the source is not already running. + * + * \param src The ID of the PLL source to enable. + */ +/** + * \fn void pll_enable_config_defaults(unsigned int pll_id) + * \brief Enable the pll with the default configuration. + * PLL is enabled, if the PLL is not already locked. + * + * \param pll_id The ID of the PLL to enable. + */ + +/** + * \brief Wait for PLL \a pll_id to become locked + * + * \todo Use a timeout to avoid waiting forever and hanging the system + * + * \param pll_id The ID of the PLL to wait for. + * + * \retval STATUS_OK The PLL is now locked. + * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. + */ +static inline int pll_wait_for_lock(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + while (!pll_is_locked(pll_id)) { + /* Do nothing */ + } + + return 0; +} + +//@} +//! @} + +#endif /* CLK_PLL_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/pll.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/pll.h.REMOVED.git-id deleted file mode 100644 index 72b463a8..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/pll.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ce88b96b836306afe5a861940a491f55ebdb77b5 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/sysclk.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/sysclk.h new file mode 100644 index 00000000..cd9457b5 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/sysclk.h @@ -0,0 +1,186 @@ +/** + * \file + * + * \brief System clock management + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef SYSCLK_H_INCLUDED +#define SYSCLK_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/sysclk.h" +#elif SAM3U +# include "sam3u/sysclk.h" +#elif SAM3N +# include "sam3n/sysclk.h" +#elif SAM3XA +# include "sam3x/sysclk.h" +#elif SAM4S +# include "sam4s/sysclk.h" +#elif SAM4E +# include "sam4e/sysclk.h" +#elif SAM4C +# include "sam4c/sysclk.h" +#elif SAM4CM +# include "sam4cm/sysclk.h" +#elif SAM4CP +# include "sam4cp/sysclk.h" +#elif SAM4L +# include "sam4l/sysclk.h" +#elif SAM4N +# include "sam4n/sysclk.h" +#elif SAMG +# include "samg/sysclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/sysclk.h" +#elif UC3A3 +# include "uc3a3_a4/sysclk.h" +#elif UC3B +# include "uc3b0_b1/sysclk.h" +#elif UC3C +# include "uc3c/sysclk.h" +#elif UC3D +# include "uc3d/sysclk.h" +#elif UC3L +# include "uc3l/sysclk.h" +#elif XMEGA +# include "xmega/sysclk.h" +#elif MEGA +# include "mega/sysclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup clk_group Clock Management + */ + +/** + * \ingroup clk_group + * \defgroup sysclk_group System Clock Management + * + * See \ref sysclk_quickstart. + * + * The sysclk API covers the system clock and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all synchronous clocks, i.e. CPU and bus/peripheral + * clocks, are based. The system clock is typically generated from one + * of a variety of sources, which may include crystal and RC oscillators + * as well as PLLs. The clocks derived from the system clock are + * sometimes also known as synchronous clocks, since they + * always run synchronously with respect to each other, as opposed to + * generic clocks which may run from different oscillators or + * PLLs. + * + * Most applications should simply call sysclk_init() to initialize + * everything related to the system clock and its source (oscillator, + * PLL or DFLL), and leave it at that. More advanced applications, and + * platform-specific drivers, may require additional services from the + * clock system, some of which may be platform-specific. + * + * \section sysclk_group_platform Platform Dependencies + * + * The sysclk API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms with the same + * parameters and functionality. These functions may be called freely by + * portable applications, drivers and services: + * - sysclk_init() + * - sysclk_set_source() + * - sysclk_get_main_hz() + * - sysclk_get_cpu_hz() + * - sysclk_get_peripheral_bus_hz() + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behavior. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - sysclk_enable_peripheral_clock() + * - sysclk_disable_peripheral_clock() + * - sysclk_enable_module() + * - sysclk_disable_module() + * - sysclk_module_is_enabled() + * - sysclk_set_prescalers() + * + * All other functions should be considered platform-specific. + * Enabling/disabling clocks to specific peripherals as well as + * determining the speed of these clocks should be done by calling + * functions provided by the driver for that peripheral. + * + * @{ + */ + +//! \name System Clock Initialization +//@{ +/** + * \fn void sysclk_init(void) + * \brief Initialize the synchronous clock system. + * + * This function will initialize the system clock and its source. This + * includes: + * - Mask all synchronous clocks except for any clocks which are + * essential for normal operation (for example internal memory + * clocks). + * - Set up the system clock prescalers as specified by the + * application's configuration file. + * - Enable the clock source specified by the application's + * configuration file (oscillator or PLL) and wait for it to become + * stable. + * - Set the main system clock source to the clock specified by the + * application's configuration file. + * + * Since all non-essential peripheral clocks are initially disabled, it + * is the responsibility of the peripheral driver to re-enable any + * clocks that are needed for normal operation. + */ +//@} + +//! @} + +#endif /* SYSCLK_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/sysclk.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/sysclk.h.REMOVED.git-id deleted file mode 100644 index ceed16d2..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/sysclk.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cd9457b517e66f743f67f3f698807f36425e3561 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/osc.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/osc.h new file mode 100644 index 00000000..a37ad2cf --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/osc.h @@ -0,0 +1,507 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef XMEGA_OSC_H_INCLUDED +#define XMEGA_OSC_H_INCLUDED + +#include +#include + +/** + * \weakgroup osc_group + * + * \section osc_group_errata Errata + * - Auto-calibration does not work on XMEGA A1 revision H and + * earlier. + * @{ + */ + +//! \name Oscillator identifiers +//@{ +//! 2 MHz Internal RC Oscillator +#define OSC_ID_RC2MHZ OSC_RC2MEN_bm +//! 32 MHz Internal RC Oscillator +#define OSC_ID_RC32MHZ OSC_RC32MEN_bm +//! 32 KHz Internal RC Oscillator +#define OSC_ID_RC32KHZ OSC_RC32KEN_bm +//! External Oscillator +#define OSC_ID_XOSC OSC_XOSCEN_bm +#if XMEGA_E +//! 8 MHz Internal RC Oscillator +# define OSC_ID_RC8MHZ OSC_RC8MEN_bm +#endif + +/** + * \brief Reference from USB Start Of Frame + * \note This cannot be enabled or disabled, but can be used as a reference for + * the autocalibration (DFLL). + */ +#define OSC_ID_USBSOF 0xff +//@} + +//! \name External oscillator types +//@{ +#define XOSC_TYPE_EXTERNAL 0 //!< External clock signal +#define XOSC_TYPE_32KHZ 2 //!< 32.768 kHz resonator on TOSC +#define XOSC_TYPE_XTAL 3 //!< 0.4 to 16 MHz resonator on XTAL +//@} + +/** + * \def CONFIG_XOSC_32KHZ_LPM + * \brief Define for enabling Low Power Mode for 32 kHz external oscillator. + */ +#ifdef __DOXYGEN__ +# define CONFIG_XOSC_32KHZ_LPM +#endif /* __DOXYGEN__ */ + +/** + * \def CONFIG_XOSC_STARTUP + * \brief Board-dependent value that determines the number of start-up cycles + * for external resonators, based on BOARD_XOSC_STARTUP_US. This is written to + * the two MSB of the XOSCSEL field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ and + * BOARD_XOSC_STARTUP_US if it is not manually set. + */ + +//! \name XTAL resonator start-up cycles +//@{ +#define XOSC_STARTUP_256 0 //!< 256 cycle start-up time +#define XOSC_STARTUP_1024 1 //!< 1 k cycle start-up time +#define XOSC_STARTUP_16384 2 //!< 16 k cycle start-up time +//@} + +/** + * \def CONFIG_XOSC_RANGE + * \brief Board-dependent value that sets the frequency range of the external + * oscillator. This is written to the FRQRANGE field of OSC.XOSCCTRL. + * + * \note This is automatically computed from BOARD_XOSC_HZ if it is not manually + * set. + */ + +//! \name XTAL resonator frequency range +//@{ +//! 0.4 to 2 MHz frequency range +#define XOSC_RANGE_04TO2 OSC_FRQRANGE_04TO2_gc +//! 2 to 9 MHz frequency range +#define XOSC_RANGE_2TO9 OSC_FRQRANGE_2TO9_gc +//! 9 to 12 MHz frequency range +#define XOSC_RANGE_9TO12 OSC_FRQRANGE_9TO12_gc +//! 12 to 16 MHz frequency range +#define XOSC_RANGE_12TO16 OSC_FRQRANGE_12TO16_gc +//@} + +/** + * \def XOSC_STARTUP_TIMEOUT + * \brief Number of us to wait for XOSC to start + * + * This is the number of slow clock cycles corresponding to + * OSC0_STARTUP_VALUE with an additional 25% safety margin. If the + * oscillator isn't running when this timeout has expired, it is assumed + * to have failed to start. + */ + +// If application intends to use XOSC. +#ifdef BOARD_XOSC_HZ +// Get start-up config for XOSC, if not manually set. +# ifndef CONFIG_XOSC_STARTUP +# ifndef BOARD_XOSC_STARTUP_US +# error BOARD_XOSC_STARTUP_US must be configured. +# else +//! \internal Number of start-up cycles for the board's XOSC. +# define BOARD_XOSC_STARTUP_CYCLES \ + (BOARD_XOSC_HZ / 1000000 * BOARD_XOSC_STARTUP_US) + +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_STARTUP_CYCLES > 16384) +# error BOARD_XOSC_STARTUP_US is too high for current BOARD_XOSC_HZ. + +# elif (BOARD_XOSC_STARTUP_CYCLES > 1024) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_16384 +# define XOSC_STARTUP_TIMEOUT (16384*(1000000/BOARD_XOSC_HZ)) + +# elif (BOARD_XOSC_STARTUP_CYCLES > 256) +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_1024 +# define XOSC_STARTUP_TIMEOUT (1024*(1000000/BOARD_XOSC_HZ)) + +# else +# define CONFIG_XOSC_STARTUP XOSC_STARTUP_256 +# define XOSC_STARTUP_TIMEOUT (256*(1000000/BOARD_XOSC_HZ)) +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_STARTUP 0 +# endif +# endif /* BOARD_XOSC_STARTUP_US */ +# endif /* CONFIG_XOSC_STARTUP */ + +// Get frequency range setting for XOSC, if not manually set. +# ifndef CONFIG_XOSC_RANGE +# if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL) +# if (BOARD_XOSC_HZ < 400000) +# error BOARD_XOSC_HZ is below minimum frequency of 400 kHz. + +# elif (BOARD_XOSC_HZ < 2000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_04TO2 + +# elif (BOARD_XOSC_HZ < 9000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_2TO9 + +# elif (BOARD_XOSC_HZ < 12000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_9TO12 + +# elif (BOARD_XOSC_HZ <= 16000000) +# define CONFIG_XOSC_RANGE XOSC_RANGE_12TO16 + +# else +# error BOARD_XOSC_HZ is above maximum frequency of 16 MHz. +# endif +# else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */ +# define CONFIG_XOSC_RANGE 0 +# endif +# endif /* CONFIG_XOSC_RANGE */ +#endif /* BOARD_XOSC_HZ */ + +#ifndef __ASSEMBLY__ + +/** + * \internal + * \brief Enable internal oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. + */ +static inline void osc_enable_internal(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL |= id; +#if (XMEGA_E && CONFIG_SYSCLK_RC8MHZ_LPM) + if(id == OSC_ID_RC8MHZ) { + OSC.CTRL |= OSC_RC8MLPM_bm; + } +#endif + cpu_irq_restore(flags); +} + +#if defined(BOARD_XOSC_HZ) || defined(__DOXYGEN__) + +/** + * \internal + * \brief Enable external oscillator \a id + * + * Do not call this function directly. Use osc_enable() instead. Also + * note that this function is only available if the board actually has + * an external oscillator crystal. + */ +static inline void osc_enable_external(uint8_t id) +{ + irqflags_t flags; + + Assert(id == OSC_ID_XOSC); + +#ifndef CONFIG_XOSC_32KHZ_LPM +# if (XMEGA_E && (BOARD_XOSC_TYPE == XOSC_TYPE_EXTERNAL) && defined(CONFIG_XOSC_EXTERNAL_PC4)) + OSC.XOSCCTRL = OSC_XOSCSEL4_bm; +# else + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE; +# endif +#else + OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) | + CONFIG_XOSC_RANGE | OSC_X32KLPM_bm; +#endif /* CONFIG_XOSC_32KHZ_LPM */ + + flags = cpu_irq_save(); + OSC.CTRL |= id; + cpu_irq_restore(flags); +} +#else + +static inline void osc_enable_external(uint8_t id) +{ + Assert(false); // No external oscillator on the selected board +} +#endif + +static inline void osc_disable(uint8_t id) +{ + irqflags_t flags; + + Assert(id != OSC_ID_USBSOF); + + flags = cpu_irq_save(); + OSC.CTRL &= ~id; + cpu_irq_restore(flags); +} + +static inline void osc_enable(uint8_t id) +{ + if (id != OSC_ID_XOSC) { + osc_enable_internal(id); + } else { + osc_enable_external(id); + } +} + +static inline bool osc_is_ready(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + return OSC.STATUS & id; +} + +//! \name XMEGA-Specific Oscillator Features +//@{ + +/** + * \brief Enable DFLL-based automatic calibration of an internal + * oscillator. + * + * The XMEGA features two Digital Frequency Locked Loops (DFLLs) which + * can be used to improve the accuracy of the 2 MHz and 32 MHz internal + * RC oscillators. The DFLL compares the oscillator frequency with a + * more accurate reference clock to do automatic run-time calibration of + * the oscillator. + * + * This function enables auto-calibration for either the 2 MHz or 32 MHz + * internal oscillator using either the 32.768 kHz calibrated internal + * oscillator or an external crystal oscillator as a reference. If the + * latter option is used, the crystal must be connected to the TOSC pins + * and run at 32.768 kHz. + * + * \param id The ID of the oscillator for which to enable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param ref_id The ID of the oscillator to use as a reference: + * \arg \c OSC_ID_RC32KHZ or \c OSC_ID_XOSC for internal or external 32 kHz + * reference, respectively. + * \arg \c OSC_ID_USBSOF for 32 MHz only when USB is available and running. + */ +static inline void osc_enable_autocalibration(uint8_t id, uint8_t ref_id) +{ + irqflags_t flags; + + flags = cpu_irq_save(); + switch (id) { + case OSC_ID_RC2MHZ: +#if !XMEGA_E + Assert((ref_id == OSC_ID_RC32KHZ) || (ref_id == OSC_ID_XOSC)); + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC2MCREF_bm; + } else { + OSC.DFLLCTRL &= ~(OSC_RC2MCREF_bm); + } + DFLLRC2M.CTRL |= DFLL_ENABLE_bm; +#endif + break; + + case OSC_ID_RC32MHZ: +#if XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_E + Assert((ref_id == OSC_ID_RC32KHZ) + || (ref_id == OSC_ID_XOSC) +# if !XMEGA_E + || (ref_id == OSC_ID_USBSOF) +#endif + ); + + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); + OSC.DFLLCTRL |= OSC_RC32MCREF_XOSC32K_gc; + } + else if (ref_id == OSC_ID_RC32KHZ) { + OSC.DFLLCTRL |= OSC_RC32MCREF_RC32K_gc; + } +# if !XMEGA_E + else if (ref_id == OSC_ID_USBSOF) { + /* + * Calibrate 32MRC at 48MHz using USB SOF + * 48MHz / 1kHz = 0xBB80 + */ + DFLLRC32M.COMP1 = 0x80; + DFLLRC32M.COMP2 = 0xBB; + OSC.DFLLCTRL |= OSC_RC32MCREF_USBSOF_gc; + } +# endif +#else + Assert((ref_id == OSC_ID_RC32KHZ) || + (ref_id == OSC_ID_XOSC)); + +# if defined(OSC_RC32MCREF_gm) + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_gm); +# endif + + if (ref_id == OSC_ID_XOSC) { + osc_enable(OSC_ID_RC32KHZ); +# if defined(OSC_RC32MCREF_gm) + OSC.DFLLCTRL |= OSC_RC32MCREF_XOSC32K_gc; +# else + OSC.DFLLCTRL |= OSC_RC32MCREF_bm; +# endif + } + else if (ref_id == OSC_ID_RC32KHZ) { +# if defined(OSC_RC32MCREF_gm) + OSC.DFLLCTRL |= OSC_RC32MCREF_RC32K_gc; +# else + OSC.DFLLCTRL &= ~(OSC_RC32MCREF_bm); +# endif + } +#endif + + DFLLRC32M.CTRL |= DFLL_ENABLE_bm; + break; + + default: + Assert(false); + break; + } + cpu_irq_restore(flags); +} + +/** + * \brief Disable DFLL-based automatic calibration of an internal + * oscillator. + * + * \see osc_enable_autocalibration + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + */ +static inline void osc_disable_autocalibration(uint8_t id) +{ + switch (id) { + case OSC_ID_RC2MHZ: +#if !XMEGA_E + DFLLRC2M.CTRL = 0; +#endif + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CTRL = 0; + break; + + default: + Assert(false); + break; + } +} + +/** + * \brief Load a specific calibration value for the specified oscillator. + * + * \param id The ID of the oscillator for which to disable + * auto-calibration: + * \arg \c OSC_ID_RC2MHZ or \c OSC_ID_RC32MHZ. + * \param calib The specific calibration value required: + * + */ +static inline void osc_user_calibration(uint8_t id, uint16_t calib) +{ + switch (id) { + case OSC_ID_RC2MHZ: +#if !XMEGA_E + DFLLRC2M.CALA=LSB(calib); + DFLLRC2M.CALB=MSB(calib); +#endif + break; + + case OSC_ID_RC32MHZ: + DFLLRC32M.CALA=LSB(calib); + DFLLRC32M.CALB=MSB(calib); + break; + +#if XMEGA_E + case OSC_ID_RC8MHZ: + OSC.RC8MCAL=LSB(calib); + break; +#endif + + default: + Assert(false); + break; + } +} +//@} + +static inline uint32_t osc_get_rate(uint8_t id) +{ + Assert(id != OSC_ID_USBSOF); + + switch (id) { + case OSC_ID_RC2MHZ: + return 2000000UL; + + case OSC_ID_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case OSC_ID_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case OSC_ID_XOSC: + return BOARD_XOSC_HZ; +#endif + + default: + Assert(false); + return 0; + } +} + +#endif /* __ASSEMBLY__ */ + +//! @} + +#endif /* XMEGA_OSC_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/osc.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/osc.h.REMOVED.git-id deleted file mode 100644 index bbff3c1a..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/osc.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a37ad2cf9d6be3bb6c2e598169991056b1957bfc \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/pll.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/pll.h new file mode 100644 index 00000000..b3254c77 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/pll.h @@ -0,0 +1,274 @@ +/** + * \file + * + * \brief Chip-specific PLL management functions + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef XMEGA_PLL_H_INCLUDED +#define XMEGA_PLL_H_INCLUDED + +#include + +/** + * \weakgroup pll_group + * @{ + */ + +#define NR_PLLS 1 +#define PLL_MIN_HZ 10000000UL +#define PLL_MAX_HZ 200000000UL +#define PLL_NR_OPTIONS 0 + +enum pll_source { + //! 2 MHz Internal RC Oscillator + PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc, + //! 32 MHz Internal RC Oscillator + PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc, + //! External Clock Source + PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc, +}; + +#define pll_get_default_rate(pll_id) \ + pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_MUL, \ + CONFIG_PLL##pll_id##_DIV) + +/** + * \internal + * \brief Return clock rate for specified PLL settings. + * + * \note Due to the hardware implementation of the PLL, \a div must be 4 if the + * 32 MHz RC oscillator is used as reference and 1 otherwise. The reference must + * be above 440 kHz, and the output between 10 and 200 MHz. + * + * \param src ID of the PLL's reference source oscillator. + * \param mul Multiplier for the PLL. + * \param div Divisor for the PLL. + * + * \retval Output clock rate from PLL. + */ +static inline uint32_t pll_get_default_rate_priv(enum pll_source src, + unsigned int mul, unsigned int div) +{ + uint32_t rate; + + switch (src) { + case PLL_SRC_RC2MHZ: + rate = 2000000UL; + Assert(div == 1); + break; + + case PLL_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL //32MHz oscillator is calibrated to another frequency + rate = CONFIG_OSC_RC32_CAL / 4; +#else + rate = 8000000UL; + #endif + Assert(div == 4); + break; + + case PLL_SRC_XOSC: + rate = osc_get_rate(OSC_ID_XOSC); + Assert(div == 1); + break; + + default: + break; + } + + Assert(rate >= 440000UL); + + rate *= mul; + + Assert(rate >= PLL_MIN_HZ); + Assert(rate <= PLL_MAX_HZ); + + return rate; +} + +struct pll_config { + uint8_t ctrl; +}; + +/** + * \note The XMEGA PLL hardware uses hard-wired input dividers, so the + * user must ensure that \a div is set as follows: + * - If \a src is PLL_SRC_32MHZ, \a div must be set to 4. + * - Otherwise, \a div must be set to 1. + */ +static inline void pll_config_init(struct pll_config *cfg, enum pll_source src, + unsigned int div, unsigned int mul) +{ + Assert(mul >= 1 && mul <= 31); + + if (src == PLL_SRC_RC32MHZ) { + Assert(div == 4); + } else { + Assert(div == 1); + } + + /* Initialize the configuration */ + cfg->ctrl = src | (mul << OSC_PLLFAC_gp); +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *cfg, unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + cfg->ctrl = OSC.PLLCTRL; +} + +static inline void pll_config_write(const struct pll_config *cfg, + unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + OSC.PLLCTRL = cfg->ctrl; +} + +/** + * \note If a different PLL reference oscillator than those enabled by + * \ref sysclk_init() is used, the user must ensure that the desired reference + * is enabled prior to calling this function. + */ +static inline void pll_enable(const struct pll_config *cfg, + unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + pll_config_write(cfg, pll_id); + OSC.CTRL |= OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +/*! \note This will not automatically disable the reference oscillator that is + * configured for the PLL. + */ +static inline void pll_disable(unsigned int pll_id) +{ + irqflags_t flags; + + Assert(pll_id < NR_PLLS); + + flags = cpu_irq_save(); + OSC.CTRL &= ~OSC_PLLEN_bm; + cpu_irq_restore(flags); +} + +static inline bool pll_is_locked(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + return OSC.STATUS & OSC_PLLRDY_bm; +} + +static inline void pll_enable_source(enum pll_source src) +{ + switch (src) { + case PLL_SRC_RC2MHZ: + break; + + case PLL_SRC_RC32MHZ: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + } + break; + + case PLL_SRC_XOSC: + if (!osc_is_ready(OSC_ID_XOSC)) { + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + } + break; + default: + Assert(false); + break; + } +} + +static inline void pll_enable_config_defaults(unsigned int pll_id) +{ + struct pll_config pllcfg; + + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + switch (pll_id) { +#ifdef CONFIG_PLL0_SOURCE + case 0: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL0_SOURCE, + CONFIG_PLL0_DIV, + CONFIG_PLL0_MUL); + break; +#endif + default: + Assert(false); + break; + } + pll_enable(&pllcfg, pll_id); + while (!pll_is_locked(pll_id)); +} + +//! @} + +#endif /* XMEGA_PLL_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/pll.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/pll.h.REMOVED.git-id deleted file mode 100644 index b26aa0ba..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/pll.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b3254c7778142cd0ad66cc5108d2277b393cc014 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/sysclk.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/sysclk.c new file mode 100644 index 00000000..103c131b --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/sysclk.c @@ -0,0 +1,260 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include + +#include +#include +#include + +#if XMEGA_AU || XMEGA_B || XMEGA_C +# include +#endif + + +void sysclk_init(void) +{ + uint8_t *reg = (uint8_t *)&PR.PRGEN; + uint8_t i; +#ifdef CONFIG_OSC_RC32_CAL + uint16_t cal; + /* avoid Cppcheck Warning */ + UNUSED(cal); +#endif + bool need_rc2mhz = false; + + /* Turn off all peripheral clocks that can be turned off. */ + for (i = 0; i <= SYSCLK_PORT_F; i++) { + *(reg++) = 0xff; + } + + /* Set up system clock prescalers if different from defaults */ + if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1) + || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) { + sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, + CONFIG_SYSCLK_PSBCDIV); + } +#if (CONFIG_OSC_RC32_CAL==48000000UL) + MSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSC)); + LSB(cal) = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(USBRCOSCA)); + /* + * If a device has an uncalibrated value in the + * production signature row (early sample part), load a + * sane default calibration value. + */ + if (cal == 0xFFFF) { + cal = 0x2340; + } + osc_user_calibration(OSC_ID_RC32MHZ,cal); +#endif + /* + * Switch to the selected initial system clock source, unless + * the default internal 2 MHz oscillator is selected. + */ + if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) { + need_rc2mhz = true; + } else { + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC32MHZ: + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + break; + + case SYSCLK_SRC_RC32KHZ: + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + + case SYSCLK_SRC_XOSC: + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) { + need_rc2mhz = true; + } + pll_enable_config_defaults(0); + break; +#endif +#if XMEGA_E + case SYSCLK_SRC_RC8MHZ: + osc_enable(OSC_ID_RC8MHZ); + osc_wait_ready(OSC_ID_RC8MHZ); + break; +#endif + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return; + } + + ccp_write_io((uint8_t *)&CLK.CTRL, CONFIG_SYSCLK_SOURCE); + Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE); + } + + if (need_rc2mhz) { +#ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC + osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); + osc_enable_autocalibration(OSC_ID_RC2MHZ, + CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC); +#endif + } else { + osc_disable(OSC_ID_RC2MHZ); + } + +#ifdef CONFIG_RTC_SOURCE + sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE); +#endif +} + +void sysclk_enable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) &= ~id; + + cpu_irq_restore(flags); +} + +void sysclk_disable_module(enum sysclk_port_id port, uint8_t id) +{ + irqflags_t flags = cpu_irq_save(); + + *((uint8_t *)&PR.PRGEN + port) |= id; + + cpu_irq_restore(flags); +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) + +/** + * \brief Enable clock for the USB module + * + * \pre CONFIG_USBCLK_SOURCE must be defined. + * + * \param frequency The required USB clock frequency in MHz: + * \arg \c 6 for 6 MHz + * \arg \c 48 for 48 MHz + */ +void sysclk_enable_usb(uint8_t frequency) +{ + uint8_t prescaler; + + Assert((frequency == 6) || (frequency == 48)); + + /* + * Enable or disable prescaler depending on if the USB frequency is 6 + * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling. + */ + if (frequency == 6) { + prescaler = CLK_USBPSDIV_8_gc; + } + else { + prescaler = 0; + } + + /* + * Switch to the system clock selected by the user. + */ + switch (CONFIG_USBCLK_SOURCE) { + case USBCLK_SRC_RCOSC: + if (!osc_is_ready(OSC_ID_RC32MHZ)) { + osc_enable(OSC_ID_RC32MHZ); + osc_wait_ready(OSC_ID_RC32MHZ); +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC + != OSC_ID_USBSOF) { + osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); + } + osc_enable_autocalibration(OSC_ID_RC32MHZ, + CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC); +#endif + } + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_RC32M_gc + | CLK_USBSEN_bm); + break; + +#ifdef CONFIG_PLL0_SOURCE + case USBCLK_SRC_PLL: + pll_enable_config_defaults(0); + ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler) + | CLK_USBSRC_PLL_gc + | CLK_USBSEN_bm); + break; +#endif + + default: + Assert(false); + break; + } + + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB); +} + +/** + * \brief Disable clock for the USB module + */ +void sysclk_disable_usb(void) +{ + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_USB); + ccp_write_io((uint8_t *)&CLK.USBCTRL, 0); +} +#endif // XMEGA_AU || XMEGA_B || XMEGA_C diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/sysclk.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/sysclk.c.REMOVED.git-id deleted file mode 100644 index 5e10f37a..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/sysclk.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -103c131b686868352cb9e9733ae5a3b56aae2478 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/sysclk.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/sysclk.h new file mode 100644 index 00000000..062a4462 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/sysclk.h @@ -0,0 +1,1534 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef XMEGA_SYSCLK_H_INCLUDED +#define XMEGA_SYSCLK_H_INCLUDED + +#include +#include +#include +#include +#include +#include + +// Include clock configuration for the project. +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (XMEGA) + * + * This is the quick start guide for the \ref sysclk_group "System Clock Management" + * service, with step-by-step instructions on how to configure and use the service for + * specific use cases. + * + * \section sysclk_quickstart_usecases System Clock Management use cases + * - \ref sysclk_quickstart_basic + * - \ref sysclk_quickstart_use_case_2 + * - \ref sysclk_quickstart_use_case_3 + * + * \section sysclk_quickstart_basic Basic usage of the System Clock Management service + * This section will present a basic use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The + * secondary peripheral bus clock and CPU clock are scaled down from the speed of the + * main system clock. + * + * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + sysclk_init(); +\endcode + * + * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + + // Fpll0 = (Fclk * PLL_mul) / PLL_div + #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + #define CONFIG_PLL0_DIV 1 + + // Fbus = Fsys / (2 ^ BUS_div) + #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 +\endcode + * + * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + #define CONFIG_PLL0_DIV 1 +\endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU clock and slow peripheral bus to run at 16MHz, run the fast peripheral bus + * at the full 32MHz speed: + * \code + #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 +\endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + */ + +/** + * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management (XMEGA) + * + * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management + * This section will present a more advanced use case for the System Clock Management service. + * This use case will configure the main system clock to 32MHz, using an internal PLL + * module to multiply the frequency of a crystal attached to the microcontroller. The peripheral bus + * clocks will run at the same speed as the CPU clock, and the USB clock will be configured to use + * the internal 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB Start-of-Frame as the + * calibration reference. + * + * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code + * Add to the application initialization code: + * \code + sysclk_init(); +\endcode + * + * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, commenting out all other + * definitions of the same symbol(s): + * \code + #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL + + // Fpll0 = (Fclk * PLL_mul) / PLL_div + #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC + #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + #define CONFIG_PLL0_DIV 1 + + // Fbus = Fsys / (2 ^ BUS_div) + #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + #define CONFIG_OSC_RC32_CAL 48000000UL + #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF +\endcode + * + * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode + * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode + * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: + * \code + #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) + #define CONFIG_PLL0_DIV 1 +\endcode + * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration + * file as the frequency of the crystal attached to XOSC. + * -# Configure the main CPU and peripheral bus clocks to run at 32MHz: + * \code + #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 + #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 +\endcode + * \note Some dividers are powers of two, while others are integer division factors. Refer to the + * formulas in the conf_clock.h template commented above each division define. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +\endcode + * \note When the internal RC oscillator is used for the USB module, it must be recalibrated to 48MHz for + * the USB peripheral to function. If this oscillator is then used as the main system clock source, + * the clock must be divided down via the peripheral and CPU bus clock division constants to ensure + * that the maximum allowable CPU frequency is not exceeded. + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz using the USB Start of Frame (SOF) + * as the calibration reference: + * \code + #define CONFIG_OSC_RC32_CAL 48000000UL + #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ + #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF +\endcode + */ + +/** + * \page sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration (XMEGA) + * + * \section sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration + * This section will present a more advanced use case for the System Clock + * Management service. This use case will configure the main system clock to + * 2MHz, using the internal 2MHz RC oscillator calibrated against the internal + * 32KHz oscillator. The peripheral bus clocks will run at the same speed as + * the CPU clock, and the USB clock will be configured to use the internal + * 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB + * Start-of-Frame as the calibration reference. + * + * \subsection sysclk_quickstart_use_case_3_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_3_setup_steps Initialization code + * Add to the application initialization code: + * \code + sysclk_init(); +\endcode + * + * \subsection sysclk_quickstart_use_case_3_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_3_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, + * commenting out all other definitions of the same symbol(s): + * \code + #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ + + #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ + + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + #define CONFIG_OSC_RC32_CAL 48000000UL + #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF +\endcode + * + * \subsection sysclk_quickstart_use_case_3_example_workflow Workflow + * -# Configure the main system clock to use the internal 2MHz RC oscillator + * as its source: + * \code + #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ +\endcode + * -# Configure the 2MHz DFLL auto-calibration to use the internal 32KHz RC + * oscillator: + * \code + #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ +\endcode + * \note For auto-calibration it's typically more relevant to use an external + * 32KHz crystal. So if that's the case use OSC_ID_XOSC instead. + * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: + * \code + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +\endcode + * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz + * using the USB Start of Frame (SOF) as the calibration reference: + * \code + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + #define CONFIG_OSC_RC32_CAL 48000000UL + #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF +\endcode + */ + +/* Wrap old config into new one */ +#ifdef CONFIG_OSC_AUTOCAL +# if CONFIG_OSC_AUTOCAL == OSC_ID_RC2MHZ +# define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# elif CONFIG_OSC_AUTOCAL == OSC_ID_RC32MHZ +# define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC +# else +# error Bad configuration of CONFIG_OSC_AUTOCAL and/or CONFIG_OSC_AUTOCAL_REF_OSC +# endif +#endif + +// Use 2 MHz with no prescaling if config was empty. +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ +#endif /* CONFIG_SYSCLK_SOURCE */ + +#ifndef CONFIG_SYSCLK_PSADIV +# define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 +#endif /* CONFIG_SYSCLK_PSADIV */ + +#ifndef CONFIG_SYSCLK_PSBCDIV +# define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 +#endif /* CONFIG_SYSCLK_PSBCDIV */ + +/** + * \weakgroup sysclk_group + * + * \section sysclk_group_config Configuration Symbols + * + * The following configuration symbols may be used to specify the + * initial system clock configuration. If any of the symbols are not + * set, reasonable defaults will be provided. + * - \b CONFIG_SYSCLK_SOURCE: The initial system clock source. + * - \b CONFIG_SYSCLK_PSADIV: The initial Prescaler A setting. + * - \b CONFIG_SYSCLK_PSBCDIV: The initial Prescaler B setting. + * - \b CONFIG_USBCLK_SOURCE: The initial USB clock source. + * + * @{ + */ + +//! \name System Clock Sources +//@{ +//! Internal 2 MHz RC oscillator +#define SYSCLK_SRC_RC2MHZ CLK_SCLKSEL_RC2M_gc +//! Internal 32 MHz RC oscillator +#define SYSCLK_SRC_RC32MHZ CLK_SCLKSEL_RC32M_gc +//! Internal 32 KHz RC oscillator +#define SYSCLK_SRC_RC32KHZ CLK_SCLKSEL_RC32K_gc +//! External oscillator +#define SYSCLK_SRC_XOSC CLK_SCLKSEL_XOSC_gc +//! Phase-Locked Loop +#define SYSCLK_SRC_PLL CLK_SCLKSEL_PLL_gc +#if XMEGA_E +//! Internal 8 MHz RC oscillator +# define SYSCLK_SRC_RC8MHZ CLK_SCLKSEL_RC8M_gc +#endif +//@} + +//! \name Prescaler A Setting (relative to CLKsys) +//@{ +#define SYSCLK_PSADIV_1 CLK_PSADIV_1_gc //!< Do not prescale +#define SYSCLK_PSADIV_2 CLK_PSADIV_2_gc //!< Prescale CLKper4 by 2 +#define SYSCLK_PSADIV_4 CLK_PSADIV_4_gc //!< Prescale CLKper4 by 4 +#define SYSCLK_PSADIV_8 CLK_PSADIV_8_gc //!< Prescale CLKper4 by 8 +#define SYSCLK_PSADIV_16 CLK_PSADIV_16_gc //!< Prescale CLKper4 by 16 +#define SYSCLK_PSADIV_32 CLK_PSADIV_32_gc //!< Prescale CLKper4 by 32 +#define SYSCLK_PSADIV_64 CLK_PSADIV_64_gc //!< Prescale CLKper4 by 64 +#define SYSCLK_PSADIV_128 CLK_PSADIV_128_gc //!< Prescale CLKper4 by 128 +#define SYSCLK_PSADIV_256 CLK_PSADIV_256_gc //!< Prescale CLKper4 by 256 +#define SYSCLK_PSADIV_512 CLK_PSADIV_512_gc //!< Prescale CLKper4 by 512 + +#if XMEGA_E +# define SYSCLK_PSADIV_6 CLK_PSADIV_6_gc //!< Prescale CLKper4 by 6 +# define SYSCLK_PSADIV_10 CLK_PSADIV_10_gc //!< Prescale CLKper4 by 10 +# define SYSCLK_PSADIV_12 CLK_PSADIV_12_gc //!< Prescale CLKper4 by 12 +# define SYSCLK_PSADIV_24 CLK_PSADIV_24_gc //!< Prescale CLKper4 by 24 +# define SYSCLK_PSADIV_48 CLK_PSADIV_48_gc //!< Prescale CLKper4 by 48 +#endif +//@} + +//! \name Prescaler B and C Setting (relative to CLKper4) +//@{ +//! Do not prescale +#define SYSCLK_PSBCDIV_1_1 CLK_PSBCDIV_1_1_gc +//! Prescale CLKper and CLKcpu by 2 +#define SYSCLK_PSBCDIV_1_2 CLK_PSBCDIV_1_2_gc +//! Prescale CLKper2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_4_1 CLK_PSBCDIV_4_1_gc +//! Prescale CLKper2 by 2, CLKper and CLKcpu by 4 +#define SYSCLK_PSBCDIV_2_2 CLK_PSBCDIV_2_2_gc +//@} + +//! \name System Clock Port Numbers +enum sysclk_port_id { + SYSCLK_PORT_GEN, //!< Devices not associated with a specific port. + SYSCLK_PORT_A, //!< Devices on PORTA + SYSCLK_PORT_B, //!< Devices on PORTB + SYSCLK_PORT_C, //!< Devices on PORTC + SYSCLK_PORT_D, //!< Devices on PORTD + SYSCLK_PORT_E, //!< Devices on PORTE + SYSCLK_PORT_F, //!< Devices on PORTF +}; + +/*! \name Clocks not associated with any port + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_DMA PR_DMA_bm //!< DMA Controller +#define SYSCLK_EDMA PR_EDMA_bm //!< EDMA Controller +#define SYSCLK_EVSYS PR_EVSYS_bm //!< Event System +#define SYSCLK_RTC PR_RTC_bm //!< Real-Time Counter +#define SYSCLK_EBI PR_EBI_bm //!< Ext Bus Interface +#define SYSCLK_AES PR_AES_bm //!< AES Module +#define SYSCLK_USB PR_USB_bm //!< USB Module +#define SYSCLK_XCL PR_XCL_bm //!< USB Module +//@} + +/*! \name Clocks on PORTA and PORTB + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_AC PR_AC_bm //!< Analog Comparator +#define SYSCLK_ADC PR_ADC_bm //!< A/D Converter +#define SYSCLK_DAC PR_DAC_bm //!< D/A Converter +//@} + +/*! \name Clocks on PORTC, PORTD, PORTE and PORTF + * + * \note See the datasheet for available modules in the device. + */ +//@{ +#define SYSCLK_TC0 PR_TC0_bm //!< Timer/Counter 0 +#define SYSCLK_TC1 PR_TC1_bm //!< Timer/Counter 1 +#define SYSCLK_TC4 PR_TC4_bm //!< Timer/Counter 0 +#define SYSCLK_TC5 PR_TC5_bm //!< Timer/Counter 1 +#define SYSCLK_HIRES PR_HIRES_bm //!< Hi-Res Extension +#define SYSCLK_SPI PR_SPI_bm //!< SPI controller +#define SYSCLK_USART0 PR_USART0_bm //!< USART 0 +#define SYSCLK_USART1 PR_USART1_bm //!< USART 1 +#define SYSCLK_TWI PR_TWI_bm //!< TWI controller +//@} + +/** + * \name RTC clock source identifiers + * + * @{ + */ + +/** 1kHz from internal ULP oscillator. Low precision */ +#define SYSCLK_RTCSRC_ULP CLK_RTCSRC_ULP_gc +/** 1.024kHz from 32.768kHz crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC CLK_RTCSRC_TOSC_gc +/** 1.024kHz from 32.768kHz internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC CLK_RTCSRC_RCOSC_gc +/** 32.768kHz from crystal oscillator TOSC */ +#define SYSCLK_RTCSRC_TOSC32 CLK_RTCSRC_TOSC32_gc +/** 32.768kHz from internal RC oscillator */ +#define SYSCLK_RTCSRC_RCOSC32 CLK_RTCSRC_RCOSC32_gc +/** External clock on TOSC1 */ +#define SYSCLK_RTCSRC_EXTCLK CLK_RTCSRC_EXTCLK_gc + +/** @} */ + +#if XMEGA_AU || XMEGA_B || XMEGA_C +//! \name USB Clock Sources +//@{ +//! Internal 32 MHz RC oscillator +#define USBCLK_SRC_RCOSC 0 +//! Phase-Locked Loop +#define USBCLK_SRC_PLL 1 +//@} + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB clock source + * + * If the device features an USB module, and this is intended to be used, this + * symbol must be defined with the clock source configuration. + * + * Define this as one of the \c USBCLK_SRC_xxx definitions. If the PLL is + * selected, it must be configured to run at 48 MHz. If the 32 MHz RC oscillator + * is selected, it must be tuned to 48 MHz by means of the DFLL. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +#endif // XMEGA_AU || XMEGA_B || XMEGA_C + +#ifndef __ASSEMBLY__ + +/** + * \name Querying the system clock and its derived clocks + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + * + * \return Frequency of the main system clock, in Hz. + */ +static inline uint32_t sysclk_get_main_hz(void) +{ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RC2MHZ: + return 2000000UL; +#if XMEGA_E + case SYSCLK_SRC_RC8MHZ: + return 8000000UL; +#endif + case SYSCLK_SRC_RC32MHZ: +#ifdef CONFIG_OSC_RC32_CAL + return CONFIG_OSC_RC32_CAL; +#else + return 32000000UL; +#endif + + case SYSCLK_SRC_RC32KHZ: + return 32768UL; + +#ifdef BOARD_XOSC_HZ + case SYSCLK_SRC_XOSC: + return BOARD_XOSC_HZ; +#endif + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL: + return pll_get_default_rate(0); +#endif + + default: + //unhandled_case(CONFIG_SYSCLK_SOURCE); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER4. + * + * This clock can run up to four times faster than the CPU clock. + * + * \return Frequency of the clk_PER4 clock, in Hz. + */ +static inline uint32_t sysclk_get_per4_hz(void) +{ + uint8_t shift = 0; + +#if XMEGA_E + if (CONFIG_SYSCLK_PSADIV > SYSCLK_PSADIV_512) { + switch (CONFIG_SYSCLK_PSADIV) { + case SYSCLK_PSADIV_6: + return sysclk_get_main_hz() / 6; + case SYSCLK_PSADIV_10: + return sysclk_get_main_hz() / 10; + case SYSCLK_PSADIV_12: + return sysclk_get_main_hz() / 12; + case SYSCLK_PSADIV_24: + return sysclk_get_main_hz() / 24; + case SYSCLK_PSADIV_48: + return sysclk_get_main_hz() / 48; + default: + //unhandled_case; + return 0; + } + } +#endif + if (CONFIG_SYSCLK_PSADIV & (1U << CLK_PSADIV_gp)) { + shift = (CONFIG_SYSCLK_PSADIV >> (1 + CLK_PSADIV_gp)) + 1; + } + + return sysclk_get_main_hz() >> shift; +} + +/** + * \brief Return the current rate in Hz of clk_PER2. + * + * This clock can run up to two times faster than the CPU clock. + * + * \return Frequency of the clk_PER2 clock, in Hz. + */ +static inline uint32_t sysclk_get_per2_hz(void) +{ + switch (CONFIG_SYSCLK_PSBCDIV) { + case SYSCLK_PSBCDIV_1_1: /* Fall through */ + case SYSCLK_PSBCDIV_1_2: + return sysclk_get_per4_hz(); + + case SYSCLK_PSBCDIV_4_1: + return sysclk_get_per4_hz() / 4; + + case SYSCLK_PSBCDIV_2_2: + return sysclk_get_per4_hz() / 2; + + default: + //unhandled_case(CONFIG_SYSCLK_PSBCDIV); + return 0; + } +} + +/** + * \brief Return the current rate in Hz of clk_PER. + * + * This clock always runs at the same rate as the CPU clock unless the divider + * is set. + * + * \return Frequency of the clk_PER clock, in Hz. + */ +static inline uint32_t sysclk_get_per_hz(void) +{ + if (CONFIG_SYSCLK_PSBCDIV & (1U << CLK_PSBCDIV_gp)) + return sysclk_get_per2_hz() / 2; + else + return sysclk_get_per2_hz(); +} + +/** + * \brief Return the current rate in Hz of the CPU clock. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + return sysclk_get_per_hz(); +} + +/** + * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached + * to the specified peripheral. + * + * \param module Pointer to the module's base address. + * + * \return Frequency of the bus attached to the specified peripheral, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + return 0; + } +#ifdef AES + else if (module == &AES) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EBI + else if (module == &EBI) { + return sysclk_get_per2_hz(); + } +#endif +#ifdef RTC + else if (module == &RTC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DMA + else if (module == &DMA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef EDMA + else if (module == &EDMA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACA + else if (module == &ACA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ACB + else if (module == &ACB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + return sysclk_get_per_hz(); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + return sysclk_get_per_hz(); + } +#endif +#ifdef DACA + else if (module == &DACA) { + return sysclk_get_per_hz(); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + return sysclk_get_per_hz(); + } +#endif +#endif // Workaround end +#ifdef FAULTC0 + else if (module == &FAULTC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef FAULTC1 + else if (module == &FAULTC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC0 + else if (module == &TCC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC4 + else if (module == &TCC4) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCC5 + else if (module == &TCC5) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD4 + else if (module == &TCD4) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TCD5 + else if (module == &TCD5) { + return sysclk_get_per_hz(); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + return sysclk_get_per4_hz(); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPID + else if (module == &SPID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWID + else if (module == &TWID) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + return sysclk_get_per_hz(); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + return sysclk_get_per_hz(); + } +#endif +#ifdef XCL + else if (module == &XCL) { + return sysclk_get_per_hz(); + } +#endif + else { + Assert(false); + return 0; + } +} + +//@} + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be enabled. + */ +extern void sysclk_enable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Disable the clock to peripheral \a id on port \a port + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to be disabled. + */ +extern void sysclk_disable_module(enum sysclk_port_id port, uint8_t id); + +/** + * \brief Enable a peripheral's clock from its base address. + * + * Enables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be enabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_enable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef EDMA + else if (module == &EDMA) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EDMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef TCC4 + else if (module == &TCC4) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC4); + } +#endif +#ifdef TCC5 + else if (module == &TCC5) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC5); + } +#endif +#ifdef TCD4 + else if (module == &TCD4) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC4); + } +#endif +#ifdef TCD5 + else if (module == &TCD5) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC5); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif +#ifdef XCL + else if (module == &XCL) { + sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_XCL); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Disable a peripheral's clock from its base address. + * + * Disables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be disabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_disable_peripheral_clock(const volatile void *module) +{ + if (module == NULL) { + Assert(false); + } +#ifdef AES + else if (module == &AES) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_AES); + } +#endif +#ifdef EBI + else if (module == &EBI) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); + } +#endif +#ifdef RTC + else if (module == &RTC) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); + } +#endif +#ifdef EVSYS + else if (module == &EVSYS) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); + } +#endif +#ifdef DMA + else if (module == &DMA) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); + } +#endif +#ifdef EDMA + else if (module == &EDMA) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EDMA); + } +#endif +#ifdef ACA + else if (module == &ACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_AC); + } +#endif +#ifdef ACB + else if (module == &ACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_AC); + } +#endif +#ifdef ADCA + else if (module == &ADCA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_ADC); + } +#endif +#ifdef ADCB + else if (module == &ADCB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_ADC); + } +#endif +#ifdef DACA + else if (module == &DACA) { + sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_DAC); + } +#endif +// Workaround for bad XMEGA D header file +#if !XMEGA_D +#ifdef DACB + else if (module == &DACB) { + sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_DAC); + } +#endif +#endif // Workaround end +#ifdef TCC0 + else if (module == &TCC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC0); + } +#endif +#ifdef TCD0 + else if (module == &TCD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC0); + } +#endif +#ifdef TCE0 + else if (module == &TCE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC0); + } +#endif +#ifdef TCF0 + else if (module == &TCF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC0); + } +#endif +#ifdef TCC1 + else if (module == &TCC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC1); + } +#endif +#ifdef TCD1 + else if (module == &TCD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC1); + } +#endif +#ifdef TCE1 + else if (module == &TCE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC1); + } +#endif +#ifdef TCF1 + else if (module == &TCF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC1); + } +#endif +#ifdef TCC4 + else if (module == &TCC4) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC4); + } +#endif +#ifdef TCC5 + else if (module == &TCC5) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC5); + } +#endif +#ifdef TCD4 + else if (module == &TCD4) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC4); + } +#endif +#ifdef TCD5 + else if (module == &TCD5) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC5); + } +#endif +#ifdef HIRESC + else if (module == &HIRESC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_HIRES); + } +#endif +#ifdef HIRESD + else if (module == &HIRESD) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_HIRES); + } +#endif +#ifdef HIRESE + else if (module == &HIRESE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_HIRES); + } +#endif +#ifdef HIRESF + else if (module == &HIRESF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_HIRES); + } +#endif +#ifdef SPIC + else if (module == &SPIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_SPI); + } +#endif +#ifdef SPID + else if (module == &SPID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_SPI); + } +#endif +#ifdef SPIE + else if (module == &SPIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_SPI); + } +#endif +#ifdef SPIF + else if (module == &SPIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_SPI); + } +#endif +#ifdef USARTC0 + else if (module == &USARTC0) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART0); + } +#endif +#ifdef USARTD0 + else if (module == &USARTD0) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART0); + } +#endif +#ifdef USARTE0 + else if (module == &USARTE0) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART0); + } +#endif +#ifdef USARTF0 + else if (module == &USARTF0) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART0); + } +#endif +#ifdef USARTC1 + else if (module == &USARTC1) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART1); + } +#endif +#ifdef USARTD1 + else if (module == &USARTD1) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART1); + } +#endif +#ifdef USARTE1 + else if (module == &USARTE1) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART1); + } +#endif +#ifdef USARTF1 + else if (module == &USARTF1) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART1); + } +#endif +#ifdef TWIC + else if (module == &TWIC) { + sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TWI); + } +#endif +#ifdef TWID + else if (module == &TWID) { + sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TWI); + } +#endif +#ifdef TWIE + else if (module == &TWIE) { + sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TWI); + } +#endif +#ifdef TWIF + else if (module == &TWIF) { + sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TWI); + } +#endif +#ifdef XCL + else if (module == &XCL) { + sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_XCL); + } +#endif + else { + Assert(false); + } +} + +/** + * \brief Check if the synchronous clock is enabled for a module + * + * \param port ID of the port to which the module is connected (one of + * the \c SYSCLK_PORT_* definitions). + * \param id The ID (bitmask) of the peripheral module to check (one of + * the \c SYSCLK_* module definitions). + * + * \retval true If the clock for module \a id on \a port is enabled. + * \retval false If the clock for module \a id on \a port is disabled. + */ +static inline bool sysclk_module_is_enabled(enum sysclk_port_id port, + uint8_t id) +{ + uint8_t mask = *((uint8_t *)&PR.PRGEN + port); + return (mask & id) == 0; +} + +#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) +# if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +# if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_RCOSC) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL) +# if (CONFIG_PLL0_SOURCE == PLL_SRC_XOSC) +# define USBCLK_STARTUP_TIMEOUT XOSC_STARTUP_TIMEOUT +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC32MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) +# define USBCLK_STARTUP_TIMEOUT 1 +# else +# error Unknow value for CONFIG_PLL0_SOURCE, see conf_clock.h. +# endif +# endif +# else /* CONFIG_USBCLK_SOURCE not defined */ +# define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +# define USBCLK_STARTUP_TIMEOUT 1 +# endif /* CONFIG_USBCLK_SOURCE */ +void sysclk_enable_usb(uint8_t frequency); +void sysclk_disable_usb(void); +#endif /* XMEGA_AU || XMEGA_B || XMEGA_C */ +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param psadiv The prescaler A setting (one of the \c SYSCLK_PSADIV_* + * definitions). This determines the clkPER4 frequency. + * \param psbcdiv The prescaler B and C settings (one of the \c SYSCLK_PSBCDIV_* + * definitions). These determine the clkPER2, clkPER and clkCPU frequencies. + */ +static inline void sysclk_set_prescalers(uint8_t psadiv, uint8_t psbcdiv) +{ + ccp_write_io((uint8_t *)&CLK.PSCTRL, psadiv | psbcdiv); +} + +/** + * \brief Change the source of the main system clock. + * + * \param src The new system clock source. Must be one of the constants + * from the System Clock Sources section. + */ +static inline void sysclk_set_source(uint8_t src) +{ + ccp_write_io((uint8_t *)&CLK.CTRL, src); +} + +/** + * \brief Lock the system clock configuration + * + * This function will lock the current system clock source and prescaler + * configuration, preventing any further changes. + */ +static inline void sysclk_lock(void) +{ + ccp_write_io((uint8_t *)&CLK.LOCK, CLK_LOCK_bm); +} + +//@} + +/** + * \name RTC clock source control + * @{ + */ + +/** + * \brief Enable RTC clock with specified clock source + * + * \param id RTC clock source ID. Select from SYSCLK_RTCSRC_ULP, + * SYSCLK_RTCSRC_RCOSC, SYSCLK_RTCSRC_TOSC, SYSCLK_RTCSRC_RCOSC32, + * SYSCLK_RTCSRC_TOSC32 or SYSCLK_RTCSRC_EXTCLK + */ +static inline void sysclk_rtcsrc_enable(uint8_t id) +{ + Assert((id & ~CLK_RTCSRC_gm) == 0); + + switch (id) { + case SYSCLK_RTCSRC_RCOSC: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_RCOSC32: +#endif + osc_enable(OSC_ID_RC32KHZ); + osc_wait_ready(OSC_ID_RC32KHZ); + break; + case SYSCLK_RTCSRC_TOSC: + case SYSCLK_RTCSRC_TOSC32: +#if !XMEGA_A && !XMEGA_D + case SYSCLK_RTCSRC_EXTCLK: +#endif + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); + break; + } + + CLK.RTCCTRL = id | CLK_RTCEN_bm; +} + +/** + * \brief Disable RTC clock + */ +static inline void sysclk_rtcsrc_disable(void) +{ + CLK.RTCCTRL = 0; +} + +/** @} */ + +//! \name System Clock Initialization +//@{ + +extern void sysclk_init(void); + +//@} + +#endif /* !__ASSEMBLY__ */ + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SYSCLK_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/sysclk.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/sysclk.h.REMOVED.git-id deleted file mode 100644 index 4aa8716a..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/clock/xmega/sysclk.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -062a4462dce2581b8d87c172250bbf346d226198 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/delay/delay.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/delay/delay.h new file mode 100644 index 00000000..c845e44b --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/delay/delay.h @@ -0,0 +1,139 @@ +/** + * \file + * + * \brief Common Delay Service + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef _DELAY_H_ +#define _DELAY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#if UC3 +# include +#elif XMEGA +# include "xmega/cycle_counter.h" +#elif MEGA +# include "mega/cycle_counter.h" +#elif SAM +# include "sam/cycle_counter.h" +#endif + +/** + * @defgroup group_common_services_delay Busy-Wait Delay Routines + * + * This module provides simple loop-based delay routines for those + * applications requiring a brief wait during execution. Common API + * for UC3, XMEGA, and AVR MEGA. + * + * @{ + */ + +/** + * @def F_CPU + * @brief MCU Clock Frequency (Hertz) + * + * @deprecated + * The \ref F_CPU configuration constant is used for compatibility with the + * \ref group_common_services_delay routines. The common loop-based delay + * routines are designed to use the \ref clk_group modules while anticipating + * support for legacy applications assuming a statically defined clock + * frequency. Applications using a statically configured MCU clock frequency + * can define \ref F_CPU (Hertz), in which case the common delay routines will + * use this value rather than calling sysclk_get_cpu_hz() to get the current + * MCU clock frequency. + */ +#ifndef F_CPU +# define F_CPU sysclk_get_cpu_hz() +#endif + +/** + * @def delay_init + * + * @brief Initialize the delay driver. + * @param fcpu_hz CPU frequency in Hz + * + * @deprecated + * This function is provided for compatibility with ASF applications that + * may not have been updated to configure the system clock via the common + * clock service; e.g. sysclk_init() and a configuration header file are + * used to configure clocks. + * + * The functions in this module call \ref sysclk_get_cpu_hz() function to + * obtain the system clock frequency. + */ +#define delay_init(fcpu_hz) + +/** + * @def delay_s + * @brief Delay in seconds. + * @param delay Delay in seconds + */ +#define delay_s(delay) cpu_delay_ms(1000 * delay, F_CPU) + +/** + * @def delay_ms + * @brief Delay in milliseconds. + * @param delay Delay in milliseconds + */ +#define delay_ms(delay) cpu_delay_ms(delay, F_CPU) + +/** + * @def delay_us + * @brief Delay in microseconds. + * @param delay Delay in microseconds + */ +#define delay_us(delay) cpu_delay_us(delay, F_CPU) + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* _DELAY_H_ */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/delay/delay.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/delay/delay.h.REMOVED.git-id deleted file mode 100644 index 65a442ea..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/delay/delay.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c845e44bac7b9b16b7f308066cdc09d04be43191 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/delay/xmega/cycle_counter.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/delay/xmega/cycle_counter.h new file mode 100644 index 00000000..e67e520a --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/delay/xmega/cycle_counter.h @@ -0,0 +1,116 @@ +/** + * \file + * + * \brief AVR functions for busy-wait delay loops + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef _CYCLE_COUNTER_H_ +#define _CYCLE_COUNTER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +/** + * @name Convenience functions for busy-wait delay loops + * + * @def delay_cycles + * @brief Delay program execution for a specified number of CPU cycles. + * @param n number of CPU cycles to wait + * + * @def cpu_delay_ms + * @brief Delay program execution for a specified number of milliseconds. + * @param delay number of milliseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_delay_us + * @brief Delay program execution for a specified number of microseconds. + * @param delay number of microseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_ms_2_cy + * @brief Convert milli-seconds into CPU cycles. + * @param ms number of milliseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @def cpu_us_2_cy + * @brief Convert micro-seconds into CPU cycles. + * @param ms number of microseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @{ + */ +__always_optimize +static inline void __portable_avr_delay_cycles(unsigned long n) +{ + do { barrier(); } while (--n); +} + +#if !defined(__DELAY_CYCLE_INTRINSICS__) +# define delay_cycles __portable_avr_delay_cycles +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 6e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 6e6) +#else +# if defined(__GNUC__) +# define delay_cycles __builtin_avr_delay_cycles +# elif defined(__ICCAVR__) +# define delay_cycles __delay_cycles +# endif +# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 1e3) +# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 1e6) +#endif + +#define cpu_delay_ms(delay, f_cpu) delay_cycles((uint64_t)cpu_ms_2_cy(delay, f_cpu)) +#define cpu_delay_us(delay, f_cpu) delay_cycles((uint64_t)cpu_us_2_cy(delay, f_cpu)) +//! @} + + +#ifdef __cplusplus +} +#endif + +#endif /* _CYCLE_COUNTER_H_ */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/delay/xmega/cycle_counter.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/delay/xmega/cycle_counter.h.REMOVED.git-id deleted file mode 100644 index a4bf8a94..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/delay/xmega/cycle_counter.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e67e520aad3e670d18d4a7e46ea3b52d41d455c6 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/docsrc/gfx_mono_overview.png b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/docsrc/gfx_mono_overview.png new file mode 100644 index 00000000..1e85b6b9 Binary files /dev/null and b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/docsrc/gfx_mono_overview.png differ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/docsrc/gfx_mono_overview.png.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/docsrc/gfx_mono_overview.png.REMOVED.git-id deleted file mode 100644 index e074b2d1..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/docsrc/gfx_mono_overview.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1e85b6b922f786034e87b59f33489b4b1849073c \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono.h new file mode 100644 index 00000000..c5488805 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono.h @@ -0,0 +1,306 @@ +/** + * \file + * + * \brief Monochrome graphic library API header file + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef GFX_MONO_H +#define GFX_MONO_H + +#include + +#include "compiler.h" +#include "progmem.h" +#ifdef CONFIG_HAVE_HUGEMEM +# include "hugemem.h" +#endif + +/** + * \defgroup gfx_mono Monochrome graphical display system + * + * See \ref gfx_mono_quickstart. + * + * This library provides an interface to drawing graphics on monochrome + * graphical displays + * + * The graphics drivers consists of the following: + * - Display driver interface (gfx_mono.h) + * - General graphics drawing primitives (gfx_mono_generic.h) + * - Display specific implementation (ex. gfx_mono_c12832_a1z.h) + * + * The generic drawing primitives is a library of functions for drawing + * graphics primitives such as lines, rectangles and circles. It uses other + * functions implemented by the display driver for drawing the primitives. The + * implementation of these functions can optionally be used by a display + * driver, but if the hardware of the display allows faster handling of any of + * the primitives, the display driver can implement it directly. + * + * The display specific drivers provides an interface to the graphical display. + * It implements the low level communication with the display hardware, putting + * pixels on the display and drawing primitives such as lines, circles and + * rectangles. Depending on the display driver implementation, drawing the + * graphics primitives might be handled by the generic graphics drawing + * primitives rather than the display driver itself. + * + * \note The functions in the library are not interrupt safe. + * @{ + */ + +typedef uint8_t gfx_mono_color_t; +typedef uint8_t gfx_coord_t; + +/** Pixel operations */ +enum gfx_mono_color { + /** Pixel is cleared */ + GFX_PIXEL_CLR = 0, + /** Pixel is set on screen (OR) */ + GFX_PIXEL_SET = 1, + /** Pixel is XORed */ + GFX_PIXEL_XOR = 2, +}; + +/** Bitmap types */ +enum gfx_mono_bitmap_type { + /** Bitmap stored in SRAM */ + GFX_MONO_BITMAP_RAM, + /** Bitmap stored in progmem */ + GFX_MONO_BITMAP_PROGMEM +}; + +/* Cannot be moved to top, as they use the bitmap and color enums. */ +#ifdef USE_SDL +# include "gfx_mono_sdl.h" +#elif defined(GFX_MONO_C12832_A1Z) +# include "gfx_mono_c12832_a1z.h" +#elif defined(GFX_MONO_UG_2832HSWEG04) +# include "gfx_mono_ug_2832hsweg04.h" +#else +/* NULL driver by default */ +# include "gfx_mono_null.h" +#endif +#include "gfx_mono_generic.h" + +/** \name Circle Sector Definitions */ +/** @{ */ + +/** Bitmask for drawing circle octant 0. */ +#define GFX_OCTANT0 (1 << 0) +/** Bitmask for drawing circle octant 1. */ +#define GFX_OCTANT1 (1 << 1) +/** Bitmask for drawing circle octant 2. */ +#define GFX_OCTANT2 (1 << 2) +/** Bitmask for drawing circle octant 3. */ +#define GFX_OCTANT3 (1 << 3) +/** Bitmask for drawing circle octant 4. */ +#define GFX_OCTANT4 (1 << 4) +/** Bitmask for drawing circle octant 5. */ +#define GFX_OCTANT5 (1 << 5) +/** Bitmask for drawing circle octant 6. */ +#define GFX_OCTANT6 (1 << 6) +/** Bitmask for drawing circle octant 7. */ +#define GFX_OCTANT7 (1 << 7) + +/** Bitmask for drawing circle quadrant 0. */ +#define GFX_QUADRANT0 (GFX_OCTANT0 | GFX_OCTANT1) +/** Bitmask for drawing circle quadrant 1. */ +#define GFX_QUADRANT1 (GFX_OCTANT2 | GFX_OCTANT3) +/** Bitmask for drawing circle quadrant 2. */ +#define GFX_QUADRANT2 (GFX_OCTANT4 | GFX_OCTANT5) +/** Bitmask for drawing circle quadrant 3. */ +#define GFX_QUADRANT3 (GFX_OCTANT6 | GFX_OCTANT7) + +/** Bitmask for drawing left half of circle. */ +#define GFX_LEFTHALF (GFX_QUADRANT3 | GFX_QUADRANT0) +/** Bitmask for drawing top half of circle. */ +#define GFX_TOPHALF (GFX_QUADRANT0 | GFX_QUADRANT1) +/** Bitmask for drawing right half of circle. */ +#define GFX_RIGHTHALF (GFX_QUADRANT1 | GFX_QUADRANT2) +/** Bitmask for drawing bottom half of circle. */ +#define GFX_BOTTOMHALF (GFX_QUADRANT2 | GFX_QUADRANT3) + +/** Bitmask for drawing whole circle. */ +#define GFX_WHOLE 0xFF + +/** @} */ + +/** \name Graphic Drawing Primitives */ +/** @{ */ + +/** + * \def gfx_mono_draw_horizontal_line(x, y, length, color) + * \brief Draw a horizontal line, one pixel wide. + * + * \param x X coordinate of leftmost pixel. + * \param y Y coordinate of the line. + * \param length Length of the line in pixels. + * \param color Pixel operation of the line. + */ + +/** + * \def gfx_mono_draw_vertical_line(x, y, length, color) + * \brief Draw a vertical line, one pixel wide. + * + * \param x X coordinate of the line. + * \param y Y coordinate of the topmost pixel. + * \param length Length of the line in pixels. + * \param color Pixel operation of the line. + */ + +/** + * \def gfx_mono_draw_line(x1, y1, x2, y2, color) + * \brief Draw a line between two arbitrary points. + * + * \param x1 Start X coordinate. + * \param y1 Start Y coordinate. + * \param x2 End X coordinate. + * \param y2 End Y coordinate. + * \param color Pixel operation of the line. + */ + +/** + * \def gfx_mono_draw_rect(x, y, width, height, color) + * \brief Draw an outline of a rectangle. + * + * \param x X coordinate of the left side. + * \param y Y coordinate of the top side. + * \param width Width of the rectangle. + * \param height Height of the rectangle. + * \param color Pixel operation of the line. + */ + +/** + * \def gfx_mono_draw_filled_rect(x, y, width, height, color) + * \brief Draw a filled rectangle. + * + * \param x X coordinate of the left side. + * \param y Y coordinate of the top side. + * \param width Width of the rectangle. + * \param height Height of the rectangle. + * \param color Pixel operation of the line + */ + +/** + * \def gfx_mono_draw_circle(x, y, radius, color, octant_mask) + * \brief Draw an outline of a circle or arc. + * + * The radius is the distance from the center to the circumference, + * which means that the total width or height of a circle will be + * (radius*2+1). + * + * The octant_mask parameter is a bitmask that decides which octants of + * the circle to draw. Use the GFX_OCTANTn, GFX_QUADRANTn, GFX_xHALF and + * GFX_WHOLE constants and OR them together if required. Radius equal to + * zero gives a single pixel. + * + * \param x X coordinate of center. + * \param y Y coordinate of center. + * \param radius Circle radius in pixels. + * \param color Pixel operation. + * \param octant_mask Bitmask indicating which octants to draw. + */ + +/** + * \def gfx_mono_draw_filled_circle(x, y, radius, color, quadrant_mask) + * \brief Draw a filled circle or sector. + * + * The radius is the distance from the center to the circumference, + * which means that the total width or height of a circle will be + * (radius*2+1). + * + * The quadrant_mask parameter is a bitmask that decides which quadrants + * of the circle to draw. Use the GFX_QUADRANTn, GFX_xHALF and + * GFX_WHOLE constants and OR them together if required. Radius equal to + * zero gives a single pixel. + * + * \note This function only supports quadrants while gfx_draw_circle() + * supports octants. This is to improve performance on drawing + * filled circles. + * + * \param x X coordinate of center. + * \param y Y coordinate of center. + * \param radius Circle radius in pixels. + * \param color Pixel operation. + * \param quadrant_mask Bitmask indicating which quadrants to draw. + */ + +/** @} */ + +/** @} */ + +/** + * \page gfx_mono_quickstart Quick Start Guide for the mono graphics service + * + * This is the quick start guide for the \ref gfx_mono "Monochrome Graphics service", + * with step-by-step instructions on how to configure and use it for a specific + * use case. + * + * \section gfx_mono_quickstart_basic Basic usage of the graphics service + * This use case will demonstrate initializing the mono graphics service and + * then draw a black line on the screen from coordinates X=10, Y=10 to X=20, + * Y=20. + * + * \section gfx_mono_basic_usage Usage steps + * \subsection gfx_mono_basic_usage_code Example code + * Add to, e.g., the main function in the application C-file: + * \code + board_init(); + sysclk_init(); + gfx_mono_init(); + gfx_mono_draw_line(10, 10, 20, 20, GFX_PIXEL_SET); +\endcode + * + * \subsection gfx_mono_basic_usage Workflow + * -# Initialize board IO: + * - \code board_init(); \endcode + * -# Initialize clocks: + * - \code sysclk_init(); \endcode + * -# Initialize monochrome graphics service + * - \code gfx_mono_init(); \endcode + * - \note This will call the init function for the low level display + * controller driver and intialize the screen to a cleared background. + * -# Draw a line from 10,10 to 20,20: + * - \code gfx_mono_draw_line(10, 10, 20, 20, GFX_PIXEL_SET); \endcode + * - \note This uses GFX_PIXEL_SET to set the display pixels on the line; + * other options can be found in \ref gfx_mono_color. + */ + +#endif /* GFX_MONO_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono.h.REMOVED.git-id deleted file mode 100644 index 24a4a681..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c548880590e71946b4e3b1e4e85ddcac9caa9cb5 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_c12832_a1z.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_c12832_a1z.c new file mode 100644 index 00000000..ba3758c5 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_c12832_a1z.c @@ -0,0 +1,369 @@ +/** + * \file + * + * \brief Haven Display C12832 A1Z display glue code for display controller + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#include "gfx_mono_c12832_a1z.h" + +/* If we are using a serial interface without readback, use framebuffer */ +#ifdef ST7565R_SERIAL_INTERFACE +# define CONFIG_ST7565R_FRAMEBUFFER +#endif + +#ifdef CONFIG_ST7565R_FRAMEBUFFER +static uint8_t framebuffer[GFX_MONO_LCD_FRAMEBUFFER_SIZE]; +#endif + +/** + * \brief Initialize ST7565R controller and LCD display. + * It will also write the graphic controller RAM to all zeroes. + * + * \note This function will clear the contents of the display. + */ +void gfx_mono_st7565r_init(void) +{ + uint8_t page; + uint8_t column; + +#ifdef CONFIG_ST7565R_FRAMEBUFFER + gfx_mono_set_framebuffer(framebuffer); +#endif + + /* Initialize the low-level display controller. */ + st7565r_init(); + + /* Set display to output data from line 0 */ + st7565r_set_display_start_line_address(0); + + /* Clear the contents of the display. + * If using a framebuffer (SPI interface) it will both clear the + * controller memory and the framebuffer. + */ + for (page = 0; page < GFX_MONO_LCD_PAGES; page++) { + for (column = 0; column < GFX_MONO_LCD_WIDTH; column++) { + gfx_mono_put_byte(page, column, 0x00); + } + } +} + +/** + * \brief Put framebuffer to LCD controller + * + * This function will output the complete framebuffer from RAM to the + * LCD controller. + * + * \note This is done automatically if using the graphic primitives. Only + * needed if you are manipulating the framebuffer directly in your code. + */ +void gfx_mono_st7565r_put_framebuffer(void) +{ + uint8_t page; + + for (page = 0; page < GFX_MONO_LCD_PAGES; page++) { + st7565r_set_page_address(page); + st7565r_set_column_address(0); + gfx_mono_st7565r_put_page(framebuffer + + (page * GFX_MONO_LCD_WIDTH), page, 0, + GFX_MONO_LCD_WIDTH); + } +} + +/** + * \brief Draw pixel to screen + * + * \param x X coordinate of the pixel + * \param y Y coordinate of the pixel + * \param color Pixel operation + * + * The following will set the pixel at x=10,y=10: + * \code + gfx_mono_st7565r_draw_pixel(10, 10, GFX_PIXEL_SET); +\endcode + * The following example will clear the pixel at x=10,y=10: + * \code + gfx_mono_st7565r_draw_pixel(10, 10, GFX_PIXEL_CLR); +\endcode + * And the following will toggle the pixel at x=10,y=10: + * \code + gfx_mono_st7565r_draw_pixel(10, 10, GFX_PIXEL_XOR); +\endcode + */ +void gfx_mono_st7565r_draw_pixel(gfx_coord_t x, gfx_coord_t y, + gfx_coord_t color) +{ + uint8_t page; + uint8_t pixel_mask; + uint8_t pixel_value; + + /* Discard pixels drawn outside the screen */ + if ((x > GFX_MONO_LCD_WIDTH - 1) || (y > GFX_MONO_LCD_HEIGHT - 1)) { + return; + } + + page = y / GFX_MONO_LCD_PIXELS_PER_BYTE; + pixel_mask = (1 << (y - (page * 8))); + + /* + * Read the page containing the pixel in interest, then perform the + * requested action on this pixel before writing the page back to the + * display. + */ + pixel_value = gfx_mono_get_byte(page, x); + + switch (color) { + case GFX_PIXEL_SET: + pixel_value |= pixel_mask; + break; + + case GFX_PIXEL_CLR: + pixel_value &= ~pixel_mask; + break; + + case GFX_PIXEL_XOR: + pixel_value ^= pixel_mask; + break; + + default: + break; + } + + gfx_mono_put_byte(page, x, pixel_value); +} + +/** + * \brief Get the pixel value at x,y + * + * \param x X coordinate of pixel + * \param y Y coordinate of pixel + * \return Non zero value if pixel is set. + * + * The following example will read the pixel value from x=10,y=10: + * \code + pixelval = gfx_mono_st7565r_get_pixel(10,10); +\endcode + */ +uint8_t gfx_mono_st7565r_get_pixel(gfx_coord_t x, gfx_coord_t y) +{ + uint8_t page; + uint8_t pixel_mask; + + if ((x > GFX_MONO_LCD_WIDTH - 1) || (y > GFX_MONO_LCD_HEIGHT - 1)) { + return 0; + } + + page = y / GFX_MONO_LCD_PIXELS_PER_BYTE; + pixel_mask = (1 << (y - (page * 8))); + + return gfx_mono_get_byte(page, x) & pixel_mask; +} + +/** + * \brief Put a page from RAM to display controller. + * + * If the controller is accessed by the SPI interface, we can not read + * back data from the LCD controller RAM. Because of this all data that is + * written to the LCD controller in this mode is also written to a framebuffer + * in MCU RAM. + * + * \param data Pointer to data to be written + * \param page Page address + * \param column Offset into page (x coordinate) + * \param width Number of bytes to be written. + * + * The following example will write 32 bytes from data_buf to the page 0, + * column 10. This will place data_buf in the rectangle x1=10,y1=0,x2=42,y2=8 + * (10 pixels from the upper left corner of the screen): + * \code + gfx_mono_st7565r_put_page(data_buf, 0, 10, 32); +\endcode + */ +void gfx_mono_st7565r_put_page(gfx_mono_color_t *data, gfx_coord_t page, + gfx_coord_t column, gfx_coord_t width) +{ +#ifdef CONFIG_ST7565R_FRAMEBUFFER + gfx_mono_framebuffer_put_page(data, page, column, width); +#endif + st7565r_set_page_address(page); + st7565r_set_column_address(column); + + do { + st7565r_write_data(*data++); + } while (--width); +} + +/** + * \brief Read a page from the LCD controller + * + * If the LCD controller is accessed by the SPI interface we cannot read + * data directly from the controller. In that case we will read the data from + * the local framebuffer instead. + * + * \param data Pointer where to store the read data + * \param page Page address + * \param column Offset into page (x coordinate) + * \param width Number of bytes to be read + * + * The following example will read back the first 128 bytes (first page) from + * the display memory: + * \code + gfx_mono_st7565r_get_page(read_buffer, 0, 0, 128); +\endcode + */ +void gfx_mono_st7565r_get_page(gfx_mono_color_t *data, gfx_coord_t page, + gfx_coord_t column, gfx_coord_t width) +{ +#ifdef CONFIG_ST7565R_FRAMEBUFFER + gfx_mono_framebuffer_get_page(data, page, column, width); +#else + st7565r_set_page_address(page); + st7565r_set_column_address(column); + + do { + *data++ = st7565r_read_data(); + } while (--width); +#endif +} + +/** + * \brief Put a byte to the display controller RAM + * + * If the LCD controller is accessed by the SPI interface we will also put the + * data to the local framebuffer. + * + * \param page Page address + * \param column Page offset (x coordinate) + * \param data Data to be written + * + * This example will put the value 0xFF to the first byte in the display memory + * setting a 8 pixel high column of pixels in the upper left corner of the + * display. + * \code + gfx_mono_st7565r_put_byte(0, 0, 0xFF); +\endcode + */ +void gfx_mono_st7565r_put_byte(gfx_coord_t page, gfx_coord_t column, + uint8_t data) +{ +#ifdef CONFIG_ST7565R_FRAMEBUFFER + gfx_mono_framebuffer_put_byte(page, column, data); +#endif + + st7565r_set_page_address(page); + st7565r_set_column_address(column); + + st7565r_write_data(data); +} + +/** + * \brief Get a byte from the display controller RAM + * + * If the LCD controller is accessed by the SPI interface we cannot read the + * data. In this case return the data from the local framebuffer instead. + * + * \param page Page address + * \param column Page offset (x coordinate) + * \return data from LCD controller or framebuffer. + * + * The following code will read the first byte from the display memory or the + * local framebuffer if direct read is not possible. The data represents the + * pixels from x = 0 and y = 0 to y = 7. + * \code + data = gfx_mono_st7565r_get_byte(0, 0); +\endcode + */ +uint8_t gfx_mono_st7565r_get_byte(gfx_coord_t page, gfx_coord_t column) +{ +#ifdef CONFIG_ST7565R_FRAMEBUFFER + return gfx_mono_framebuffer_get_byte(page, column); + +#else + st7565r_set_page_address(page); + st7565r_set_column_address(column); + + return st7565r_read_data(); + +#endif +} + +/** + * \brief Read/Modify/Write a byte on the display controller + * + * This function will read the byte from the display controller (or the + * framebuffer if we cannot read directly from the controller) and + * do a mask operation on the byte according to the pixel operation selected + * by the color argument and the pixel mask provided. + * + * \param page Page address + * \param column Page offset (x coordinate) + * \param pixel_mask Mask for pixel operation + * \param color Pixel operation + * + * A small example that will XOR the first byte of display memory with 0xAA + * \code + gfx_mono_st7565r_mask_byte(0,0,0xAA,GFX_PIXEL_XOR); +\endcode + */ +void gfx_mono_st7565r_mask_byte(gfx_coord_t page, gfx_coord_t column, + gfx_mono_color_t pixel_mask, gfx_mono_color_t color) +{ + gfx_mono_color_t temp = gfx_mono_get_byte(page, column); + + switch (color) { + case GFX_PIXEL_SET: + temp |= pixel_mask; + break; + + case GFX_PIXEL_CLR: + temp &= ~pixel_mask; + break; + + case GFX_PIXEL_XOR: + temp ^= pixel_mask; + break; + + default: + break; + } + + gfx_mono_put_byte(page, column, temp); +} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_c12832_a1z.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_c12832_a1z.c.REMOVED.git-id deleted file mode 100644 index 46a5bfc2..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_c12832_a1z.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ba3758c5bed09192126124cfc926e6fc75637b87 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_c12832_a1z.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_c12832_a1z.h new file mode 100644 index 00000000..1fe5acff --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_c12832_a1z.h @@ -0,0 +1,158 @@ +/** + * \file + * + * \brief Haven Display C12832 A1Z display glue code for display controller + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef GFX_MONO_C12832_A1Z_H +#define GFX_MONO_C12832_A1Z_H +#include "compiler.h" +#include "st7565r.h" + +#include "gfx_mono.h" +#include "gfx_mono_framebuffer.h" + +/** + * \ingroup gfx_mono + * \defgroup gfx_mono_C12832_A1Z_group C12832_A1Z graphic library abstraction + * + * This module is an abstraction layer between the graphic library and the + * C12832_A1Z monochrome LCD display connected to a ST7565R LCD controller. + * + * As the controller does not provide any hardware accelerated graphic, all the + * graphic primitives are provided by the \ref gfx_mono_generic_group service. + * + * \note Do not call the gfx_mono_st7565r_ functions directly. use the gfx_mono + * names that are defined in this header and documented in \ref gfx_mono . + * Ie. gfx_mono_draw_pixel() should be used, not gfx_mono_st7565r_draw_pixel() + * @{ + */ + +#define GFX_MONO_LCD_WIDTH 128 +#define GFX_MONO_LCD_HEIGHT 32 +#define GFX_MONO_LCD_PIXELS_PER_BYTE 8 +#define GFX_MONO_LCD_PAGES (GFX_MONO_LCD_HEIGHT / \ + GFX_MONO_LCD_PIXELS_PER_BYTE) +#define GFX_MONO_LCD_FRAMEBUFFER_SIZE ((GFX_MONO_LCD_WIDTH * \ + GFX_MONO_LCD_HEIGHT) / GFX_MONO_LCD_PIXELS_PER_BYTE) + +#define gfx_mono_draw_horizontal_line(x, y, length, color) \ + gfx_mono_generic_draw_horizontal_line(x, y, length, color) + +#define gfx_mono_draw_vertical_line(x, y, length, color) \ + gfx_mono_generic_draw_vertical_line(x, y, length, color) + +#define gfx_mono_draw_line(x1, y1, x2, y2, color) \ + gfx_mono_generic_draw_line(x1, y1, x2, y2, color) + +#define gfx_mono_draw_rect(x, y, width, height, color) \ + gfx_mono_generic_draw_rect(x, y, width, height, color) + +#define gfx_mono_draw_filled_rect(x, y, width, height, color) \ + gfx_mono_generic_draw_filled_rect(x, y, width, height, \ + color) + +#define gfx_mono_draw_circle(x, y, radius, color, octant_mask) \ + gfx_mono_generic_draw_circle(x, y, radius, color, \ + octant_mask) + +#define gfx_mono_draw_filled_circle(x, y, radius, color, quadrant_mask) \ + gfx_mono_generic_draw_filled_circle(x, y, radius, \ + color, quadrant_mask) + +#define gfx_mono_put_bitmap(bitmap, x, y) \ + gfx_mono_generic_put_bitmap(bitmap, x, y) + +#define gfx_mono_draw_pixel(x, y, color) \ + gfx_mono_st7565r_draw_pixel(x, y, color) + +#define gfx_mono_get_pixel(x, y) \ + gfx_mono_st7565r_get_pixel(x, y) + +#define gfx_mono_init() \ + gfx_mono_st7565r_init() + +#define gfx_mono_put_page(data, page, column, width) \ + gfx_mono_st7565r_put_page(data, page, column, width) + +#define gfx_mono_get_page(data, page, column, width) \ + gfx_mono_st7565r_get_page(data, page, column, width) + +#define gfx_mono_put_byte(page, column, data) \ + gfx_mono_st7565r_put_byte(page, column, data) + +#define gfx_mono_get_byte(page, column) \ + gfx_mono_st7565r_get_byte(page, column) + +#define gfx_mono_mask_byte(page, column, pixel_mask, color) \ + gfx_mono_st7565r_mask_byte(page, column, pixel_mask, color) + +#define gfx_mono_put_framebuffer() \ + gfx_mono_st7565r_put_framebuffer() + +void gfx_mono_st7565r_put_framebuffer(void); + +void gfx_mono_st7565r_put_page(gfx_mono_color_t *data, gfx_coord_t page, + gfx_coord_t page_offset, gfx_coord_t width); + +void gfx_mono_st7565r_get_page(gfx_mono_color_t *data, gfx_coord_t page, + gfx_coord_t page_offset, gfx_coord_t width); + +void gfx_mono_st7565r_init(void); + +void gfx_mono_st7565r_draw_pixel(gfx_coord_t x, gfx_coord_t y, + gfx_mono_color_t color); + +uint8_t gfx_mono_st7565r_get_pixel(gfx_coord_t x, gfx_coord_t y); + +void gfx_mono_st7565r_put_byte(gfx_coord_t page, gfx_coord_t column, + uint8_t data); + +uint8_t gfx_mono_st7565r_get_byte(gfx_coord_t page, gfx_coord_t column); + +void gfx_mono_st7565r_mask_byte(gfx_coord_t page, gfx_coord_t column, + gfx_mono_color_t pixel_mask, gfx_mono_color_t color); + +/** @} */ + +#endif /* GFX_MONO_C12832_A1Z_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_c12832_a1z.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_c12832_a1z.h.REMOVED.git-id deleted file mode 100644 index 5c440351..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_c12832_a1z.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1fe5acffbf067acbfa022e9a98e0245d20a2ebd8 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_framebuffer.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_framebuffer.c new file mode 100644 index 00000000..4a1d2939 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_framebuffer.c @@ -0,0 +1,265 @@ +/** + * \file + * + * \brief Local framebuffer + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "gfx_mono_framebuffer.h" + +/* Pointer to the framebuffer; updated by the gfx_mono_set_framebuffer function */ +static uint8_t *fbpointer; + +/* \brief Set the LCD framebuffer. + * + * \param framebuffer A pointer to an allocated area of RAM that can hold the + * framebuffer. + * + * A small example: + * \code + uint8_t framebuffer[FRAMEBUFFER_SIZE]; + gfx_mono_set_framebuffer(framebuffer); +\endcode + */ +void gfx_mono_set_framebuffer(uint8_t *framebuffer) +{ + fbpointer = framebuffer; +} + +/** + * \brief Put a page from RAM to the framebuffer + * + * \param data Pointer to data to be written + * \param page Page address + * \param column Offset into page (x coordinate) + * \param width Number of bytes to be written. + * + * The following example will write 32 bytes from data_buf to the page 0, + * column 10 (byte 10 to 42 in the framebuffer). + * \code + gfx_mono_framebuffer_put_page(data_buf, 0, 10, 32); +\endcode + */ +void gfx_mono_framebuffer_put_page(gfx_mono_color_t *data, gfx_coord_t page, + gfx_coord_t column, gfx_coord_t width) +{ + gfx_mono_color_t *data_pt = data; + gfx_coord_t *framebuffer_pt = fbpointer + + ((page * GFX_MONO_LCD_WIDTH) + column); + + do { + *framebuffer_pt++ = *data_pt++; + } while (--width > 0); +} + +/** + * \brief Read a page from the framebuffer + * + * \param data Pointer where to store the read data + * \param page Page address + * \param column Offset into page (x coordinate) + * \param width Number of bytes to be read + * + * The following example will read back the first 128 bytes (first page) from + * the framebuffer: + * \code + gfx_mono_framebuffer_get_page(read_buffer, 0, 0, 128); +\endcode + */ +void gfx_mono_framebuffer_get_page(gfx_mono_color_t *data, gfx_coord_t page, \ + gfx_coord_t column, gfx_coord_t width) +{ + gfx_coord_t *framebuffer_pt = fbpointer + + ((page * GFX_MONO_LCD_WIDTH) + column); + do { + *data++ = *framebuffer_pt++; + } while (--width > 0); +} + +/** + * \brief Draw pixel to framebuffer + * + * \param x X coordinate of the pixel + * \param y Y coordinate of the pixel + * \param color Pixel operation + * + */ +void gfx_mono_framebuffer_draw_pixel(gfx_coord_t x, gfx_coord_t y, + gfx_mono_color_t color) +{ + uint8_t page; + uint8_t pixel_mask; + uint8_t pixel_value; + + /* Discard pixels drawn outside the screen */ + if ((x > GFX_MONO_LCD_WIDTH - 1) || (y > GFX_MONO_LCD_HEIGHT - 1)) { + return; + } + + page = y / GFX_MONO_LCD_PIXELS_PER_BYTE; + pixel_mask = (1 << (y - (page * 8))); + + /* + * Read the page containing the pixel in interest, then perform the + * requested action on this pixel before writing the page back to the + * display. + */ + pixel_value = gfx_mono_framebuffer_get_byte(page, x); + + switch (color) { + case GFX_PIXEL_SET: + pixel_value |= pixel_mask; + break; + + case GFX_PIXEL_CLR: + pixel_value &= ~pixel_mask; + break; + + case GFX_PIXEL_XOR: + pixel_value ^= pixel_mask; + break; + + default: + break; + } + + gfx_mono_framebuffer_put_byte(page, x, pixel_value); +} + +/** + * \brief Get the pixel value at x,y in framebuffer + * + * \param x X coordinate of pixel + * \param y Y coordinate of pixel + * \return Non zero value if pixel is set. + * + */ +uint8_t gfx_mono_framebuffer_get_pixel(gfx_coord_t x, gfx_coord_t y) +{ + uint8_t page; + uint8_t pixel_mask; + + if ((x > GFX_MONO_LCD_WIDTH - 1) || (y > GFX_MONO_LCD_HEIGHT - 1)) { + return 0; + } + + page = y / GFX_MONO_LCD_PIXELS_PER_BYTE; + pixel_mask = (1 << (y - (page * 8))); + + return gfx_mono_framebuffer_get_byte(page, x) & pixel_mask; +} + +/** + * \brief Put a byte to the framebuffer + * + * \param page Page address + * \param column Page offset (x coordinate) + * \param data Data to be written + * + * This example will put the value 0xFF to the first byte in the framebuffer + * \code + gfx_mono_framebuffer_put_byte(0, 0, 0xFF); +\endcode + */ +void gfx_mono_framebuffer_put_byte(gfx_coord_t page, gfx_coord_t column, + uint8_t data) +{ + *(fbpointer + (page * GFX_MONO_LCD_WIDTH) + column) = data; +} + +/** + * \brief Get a byte from the framebuffer + * + * \param page Page address + * \param column Page offset (x coordinate) + * \return data from LCD controller or framebuffer. + * + * The following code will read the first byte of the framebuffer + * \code + data = gfx_mono_framebuffer_get_byte(0, 0); +\endcode + */ +uint8_t gfx_mono_framebuffer_get_byte(gfx_coord_t page, gfx_coord_t column) +{ + return *(fbpointer + (page * GFX_MONO_LCD_WIDTH) + column); +} + +/** + * \brief Read/Modify/Write a byte in the framebuffer + * + * This function will read the byte from the framebuffer and + * do a mask operation on the byte according to the pixel operation selected + * by the color argument and the pixel mask provided. + * + * \param page Page address + * \param column Page offset (x coordinate) + * \param pixel_mask Mask for pixel operation + * \param color Pixel operation + * + * A small example that will XOR the first byte of the framebuffer with 0xAA + * \code + gfx_mono_framebuffer_mask_byte(0,0,0xAA,GFX_PIXEL_XOR); +\endcode + */ +void gfx_mono_framebuffer_mask_byte(gfx_coord_t page, gfx_coord_t column, + gfx_mono_color_t pixel_mask, gfx_mono_color_t color) +{ + gfx_mono_color_t temp; + + temp = gfx_mono_get_byte(page, column); + + switch (color) { + case GFX_PIXEL_SET: + temp |= pixel_mask; + break; + + case GFX_PIXEL_CLR: + temp &= ~pixel_mask; + break; + + case GFX_PIXEL_XOR: + temp ^= pixel_mask; + break; + } + + gfx_mono_put_byte(page, column, temp); +} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_framebuffer.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_framebuffer.c.REMOVED.git-id deleted file mode 100644 index 9ae63d7f..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_framebuffer.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4a1d293910dd0d9f4355d64bfa35254788288fc6 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_framebuffer.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_framebuffer.h new file mode 100644 index 00000000..a3118409 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_framebuffer.h @@ -0,0 +1,87 @@ +/** + * \file + * + * \brief Monochrome graphic library framebuffer device + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef GFX_MONO_FRAMEBUFFER +#define GFX_MONO_FRAMEBUFFER + +#include "gfx_mono.h" + +/** + * \ingroup gfx_mono + * \defgroup gfx_mono_framebuffer_group Framebuffer + * + * This module provides read/write from and to a framebuffer in RAM. This is + * needed when using a controller that does not provide a way to read back data + * from the LCD controller memory. In this case we need to buffer the data in + * a local framebuffer to allow manipulation on pixel level. It is generally + * not recommended to access the framebuffer directly; this is handled by the + * graphic driver when needed. + * + * @{ + */ + +void gfx_mono_set_framebuffer(uint8_t *framebuffer); + +void gfx_mono_framebuffer_put_page(gfx_mono_color_t *data, gfx_coord_t page, + gfx_coord_t page_offset, gfx_coord_t width); + +void gfx_mono_framebuffer_get_page(gfx_mono_color_t *data, gfx_coord_t page, + gfx_coord_t page_offset, gfx_coord_t width); + +void gfx_mono_framebuffer_draw_pixel(gfx_coord_t x, gfx_coord_t y, + gfx_mono_color_t color); + +uint8_t gfx_mono_framebuffer_get_pixel(gfx_coord_t x, gfx_coord_t y); + +void gfx_mono_framebuffer_put_byte(gfx_coord_t page, gfx_coord_t column, + uint8_t data); + +uint8_t gfx_mono_framebuffer_get_byte(gfx_coord_t page, gfx_coord_t column); + +void gfx_mono_framebuffer_mask_byte(gfx_coord_t page, gfx_coord_t column, + gfx_mono_color_t pixel_mask, gfx_mono_color_t color); + +/** @} */ +#endif /* GFX_MONO_FRAMEBUFFER */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_framebuffer.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_framebuffer.h.REMOVED.git-id deleted file mode 100644 index 2d449820..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_framebuffer.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a31184094b0e2a83f94f2b50d60d9a81447d419f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_generic.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_generic.c new file mode 100644 index 00000000..38e98345 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_generic.c @@ -0,0 +1,506 @@ +/** + * \file + * + * \brief Generic monochrome LCD graphic primitives + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +/** + * \ingroup gfx_mono_generic_group + * @{ + */ +/* + * Support and FAQ: visit Atmel Support + */ +#include "gfx_mono_generic.h" + +/** + * \brief Draw a horizontal line, one pixel wide (generic implementation) + * + * \note This function does a very simple bounds checking that does not + * check if the line is placed outside the screen. If you supply an + * x- or y-coordinate outside the display the behaviour is undefined, + * and you risk overwriting portions of internal SRAM. + * + * \param x X coordinate of leftmost pixel. + * \param y Y coordinate of the line. + * \param length Length of the line in pixels. + * \param color Pixel operation of the line. + */ +void gfx_mono_generic_draw_horizontal_line(gfx_coord_t x, gfx_coord_t y, + gfx_coord_t length, enum gfx_mono_color color) +{ + uint8_t page; + uint8_t pixelmask; + uint8_t temp; + + /* Clip line length if too long */ + if (x + length > GFX_MONO_LCD_WIDTH) { + length = GFX_MONO_LCD_WIDTH - x; + } + + page = y / 8; + pixelmask = (1 << (y - (page * 8))); + + if (length == 0) { + /* Nothing to do. Move along. */ + return; + } + + switch (color) { + case GFX_PIXEL_SET: + while (length-- > 0) { + temp = gfx_mono_get_byte(page, x + length); + temp |= pixelmask; + gfx_mono_put_byte(page, x + length, temp); + } + break; + + case GFX_PIXEL_CLR: + while (length-- > 0) { + temp = gfx_mono_get_byte(page, x + length); + temp &= ~pixelmask; + gfx_mono_put_byte(page, x + length, temp); + } + break; + + case GFX_PIXEL_XOR: + while (length-- > 0) { + temp = gfx_mono_get_byte(page, x + length); + temp ^= pixelmask; + gfx_mono_put_byte(page, x + length, temp); + } + break; + + default: + break; + } +} + +/** + * \brief Draw a vertical line, one pixel wide (generic implementation) + * + * \note This function does a very simple bounds checking that does not + * check if the line is placed outside the screen. If you supply an + * x- or y-coordinate outside the display the behaviour is undefined, + * and you risk overwriting portions of internal SRAM. + * + * \param x X coordinate of the line. + * \param y Y coordinate of the topmost pixel. + * \param length Length of the line in pixels. + * \param color Pixel operation of the line. + */ +void gfx_mono_generic_draw_vertical_line(gfx_coord_t x, gfx_coord_t y, + gfx_coord_t length, enum gfx_mono_color color) +{ + if (length == 0) { + return; + } + + gfx_coord_t y2 = y + length - 1; + + if (y == y2) { + gfx_mono_draw_pixel(x, y, color); + return; + } + + if (y2 >= GFX_MONO_LCD_HEIGHT - 1) { + y2 = GFX_MONO_LCD_HEIGHT - 1; + } + + gfx_coord_t y1page = y / 8; + gfx_coord_t y2page = y2 / 8; + + uint8_t y1bitpos = y & 0x07; + uint8_t y2bitpos = y2 & 0x07; + + uint8_t y1pixelmask = 0xFF << y1bitpos; + uint8_t y2pixelmask = 0xFF >> (7 - y2bitpos); + + /* The pixels are on the same page; combine masks */ + if (y1page == y2page) { + uint8_t pixelmask = y1pixelmask & y2pixelmask; + gfx_mono_mask_byte(y1page, x, pixelmask, color); + } else { + gfx_mono_mask_byte(y1page, x, y1pixelmask, color); + + while (++y1page < y2page) { + gfx_mono_mask_byte(y1page, x, 0xFF, color); + } + + gfx_mono_mask_byte(y2page, x, y2pixelmask, color); + } +} + +/** + * \brief Draw a line between two arbitrary points (generic implementation). + * + * \param x1 Start X coordinate. + * \param y1 Start Y coordinate. + * \param x2 End X coordinate. + * \param y2 End Y coordinate. + * \param color Pixel operation of the line. + */ +void gfx_mono_generic_draw_line(gfx_coord_t x1, gfx_coord_t y1, + gfx_coord_t x2, gfx_coord_t y2, + enum gfx_mono_color color) +{ + uint8_t i; + uint8_t x; + uint8_t y; + int8_t xinc; + int8_t yinc; + int8_t dx; + int8_t dy; + int8_t e; + + /* swap x1,y1 with x2,y2 */ + if (x1 > x2) { + dx = x1; + x1 = x2; + x2 = dx; + dy = y1; + y1 = y2; + y2 = dy; + } + + dx = x2 - x1; + dy = y2 - y1; + + x = x1; + y = y1; + + if (dx < 0) { + xinc = -1; + dx = -dx; + } else { + xinc = 1; + } + + if (dy < 0) { + yinc = -1; + dy = -dy; + } else { + yinc = 1; + } + + if (dx > dy) { + e = dy - dx; + for (i = 0; i <= dx; i++) { + gfx_mono_draw_pixel(x, y, color); + if (e >= 0) { + e -= dx; + y += yinc; + } + + e += dy; + x += xinc; + } + } else { + e = dx - dy; + for (i = 0; i <= dy; i++) { + gfx_mono_draw_pixel(x, y, color); + if (e >= 0) { + e -= dy; + x += xinc; + } + + e += dx; + y += yinc; + } + } +} + +/** + * \brief Draw an outline of a rectangle (generic implementation). + * + * \param x X coordinate of the left side. + * \param y Y coordinate of the top side. + * \param width Width of the rectangle. + * \param height Height of the rectangle. + * \param color Pixel operation of the line. + */ +void gfx_mono_generic_draw_rect(gfx_coord_t x, gfx_coord_t y, + gfx_coord_t width, gfx_coord_t height, + enum gfx_mono_color color) +{ + gfx_mono_draw_horizontal_line(x, y, width, color); + gfx_mono_draw_horizontal_line(x, y + height - 1, width, color); + + gfx_mono_draw_vertical_line(x, y, height, color); + gfx_mono_draw_vertical_line(x + width - 1, y, height, color); +} + +/** + * \brief Draw a filled rectangle (generic implementation). + * + * \param x X coordinate of the left side. + * \param y Y coordinate of the top side. + * \param width Width of the rectangle. + * \param height Height of the rectangle. + * \param color Pixel operation of the line + */ +void gfx_mono_generic_draw_filled_rect(gfx_coord_t x, gfx_coord_t y, + gfx_coord_t width, gfx_coord_t height, + enum gfx_mono_color color) +{ + if (height == 0) { + /* Nothing to do. Move along. */ + return; + } + + while (height-- > 0) { + gfx_mono_draw_horizontal_line(x, y + height, width, color); + } +} + +/** + * \brief Draw an outline of a circle or arc (generic implementation). + * + * The radius is the distance from the center to the circumference, + * which means that the total width or height of a circle will be + * (radius*2+1). + * + * The octant_mask parameter is a bitmask that decides which octants of + * the circle to draw. Use the GFX_OCTANTn, GFX_QUADRANTn, GFX_xHALF and + * GFX_WHOLE constants and OR them together if required. Radius equal to + * zero gives a single pixel. + * + * \param x X coordinate of center. + * \param y Y coordinate of center. + * \param radius Circle radius in pixels. + * \param color Pixel operation. + * \param octant_mask Bitmask indicating which octants to draw. + */ +void gfx_mono_generic_draw_circle(gfx_coord_t x, gfx_coord_t y, + gfx_coord_t radius, enum gfx_mono_color color, + uint8_t octant_mask) +{ + gfx_coord_t offset_x; + gfx_coord_t offset_y; + int16_t error; + + /* Draw only a pixel if radius is zero. */ + if (radius == 0) { + gfx_mono_draw_pixel(x, y, color); + return; + } + + /* Set up start iterators. */ + offset_x = 0; + offset_y = radius; + error = 3 - 2 * radius; + + /* Iterate offsetX from 0 to radius. */ + while (offset_x <= offset_y) { + /* Draw one pixel for each octant enabled in octant_mask. */ + if (octant_mask & GFX_OCTANT0) { + gfx_mono_draw_pixel(x + offset_y, y - offset_x, color); + } + + if (octant_mask & GFX_OCTANT1) { + gfx_mono_draw_pixel(x + offset_x, y - offset_y, color); + } + + if (octant_mask & GFX_OCTANT2) { + gfx_mono_draw_pixel(x - offset_x, y - offset_y, color); + } + + if (octant_mask & GFX_OCTANT3) { + gfx_mono_draw_pixel(x - offset_y, y - offset_x, color); + } + + if (octant_mask & GFX_OCTANT4) { + gfx_mono_draw_pixel(x - offset_y, y + offset_x, color); + } + + if (octant_mask & GFX_OCTANT5) { + gfx_mono_draw_pixel(x - offset_x, y + offset_y, color); + } + + if (octant_mask & GFX_OCTANT6) { + gfx_mono_draw_pixel(x + offset_x, y + offset_y, color); + } + + if (octant_mask & GFX_OCTANT7) { + gfx_mono_draw_pixel(x + offset_y, y + offset_x, color); + } + + /* Update error value and step offset_y when required. */ + if (error < 0) { + error += ((offset_x << 2) + 6); + } else { + error += (((offset_x - offset_y) << 2) + 10); + --offset_y; + } + + /* Next X. */ + ++offset_x; + } +} + +/** + * \brief Draw a filled circle or sector (generic implementation). + * + * The radius is the distance from the center to the circumference, + * which means that the total width or height of a circle will be + * (radius*2+1). + * + * The quadrant_mask parameter is a bitmask that decides which quadrants + * of the circle to draw. Use the GFX_QUADRANTn, GFX_xHALF and + * GFX_WHOLE constants and OR them together if required. Radius equal to + * zero gives a single pixel. + * + * \note This function only supports quadrants while gfx_draw_circle() + * supports octants. This is to improve performance on drawing + * filled circles. + * + * \param x X coordinate of center. + * \param y Y coordinate of center. + * \param radius Circle radius in pixels. + * \param color Pixel operation. + * \param quadrant_mask Bitmask indicating which quadrants to draw. + */ +void gfx_mono_generic_draw_filled_circle(gfx_coord_t x, gfx_coord_t y, + gfx_coord_t radius, enum gfx_mono_color color, + uint8_t quadrant_mask) +{ + gfx_coord_t offset_x; + gfx_coord_t offset_y; + int16_t error; + + /* Draw only a pixel if radius is zero. */ + if (radius == 0) { + gfx_mono_draw_pixel(x, y, color); + return; + } + + /* Set up start iterators. */ + offset_x = 0; + offset_y = radius; + error = 3 - 2 * radius; + + /* Iterate offset_x from 0 to radius. */ + while (offset_x <= offset_y) { + /* Draw vertical lines tracking each quadrant. */ + if (quadrant_mask & GFX_QUADRANT0) { + gfx_mono_draw_vertical_line(x + offset_y, + y - offset_x, offset_x + 1, color); + gfx_mono_draw_vertical_line(x + offset_x, + y - offset_y, offset_y + 1, color); + } + + if (quadrant_mask & GFX_QUADRANT1) { + gfx_mono_draw_vertical_line(x - offset_y, + y - offset_x, offset_x + 1, color); + gfx_mono_draw_vertical_line(x - offset_x, + y - offset_y, offset_y + 1, color); + } + + if (quadrant_mask & GFX_QUADRANT2) { + gfx_mono_draw_vertical_line(x - offset_y, + y, offset_x + 1, color); + gfx_mono_draw_vertical_line(x - offset_x, + y, offset_y + 1, color); + } + + if (quadrant_mask & GFX_QUADRANT3) { + gfx_mono_draw_vertical_line(x + offset_y, + y, offset_x + 1, color); + gfx_mono_draw_vertical_line(x + offset_x, + y, offset_y + 1, color); + } + + /* Update error value and step offset_y when required. */ + if (error < 0) { + error += ((offset_x << 2) + 6); + } else { + error += (((offset_x - offset_y) << 2) + 10); + --offset_y; + } + + /* Next X. */ + ++offset_x; + } +} + +/** + * \brief Put bitmap from FLASH or RAM to display + * + * This function will output bitmap data from FLASH or RAM. + * The bitmap y-coordinate will be aligned with display pages, rounded down. + * Ie: placing a bitmap at x=10, y=5 will put the bitmap at x = 10,y = 0 and + * placing a bitmap at x = 10, y = 10 will put the bitmap at x = 10, y = 8 + * + */ +void gfx_mono_generic_put_bitmap(struct gfx_mono_bitmap *bitmap, gfx_coord_t x, + gfx_coord_t y) +{ + gfx_coord_t num_pages = bitmap->height / 8; + gfx_coord_t page = y / 8; + gfx_coord_t column; + gfx_coord_t i; + gfx_mono_color_t temp; + + switch (bitmap->type) { + case GFX_MONO_BITMAP_PROGMEM: + for (i = 0; i < num_pages; i++) { + for (column = 0; column < bitmap->width; column++) { + temp = PROGMEM_READ_BYTE(bitmap->data.progmem + + (i * bitmap->width) + + column); + gfx_mono_put_byte(i + page, column + x, temp); + } + } + break; + + case GFX_MONO_BITMAP_RAM: + for (i = 0; i < num_pages; i++) { + gfx_mono_put_page(bitmap->data.pixmap + + (i * bitmap->width), page + i, x, + bitmap->width); + } + break; + + default: + break; + } +} + +/** @} */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_generic.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_generic.c.REMOVED.git-id deleted file mode 100644 index c92358fe..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_generic.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -38e98345e46d2183e8a8340da0d395ddf857c183 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_generic.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_generic.h new file mode 100644 index 00000000..4701e943 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_generic.h @@ -0,0 +1,123 @@ +/** + * \file + * + * \brief Generic monochrome LCD graphic primitives + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef GFX_MONO_GENERIC +#define GFX_MONO_GENERIC +#include "gfx_mono.h" + +/** + * \ingroup gfx_mono + * \defgroup gfx_mono_generic_group Generic monochrome graphic primitives + * + * This is a service providing generic implementations of graphic primitives + * - Horizontal line + * - Vertical line + * - Line + * - Circle (filled/not filled) + * - Rectangle (filled/not filled) + * + * it also provides functionality to draw a bitmap to the graphic memory. + * + * These functions are made available if the graphic hardware being used do + * not implement the functionality in hardware. This is true in most cases. + * + * This service is included as a requirement for a + * hardware specific component that uses these functions, and provides a + * gfx_draw_pixel function. + * + * @{ + */ + +/** + * \brief Storage structure for bitmap pixel data and metadata + */ +struct gfx_mono_bitmap { + /** Width of bitmap */ + gfx_coord_t width; + /** Height of bitmap */ + gfx_coord_t height; + /** Bitmap type */ + enum gfx_mono_bitmap_type type; + union { + /** Pointer to pixels for bitmap stored in RAM */ + gfx_mono_color_t *pixmap; + /** Pointer to pixels for bitmap stored in progmem */ + gfx_mono_color_t PROGMEM_T *progmem; + } + data; +}; + +void gfx_mono_generic_draw_horizontal_line(gfx_coord_t x, gfx_coord_t y, + gfx_coord_t length, enum gfx_mono_color color); + +void gfx_mono_generic_draw_vertical_line(gfx_coord_t x, gfx_coord_t y, + gfx_coord_t length, enum gfx_mono_color color); + +void gfx_mono_generic_draw_line(gfx_coord_t x1, gfx_coord_t y1, + gfx_coord_t x2, gfx_coord_t y2, + enum gfx_mono_color color); + +void gfx_mono_generic_draw_rect(gfx_coord_t x, gfx_coord_t y, + gfx_coord_t width, gfx_coord_t height, + enum gfx_mono_color color); + +void gfx_mono_generic_draw_filled_rect(gfx_coord_t x, gfx_coord_t y, + gfx_coord_t width, gfx_coord_t height, + enum gfx_mono_color color); + +void gfx_mono_generic_draw_circle(gfx_coord_t x, gfx_coord_t y, + gfx_coord_t radius, enum gfx_mono_color color, + uint8_t octant_mask); + +void gfx_mono_generic_draw_filled_circle(gfx_coord_t x, gfx_coord_t y, + gfx_coord_t radius, enum gfx_mono_color color, + uint8_t quadrant_mask); + +void gfx_mono_generic_put_bitmap(struct gfx_mono_bitmap *bitmap, gfx_coord_t x, + gfx_coord_t y); + +/** @} */ + +#endif /* GFX_MONO_GENERIC */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_generic.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_generic.h.REMOVED.git-id deleted file mode 100644 index 5a73cc38..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_generic.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4701e943c5ebcf0f92cb5c3583d76f3eb415dc4b \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_menu.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_menu.c new file mode 100644 index 00000000..f278a292 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_menu.c @@ -0,0 +1,188 @@ +/** + * \file + * + * \brief Simple menu system + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "sysfont.h" +#include "gfx_mono.h" +#include + +#include "gfx_mono_menu.h" + +/** + * \ingroup gfx_mono_menu + * @{ + */ + +PROGMEM_DECLARE(gfx_mono_color_t, arrow_right_data[]) = { + GFX_MONO_MENU_INDICATOR_BITMAP +}; + +struct gfx_mono_bitmap menu_bitmap_indicator = { + .height = GFX_MONO_MENU_INDICATOR_HEIGHT, + .width = GFX_MONO_MENU_INDICATOR_WIDTH, + .type = GFX_MONO_BITMAP_PROGMEM, + .data.progmem = arrow_right_data +}; + +/** + * \brief Draw menu strings and an icon by the current selection. + * + * \param menu a menu struct with menu settings + * \param redraw clear screen before drawing menu + */ +static void menu_draw(struct gfx_mono_menu *menu, bool redraw) +{ + static bool redraw_state; + uint8_t i; + uint8_t line = 1; + uint8_t menu_page = menu->current_selection / + GFX_MONO_MENU_ELEMENTS_PER_SCREEN; + + if (menu->current_page != menu_page || redraw == true) { + /* clear screen if we have changed the page or menu and prepare + * redraw */ + gfx_mono_draw_filled_rect(0, SYSFONT_LINESPACING, + GFX_MONO_LCD_WIDTH, + GFX_MONO_LCD_HEIGHT - SYSFONT_LINESPACING, + GFX_PIXEL_CLR); + redraw_state = true; + } + + menu->current_page = menu_page; + + /* Clear old indicator icon */ + gfx_mono_draw_filled_rect(0, SYSFONT_LINESPACING, + GFX_MONO_MENU_INDICATOR_WIDTH, GFX_MONO_LCD_HEIGHT - + SYSFONT_LINESPACING, GFX_PIXEL_CLR); + + /* Put indicator icon on current selection */ + gfx_mono_put_bitmap(&menu_bitmap_indicator, 0, + SYSFONT_LINESPACING * ((menu->current_selection % + GFX_MONO_MENU_ELEMENTS_PER_SCREEN) + 1)); + + /* Print visible options if page or menu has changed */ + if (redraw_state == true) { + for (i = menu_page * GFX_MONO_MENU_ELEMENTS_PER_SCREEN; + i < menu_page * + GFX_MONO_MENU_ELEMENTS_PER_SCREEN + + GFX_MONO_MENU_ELEMENTS_PER_SCREEN && + i < menu->num_elements; i++) { + gfx_mono_draw_progmem_string( + (char PROGMEM_PTR_T)menu->strings[i], + GFX_MONO_MENU_INDICATOR_WIDTH + 1, + line * SYSFONT_LINESPACING, &sysfont); + line++; + } + redraw_state = false; + } +} + +/** + * *\brief Initialize the menu handling. Clear screen and draw menu. + * + * \param menu menu struct with menu options + * + */ +void gfx_mono_menu_init(struct gfx_mono_menu *menu) +{ + /* Clear screen */ + gfx_mono_draw_filled_rect(0, 0, + GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT, GFX_PIXEL_CLR); + + /* Draw the menu title on the top of the screen */ + gfx_mono_draw_progmem_string((char PROGMEM_PTR_T)menu->title, + 0, 0, &sysfont); + + /* Draw menu options below */ + menu_draw(menu, true); +} + +/** + * \brief Update menu depending on input. + * + * \param menu menu struct with menu options + * \param keycode keycode to process + * + * \retval selected menu option or status code + */ +uint8_t gfx_mono_menu_process_key(struct gfx_mono_menu *menu, uint8_t keycode) +{ + switch (keycode) { + case GFX_MONO_MENU_KEYCODE_DOWN: + if (menu->current_selection == menu->num_elements - 1) { + menu->current_selection = 0; + } else { + menu->current_selection++; + } + + /* Update menu on display */ + menu_draw(menu, false); + /* Nothing selected yet */ + return GFX_MONO_MENU_EVENT_IDLE; + + case GFX_MONO_MENU_KEYCODE_UP: + if (menu->current_selection) { + menu->current_selection--; + } else { + menu->current_selection = menu->num_elements - 1; + } + + /* Update menu on display */ + menu_draw(menu, false); + /* Nothing selected yet */ + return GFX_MONO_MENU_EVENT_IDLE; + + case GFX_MONO_MENU_KEYCODE_ENTER: + /* Got what we want. Return selection. */ + return menu->current_selection; + + case GFX_MONO_MENU_KEYCODE_BACK: + /* User pressed "back" key, inform user */ + return GFX_MONO_MENU_EVENT_EXIT; + + default: + /* Unknown key event */ + return GFX_MONO_MENU_EVENT_IDLE; + } +} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_menu.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_menu.c.REMOVED.git-id deleted file mode 100644 index 1f8843c9..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_menu.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f278a2926bda7a4c5250345994e843b91d548173 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_menu.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_menu.h new file mode 100644 index 00000000..1536a823 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_menu.h @@ -0,0 +1,127 @@ +/** + * \file + * + * \brief Simple menu system + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef GFX_MONO_MENU_H +#define GFX_MONO_MENU_H + +#include "compiler.h" +#include "conf_menu.h" + +/** + * \ingroup gfx_mono + * \defgroup gfx_mono_menu Menu system for monochrome graphical displays + * + * This module provides a simple menu system for monochrome graphical + * displays. + * + * Typical flow of an application using the menu system: + * + * 1) Define menu structure.\n + * 2) Call gfx_mono_menu_init.\n + * 3) Get user input.\n + * 4) Update menu with user input using function \ref + * gfx_mono_menu_process_key.\n + * 5) Interpret \ref gfx_mono_menu_process_key return value.\n + * 6) Go to 3.\n + * + * The menu is declared using the \ref gfx_mono_menu struct. + * + * To start the menu system, call the \ref gfx_mono_menu_init function. + * This function will clear the display and draw the menu. + * + * Before the menu can be updated, you need input from the user. Methods for + * getting input is not part of the menu module. + * + * As soon as input is received, inform the menu system using the + * \ref gfx_mono_menu_process_key function. + * This function will then return a status code and act depending on the given + * keycode: + * + * MENU_KEYCODE_DOWN : Change selection to next menu item (or first if at + * bottom). + * Returns MENU_EVENT_IDLE. + * + * MENU_KEYCODE_UP : Change selection to previous menu item (or last if at top). + * Returns MENU_EVENT_IDLE. + * + * MENU_KEYCODE_ENTER : Nothing changes in menu. Returns the line selected. + * + * MENU_KEYCODE_BACK : Nothing changes in menu. Returns MENU_EVENT_EXIT. + * + * The value of the keycodes used are defined in conf_menu.h. These value can + * be changed if needed. + * + * The graphical indicator used to indicate menu selection is defined in + * conf_menu.h. This indicator can be changed if needed. + * @{ + */ + +/** \name Menu events definitions */ +/** @{ */ +/** Idle. Nothing to report. */ +#define GFX_MONO_MENU_EVENT_IDLE 0xFF +/** Exit. User has pressed the back button. */ +#define GFX_MONO_MENU_EVENT_EXIT 0xFE +/** @} */ + +/** Maximum number of menu elements on display */ +#define GFX_MONO_MENU_ELEMENTS_PER_SCREEN ((GFX_MONO_LCD_HEIGHT / \ + SYSFONT_LINESPACING) - 1) + +/** Menu struct */ +struct gfx_mono_menu { + PROGMEM_STRING_T title; + PROGMEM_STRING_T *strings; + uint8_t num_elements; + uint8_t current_selection; + uint8_t current_page; +}; + +void gfx_mono_menu_init(struct gfx_mono_menu *menu); +uint8_t gfx_mono_menu_process_key(struct gfx_mono_menu *menu, uint8_t keycode); + +/** @} */ + +#endif /* GFX_MONO_MENU_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_menu.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_menu.h.REMOVED.git-id deleted file mode 100644 index f7af767e..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_menu.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1536a823252b9c40f438ded4f9e94c38e067364e \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_spinctrl.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_spinctrl.c new file mode 100644 index 00000000..4c97c1ee --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_spinctrl.c @@ -0,0 +1,697 @@ +/** + * \file + * + * \brief Spin control widget + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "sysfont.h" +#include "stdio.h" +#include "gfx_mono.h" +#include "gfx_mono_spinctrl.h" + +PROGMEM_DECLARE(gfx_mono_color_t, spin_indicator_data[]) = { + GFX_MONO_SPINCTRL_SPIN_INDICATOR_BITMAP +}; + +PROGMEM_DECLARE(gfx_mono_color_t, indicator_data[]) = { + GFX_MONO_SPINCTRL_INDICATOR_BITMAP +}; + +struct gfx_mono_bitmap gfx_mono_spinctrl_bitmap_spin_indicator = { + .height = GFX_MONO_SPINCTRL_SPIN_INDICATOR_HEIGHT, + .width = GFX_MONO_SPINCTRL_SPIN_INDICATOR_WIDTH, + .type = GFX_MONO_BITMAP_PROGMEM, + .data.progmem = spin_indicator_data +}; + +struct gfx_mono_bitmap gfx_mono_spinctrl_bitmap_indicator = { + .height = GFX_MONO_SPINCTRL_INDICATOR_HEIGHT, + .width = GFX_MONO_SPINCTRL_INDICATOR_WIDTH, + .type = GFX_MONO_BITMAP_PROGMEM, + .data.progmem = indicator_data +}; + +/** + * \brief Draw or delete indicator arrow in front of spinner + * + * \param *spinner initialized gfx_mono_spinctrl struct + * \param draw true on draw, false on delete + */ +static void gfx_mono_spinctrl_draw_indicator(struct gfx_mono_spinctrl *spinner, + bool draw) +{ + if (draw) { + gfx_mono_put_bitmap(&gfx_mono_spinctrl_bitmap_indicator, 0, + spinner->y); + } else { + gfx_mono_draw_filled_rect(0, spinner->y, + GFX_MONO_SPINCTRL_INDICATOR_WIDTH, + GFX_MONO_SPINCTRL_INDICATOR_HEIGHT, + GFX_PIXEL_CLR); + } +} + +/** + * \brief Draw or delete indicator in front of spinner data + * + * \param spinner pointer to initialized gfx_mono_spinctrl struct + * \param draw true on draw, false on delete + */ +static void gfx_mono_spinctrl_draw_spin_indicator(struct gfx_mono_spinctrl + *spinner, bool draw) +{ + if (draw) { + gfx_mono_put_bitmap(&gfx_mono_spinctrl_bitmap_spin_indicator, + GFX_MONO_LCD_WIDTH - GFX_MONO_SPINCTRL_SPIN_INDICATOR_WIDTH, + spinner->y); + } else { + gfx_mono_draw_filled_rect(GFX_MONO_LCD_WIDTH - + GFX_MONO_SPINCTRL_SPIN_INDICATOR_WIDTH, + spinner->y, + GFX_MONO_SPINCTRL_SPIN_INDICATOR_WIDTH, + GFX_MONO_SPINCTRL_SPIN_INDICATOR_HEIGHT, + GFX_PIXEL_CLR); + } +} + +/** + * \brief Draw OK button at bottom of screen + * + * This function draws an OK button at the bottom of the screen. It will + * also draw an indicator arrow in front of the button if the indicator bool + * is true. If the draw bool is false, the OK button will be deleted, and if + * the indicator bool is false, the indicator will be deleted. + * + * \param draw true on draw, false on delete + * \param indicator true on draw indicator, false on delete + */ +static void gfx_mono_spinctrl_draw_button(bool draw, bool indicator) +{ + uint8_t width; + uint8_t height; + uint8_t offset; + char string_buf[22]; + + /* Clear bottom line */ + gfx_mono_draw_filled_rect(0, + (SYSFONT_HEIGHT + 1) * + GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION, + GFX_MONO_LCD_WIDTH, SYSFONT_HEIGHT, GFX_PIXEL_CLR); + + snprintf(string_buf, sizeof(string_buf), "OK"); + gfx_mono_get_string_bounding_box(string_buf, &sysfont, &width, &height); + offset = (GFX_MONO_LCD_WIDTH - width) / 2; + + if (draw) { + /* Draw OK button in the middle of the last line */ + gfx_mono_draw_string(string_buf, offset, + (SYSFONT_HEIGHT + 1) * + GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION, + &sysfont); + if (indicator) { + /* Draw indicator arrow in front of button */ + gfx_mono_put_bitmap(&gfx_mono_spinctrl_bitmap_indicator, + offset - GFX_MONO_SPINCTRL_INDICATOR_WIDTH, + (SYSFONT_HEIGHT + 1) * + GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION); + } else { + /* Delete indicator */ + gfx_mono_draw_filled_rect(offset - + GFX_MONO_SPINCTRL_INDICATOR_WIDTH, + (SYSFONT_HEIGHT + 1) * + GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION, + GFX_MONO_SPINCTRL_INDICATOR_WIDTH, + GFX_MONO_SPINCTRL_INDICATOR_HEIGHT, + GFX_PIXEL_CLR); + } + } else { + /* Delete OK button */ + gfx_mono_draw_filled_rect( + offset - GFX_MONO_SPINCTRL_INDICATOR_WIDTH, + (SYSFONT_HEIGHT + 1) * + GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION, 20, + SYSFONT_HEIGHT, GFX_PIXEL_CLR); + } +} + +/** + * \brief Draw spinner at its position. + * + * This function draws a spinner at its position. + * The title of the spinner is only drawn if the redraw option is set. + * If the spinner is in focus, arrows will be drawn next to the spinner value + * to indicate that it is spinnable. + * + * \param spinner pointer to initialized gfx_mono_spinctrl struct + * \param redraw true if title of spinner should be drawn + */ +void gfx_mono_spinctrl_draw(struct gfx_mono_spinctrl *spinner, bool redraw) +{ + char string_buf[GFX_MONO_SPINCTRL_INT_SPINNER_WIDTH]; + uint8_t index; + uint8_t offset; + + if (redraw) { + /* Clear line */ + gfx_mono_draw_filled_rect(0, spinner->y, GFX_MONO_LCD_WIDTH, + SYSFONT_HEIGHT, GFX_PIXEL_CLR); + /* Draw title */ + gfx_mono_draw_progmem_string((char PROGMEM_PTR_T)spinner->title, + GFX_MONO_SPINCTRL_INDICATOR_WIDTH + 1, + spinner->y, &sysfont); + } + + if (spinner->in_focus) { + gfx_mono_spinctrl_draw_spin_indicator(spinner, true); + } else { + gfx_mono_spinctrl_draw_spin_indicator(spinner, false); + } + + if (spinner->datatype == SPINTYPE_INTEGER) { + offset = GFX_MONO_LCD_WIDTH - + (SYSFONT_WIDTH * + GFX_MONO_SPINCTRL_INT_SPINNER_WIDTH); + snprintf(string_buf, sizeof(string_buf), "%d", + spinner->integer_data); + /* Delete previous spinner data */ + gfx_mono_draw_filled_rect(offset, spinner->y, + GFX_MONO_LCD_WIDTH - offset - + GFX_MONO_SPINCTRL_SPIN_INDICATOR_WIDTH, + SYSFONT_HEIGHT, + GFX_PIXEL_CLR); + /* Draw integer data */ + gfx_mono_draw_string(string_buf, offset, spinner->y, &sysfont); + } else if (spinner->datatype == SPINTYPE_STRING) { + index = spinner->strings.index; + offset = GFX_MONO_LCD_WIDTH - + (SYSFONT_WIDTH * + GFX_MONO_SPINCTRL_STRING_SPINNER_WIDTH); + + /* Delete previous spinner data */ + gfx_mono_draw_filled_rect(offset, spinner->y, + GFX_MONO_LCD_WIDTH - offset - + GFX_MONO_SPINCTRL_SPIN_INDICATOR_WIDTH, + SYSFONT_HEIGHT, + GFX_PIXEL_CLR); + + /* Draw string data */ + gfx_mono_draw_progmem_string( + (char PROGMEM_PTR_T)spinner->strings.data[index], offset, + spinner->y, &sysfont); + } +} + +/** + * \brief Initialize a spinner. + * + * This function initializes a spinner to either + * \ref gfx_mono_spinctrl_type_t "SPINTYPE_STRING" spinner that spins through + * the strings in a \ref PROGMEM_STRING_T or a + * \ref gfx_mono_spinctrl_type_t "SPINTYPE_INTEGER" spinner that spins through + * integers. + * If the spinner type is SPINTYPE_INTEGER, it will spin from lower_limit to + * upper_limit. + * If the spinner type is SPINTYPE_STRING, a pointer to a PROGMEM_STRING_T must + * be provided, and the spinner will spin through the strings starting at + * index lower_limit ending at index upper_limit. + * The y parameter specifies where to place the spinner on the screen, but is + * overwritten if the spinner is put in a spincollection. + * + * \param spinner pointer to initialized gfx_mono_spinctrl struct + * \param datatype typer of spinner, integer or string + * \param title title of spinner + * \param data pointer to progmem string array if datatype is string. + * NULL if datatype is integer. + * \param lower_limit lower limit and start value of spinner's data + * \param upper_limit upper limit of spinner's data + * \param y y position of spinner + */ +void gfx_mono_spinctrl_init(struct gfx_mono_spinctrl *spinner, + gfx_mono_spinctrl_type_t datatype, PROGMEM_STRING_T title, + PROGMEM_STRING_T *data, int16_t lower_limit, + int16_t upper_limit, + gfx_coord_t y) +{ + /* Initialization of spinner parameters */ + spinner->title = title; + spinner->datatype = datatype; + spinner->lower_limit = lower_limit; + spinner->upper_limit = upper_limit; + spinner->y = y; + spinner->in_focus = false; + spinner->last_saved_value = spinner->lower_limit; + + if (datatype == SPINTYPE_STRING) { + spinner->strings.data = data; + spinner->strings.index = lower_limit; + } else { + spinner->integer_data = lower_limit; + } +} + +/** + * \brief Initialize a spincollection. + * + * This function initializes a spincollection to which spinners can be added. + * + * \param collection pointer to gfx_mono_spinctrl_spincollection to Initialize + */ +void gfx_mono_spinctrl_spincollection_init(struct + gfx_mono_spinctrl_spincollection *collection) +{ + collection->active_spinner = false; + collection->current_selection = 0; + collection->number_of_spinners = 0; + collection->init = true; +} + +/** + * \brief Add spinner to spincollection + * + * This function adds an initialized spinner to a spincollection and positions + * it below any other spinners in the spincollection on the screen. The + * spinners in the spincollection are linked together and number of spinners is + * updated. + * It is not possible to add more spinners than + * \ref GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION "maximum number of + * spinners in a spincollection". + * + * \param spinner pointer to initialized gfx_mono_spinctrl struct to add + * to collection + * \param spinners pointer to initialized gfx_mono_spinctrl_spincollection + * struct + * + */ +void gfx_mono_spinctrl_spincollection_add_spinner(struct + gfx_mono_spinctrl *spinner, + struct gfx_mono_spinctrl_spincollection *spinners) +{ + uint8_t i; + struct gfx_mono_spinctrl *lastspinner; + + /* Do not add more spinner elements than maximum number of spinners */ + if (spinners->number_of_spinners >= + GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION) { + return; + } + + /* Place new spinner below previous spinners on screen */ + spinner->y = (SYSFONT_HEIGHT + 1) * spinners->number_of_spinners; + + /* Add pointer to the spinner in spincollection if empty */ + if (spinners->number_of_spinners == 0) { + spinners->collection = spinner; + } else { + lastspinner = spinners->collection; + for (i = 1; i < spinners->number_of_spinners; i++) { + lastspinner = lastspinner->next; + } + /* Link the new spinner to the current last spinner in the + * collection */ + lastspinner->next = spinner; + /* Link the current last spinner as previous spinner for new + * spinner */ + spinner->prev = lastspinner; + } + + /* Set added spinner as last spinner in collection */ + spinners->collection_last = spinner; + /* Update number of spinners in collection */ + spinners->number_of_spinners++; +} + +/** + * \brief Show spincollection + * + * This function draws all the spinners in a spincollection to the screen, + * together with an OK button at the bottom. It also draws an indicator arrow + * in front of the top spinner. + * + * \param spinners pointer to initialized spincollection to display + */ +void gfx_mono_spinctrl_spincollection_show(struct + gfx_mono_spinctrl_spincollection *spinners) +{ + uint8_t i; + struct gfx_mono_spinctrl *iterator; + + /* Clear screen */ + gfx_mono_draw_filled_rect(0, 0, GFX_MONO_LCD_WIDTH, GFX_MONO_LCD_HEIGHT, + GFX_PIXEL_CLR); + + /* Make sure there are spinners in the collection */ + if (spinners->number_of_spinners == 0) { + return; + } + + /* Draw spinners on screen */ + iterator = spinners->collection; + for (i = 0; i < spinners->number_of_spinners; i++) { + gfx_mono_spinctrl_draw(iterator, true); + iterator = iterator->next; + } + /* Draw OK button at bottom of screen */ + gfx_mono_spinctrl_draw_button(true, false); + /* Draw indicator arrow in front of first spinner */ + gfx_mono_spinctrl_draw_indicator(spinners->collection, true); +} + +/** + * \brief Step up spinner data + * + * This function steps up the data, making sure it does not go + * beyond the upper limit. Wraps around if it does. + * + * \param spinner pointer to initialized spinner. + */ +static void gfx_mono_spinctrl_step_up(struct gfx_mono_spinctrl *spinner) +{ + /* Check if spinner type is integer or string, increment integer data or + * move to next string index. + */ + if (spinner->datatype == SPINTYPE_INTEGER) { + if (spinner->integer_data < spinner->upper_limit) { + spinner->integer_data++; + } else { + spinner->integer_data = spinner->lower_limit; + } + } else if (spinner->datatype == SPINTYPE_STRING) { + if (spinner->strings.index < spinner->upper_limit) { + spinner->strings.index++; + } else { + (spinner->strings.index) = spinner->lower_limit; + } + } +} + +/** + * \brief Step down spinner data + * + * * This function steps down the data, making sure it does not go + * below the lower limit. Wraps around if it does. + * + * \param spinner pointer to initialized spinner. + */ +static void gfx_mono_spinctrl_step_down(struct gfx_mono_spinctrl *spinner) +{ + /* Check if spinner type is integer or string, increment integer data, + * move to next string index. + */ + if (spinner->datatype == SPINTYPE_INTEGER) { + if (spinner->integer_data > spinner->lower_limit) { + spinner->integer_data--; + } else { + spinner->integer_data = spinner->upper_limit; + } + } else if (spinner->datatype == SPINTYPE_STRING) { + if (spinner->strings.index > (spinner->lower_limit)) { + spinner->strings.index--; + } else { + spinner->strings.index = spinner->upper_limit; + } + } +} + +/** + * \brief Update single spinner depending on input. + * + * \param spinner pointer to initialized spinner. + * \param keycode keycode to process + * + * \retval selected selected spinner value + * \retval GFX_MONO_SPINCTRL_EVENT_IDLE spinner spinning + * \retval GFX_MONO_SPINCTRL_EVENT_BACK spinner deselected + */ +int16_t gfx_mono_spinctrl_process_key(struct gfx_mono_spinctrl *spinner, + uint8_t keycode) +{ + switch (keycode) { + case GFX_MONO_SPINCTRL_KEYCODE_DOWN: + if (spinner->in_focus) { + gfx_mono_spinctrl_step_down(spinner); + /* Update spinner on display */ + gfx_mono_spinctrl_draw(spinner, false); + } + + /* Nothing selected yet */ + return GFX_MONO_SPINCTRL_EVENT_IDLE; + + case GFX_MONO_SPINCTRL_KEYCODE_UP: + if (spinner->in_focus) { + gfx_mono_spinctrl_step_up(spinner); + /* Update spinner on display */ + gfx_mono_spinctrl_draw(spinner, false); + } + + /* Nothing selected yet */ + return GFX_MONO_SPINCTRL_EVENT_IDLE; + + case GFX_MONO_SPINCTRL_KEYCODE_ENTER: + if (spinner->in_focus) { + if (spinner->datatype == SPINTYPE_INTEGER) { + spinner->in_focus = false; + gfx_mono_spinctrl_draw(spinner, false); + /* Store saved value in case of aborting spinner + * later */ + spinner->last_saved_value + = spinner->integer_data; + /* Got what we want. Return selection. */ + return spinner->integer_data; + } else if (spinner->datatype == SPINTYPE_STRING) { + spinner->in_focus = false; + gfx_mono_spinctrl_draw(spinner, false); + /* Store saved value in case of aborting spinner + * later */ + spinner->last_saved_value + = spinner->strings.index; + /* Got what we want. Return selection. */ + return spinner->strings.index; + } + } else { + /* Spinner selected */ + spinner->in_focus = true; + gfx_mono_spinctrl_draw(spinner, false); + return GFX_MONO_SPINCTRL_EVENT_IDLE; + } + + case GFX_MONO_SPINCTRL_KEYCODE_BACK: + /* User pressed "back" key, */ + spinner->in_focus = false; + /* Spinner choice aborted, show last saved value instead */ + if (spinner->datatype == SPINTYPE_INTEGER) { + spinner->integer_data = spinner->last_saved_value; + } else if (spinner->datatype == SPINTYPE_STRING) { + spinner->strings.index = spinner->last_saved_value; + } + + gfx_mono_spinctrl_draw(spinner, false); + return GFX_MONO_SPINCTRL_EVENT_BACK; + + default: + /* Unknown key event */ + return GFX_MONO_SPINCTRL_EVENT_IDLE; + } +} + +/** + * \brief Update spincollection on screen depending on input + * + * This function returns \ref GFX_MONO_SPINCTRL_EVENT_FINISH if user has + * pressed the OK button. The spinner choices can then be extracted from the + * results array. If a spinner is of type SPINTYPE_STRING, the index of the + * progmem string will be stored in the results array, else the selected + * integer value will be stored. + * The choice from the first spinner added to the spincollection will be stored + * at index 0 in the results array, the second at index 1 and so on. + * If user has pressed the back button, \ref GFX_MONO_SPINCTRL_EVENT_BACK is + * returned, signalling that the application should be cancelled. + * + * \param spinners pointer to initialized + * gfx_mono_spinctrl_spincollection + * \param keycode keycode to process + * \param results array to store results from the spinners, must be of + * same length as number of spinners + * + * \retval GFX_MONO_SPINCTRL_EVENT_FINISH user pressed ok button + * \retval GFX_MONO_SPINCTRL_EVENT_BACK user cancelled + * \retval GFX_MONO_SPINCTRL_EVENT_IDLE user is navigating in spincollection + */ +int16_t gfx_mono_spinctrl_spincollection_process_key(struct + gfx_mono_spinctrl_spincollection *spinners, uint8_t keycode, + int16_t results[]) +{ + uint8_t i; + struct gfx_mono_spinctrl *iterator; + + /* Make sure there are spinners in the collection, if not, cancel */ + if (spinners->number_of_spinners == 0) { + return GFX_MONO_SPINCTRL_EVENT_BACK; + } + + /* Store initial values in results array first time function is run */ + if (spinners->init) { + iterator = spinners->collection; + for (i = 0; i < spinners->number_of_spinners; i++) { + if (iterator->datatype == SPINTYPE_INTEGER) { + results[i] = iterator->integer_data; + } else { + results[i] = iterator->strings.index; + } + + iterator = iterator->next; + } + spinners->init = false; + } + + /* Find current spinner selection */ + iterator = spinners->collection; + if (spinners->current_selection != GFX_MONO_SPINCTRL_BUTTON) { + for (i = 0; i < spinners->current_selection; i++) { + iterator = iterator->next; + } + } + + if (spinners->active_spinner) { + /* Process chosen spinner */ + spinners->selection = gfx_mono_spinctrl_process_key(iterator, + keycode); + if (spinners->selection == GFX_MONO_SPINCTRL_EVENT_BACK) { + /* User has exited spinner without saving the result */ + spinners->active_spinner = false; + } else if (spinners->selection != + GFX_MONO_SPINCTRL_EVENT_IDLE) { + /* Value selected, store in array */ + results[spinners->current_selection] + = spinners->selection; + /* Step out of spinner and into spincollection */ + spinners->active_spinner = false; + } + + return GFX_MONO_SPINCTRL_EVENT_IDLE; + } else { + switch (keycode) { + case GFX_MONO_SPINCTRL_KEYCODE_DOWN: + if (spinners->current_selection == + GFX_MONO_SPINCTRL_BUTTON) { + spinners->current_selection = 0; + /* Delete indicator arrow in front of button */ + gfx_mono_spinctrl_draw_button(true, false); + /* Draw indicator arrow in front of first + * spinner */ + gfx_mono_spinctrl_draw_indicator(iterator, + true); + } else if (spinners->current_selection < + spinners->number_of_spinners - 1) { + /* Delete indicator arrow */ + gfx_mono_spinctrl_draw_indicator(iterator, + false); + spinners->current_selection++; + /* Draw indicator arrow in front of new spinner */ + gfx_mono_spinctrl_draw_indicator(iterator->next, + true); + } else { + /* Delete indicator arrow */ + gfx_mono_spinctrl_draw_indicator(iterator, + false); + spinners->current_selection + = GFX_MONO_SPINCTRL_BUTTON; + /* Draw indicator arrow in front of button */ + gfx_mono_spinctrl_draw_button(true, true); + } + + return GFX_MONO_SPINCTRL_EVENT_IDLE; + + case GFX_MONO_SPINCTRL_KEYCODE_UP: + if (spinners->current_selection == + GFX_MONO_SPINCTRL_BUTTON) { + /* Delete indicator arrow in front of button */ + gfx_mono_spinctrl_draw_button(true, false); + spinners->current_selection + = spinners->number_of_spinners - 1; + /* Draw indicator arrow in front of new spinner */ + gfx_mono_spinctrl_draw_indicator( + spinners->collection_last, + true); + } else if (spinners->current_selection > 0) { + /* Delete indicator arrow */ + gfx_mono_spinctrl_draw_indicator(iterator, + false); + spinners->current_selection--; + /* Draw indicator arrow in front of new spinner */ + gfx_mono_spinctrl_draw_indicator(iterator->prev, + true); + } else { + /* Delete indicator arrow */ + gfx_mono_spinctrl_draw_indicator(iterator, + false); + spinners->current_selection + = GFX_MONO_SPINCTRL_BUTTON; + /* Draw indicator arrow in front of button */ + gfx_mono_spinctrl_draw_button(true, true); + } + + return GFX_MONO_SPINCTRL_EVENT_IDLE; + + case GFX_MONO_SPINCTRL_KEYCODE_ENTER: + if (spinners->current_selection == + GFX_MONO_SPINCTRL_BUTTON) { + /* Finished with all selections, return */ + return GFX_MONO_SPINCTRL_EVENT_FINISH; + } else { + /* Spinner selected, send next keycode directly + * to spinner */ + gfx_mono_spinctrl_process_key(iterator, + keycode); + spinners->active_spinner = true; + return GFX_MONO_SPINCTRL_EVENT_IDLE; + } + + case GFX_MONO_SPINCTRL_KEYCODE_BACK: + /* User pressed "back" key, */ + return GFX_MONO_SPINCTRL_EVENT_BACK; + + default: + /* Unknown key event */ + return GFX_MONO_SPINCTRL_EVENT_IDLE; + } + } +} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_spinctrl.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_spinctrl.c.REMOVED.git-id deleted file mode 100644 index 546457d2..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_spinctrl.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4c97c1ee1900d01814db4885dd5c35ed0c11a4e5 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_spinctrl.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_spinctrl.h new file mode 100644 index 00000000..98ec70ee --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_spinctrl.h @@ -0,0 +1,243 @@ +/** + * \file + * + * \brief Spin control widget + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef GFX_MONO_SPINCTRL_H +#define GFX_MONO_SPINCTRL_H + +#include "gfx_mono.h" +#include "conf_spinctrl.h" + +/** + * \ingroup gfx_mono + * \defgroup gfx_mono_spinctrl Spinner widget for monochrome graphical displays + * + * This module provides a spinner widget system for monochrome graphical + * displays. + * + * There is support for having one single spinner on the screen, or a + * collection of spinners. + * + * Typical flow of an application using the spincollection system: + * + * 1) Define spinners.\n + * 2) Initialize each spinners with \ref gfx_mono_spinctrl_init.\n + * 3) Define a spincollection struct and initialize it with + * \ref gfx_mono_spinctrl_spincollection_init.\n + * 4) Add spinners to spincollection with + * \ref gfx_mono_spinctrl_spincollection_add_spinner.\n + * 5) Draw spincollection to screen with + * \ref gfx_mono_spinctrl_spincollection_show.\n + * 6) Define a result array to store the spinner choices.\n + * 7) Update spinners and result array with user input using function + * \ref gfx_mono_spinctrl_spincollection_process_key.\n + * 8) Interpret \ref gfx_mono_spinctrl_spincollection_process_key return + * value.\n + * 9) Go to 7.\n + * + * Typical flow of an application using a single spinner: + * + * 1) Define spinner.\n + * 2) Initialize the spinners with \ref gfx_mono_spinctrl_init with preferred y + * position on screen.\n + * 3) Draw spinner to screen with \ref gfx_mono_spinctrl_draw.\n + * 4) Update spinner with user input using function + * \ref gfx_mono_spinctrl_process_key.\n + * 5) Interpret \ref gfx_mono_spinctrl_process_key return value.\n + * 6) Go to 4.\n + * + * Before the spinners can be updated, you need input from the user. Methods + * for getting input is not part of the spinner widget. + * + * \note The spinners will be linked together when added to a spincollection, + * and can therefore not be used in two spincollections at the same time. + * + * As soon as input is received, inform the spincollection system or the single + * spinner using the \ref gfx_mono_spinctrl_spincollection_process_key function + * or the \ref gfx_mono_spinctrl_process_key function. + * These functions will then return a status code and act depending on the + * given keycode: + * + * GFX_MONO_SPINCTRL_KEYCODE_DOWN : Change selection to next spinner value or + * to next spinner or OK button in a spincollection. + * + * GFX_MONO_SPINCTRL_KEYCODE_UP : Change selection to previous spinner value + * or to previous spinner or OK button in a spincollection. + * + * GFX_MONO_SPINCTRL_KEYCODE_ENTER : Select spinner value or select spinner or + * OK button in a spincollection. + * + * GFX_MONO_SPINCTRL_KEYCODE_BACK : Deselect spinner or cancel spincollection + * application. + * + * The value of the keycodes used are defined in conf_spinctrl.h. These values + * can be changed if needed. + * + * The graphical indicators used to indicate spinner selections are defined in + * conf_spinctrl.h. These indicators can be changed if needed. + * @{ + */ + +/** Spinner idle event */ +#define GFX_MONO_SPINCTRL_EVENT_IDLE 0xFF +/** Spinner back button pressed event */ +#define GFX_MONO_SPINCTRL_EVENT_BACK 0xFE +/** Spinner ok button pressed event */ +#define GFX_MONO_SPINCTRL_EVENT_FINISH 0xFD + +/** OK button */ +#define GFX_MONO_SPINCTRL_BUTTON 0xFF + +/** Maximum number of spinner elements on display */ +#define GFX_MONO_SPINCTRL_ELEMENTS_PER_SCREEN \ + ((GFX_MONO_LCD_HEIGHT / SYSFONT_LINESPACING) - 1) + +/** + * Maximum numbers of spinner elements in a spincollection - limited to + * one screen. + */ +#define GFX_MONO_SPINCTRL_MAX_ELEMENTS_IN_SPINCOLLECTION \ + GFX_MONO_SPINCTRL_ELEMENTS_PER_SCREEN + +/** Width of string spinner choices */ +#define GFX_MONO_SPINCTRL_STRING_SPINNER_WIDTH 9 +/** Width of integer spinner choices */ +#define GFX_MONO_SPINCTRL_INT_SPINNER_WIDTH 9 + +/** Enum to specify what kind of data spinner should spin */ +typedef enum gfx_mono_spinctrl_type_enum { + SPINTYPE_STRING, + SPINTYPE_INTEGER +} gfx_mono_spinctrl_type_t; + +/** String struct */ +struct gfx_mono_spinctrl_string { + /** Pointer to progmem strings to spin through + * \note Each string must be shorter than + * \ref GFX_MONO_SPINCTRL_STRING_SPINNER_WIDTH characters. + * If not, printing it to the screen will corrupt the spinner + * appearance. + */ + PROGMEM_STRING_T *data; + /** Index in string array */ + uint8_t index; +}; + +/** Spin control struct */ +struct gfx_mono_spinctrl { + /** Spinner title */ + PROGMEM_STRING_T title; + /** Type of data to spin */ + gfx_mono_spinctrl_type_t datatype; + /** Spinner data, depends on spinner datatype. */ + union { + /** Spinner strings and index */ + struct gfx_mono_spinctrl_string strings; + /** Spinner integer data */ + int16_t integer_data; + }; + /** Variable to store the last selected spinner value */ + uint16_t last_saved_value; + + /** + * Lower limit for spinning, must be positive and fit in uin8_t for + * spinner type SPINTYPE_STRING + */ + int16_t lower_limit; + + /** + * Upper limit for spinning, must be positive and fit in uin8_t for + * spinner type SPINTYPE_STRING + */ + int16_t upper_limit; + /** Y coordinate for placement of spinner on screen */ + gfx_coord_t y; + /** Boolean to tell if spinner is in focus or not */ + bool in_focus; + /** Pointer to next spinner in a spincollection */ + struct gfx_mono_spinctrl *next; + /** Pointer to previous spinner in a spincollection */ + struct gfx_mono_spinctrl *prev; +}; + +/** Collection of spinners struct */ +struct gfx_mono_spinctrl_spincollection { + /** Pointer to the first spinner in the collection */ + struct gfx_mono_spinctrl *collection; + /** Pointer to the last spinner in the collection */ + struct gfx_mono_spinctrl *collection_last; + /** Number of spinners in collection */ + uint8_t number_of_spinners; + /** Current spinner/button */ + uint8_t current_selection; + /** Return value from selected spinner */ + uint16_t selection; + /** Boolean to tell if input should be sent directly to a spinner */ + bool active_spinner; + /** Boolean to initialize results array when starting key processing */ + bool init; +}; + +void gfx_mono_spinctrl_init(struct gfx_mono_spinctrl *spinner, + gfx_mono_spinctrl_type_t datatype, PROGMEM_STRING_T title, + PROGMEM_STRING_T *data, int16_t lower_limit, + int16_t upper_limit, + gfx_coord_t y); +void gfx_mono_spinctrl_draw(struct gfx_mono_spinctrl *spinner, bool redraw); +void gfx_mono_spinctrl_spincollection_init(struct + gfx_mono_spinctrl_spincollection *collection); +void gfx_mono_spinctrl_spincollection_add_spinner(struct gfx_mono_spinctrl + *spinner, struct gfx_mono_spinctrl_spincollection *spinners); +void gfx_mono_spinctrl_spincollection_show(struct + gfx_mono_spinctrl_spincollection *spinners); +int16_t gfx_mono_spinctrl_process_key(struct gfx_mono_spinctrl *spinner, + uint8_t keycode); + +int16_t gfx_mono_spinctrl_spincollection_process_key(struct +gfx_mono_spinctrl_spincollection *spinners, uint8_t keycode, +int16_t results[]); + +/** @} */ + +#endif /* GFX_MONO_SPINCTRL_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_spinctrl.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_spinctrl.h.REMOVED.git-id deleted file mode 100644 index bfda6d5a..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_spinctrl.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -98ec70ee8bbb53184bed42ebe03e4b80f3446d66 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_text.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_text.c new file mode 100644 index 00000000..1412c5ef --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_text.c @@ -0,0 +1,428 @@ +/** + * \file + * + * \brief Font and text drawing routines + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#include "stddef.h" +#include "assert.h" +#ifdef CONFIG_HUGEMEM +# include "hugemem.h" +#endif +#include "progmem.h" + +#include "gfx_mono.h" +#include "gfx_mono_text.h" + +#ifndef CONFIG_FONT_PIXELS_PER_BYTE +# define CONFIG_FONT_PIXELS_PER_BYTE 8 +#endif + +#define EXTMEM_BUF_SIZE 20 + +#if defined(CONFIG_HUGEMEM) || defined(__DOXYGEN__) + +/** + * \internal + * \brief Helper function that draws a character from a font in hugemem + * to the display + * + * This function will first calculate the start offset in the font character + * data before iterating over the specific character data. + * + * Only pixels in the character that should be enabled are done so, the caller + * is required to prepare the drawing area before printing a character to it. + * This is done by the gfx_mono_draw_string() and + * gfx_mono_draw_progmem_string() functions. + * + * \param ch Character to be drawn + * \param x X coordinate on screen. + * \param y Y coordinate on screen. + * \param font Font to draw character in + */ +static void gfx_mono_draw_char_hugemem(const char ch, const gfx_coord_t x, + const gfx_coord_t y, const struct font *font) +{ + uint8_t i; + uint8_t char_row_size; + uint8_t glyph_size; + uint16_t glyph_data_offset; + uint8_t char_buff[EXTMEM_BUF_SIZE]; + uint8_t buffer_pos; + uint8_t rows_left; + + /* Sanity check on parameters, assert if font is NULL. */ + Assert(font != NULL); + + gfx_coord_t inc_x = x; + gfx_coord_t inc_y = y; + + char_row_size = font->width / CONFIG_FONT_PIXELS_PER_BYTE; + if (font->width % CONFIG_FONT_PIXELS_PER_BYTE) { + char_row_size++; + } + + glyph_size = char_row_size * font->height; + glyph_data_offset = glyph_size * ((uint8_t)ch - font->first_char); + buffer_pos = EXTMEM_BUF_SIZE; + rows_left = font->height; + + do { + static uint8_t glyph_byte = 0; + uint8_t pixelsToDraw = font->width; + + for (i = 0; i < pixelsToDraw; i++) { + if (i % CONFIG_FONT_PIXELS_PER_BYTE == 0) { + /* Read another byte from hugemem */ + if (buffer_pos >= EXTMEM_BUF_SIZE) { + hugemem_ptr_t source + = font->data.hugemem; + source = (hugemem_ptr_t) + ((uint32_t)source + + glyph_data_offset); + + hugemem_read_block(char_buff, source, + EXTMEM_BUF_SIZE); + + glyph_data_offset += EXTMEM_BUF_SIZE; + buffer_pos = 0; + } + + glyph_byte = char_buff[buffer_pos]; + buffer_pos++; + } + + /* Draw bit of glyph to screen */ + if ((glyph_byte & 0x80)) { + gfx_mono_draw_pixel(inc_x, inc_y, + GFX_PIXEL_SET); + } + + inc_x += 1; + glyph_byte <<= 1; + } + + inc_y += 1; + inc_x = x; + } while (--rows_left > 0); +} + +#endif + +/** + * \internal + * \brief Helper function that draws a character from a font in progmem + * to the display + * + * This function will first calculate the start offset in the font character + * data before iterating over the specific character data. + * + * Only pixels in the character that should be enabled are done so, the caller + * is required to prepare the drawing area before printing a character to it. + * This is done by the gfx_mono_draw_string() and + * gfx_mono_draw_progmem_string() functions. + * + * \param ch Character to be drawn + * \param x X coordinate on screen. + * \param y Y coordinate on screen. + * \param font Font to draw character in + */ +static void gfx_mono_draw_char_progmem(const char ch, const gfx_coord_t x, + const gfx_coord_t y, const struct font *font) +{ + uint8_t PROGMEM_PTR_T glyph_data; + uint16_t glyph_data_offset; + uint8_t char_row_size; + uint8_t rows_left; + uint8_t i; + + /* Sanity check on parameters, assert if font is NULL. */ + Assert(font != NULL); + + gfx_coord_t inc_x = x; + gfx_coord_t inc_y = y; + + char_row_size = font->width / CONFIG_FONT_PIXELS_PER_BYTE; + if (font->width % CONFIG_FONT_PIXELS_PER_BYTE) { + char_row_size++; + } + + glyph_data_offset = char_row_size * font->height * + ((uint8_t)ch - font->first_char); + glyph_data = font->data.progmem + glyph_data_offset; + rows_left = font->height; + + do { + uint8_t glyph_byte = 0; + uint8_t pixelsToDraw = font->width; + + for (i = 0; i < pixelsToDraw; i++) { + if (i % CONFIG_FONT_PIXELS_PER_BYTE == 0) { + glyph_byte = PROGMEM_READ_BYTE(glyph_data); + glyph_data++; + } + + if ((glyph_byte & 0x80)) { + gfx_mono_draw_pixel(inc_x, inc_y, + GFX_PIXEL_SET); + } + + inc_x += 1; + glyph_byte <<= 1; + } + + inc_y += 1; + inc_x = x; + rows_left--; + } while (rows_left > 0); +} + +/** + * \brief Draws a character to the display + * + * \param c Character to be drawn + * \param x X coordinate on screen. + * \param y Y coordinate on screen. + * \param font Font to draw character in + */ +void gfx_mono_draw_char(const char c, const gfx_coord_t x, const gfx_coord_t y, + const struct font *font) +{ + gfx_mono_draw_filled_rect(x, y, font->width, font->height, + GFX_PIXEL_CLR); + + switch (font->type) { + case FONT_LOC_PROGMEM: + gfx_mono_draw_char_progmem(c, x, y, font); + break; + +#ifdef CONFIG_HUGEMEM + case FONT_LOC_HUGEMEM: + gfx_mono_draw_char_hugemem(c, x, y, font); + break; + +#endif + default: + /* Unsupported mode, call assert */ + Assert(false); + break; + } +} + +/** + * \brief Draws a string to the display + * + * This function will draw a string located in memory to the display. + * + * \param str Pointer to string + * \param x X coordinate on screen. + * \param y Y coordinate on screen. + * \param font Font to draw string in + */ +void gfx_mono_draw_string(const char *str, gfx_coord_t x, gfx_coord_t y, + const struct font *font) +{ + /* Save X in order to know where to return to on CR. */ + const gfx_coord_t start_of_string_position_x = x; + + /* Sanity check on parameters, assert if str or font is NULL. */ + Assert(str != NULL); + Assert(font != NULL); + + /* Draw characters until trailing null byte */ + do { + /* Handle '\n' as newline, draw normal characters. */ + if (*str == '\n') { + x = start_of_string_position_x; + y += font->height + 1; + } else if (*str == '\r') { + /* Skip '\r' characters. */ + } else { + gfx_mono_draw_char(*str, x, y, font); + x += font->width; + } + } while (*(++str)); +} + +/** + * \brief Draws a string located in program memory to the display + * + * This function will draw a string located in program memory to the display, + * this differs from gfx_mono_draw_string() by using constant string data from + * the program memory instead of string data in RAM. + * + * Using program memory for constant strings will reduce the applications need + * for RAM, and thus lower the overall size footprint. + * + * \param str Pointer to string located in program memory + * \param x X coordinate on screen. + * \param y Y coordinate on screen. + * \param font Font to draw string in + */ +void gfx_mono_draw_progmem_string(char PROGMEM_PTR_T str, gfx_coord_t x, + gfx_coord_t y, const struct font *font) +{ + char temp_char; + + /* Sanity check on parameters, assert if str or font is NULL. */ + Assert(str != NULL); + Assert(font != NULL); + + /* Save X in order to know where to return to on CR. */ + const gfx_coord_t start_of_string_position_x = x; + + /* Draw characters until trailing null byte */ + temp_char = PROGMEM_READ_BYTE((uint8_t PROGMEM_PTR_T)str); + + while (temp_char) { + /* Handle '\n' as newline, draw normal characters. */ + if (temp_char == '\n') { + x = start_of_string_position_x; + y += font->height + 1; + } else if (temp_char == '\r') { + /* Skip '\r' characters. */ + } else { + gfx_mono_draw_char(temp_char, x, y, font); + x += font->width; + } + + temp_char = PROGMEM_READ_BYTE((uint8_t PROGMEM_PTR_T)(++str)); + } +} + +/** + * \brief Computes the bounding box of a string + * + * \note If string is empty the returned width will be 1 pixel and the height + * equal to the font height. + * + * \param str String to calculate bounding box for + * \param font Font used + * \param width Pointer to width result + * \param height Pointer to height result + */ +void gfx_mono_get_string_bounding_box(const char *str, const struct font *font, + gfx_coord_t *width, gfx_coord_t *height) +{ + gfx_coord_t font_width = font->width; + gfx_coord_t font_height = font->height; + + gfx_coord_t max_width = 1; + gfx_coord_t max_height = font_height; + gfx_coord_t x = 0; + + /* Sanity check on parameters, assert if str or font is NULL. */ + Assert(str != NULL); + Assert(font != NULL); + + /* Handle each character until trailing null byte */ + do { + /* Handle '\n' as newline, draw normal characters. */ + if (*str == '\n') { + x = 0; + max_height += font_height; + } else if (*str == '\r') { + /* Skip '\r' characters. */ + } else { + x += font_width; + if (x > max_width) { + max_width = x; + } + } + } while (*(++str)); + + /* Return values through references */ + *width = max_width; + *height = max_height; +} + +/** + * \brief Computes the bounding box of a string located in program memory + * + * \note If string is empty the returned width will be 1 pixel and the height + * equal to the font height. + * + * \param str String in program memory to calculate bounding box for + * \param font Font used + * \param width Pointer to width result + * \param height Pointer to height result + */ +void gfx_mono_get_progmem_string_bounding_box(char PROGMEM_PTR_T str, + const struct font *font, gfx_coord_t *width, + gfx_coord_t *height) +{ + gfx_coord_t font_width = font->width; + gfx_coord_t font_height = font->height; + + char temp_char; + gfx_coord_t max_width = 1; + gfx_coord_t max_height = font_height; + gfx_coord_t x = 0; + + /* Sanity check on parameters, assert if str or font is NULL. */ + Assert(str != NULL); + Assert(font != NULL); + + /* Handle each character until trailing null byte */ + temp_char = PROGMEM_READ_BYTE((uint8_t PROGMEM_PTR_T)str); + + while (temp_char) { + /* Handle '\n' as newline, draw normal characters. */ + if (temp_char == '\n') { + x = 0; + max_height += font_height; + } else if (*str == '\r') { + /* Skip '\r' characters. */ + } else { + x += font_width; + if (x > max_width) { + max_width = x; + } + } + + temp_char = PROGMEM_READ_BYTE((uint8_t PROGMEM_PTR_T)(++str)); + } + + /* Return values through references */ + *width = max_width; + *height = max_height; +} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_text.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_text.c.REMOVED.git-id deleted file mode 100644 index b2cb8a5e..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_text.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1412c5ef14fe715d6f65a036a704041096a11faf \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_text.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_text.h new file mode 100644 index 00000000..ecbe790c --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_text.h @@ -0,0 +1,131 @@ +/** + * \file + * + * \brief Monochrome graphic library API header file + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef GFX_MONO_TEXT_H_INCLUDED +#define GFX_MONO_TEXT_H_INCLUDED + +#include + +#include "compiler.h" +#include "progmem.h" +#ifdef CONFIG_HAVE_HUGEMEM +# include "hugemem.h" +#endif + +/** + * \ingroup gfx_mono + * \defgroup gfx_mono_font Font support + * This modules provides functionality for outputting a monochrome font + * to a display. + * + * @{ + */ + +/** + * \brief Valid storage locations for font data + * + * \todo Add support for fonts in regular ram + */ +enum font_data_type { + /** Font data stored in program/flash memory. */ + FONT_LOC_PROGMEM, +#ifdef CONFIG_HAVE_HUGEMEM + /** Font data stored in HUGEMEM. */ + FONT_LOC_HUGEMEM, +#endif +}; + +/** Storage structure for font meta data. */ +struct font { + /** Type of storage used for binary font data. See \ref font_data_type. */ + enum font_data_type type; + union { + /** + * Pointer to where the binary font data is stored. This + * variable is accessed either through hugemem or progmem + * depending on the value of \a type. + */ +#ifdef CONFIG_HAVE_HUGEMEM + hugemem_ptr_t hugemem; +#endif + uint8_t PROGMEM_PTR_T progmem; + } data; + /** Width of one font character, in pixels. */ + uint8_t width; + /** Height of one font character, in pixels. */ + uint8_t height; + /** ASCII value of first character in font set. */ + uint8_t first_char; + /** ASCII value of last character in the set. */ + uint8_t last_char; +}; + +/** \name Strings and characters located in RAM */ +/** @{ */ +void gfx_mono_draw_char(const char c, const gfx_coord_t x, const gfx_coord_t y, + const struct font *font); + +void gfx_mono_draw_string(const char *str, const gfx_coord_t x, + const gfx_coord_t y, const struct font *font); + +void gfx_mono_get_string_bounding_box(char const *str, const struct font *font, + gfx_coord_t *width, gfx_coord_t *height); + +/** @} */ + +/** \name Strings located in flash */ +/** @{ */ +void gfx_mono_draw_progmem_string(char PROGMEM_PTR_T str, gfx_coord_t x, + gfx_coord_t y, const struct font *font); + +void gfx_mono_get_progmem_string_bounding_box(char PROGMEM_PTR_T str, + const struct font *font, gfx_coord_t *width, + gfx_coord_t *height); + +/** @} */ + +/** @} */ + +#endif /* GFX_MONO_TEXT_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_text.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_text.h.REMOVED.git-id deleted file mode 100644 index 38c1d085..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/gfx_mono_text.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ecbe790c335b59001bbd2cd25be836d4c43be231 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/sysfont.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/sysfont.c new file mode 100644 index 00000000..cd0d0275 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/sysfont.c @@ -0,0 +1,75 @@ +/** + * \file + * + * \brief Graphical font support + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#include +#include +#include +#include + +#include "conf_sysfont.h" + +#include "gfx_mono.h" +#include "sysfont.h" + +// Use macro from conf_sysfont.h to define font glyph data. +SYSFONT_DEFINE_GLYPHS; + +/** + * \brief Initialize a basic system font + * + * This initializes a basic system font globally usable by the application. + */ +struct font sysfont = { + .type = FONT_LOC_PROGMEM, + .width = SYSFONT_WIDTH, + .height = SYSFONT_HEIGHT, + .first_char = SYSFONT_FIRSTCHAR, + .last_char = SYSFONT_LASTCHAR, + .data = { + .progmem = sysfont_glyphs, + }, +}; + +/** @} */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/sysfont.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/sysfont.c.REMOVED.git-id deleted file mode 100644 index 3eb3d5dc..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/sysfont.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cd0d0275c448af573ee6850aadb90ec763159a63 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/sysfont.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/sysfont.h new file mode 100644 index 00000000..8e57567b --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/sysfont.h @@ -0,0 +1,70 @@ +/** + * \file + * + * \brief Graphical System Font system + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef SYSFONT_H_INCLUDED +#define SYSFONT_H_INCLUDED + +#include "conf_sysfont.h" +#include "gfx_mono.h" +#include "gfx_mono_text.h" + +/** + * \ingroup gfx_mono_font + * \defgroup gfx_mono_sysfont System font + * + * The system font objects are globally available for a graphical application. + * System fonts are by design read only, hence there are not any functions to + * change them during runtime. If the application needs additional fonts it + * should add additional font objects. + * + * @{ + */ + +extern struct font sysfont; + +/** @} */ + +#endif /* SYSFONT_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/sysfont.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/sysfont.h.REMOVED.git-id deleted file mode 100644 index f464db4f..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/sysfont.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8e57567b40b7903168a57089624d38e2bd8a7fc6 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/bitmap.py b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/bitmap.py new file mode 100644 index 00000000..fcddb9ca --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/bitmap.py @@ -0,0 +1,58 @@ +## +# \file +# +# \brief Output a 2 color bitmap as an uint8_t array +# +# Copyright (C) 2011-2014 Atmel Corporation. All rights reserved. +# +# \page License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. The name of Atmel may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# 4. This software may only be redistributed and used in connection with an +# Atmel microcontroller product. +# +# THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE +# EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from PIL import Image +import sys + +im = Image.open(sys.argv[1]); +new_im = im.load() + +width, height = im.size + +for y in range(0, height) : + for x in range(0, width) : + if 0 < new_im[x, y]: + new_im[x, y] = 1 + sys.stdout.write(str(new_im[x, y])) + sys.stdout.write("\n") + +sys.stdout.write("\n uint8_t image_header[] = {\n") +for y in range(0, height, 8) : + for x in range(0, width) : + first_byte = str(new_im[x, y + 7]) + str(new_im[x, y+6]) + str(new_im[x, y+5]) + str(new_im[x, y+4]) + str(new_im[x, y+3]) + str(new_im[x, y+2]) + str(new_im[x, y+1]) + str(new_im[x, y+0]) + print "0x%x," % int(first_byte, 2), + +sys.stdout.write("};\n") diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/bitmap.py.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/bitmap.py.REMOVED.git-id deleted file mode 100644 index c7b5bcd4..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/bitmap.py.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fcddb9ca488821674cbb91087cb479149a9d829c \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/dump_display_over_serial.py b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/dump_display_over_serial.py new file mode 100644 index 00000000..5b532420 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/dump_display_over_serial.py @@ -0,0 +1,133 @@ +## +# \file +# +# \brief Convert display data on a serial line to a graphical representation +# +# Copyright (C) 2011-2014 Atmel Corporation. All rights reserved. +# +# \page License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. The name of Atmel may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# 4. This software may only be redistributed and used in connection with an +# Atmel microcontroller product. +# +# THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE +# EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import sys +import serial +import os.path +import argparse + +def scan_for_ports(): + available_ports = [] + + for index in range(64): + try: + serial_port = serial.Serial(index) + available_ports.append((index, serial_port.portstr)) + serial_port.close() + except serial.SerialException: + pass + except IndexError as Error: + pass + + for port_number, port_name in available_ports: + print "%02d - %s" % (port_number, port_name) + + return available_ports + +def dump_display_data(serial_port, baud_rate, output_file_name): + try: + output_file = open(output_file_name, 'w') + port = serial.Serial(port = serial_port, + baudrate = baud_rate, timeout = 1) + port.close() + port.open() + except ValueError as e: + print "error: invalid serial port parameters. %s" % (str(e)) + output_file.close() + return -1 + except serial.SerialException as e: + print "error: could not open serial port. %s" % (str(e)) + output_file.close() + return -1 + except IOError as e: + print "error: could not open output file. %s" % (str(e)) + return -1 + + print "Display on %s: %u,8,N,1" % (port.name, port.baudrate) + port.write("D") + line = port.readline() + display_data = "" + while(line[:2] != "};") : + display_data = display_data + line[:-1] + line = port.readline() + display_data = display_data + line + port.close() + + print "Writing data to file %s" % (output_file_name) + output_file.write(display_data) + + output_file.close() + +def main(): + parser = argparse.ArgumentParser(description="This script will try to " + "open the given serial port, send a string to " + "instruct the target device to dump the contents of " + "the display to a serial link in XPM format. The " + "received file is then written to 'display.xpm', " + "unless a file is specified by the -o option.") + parser.add_argument("-p", "--port", dest="serial_port", + help="which serial port to open") + parser.add_argument("-b", "--baud", dest="baudrate", type=int, + help="baud rate to use for serial communication", + default=19200) + parser.add_argument("-o", "--output", dest="output_file", + help="write XPM image to FILE. Default is display.xpm.", + metavar="FILE", default="display.xpm") + parser.add_argument("-s", "--scan", action="store_true", + dest="scan_ports", + help="scan for available serial ports and exit", + default=False) + + arguments = parser.parse_args() + + if arguments.scan_ports: + scan_for_ports() + sys.exit() + + if arguments.serial_port is None: + parser.print_usage() + sys.exit() + + if os.path.exists(arguments.output_file): + print "Warning: output file '%s' already exists" % (arguments.output_file) + print "Do you want to write over file '%s'?" % (arguments.output_file) + answer = raw_input("[yes/NO] ") + if answer not in ("yes", "Yes", "YES"): + sys.exit() + + dump_display_data(arguments.serial_port, arguments.baudrate, arguments.output_file) + +if __name__ == "__main__": + main() diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/dump_display_over_serial.py.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/dump_display_over_serial.py.REMOVED.git-id deleted file mode 100644 index f8d6ecbf..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/dump_display_over_serial.py.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5b532420fac4c1e3025c6ff62c63f5fdff77242a \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/readme.txt b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/readme.txt new file mode 100644 index 00000000..ebe2b166 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/readme.txt @@ -0,0 +1,6 @@ + +dump_display_over_serial.py + Convert display data on a serial line to a .XPM file + +bitmap.py + Convert an indexed 2 color bitmap to an uint8_t array diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/readme.txt.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/readme.txt.REMOVED.git-id deleted file mode 100644 index dba66857..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gfx_mono/tools/readme.txt.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ebe2b166ab92575d0c3553501b18d3a6d4d53d3d \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gpio/gpio.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gpio/gpio.h new file mode 100644 index 00000000..2b261aad --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gpio/gpio.h @@ -0,0 +1,86 @@ +/** + * \file + * + * \brief Common GPIO API. + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef _GPIO_H_ +#define _GPIO_H_ + +#include + +#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM) +# include "sam_gpio/sam_gpio.h" +#elif XMEGA +# include "xmega_gpio/xmega_gpio.h" +#elif MEGA || MEGA_RF +# include "mega_gpio/mega_gpio.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup gpio_group General Purpose Input/Output + * + * This is the common API for GPIO. Additional features are available + * in the documentation of the specific modules. + * + * \section io_group_platform Platform Dependencies + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behaviour. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - gpio_pin_is_low() + * - gpio_pin_is_high() + * - gpio_set_pin_high() + * - gpio_set_pin_group_high() + * - gpio_set_pin_low() + * - gpio_set_pin_group_low() + * - gpio_toggle_pin() + * - gpio_toggle_pin_group() + * - gpio_configure_pin() + * - gpio_configure_group() + */ + +#endif /* _GPIO_H_ */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gpio/gpio.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gpio/gpio.h.REMOVED.git-id deleted file mode 100644 index 5c96ae1c..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gpio/gpio.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2b261aad859f43d5fe29001de27bf81a36fa96b1 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gpio/xmega_gpio/xmega_gpio.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gpio/xmega_gpio/xmega_gpio.h new file mode 100644 index 00000000..110d9c36 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gpio/xmega_gpio/xmega_gpio.h @@ -0,0 +1,83 @@ +/** + * \file + * + * \brief Common gpio data/structure for all AVR XMEGA implementations. + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _XMEGA_GPIO_H_ +#define _XMEGA_GPIO_H_ + +#include "compiler.h" +#include "ioport.h" + +#define gpio_pin_is_low(io_id) \ + ioport_pin_is_low(io_id) + +#define gpio_pin_is_high(io_id) \ + ioport_pin_is_high(io_id) + +#define gpio_set_pin_high(io_id) \ + ioport_set_value(io_id,1) + +#define gpio_set_pin_low(io_id) \ + ioport_set_value(io_id,0) + +#define gpio_toggle_pin(io_id) \ + ioport_toggle_pin(io_id) + +#define gpio_configure_pin(io_id,io_flags) \ + ioport_configure_pin(io_id,io_flags) + +#define gpio_configure_group(port_id,port_mask,io_flags) \ + ioport_configure_group(port_id,port_mask,io_flags) + +#define gpio_set_pin_group_high(port_id,mask) \ + ioport_set_group_high(port_id,mask) + +#define gpio_set_pin_group_low(port_id,mask) \ + ioport_set_group_low(port_id,mask) + +#define gpio_toggle_pin_group(port_id,mask) \ + ioport_tgl_group(port_id,mask) + +#endif // _XMEGA_GPIO_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gpio/xmega_gpio/xmega_gpio.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/gpio/xmega_gpio/xmega_gpio.h.REMOVED.git-id deleted file mode 100644 index a1cdb815..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/gpio/xmega_gpio/xmega_gpio.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -110d9c362b77b4099a14a9ef7193f91a315c3420 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/ioport.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/ioport.h new file mode 100644 index 00000000..a0320956 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/ioport.h @@ -0,0 +1,541 @@ +/** + * \file + * + * \brief Common IOPORT service main header file for AVR, UC3 and ARM + * architectures. + * + * Copyright (c) 2012-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef IOPORT_H +#define IOPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \defgroup ioport_group Common IOPORT API + * + * See \ref ioport_quickstart. + * + * This is common IOPORT service for GPIO pin configuration and control in a + * standardized manner across the MEGA, MEGA_RF, XMEGA, UC3 and ARM devices. + * + * Port pin control code is optimized for each platform, and should produce + * both compact and fast execution times when used with constant values. + * + * \section dependencies Dependencies + * This driver depends on the following modules: + * - \ref sysclk_group for clock speed and functions. + * @{ + */ + +/** + * \def IOPORT_CREATE_PIN(port, pin) + * \brief Create IOPORT pin number + * + * Create a IOPORT pin number for use with the IOPORT functions. + * + * \param port IOPORT port (e.g. PORTA, PA or PIOA depending on chosen + * architecture) + * \param pin IOPORT zero-based index of the I/O pin + */ + +/** \brief IOPORT pin directions */ +enum ioport_direction { + IOPORT_DIR_INPUT, /*!< IOPORT input direction */ + IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */ +}; + +/** \brief IOPORT levels */ +enum ioport_value { + IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */ + IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */ +}; + +#if MEGA_RF +/** \brief IOPORT edge sense modes */ +enum ioport_sense { + IOPORT_SENSE_LEVEL, /*!< IOPORT sense low level */ + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ +}; +#elif SAM && !SAM4L +/** \brief IOPORT edge sense modes */ +enum ioport_sense { + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ + IOPORT_SENSE_LEVEL_LOW, /*!< IOPORT sense low level */ + IOPORT_SENSE_LEVEL_HIGH,/*!< IOPORT sense High level */ +}; +#else +enum ioport_sense { + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ +}; +#endif + + +#if XMEGA +# include "xmega/ioport.h" +# if defined(IOPORT_XMEGA_COMPAT) +# include "xmega/ioport_compat.h" +# endif +#elif MEGA +# include "mega/ioport.h" +#elif UC3 +# include "uc3/ioport.h" +#elif SAM +# if SAM4L +# include "sam/ioport_gpio.h" +# elif (SAMD20 | SAMD21) +# include "sam0/ioport.h" +# else +# include "sam/ioport_pio.h" +# endif +#endif + +/** + * \brief Initializes the IOPORT service, ready for use. + * + * This function must be called before using any other functions in the IOPORT + * service. + */ +static inline void ioport_init(void) +{ + arch_ioport_init(); +} + +/** + * \brief Enable an IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to enable + */ +static inline void ioport_enable_pin(ioport_pin_t pin) +{ + arch_ioport_enable_pin(pin); +} + +/** + * \brief Enable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to enable + * \param mask Mask of pins within the port to enable + */ +static inline void ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_enable_port(port, mask); +} + +/** + * \brief Disable IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to disable + */ +static inline void ioport_disable_pin(ioport_pin_t pin) +{ + arch_ioport_disable_pin(pin); +} + +/** + * \brief Disable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to disable + * \param mask Pin mask of pins to disable + */ +static inline void ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_disable_port(port, mask); +} + +/** + * \brief Set multiple pin modes in a single IOPORT port, such as pull-up, + * pull-down, etc. configuration. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param mode Mode masks to configure for the specified pins (\ref + * ioport_modes) + */ +static inline void ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + arch_ioport_set_port_mode(port, mask, mode); +} + +/** + * \brief Set pin mode for one single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param mode Mode masks to configure for the specified pin (\ref ioport_modes) + */ +static inline void ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode) +{ + arch_ioport_set_pin_mode(pin, mode); +} + +/** + * \brief Reset multiple pin modes in a specified IOPORT port to defaults. + * + * \param port IOPORT port to configure + * \param mask Mask of pins whose mode configuration is to be reset + */ +static inline void ioport_reset_port_mode(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_set_port_mode(port, mask, 0); +} + +/** + * \brief Reset pin mode configuration for a single IOPORT pin + * + * \param pin IOPORT pin to configure + */ +static inline void ioport_reset_pin_mode(ioport_pin_t pin) +{ + arch_ioport_set_pin_mode(pin, 0); +} + +/** + * \brief Set I/O direction for a group of pins in a single IOPORT. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param dir Direction to set for the specified pins (\ref ioport_direction) + */ +static inline void ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + arch_ioport_set_port_dir(port, mask, dir); +} + +/** + * \brief Set direction for a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param dir Direction to set for the specified pin (\ref ioport_direction) + */ +static inline void ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + arch_ioport_set_pin_dir(pin, dir); +} + +/** + * \brief Set an IOPORT pin to a specified logical value. + * + * \param pin IOPORT pin to configure + * \param level Logical value of the pin + */ +static inline void ioport_set_pin_level(ioport_pin_t pin, bool level) +{ + arch_ioport_set_pin_level(pin, level); +} + +/** + * \brief Set a group of IOPORT pins in a single port to a specified logical + * value. + * + * \param port IOPORT port to write to + * \param mask Pin mask of pins to modify + * \param level Level of the pins to be modified + */ +static inline void ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + arch_ioport_set_port_level(port, mask, level); +} + +/** + * \brief Get current value of an IOPORT pin, which has been configured as an + * input. + * + * \param pin IOPORT pin to read + * \return Current logical value of the specified pin + */ +static inline bool ioport_get_pin_level(ioport_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Get current value of several IOPORT pins in a single port, which have + * been configured as an inputs. + * + * \param port IOPORT port to read + * \param mask Pin mask of pins to read + * \return Logical levels of the specified pins from the read port, returned as + * a mask. + */ +static inline ioport_port_mask_t ioport_get_port_level(ioport_pin_t port, + ioport_port_mask_t mask) +{ + return arch_ioport_get_port_level(port, mask); +} + +/** + * \brief Toggle the value of an IOPORT pin, which has previously configured as + * an output. + * + * \param pin IOPORT pin to toggle + */ +static inline void ioport_toggle_pin_level(ioport_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/** + * \brief Toggle the values of several IOPORT pins located in a single port. + * + * \param port IOPORT port to modify + * \param mask Pin mask of pins to toggle + */ +static inline void ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_toggle_port_level(port, mask); +} + +/** + * \brief Set the pin sense mode of a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param pin_sense Edge to sense for the pin (\ref ioport_sense) + */ +static inline void ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + arch_ioport_set_pin_sense_mode(pin, pin_sense); +} + +/** + * \brief Set the pin sense mode of a multiple IOPORT pins on a single port. + * + * \param port IOPORT port to configure + * \param mask Bitmask if pins whose edge sense is to be configured + * \param pin_sense Edge to sense for the pins (\ref ioport_sense) + */ +static inline void ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, + enum ioport_sense pin_sense) +{ + arch_ioport_set_port_sense_mode(port, mask, pin_sense); +} + +/** + * \brief Convert a pin ID into a its port ID. + * + * \param pin IOPORT pin ID to convert + * \retval Port ID for the given pin ID + */ +static inline ioport_port_t ioport_pin_to_port_id(ioport_pin_t pin) +{ + return arch_ioport_pin_to_port_id(pin); +} + +/** + * \brief Convert a pin ID into a bitmask mask for the given pin on its port. + * + * \param pin IOPORT pin ID to convert + * \retval Bitmask with a bit set that corresponds to the given pin ID in its port + */ +static inline ioport_port_mask_t ioport_pin_to_mask(ioport_pin_t pin) +{ + return arch_ioport_pin_to_mask(pin); +} + +/** @} */ + +/** + * \page ioport_quickstart Quick start guide for the common IOPORT service + * + * This is the quick start guide for the \ref ioport_group, with + * step-by-step instructions on how to configure and use the service in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section ioport_quickstart_basic Basic use case + * In this use case we will configure one IO pin for button input and one for + * LED control. Then it will read the button state and output it on the LED. + * + * \section ioport_quickstart_basic_setup Setup steps + * + * \subsection ioport_quickstart_basic_setup_code Example code + * \code + #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + + ioport_init(); + + ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); + ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); + ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); +\endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the GPIOs symbolic names and this can be done with + * the \ref IOPORT_CREATE_PIN macro. We define one for a LED and one for a + * button. + * - \code + #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) +\endcode + * - \note The usefulness of the \ref IOPORT_CREATE_PIN macro and port names + * differ between architectures: + * - MEGA, MEGA_RF and XMEGA: Use \ref IOPORT_CREATE_PIN macro with port definitions + * PORTA, PORTB ... + * - UC3: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: AVR32_PIN_PB06 + * - SAM: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: PIO_PA5_IDX
+ * \ref IOPORT_CREATE_PIN can also be used with port definitions + * PIOA, PIOB ... + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set the LED GPIO as output: + * - \code ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); \endcode + * -# Set the button GPIO as input: + * - \code ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); \endcode + * -# Enable pull-up for the button GPIO: + * - \code ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + bool value; + + value = ioport_get_pin_level(MY_BUTTON); + ioport_set_pin_level(MY_LED, value); +\endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a boolean variable for state storage: + * - \code bool value; \endcode + * -# Read out the button level into variable value: + * - \code value = ioport_get_pin_level(MY_BUTTON); \endcode + * -# Set the LED to read out value from the button: + * - \code ioport_set_pin_level(MY_LED, value); \endcode + * + * \section ioport_quickstart_advanced Advanced use cases + * - \subpage ioport_quickstart_use_case_1 : Port access + */ + +/** + * \page ioport_quickstart_use_case_1 Advanced use case doing port access + * + * In this case we will read out the pins from one whole port and write the + * read value to another port. + * + * \section ioport_quickstart_use_case_1_setup Setup steps + * + * \subsection ioport_quickstart_use_case_1_setup_code Example code + * \code + #define IN_PORT IOPORT_PORTA + #define OUT_PORT IOPORT_PORTB + #define MASK 0x00000060 + + ioport_init(); + + ioport_set_port_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); + ioport_set_port_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); +\endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the ports symbolic names: + * - \code + #define IN_PORT IOPORT_PORTA + #define OUT_PORT IOPORT_PORTB +\endcode + * - \note The port names differ between architectures: + * - MEGA_RF, MEGA and XMEGA: There are predefined names for ports: IOPORT_PORTA, + * IOPORT_PORTB ... + * - UC3: Use the index value of the different IO blocks: 0, 1 ... + * - SAM: There are predefined names for ports: IOPORT_PIOA, IOPORT_PIOB + * ... + * -# Also useful to define a mask for the bits to work with: + * - \code #define MASK 0x00000060 \endcode + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set one of the ports as input: + * - \code ioport_set_pin_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); \endcode + * -# Set the other port as output: + * - \code ioport_set_pin_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + ioport_port_mask_t value; + + value = ioport_get_port_level(IN_PORT, MASK); + ioport_set_port_level(OUT_PORT, MASK, value); +\endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a variable for port date storage: + * - \code ioport_port_mask_t value; \endcode + * -# Read out from one port: + * - \code value = ioport_get_port_level(IN_PORT, MASK); \endcode + * -# Put the read data out on the other port: + * - \code ioport_set_port_level(OUT_PORT, MASK, value); \endcode + */ + +#ifdef __cplusplus +} +#endif + +#endif /* IOPORT_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/ioport.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/ioport.h.REMOVED.git-id deleted file mode 100644 index 9976be3c..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/ioport.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a03209562a3bd7abd18ef9c237dbb7c4b9d98a89 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport.h new file mode 100644 index 00000000..00b66e8b --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport.h @@ -0,0 +1,364 @@ +/** + * \file + * + * \brief XMEGA architecture specific IOPORT service implementation header file. + * + * Copyright (c) 2012-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef IOPORT_XMEGA_H +#define IOPORT_XMEGA_H + +#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin)) +#define IOPORT_BASE_ADDRESS 0x600 +#define IOPORT_PORT_OFFSET 0x20 + +/** \name IOPORT port numbers */ +/** @{ */ +#if !XMEGA_B3 +# define IOPORT_PORTA 0 +#endif + +#define IOPORT_PORTB 1 +#define IOPORT_PORTC 2 +#define IOPORT_PORTD 3 + +#if !XMEGA_B3 +# define IOPORT_PORTE 4 +#endif + +#if XMEGA_A1 || XMEGA_A1U || XMEGA_A3 || XMEGA_A3U || XMEGA_A3B || XMEGA_A3BU || \ + XMEGA_C3 || XMEGA_D3 +# define IOPORT_PORTF 5 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTG 6 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTH 7 +# define IOPORT_PORTJ 8 +# define IOPORT_PORTK 9 +#endif + +#if XMEGA_B1 || XMEGA_B3 +# define IOPORT_PORTM 11 +#endif + +#if XMEGA_A1 || XMEGA_A1U +# define IOPORT_PORTQ 14 +#endif + +#define IOPORT_PORTR 15 +/** @} */ + +/** + * \weakgroup ioport_group + * \section ioport_modes IOPORT Modes + * + * For details on these please see the XMEGA Manual. + * + * @{ + */ + +/** \name IOPORT Mode bit definitions */ +/** @{ */ +#define IOPORT_MODE_TOTEM (0x00 << 3) /*!< Totem-pole */ +#define IOPORT_MODE_BUSKEEPER (0x01 << 3) /*!< Buskeeper */ +#define IOPORT_MODE_PULLDOWN (0x02 << 3) /*!< Pull-down */ +#define IOPORT_MODE_PULLUP (0x03 << 3) /*!< Pull-up */ +#define IOPORT_MODE_WIREDOR (0x04 << 3) /*!< Wired OR */ +#define IOPORT_MODE_WIREDAND (0x05 << 3) /*!< Wired AND */ +#define IOPORT_MODE_WIREDORPULL (0x06 << 3) /*!< Wired OR with pull-down */ +#define IOPORT_MODE_WIREDANDPULL (0x07 << 3) /*!< Wired AND with pull-up */ +#define IOPORT_MODE_INVERT_PIN (0x01 << 6) /*!< Invert output and input */ +#define IOPORT_MODE_SLEW_RATE_LIMIT (0x01 << 7) /*!< Slew rate limiting */ +/** @} */ + +/** @} */ + +typedef uint8_t ioport_mode_t; +typedef uint8_t ioport_pin_t; +typedef uint8_t ioport_port_t; +typedef uint8_t ioport_port_mask_t; + +__always_inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin) +{ + return pin >> 3; +} + +__always_inline static PORT_t *arch_ioport_port_to_base(ioport_port_t port) +{ + return (PORT_t *)((uintptr_t)IOPORT_BASE_ADDRESS + + (port * IOPORT_PORT_OFFSET)); +} + +__always_inline static PORT_t *arch_ioport_pin_to_base(ioport_pin_t pin) +{ + return arch_ioport_port_to_base(arch_ioport_pin_to_port_id(pin)); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_mask( + ioport_pin_t pin) +{ + return 1U << (pin & 0x07); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_index( + ioport_pin_t pin) +{ + return (pin & 0x07); +} + +__always_inline static void arch_ioport_init(void) +{ +} + +__always_inline static void arch_ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] &= ~PORT_ISC_gm; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_enable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl + = (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] |= PORT_ISC_INPUT_DISABLE_gc; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_disable_pin(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl + = (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl |= PORT_ISC_INPUT_DISABLE_gc; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + uint8_t new_mode_bits = (mode & ~PORT_ISC_gm); + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] + = (pin_ctrl[i] & + PORT_ISC_gm) | new_mode_bits; + } + } + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin, + ioport_mode_t mode) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl + = (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= PORT_ISC_gm; + *pin_ctrl |= mode; + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = mask; + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = mask; + } +} + +__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (dir == IOPORT_DIR_OUTPUT) { + base->DIRSET = arch_ioport_pin_to_mask(pin); + } else if (dir == IOPORT_DIR_INPUT) { + base->DIRCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin, + bool level) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + if (level) { + base->OUTSET = arch_ioport_pin_to_mask(pin); + } else { + base->OUTCLR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + PORT_t *base = arch_ioport_port_to_base(port); + if (level) { + base->OUTSET |= mask; + base->OUTCLR &= ~mask; + } else { + base->OUTSET &= ~mask; + base->OUTCLR |= mask; + } +} + +__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + return base->IN & arch_ioport_pin_to_mask(pin); +} + +__always_inline static ioport_port_mask_t arch_ioport_get_port_level( + ioport_port_t port, ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + return base->IN & mask; +} + +__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + + base->OUTTGL = arch_ioport_pin_to_mask(pin); +} + +__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + PORT_t *base = arch_ioport_port_to_base(port); + + base->OUTTGL = mask; +} + +__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_pin_to_base(pin); + volatile uint8_t *pin_ctrl + = (&base->PIN0CTRL + arch_ioport_pin_to_index(pin)); + + uint8_t flags = cpu_irq_save(); + + *pin_ctrl &= ~PORT_ISC_gm; + *pin_ctrl |= (pin_sense & PORT_ISC_gm); + + cpu_irq_restore(flags); +} + +__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_sense pin_sense) +{ + PORT_t *base = arch_ioport_port_to_base(port); + volatile uint8_t *pin_ctrl = &base->PIN0CTRL; + uint8_t new_sense_bits = (pin_sense & PORT_ISC_gm); + + uint8_t flags = cpu_irq_save(); + + for (uint8_t i = 0; i < 8; i++) { + if (mask & arch_ioport_pin_to_mask(i)) { + pin_ctrl[i] + = (pin_ctrl[i] & + ~PORT_ISC_gm) | new_sense_bits; + } + } + + cpu_irq_restore(flags); +} + +#endif /* IOPORT_XMEGA_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport.h.REMOVED.git-id deleted file mode 100644 index d21d4146..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -00b66e8b6733eb6d8f883d766a9382050dda722a \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport_compat.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport_compat.c new file mode 100644 index 00000000..ce47189a --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport_compat.c @@ -0,0 +1,73 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface. + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#include "ioport_compat.h" + +#if defined(IOPORT_XMEGA_COMPAT) +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + uint8_t pin; + + for (pin = 0; pin < 8; pin++) { + if (pin_mask & (1 << pin)) { + *((uint8_t *)port + PORT_PIN0CTRL + pin) = flags >> 8; + } + } + /* Select direction and initial pin state */ + if (flags & IOPORT_DIR_OUTPUT) { + if (flags & IOPORT_INIT_HIGH) { + *((uint8_t *)port + PORT_OUTSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_OUTCLR) = pin_mask; + } + + *((uint8_t *)port + PORT_DIRSET) = pin_mask; + } else { + *((uint8_t *)port + PORT_DIRCLR) = pin_mask; + } +} + +#endif diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport_compat.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport_compat.c.REMOVED.git-id deleted file mode 100644 index 780fcccd..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport_compat.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ce47189a899d1ceabb8e881e162c6b822627191c \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport_compat.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport_compat.h new file mode 100644 index 00000000..aaba63f4 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport_compat.h @@ -0,0 +1,321 @@ +/** + * \file + * + * \brief XMEGA legacy IOPORT software compatibility driver interface header + * file. + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef IOPORT_XMEGA_COMPAT_H_ +#define IOPORT_XMEGA_COMPAT_H_ + +#include "../ioport.h" + +/** + * \brief A pin mask + * + * This type is used to describe the port pin mask on the part. + */ +typedef uint8_t pin_mask_t; + +/** + * \brief A PORT pin + * + * This type is used to describe the PORT pins on the part. + */ +typedef uint8_t port_pin_t; + +/** + * \brief Pin configuration flags + * + * This is a bitmask containing configuration flags for the pins that shall be + * configured. + */ +typedef uint16_t port_pin_flags_t; + +/** + * \brief A port id + * + * This type is used to describe the port id on the part (0 is PORTA). + */ +typedef uint8_t port_id_t; + +/** \name Initial Output State Flags */ +/** @{ */ +#define IOPORT_INIT_LOW (0 << 1) /*!< Initial Output State Low */ +#define IOPORT_INIT_HIGH (1 << 1) /*!< Initial Output State High */ +/** @} */ + +/** \name Input/Sense Configuration Flags */ +/** @{ */ +#define IOPORT_BOTHEDGES (0 << 8) /*!< Sense Both Edges */ +#define IOPORT_RISING (1 << 8) /*!< Sense Rising Edge */ +#define IOPORT_FALLING (2 << 8) /*!< Sense Falling Edge */ +#define IOPORT_LEVEL (3 << 8) /*!< Sense Low Level */ +#if XMEGA_E +# define IOPORT_FORCE_ENABLE (6 << 8) /*!< Sense Force Input Enable Low Level */ +#endif +#define IOPORT_INPUT_DISABLE (7 << 8) /*!< Input Buffer Disabled */ +/** @} */ + +/** \name Output and Pull Configuration Flags */ +/** @{ */ +#define IOPORT_TOTEM (0 << 11) /*!< Normal push/pull output */ +#define IOPORT_BUSKEEPER (1 << 11) /*!< Bus Keeper */ +#define IOPORT_PULL_DOWN (2 << 11) /*!< Pull-Down (when input) */ +#define IOPORT_PULL_UP (3 << 11) /*!< Pull-Up (when input) */ +#define IOPORT_WIRED_OR (4 << 11) /*!< Wired OR */ +#define IOPORT_WIRED_AND (5 << 11) /*!< Wired AND */ +#define IOPORT_WIRED_OR_PULL_DOWN (6 << 11) /*!< Wired OR and Pull-Down */ +#define IOPORT_WIRED_AND_PULL_UP (7 << 11) /*!< Wired AND and Pull-Up */ +/** @} */ + +/** \name Inverted I/O Configuration Flags */ +/** @{ */ +#define IOPORT_INV_ENABLED (1 << 14) /*!< I/O is Inverted */ +#define IOPORT_INV_DISABLE (0 << 14) /*!< I/O is Not Inverted */ +/** @} */ + +/** \name Slew Rate Limit Configuration Flags */ +/** @{ */ +#define IOPORT_SRL_ENABLED (1 << 15) /*!< Slew Rate Limit Enabled */ +#define IOPORT_SRL_DISABLED (0 << 15) /*!< Slew Rate Limit Disabled */ +/** @} */ + +/** + * \internal + * \name PORT fields structure offset + * + * These macros are used to compute the field offset number with the PORT_t + * structure. + */ +/** @{ */ +#define PORT_DIR 0x00 /*!< Data Direction */ +#define PORT_DIRSET 0x01 /*!< Data Direction Set */ +#define PORT_DIRCLR 0x02 /*!< Data Direction Clear */ +#define PORT_DIRTGL 0x03 /*!< Data Direction Toggle */ +#define PORT_OUT 0x04 /*!< Data Output Value */ +#define PORT_OUTSET 0x05 /*!< Data Output Value Set */ +#define PORT_OUTCLR 0x06 /*!< Data Output Value Clear */ +#define PORT_OUTTGL 0x07 /*!< Data Output Value Toggle */ +#define PORT_IN 0x08 /*!< Data Input Value */ +#define PORT_INTCTRL 0x09 /*!< Interrupt Control */ +#define PORT_INT0MASK 0x0A /*!< Interrupt 0 Mask */ +#define PORT_INT1MASK 0x0B /*!< Interrupt 1 Mask */ +#define PORT_INTFLAGS 0x0C /*!< Interrupt Flags */ +#define PORT_PIN0CTRL 0x10 /*!< Pin 0 Configuration */ +#define PORT_PIN1CTRL 0x11 /*!< Pin 1 Configuration */ +#define PORT_PIN2CTRL 0x12 /*!< Pin 2 Configuration */ +#define PORT_PIN3CTRL 0x13 /*!< Pin 3 Configuration */ +#define PORT_PIN4CTRL 0x14 /*!< Pin 4 Configuration */ +#define PORT_PIN5CTRL 0x15 /*!< Pin 5 Configuration */ +#define PORT_PIN6CTRL 0x16 /*!< Pin 6 Configuration */ +#define PORT_PIN7CTRL 0x17 /*!< Pin 7 Configuration */ +/** @} */ + +static inline PORT_t *ioport_pin_to_port(port_pin_t pin) +{ + return arch_ioport_pin_to_base(pin); +} + +static inline PORT_t *ioport_id_pin_to_port(port_id_t port) +{ + return arch_ioport_port_to_base(port); +} + +/** + * \brief Configure the IO PORT pin function for a set of pins on a port + * + * \param port Pointer to the port + * \param pin_mask Mask containing the pins that should be configured + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +void ioport_configure_port_pin(void *port, pin_mask_t pin_mask, + port_pin_flags_t flags); + +/** + * \brief Select the port function for a single pin + * + * \param pin The pin to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_pin(port_pin_t pin, port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_pin_to_base(pin), + arch_ioport_pin_to_mask(pin), flags); +} + +/** + * \brief Configure a group of I/O pins on a specified port number + * + * \param port The port number + * \param pin_mask The pin mask to configure + * \param flags Bitmask of flags specifying additional configuration + * parameters. + */ +static inline void ioport_configure_group(port_id_t port, pin_mask_t pin_mask, + port_pin_flags_t flags) +{ + ioport_configure_port_pin(arch_ioport_port_to_base(port), pin_mask, flags); +} + +/** + * \brief Drive a PORT pin to a given state + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + * \param value The desired state of the pin. \a true means drive the + * pin high (towards Vdd), while \a false means drive the pin low + * (towards Vss). + */ +static inline void ioport_set_value(port_pin_t pin, bool value) +{ + arch_ioport_set_pin_level(pin, value); +} + +/** + * \brief Drive a PORT pin to a low level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_low(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, false); +} + +/** + * \brief Drive a PORT pin to a high level + * + * This function will only have an effect if \a pin is configured as + * an output. + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_set_pin_high(port_pin_t pin) +{ + arch_ioport_set_pin_level(pin, true); +} + +/** + * \brief Read the current state of a PORT pin + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_get_value(port_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_high(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == true); +} + +/** + * \brief Read the current state of a PORT pin and test high level + * + * \param pin A number identifying the pin to read. + * \retval true The pin is currently high (close to Vdd) + * \retval false The pin is currently low (close to Vss) + */ +static inline bool ioport_pin_is_low(port_pin_t pin) +{ + return (arch_ioport_get_pin_level(pin) == false); +} + +/** + * \brief Toggle the current state of a PORT pin + * + * \param pin A number identifying the pin to act on. + */ +static inline void ioport_toggle_pin(port_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/*! \brief Drives a group of I/O pin of a port to high level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_high(port_id_t port_id, + pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, port_mask); +} + +/*! \brief Drives a group of I/O pin of a port to low level. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_set_group_low(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_set_port_level(port_id, port_mask, 0); +} + +/*! \brief Toggles a group of I/O pin of a port. + * + * \param port_id The port number. + * \param port_mask The mask. + */ +static inline void ioport_tgl_group(port_id_t port_id, pin_mask_t port_mask) +{ + arch_ioport_toggle_port_level(port_id, port_mask); +} + +#endif /* IOPORT_COMPAT_H_ */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport_compat.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport_compat.h.REMOVED.git-id deleted file mode 100644 index 902defce..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/ioport/xmega/ioport_compat.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aaba63f4d4fd13628d025cda510c12a2393f5b37 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/sleepmgr.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/sleepmgr.h new file mode 100644 index 00000000..2435d44c --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/sleepmgr.h @@ -0,0 +1,271 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef SLEEPMGR_H +#define SLEEPMGR_H + +#include +#include + +#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM) +# include "sam/sleepmgr.h" +#elif XMEGA +# include "xmega/sleepmgr.h" +#elif UC3 +# include "uc3/sleepmgr.h" +#elif SAM4L +# include "sam4l/sleepmgr.h" +#elif MEGA +# include "mega/sleepmgr.h" +#elif (SAMD20 || SAMD21 || SAMR21 || SAMD11) +# include "samd/sleepmgr.h" +#elif (SAML21) +# include "saml/sleepmgr.h" +#else +# error Unsupported device. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup sleepmgr_group Sleep manager + * + * The sleep manager is a service for ensuring that the device is not put to + * sleep in deeper sleep modes than the system (e.g., peripheral drivers, + * services or the application) allows at any given time. + * + * It is based on the use of lock counting for the individual sleep modes, and + * will put the device to sleep in the shallowest sleep mode that has a non-zero + * lock count. The drivers/services/application can change these counts by use + * of \ref sleepmgr_lock_mode and \ref sleepmgr_unlock_mode. + * Refer to \ref sleepmgr_mode for a list of the sleep modes available for + * locking, and the device datasheet for information on their effect. + * + * The application must supply the file \ref conf_sleepmgr.h. + * + * For the sleep manager to be enabled, the symbol \ref CONFIG_SLEEPMGR_ENABLE + * must be defined, e.g., in \ref conf_sleepmgr.h. If this symbol is not + * defined, the functions are replaced with dummy functions and no RAM is used. + * + * @{ + */ + +/** + * \def CONFIG_SLEEPMGR_ENABLE + * \brief Configuration symbol for enabling the sleep manager + * + * If this symbol is not defined, the functions of this service are replaced + * with dummy functions. This is useful for reducing code size and execution + * time if the sleep manager is not needed in the application. + * + * This symbol may be defined in \ref conf_sleepmgr.h. + */ +#if defined(__DOXYGEN__) && !defined(CONFIG_SLEEPMGR_ENABLE) +# define CONFIG_SLEEPMGR_ENABLE +#endif + +/** + * \enum sleepmgr_mode + * \brief Sleep mode locks + * + * Identifiers for the different sleep mode locks. + */ + +/** + * \brief Initialize the lock counts + * + * Sets all lock counts to 0, except the very last one, which is set to 1. This + * is done to simplify the algorithm for finding the deepest allowable sleep + * mode in \ref sleepmgr_enter_sleep. + */ +static inline void sleepmgr_init(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t i; + + for (i = 0; i < SLEEPMGR_NR_OF_MODES - 1; i++) { + sleepmgr_locks[i] = 0; + } + sleepmgr_locks[SLEEPMGR_NR_OF_MODES - 1] = 1; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Increase lock count for a sleep mode + * + * Increases the lock count for \a mode to ensure that the sleep manager does + * not put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to lock. + */ +static inline void sleepmgr_lock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + if(sleepmgr_locks[mode] >= 0xff) { + while (true) { + // Warning: maximum value of sleepmgr_locks buffer is no more than 255. + // Check APP or change the data type to uint16_t. + } + } + + // Enter a critical section + flags = cpu_irq_save(); + + ++sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#else + UNUSED(mode); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Decrease lock count for a sleep mode + * + * Decreases the lock count for \a mode. If the lock count reaches 0, the sleep + * manager can put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to unlock. + */ +static inline void sleepmgr_unlock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + if(sleepmgr_locks[mode] == 0) { + while (true) { + // Warning: minimum value of sleepmgr_locks buffer is no less than 0. + // Check APP. + } + } + + // Enter a critical section + flags = cpu_irq_save(); + + --sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#else + UNUSED(mode); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + /** + * \brief Retrieves the deepest allowable sleep mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The deepest allowable + * sleep mode is then returned. + */ +static inline enum sleepmgr_mode sleepmgr_get_sleep_mode(void) +{ + enum sleepmgr_mode sleep_mode = SLEEPMGR_ACTIVE; + +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t *lock_ptr = sleepmgr_locks; + + // Find first non-zero lock count, starting with the shallowest modes. + while (!(*lock_ptr)) { + lock_ptr++; + sleep_mode = (enum sleepmgr_mode)(sleep_mode + 1); + } + + // Catch the case where one too many sleepmgr_unlock_mode() call has been + // performed on the deepest sleep mode. + Assert((uintptr_t)(lock_ptr - sleepmgr_locks) < SLEEPMGR_NR_OF_MODES); + +#endif /* CONFIG_SLEEPMGR_ENABLE */ + + return sleep_mode; +} + +/** + * \fn sleepmgr_enter_sleep + * \brief Go to sleep in the deepest allowed mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The device is then put to + * sleep in the sleep mode that corresponds to the lock. + * + * \note This function enables interrupts before going to sleep, and will leave + * them enabled upon return. This also applies if sleep is skipped due to ACTIVE + * mode being locked. + */ + +static inline void sleepmgr_enter_sleep(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + enum sleepmgr_mode sleep_mode; + + cpu_irq_disable(); + + // Find the deepest allowable sleep mode + sleep_mode = sleepmgr_get_sleep_mode(); + // Return right away if first mode (ACTIVE) is locked. + if (sleep_mode==SLEEPMGR_ACTIVE) { + cpu_irq_enable(); + return; + } + // Enter the deepest allowable sleep mode with interrupts enabled + sleepmgr_sleep(sleep_mode); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* SLEEPMGR_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/sleepmgr.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/sleepmgr.h.REMOVED.git-id deleted file mode 100644 index 114fa659..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/sleepmgr.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2435d44c0e504c229767482b27af83535dccb994 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/xmega/sleepmgr.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/xmega/sleepmgr.c new file mode 100644 index 00000000..0877e284 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/xmega/sleepmgr.c @@ -0,0 +1,61 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#include +#include + +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) + +uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES]; + +enum SLEEP_SMODE_enum sleepmgr_configs[SLEEPMGR_NR_OF_MODES] = { + SLEEP_SMODE_IDLE_gc, + SLEEP_SMODE_ESTDBY_gc, + SLEEP_SMODE_PSAVE_gc, + SLEEP_SMODE_STDBY_gc, + SLEEP_SMODE_PDOWN_gc, +}; + +#endif /* CONFIG_SLEEPMGR_ENABLE */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/xmega/sleepmgr.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/xmega/sleepmgr.c.REMOVED.git-id deleted file mode 100644 index d310d98d..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/xmega/sleepmgr.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0877e284b4e07f3e29337ceb9e41be9308a84ae9 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/xmega/sleepmgr.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/xmega/sleepmgr.h new file mode 100644 index 00000000..7ca32273 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/xmega/sleepmgr.h @@ -0,0 +1,117 @@ +/** + * \file + * + * \brief AVR XMEGA Sleep manager implementation + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef XMEGA_SLEEPMGR_H +#define XMEGA_SLEEPMGR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** + * \weakgroup sleepmgr_group + * @{ + */ + +enum sleepmgr_mode { + //! Active mode. + SLEEPMGR_ACTIVE = 0, + //! Idle mode. + SLEEPMGR_IDLE, + //! Extended Standby mode. + SLEEPMGR_ESTDBY, + //! Power Save mode. + SLEEPMGR_PSAVE, + //! Standby mode. + SLEEPMGR_STDBY, + //! Power Down mode. + SLEEPMGR_PDOWN, + SLEEPMGR_NR_OF_MODES, +}; + +/** + * \internal + * \name Internal arrays + * @{ + */ +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) +//! Sleep mode lock counters +extern uint8_t sleepmgr_locks[]; +/** + * \brief Look-up table with sleep mode configurations + * \note This is located in program memory (Flash) as it is constant. + */ +extern enum SLEEP_SMODE_enum sleepmgr_configs[]; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +//! @} + +static inline void sleepmgr_sleep(const enum sleepmgr_mode sleep_mode) +{ + Assert(sleep_mode != SLEEPMGR_ACTIVE); +#ifdef CONFIG_SLEEPMGR_ENABLE + sleep_set_mode(sleepmgr_configs[sleep_mode-1]); + sleep_enable(); + + cpu_irq_enable(); + sleep_enter(); + + sleep_disable(); +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ + +} + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* XMEGA_SLEEPMGR_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/xmega/sleepmgr.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/xmega/sleepmgr.h.REMOVED.git-id deleted file mode 100644 index 2509aca1..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/sleepmgr/xmega/sleepmgr.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7ca322738b55b4b099718f32844e4bc1b3749503 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/spi_master.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/spi_master.h new file mode 100644 index 00000000..e92f4ca5 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/spi_master.h @@ -0,0 +1,273 @@ +/** + * \file + * + * \brief SPI Master Mode management + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef SPI_MASTER_H_INCLUDED +#define SPI_MASTER_H_INCLUDED + +#include + +#if XMEGA +# include "xmega_spi/spi_master.h" +#elif MEGA_RF +# include "megarf_spi/spi_master.h" +#elif UC3 +# include "uc3_spi/spi_master.h" +#elif SAM +# include "sam_spi/spi_master.h" +#else +# error Unsupported chip type +#endif + +/** + * + * \defgroup spi_group Serial Peripheral Interface (SPI) + * + * This is the common API for SPI interface. Additional features are available + * in the documentation of the specific modules. + * + * \section spi_group_platform Platform Dependencies + * + * The SPI API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behavior. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - spi_master_init() + * - spi_master_setup_device() + * - spi_select_device() + * - spi_deselect_device() + * - spi_write_single() + * - spi_write_packet() + * - spi_read_single() + * - spi_read_packet() + * - spi_is_tx_empty() + * - spi_is_tx_ready() + * - spi_is_rx_full() + * - spi_is_rx_ready() + * - spi_enable() + * - spi_disable() + * - spi_is_enabled() + * + * \section spi_master_quickstart_section Quick Start Guide + * See \ref common_spi_master_quickstart + * @{ + */ + +//! @} + +/** + * \page common_spi_master_quickstart Quick Start Guide for the SPI Master Driver + * + * This is the quick start guide for the \ref spi_group "SPI Driver", with + * step-by-step instructions on how to configure and use the driver for a + * specific use case. + * + * The use case contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * The steps for setting up the SPI master for XMEGA and UC3 use exactly the + * same approach, but note that there are different names on the peripherals. So + * to use this Quick Start for UC3 please make sure that all the peripheral + * names are updated according to the UC3 datasheet. + * - \subpage spi_master_xmega + * + */ +/** + * \page spi_master_xmega Basic setup for SPI master on XMEGA devices + * + * \section spi_master_xmega_basic Basic setup for XMEGA devices + * The SPI module will be set up as master: + * - SPI on PORTD + * - 1MHz SPI clock speed + * - Slave Chip Select connected on PORTD pin 1 + * - SPI mode 0 (data on rising clock edge) + * + * \section spi_master_xmega_basic_setup Setup steps + * \subsection spi_master_xmega_basic_setup_code Example code + * Add to application C-file (e.g. main.c): + * \code + void spi_init_pins(void) + { + ioport_configure_port_pin(&PORTD, PIN1_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); + + ioport_configure_port_pin(&PORTD, PIN4_bm, IOPORT_PULL_UP | IOPORT_DIR_INPUT); + ioport_configure_port_pin(&PORTD, PIN5_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); + ioport_configure_port_pin(&PORTD, PIN6_bm, IOPORT_DIR_INPUT); + ioport_configure_port_pin(&PORTD, PIN7_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); + } + + void spi_init_module(void) + { + struct spi_device spi_device_conf = { + .id = IOPORT_CREATE_PIN(PORTD, 1) + }; + + spi_master_init(&SPID); + spi_master_setup_device(&SPID, &spi_device_conf, SPI_MODE_0, 1000000, 0); + spi_enable(&SPID); + } +\endcode + * + * \subsection spi_master_xmega_basic_setup Workflow + * -# Ensure that \ref conf_spi_master.h is present for the driver. + * - \note This file is only for the driver and should not be included by the + * user. In this example the file can be left empty. + * -# Initialize the pins used by the SPI interface (this initialization is for + * the ATxmega32A4U device). + * -# Set the pin used for slave select as output high: + * \code + ioport_configure_port_pin(&PORTD, PIN1_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); +\endcode + * -# Enable pull-up on own chip select (SS): + * \code + ioport_configure_port_pin(&PORTD, PIN4_bm, IOPORT_PULL_UP | IOPORT_DIR_INPUT); +\endcode + * \attention If this pin is pulled low the SPI module will go into slave mode. + * -# Set MOSI and SCL as output high, and set MISO as input: + * \code + ioport_configure_port_pin(&PORTD, PIN5_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); + ioport_configure_port_pin(&PORTD, PIN6_bm, IOPORT_DIR_INPUT); + ioport_configure_port_pin(&PORTD, PIN7_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); +\endcode + * -# Define the SPI device configuration struct to describe which pin the + * slave select (slave chip select) is connected to, in this case the slave + * select pin has been connected to PORTD pin 1 (PD1): + * - \code + struct spi_device spi_device_conf = { + .id = IOPORT_CREATE_PIN(PORTD, 1) + }; +\endcode + * -# Initialize the SPI module, in this case SPI on PORTD has been chosen: + * - \code + spi_master_init(&SPID); +\endcode + * -# Setup the SPI master module for a specific device: + * - \code + spi_master_setup_device(&SPID, &spi_device_conf, SPI_MODE_0, 1000000, 0); +\endcode + * - \note The last argument, which is zero in this case, can be ignored and is + * only included for compatibility purposes. + * -# Then enable the SPI: + * - \code + spi_enable(&SPID); +\endcode + * + * \section spi_master_xmega_basic_usage Usage steps + * \subsection spi_master_xmega_basic_usage_code Example code + * Add to, e.g., the main loop in the application C-file: + * \code + uint8_t data_buffer[1] = {0xAA}; + + struct spi_device spi_device_conf = { + .id = IOPORT_CREATE_PIN(PORTD, 1) + }; + + spi_select_device(&SPID, &spi_device_conf); + + spi_write_packet(&SPID, data_buffer, 1); + spi_read_packet(&SPID, data_buffer, 1); + + spi_deselect_device(&SPID, &spi_device_conf); +\endcode + * + * \subsection spi_master_xmega_basic_usage_flow Workflow + * -# Create a buffer for data to be sent/received on the SPI bus, in this case + * a single byte buffer is used. The buffer can be of arbitrary size as long as + * there is space left in SRAM: + * - \code + uint8_t data_buffer[1] = {0xAA}; +\endcode + * -# Define the SPI device configuration struct to describe which pin the + * slave select (slave chip select) is connected to, in this case the slave + * select pin has been connected to PORTD pin 1 (PD1): + * - \code + struct spi_device spi_device_conf = { + .id = IOPORT_CREATE_PIN(PORTD, 1) + }; +\endcode + * - \note As this struct is the same for both the initializing part and the usage + * part it could be a good idea to make the struct global, and hence accessible + * for both the initializing part and usage part. Another solution could be to + * create the struct in the main function and pass the address of the struct to + * the spi_init_module() function, e.g.: + * \code + void spi_init_module(struct spi_device *spi_device_conf) + { + ... + + spi_master_setup_device(&SPID, spi_device_conf, SPI_MODE_0, 1000000, 0); + + ... + } +\endcode + * -# Write data to the SPI slave device, in this case write one byte from the + * data_buffer: + * - \code + spi_write_packet(&SPID, data_buffer, 1); +\endcode + * -# Read data from the SPI slave device, in this case read one byte and put it + * into the data_buffer: + * - \code + spi_read_packet(&SPID, data_buffer, 1); +\endcode + * - \attention As the SPI works as a shift register so that data is shifted in at + * the same time as data is shifted out a read operation will mean that a dummy + * byte \ref CONFIG_SPI_MASTER_DUMMY is written to the SPI bus. \ref CONFIG_SPI_MASTER_DUMMY + * defaults to 0xFF, but can be changed by defining it inside the \ref conf_spi_master.h + * file. + * -# When read and write operations is done de-select the slave: + * - \code + spi_deselect_device(&SPID, &spi_device_conf); +\endcode + * + */ + +#endif /* SPI_MASTER_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/spi_master.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/spi_master.h.REMOVED.git-id deleted file mode 100644 index 0165616c..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/spi_master.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e92f4ca5acb245de380ce60d0cc4c9b8c8829e7e \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/usart_spi.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/usart_spi.h new file mode 100644 index 00000000..92b407ff --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/usart_spi.h @@ -0,0 +1,104 @@ +/** + * \file + * + * \brief USART in SPI mode driver functions. + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef USART_SPI_H_INCLUDED +#define USART_SPI_H_INCLUDED + +#include + +#if XMEGA +# include "xmega_usart_spi/usart_spi.h" +#elif MEGA_RF +# include "megarf_usart_spi/usart_spi.h" +#elif UC3 +# include "uc3_usart_spi/usart_spi.h" +#elif SAM +# include "sam_usart_spi/usart_spi.h" +#else +# error Unsupported chip type +#endif + +/** + * + * \defgroup usart_spi_group USART in SPI (Serial Peripheral Interface) mode + * + * This is the common API for USART in SPI mode. Additional features are available + * in the documentation of the specific modules. + * + * \section spi_group_platform Platform Dependencies + * + * The spi API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behaviour. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - usart_spi_init() + * - usart_spi_setup_device() + * - usart_spi_select_device() + * - usart_spi_deselect_device() + * - usart_spi_write_single() + * - usart_spi_write_packet() + * - usart_spi_read_single() + * - usart_spi_read_packet() + * - usart_spi_is_tx_empty() + * - usart_spi_is_tx_ready() + * - usart_spi_is_rx_full() + * - usart_spi_is_rx_ready() + * - usart_spi_enable() + * - usart_spi_disable() + * - usart_spi_is_enabled() + * + * + * @{ + */ + +//! @} + +#endif /* USART_SPI_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/usart_spi.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/usart_spi.h.REMOVED.git-id deleted file mode 100644 index 6d2d8c88..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/usart_spi.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -92b407ff5c005cb60ac2ef0fd1bcf767f0de6598 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_spi/spi_master.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_spi/spi_master.c new file mode 100644 index 00000000..9feeebcf --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_spi/spi_master.c @@ -0,0 +1,195 @@ +/***************************************************************************** + * + * \file + * + * \brief SPI software driver functions. + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + *****************************************************************************/ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "spi_master.h" +#include "sysclk.h" + +/*! \brief Initializes the SPI in master mode. + * + * \param spi Base address of the SPI instance. + * + */ +void spi_master_init(SPI_t *spi) +{ +#ifdef SPIA + if ((uint16_t)spi == (uint16_t)&SPIA) { + sysclk_enable_module(SYSCLK_PORT_A, PR_SPI_bm); + } +#endif +#ifdef SPIB + if ((uint16_t)spi == (uint16_t)&SPIB) { + sysclk_enable_module(SYSCLK_PORT_B, PR_SPI_bm); + } +#endif +#ifdef SPIC + if ((uint16_t)spi == (uint16_t)&SPIC) { + sysclk_enable_module(SYSCLK_PORT_C, PR_SPI_bm); + } +#endif +#ifdef SPID + if ((uint16_t)spi == (uint16_t)&SPID) { + sysclk_enable_module(SYSCLK_PORT_D, PR_SPI_bm); + } +#endif +#ifdef SPIE + if ((uint16_t)spi == (uint16_t)&SPIE) { + sysclk_enable_module(SYSCLK_PORT_E, PR_SPI_bm); + } +#endif +#ifdef SPIF + if ((uint16_t)spi == (uint16_t)&SPIF) { + sysclk_enable_module(SYSCLK_PORT_F, PR_SPI_bm); + } +#endif + spi_enable_master_mode(spi); +} + +/** + * \brief Setup a SPI device. + * + * The returned device descriptor structure must be passed to the driver + * whenever that device should be used as current slave device. + * + * \param spi Base address of the SPI instance. + * \param device Pointer to SPI device struct that should be initialized. + * \param flags SPI configuration flags. Common flags for all + * implementations are the SPI modes SPI_MODE_0 ... + * SPI_MODE_3. + * \param baud_rate Baud rate for communication with slave device in Hz. + * \param sel_id Board specific select id + */ +void spi_master_setup_device(SPI_t *spi, struct spi_device *device, + spi_flags_t flags, uint32_t baud_rate, + board_spi_select_id_t sel_id) +{ + if (spi_xmega_set_baud_div(spi, baud_rate, sysclk_get_cpu_hz()) < 0) { + Assert(false); + return; + } + + /* Clear any set SPI mode flags and set them to the user-specified mode */ + spi->CTRL = (spi->CTRL & ~SPI_MODE_gm) | + ((flags << SPI_MODE_gp) & SPI_MODE_gm); +} + +/** + * \brief Send a sequence of bytes to a SPI device + * + * Received bytes on the SPI bus are discarded. + * + * \param spi Base address of the SPI instance. + * \param data data buffer to write + * \param len Length of data + * + * \pre SPI device must be selected with spi_select_device() first + */ +status_code_t spi_write_packet(SPI_t *spi, const uint8_t *data, size_t len) +{ + while (len--) { + spi_write_single(spi, *data++); + + while (!spi_is_rx_full(spi)) { + } + } + + return STATUS_OK; +} + +/** + * \brief Receive a sequence of bytes from a SPI device + * + * All bytes sent out on SPI bus are sent as value 0. + * + * \param spi Base address of the SPI instance. + * \param data data buffer to read + * \param len Length of data + * + * \pre SPI device must be selected with spi_select_device() first + */ +status_code_t spi_read_packet(SPI_t *spi, uint8_t *data, size_t len) +{ + while (len--) { + spi_write_single(spi,CONFIG_SPI_MASTER_DUMMY); //Dummy write + + while (!spi_is_rx_full(spi)) { + } + + spi_read_single(spi, data); + data++; + } + + return STATUS_OK; +} + +/** + * \brief Select given device on the SPI bus + * + * Set device specific setting and calls board chip select. + * + * \param spi Base address of the SPI instance. + * \param device SPI device + * + */ +void spi_select_device(SPI_t *spi, struct spi_device *device) +{ + ioport_set_pin_low(device->id); +} + +/** + * \brief Deselect given device on the SPI bus + * + * Calls board chip deselect. + * + * \param spi Base address of the SPI instance. + * \param device SPI device + * + * \pre SPI device must be selected with spi_select_device() first + */ +void spi_deselect_device(SPI_t *spi, struct spi_device *device) +{ + ioport_set_pin_high(device->id); +} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_spi/spi_master.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_spi/spi_master.c.REMOVED.git-id deleted file mode 100644 index f3aa21eb..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_spi/spi_master.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9feeebcff33d69c58a2619b43bd092ed11830359 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_spi/spi_master.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_spi/spi_master.h new file mode 100644 index 00000000..12fc7088 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_spi/spi_master.h @@ -0,0 +1,450 @@ +/***************************************************************************** + * + * \file + * + * \brief SPI Master driver for AVR. + * + * This file defines a useful set of functions for the SPI interface on AVR + * devices. + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + ******************************************************************************/ +/* + * Support and FAQ: visit Atmel Support + */ + + +#ifndef _SPI_MASTER_H_ +#define _SPI_MASTER_H_ + +#include "compiler.h" +#include "status_codes.h" +#include "ioport.h" +#include "spi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup xmega_spi_master_group XMEGA SPI master service. + * + * This is the API for SPI master service on XMEGA. + * + * @{ + * + * \section xmega_spi_master_qucikstart_section Quick Start Guide + * See \ref common_spi_master_quickstart + */ + +/*! \name Spi Master Management Configuration + */ +//! @{ +#include "conf_spi_master.h" + +//! Default Config Spi Master Dummy Field +#ifndef CONFIG_SPI_MASTER_DUMMY +#define CONFIG_SPI_MASTER_DUMMY 0xFF +#endif +//! @} + +/** + * \brief Clock phase + */ +#define SPI_CPHA (1 << 0) + +/** + * \brief Clock polarity + */ +#define SPI_CPOL (1 << 1) + +/** + * \brief SPI mode 0 + */ +#define SPI_MODE_0 0 +/** + * \brief SPI mode 1 + */ +#define SPI_MODE_1 (SPI_CPHA) +/** + * \brief SPI mode 2 + */ +#define SPI_MODE_2 (SPI_CPOL) +/** + * \brief SPI mode 3 + */ +#define SPI_MODE_3 (SPI_CPOL | SPI_CPHA) + +typedef uint8_t spi_flags_t; +typedef uint32_t board_spi_select_id_t; + +//! \brief Polled SPI device definition +struct spi_device { + //! Board specific select id + port_pin_t id; +}; + +/*! \brief Initializes the SPI in master mode. + * + * \param spi Base address of the SPI instance. + * + */ +extern void spi_master_init(SPI_t *spi); + +/** + * \brief Setup a SPI device. + * + * The returned device descriptor structure must be passed to the driver + * whenever that device should be used as current slave device. + * + * \param spi Base address of the SPI instance. + * \param device Pointer to SPI device struct that should be initialized. + * \param flags SPI configuration flags. Common flags for all + * implementations are the SPI modes SPI_MODE_0 ... + * SPI_MODE_3. + * \param baud_rate Baud rate for communication with slave device in Hz. + * \param sel_id Board specific select id + */ +extern void spi_master_setup_device(SPI_t *spi, struct spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id); + +/*! \brief Enables the SPI. + * + * \param spi Base address of the SPI instance. + */ +extern void spi_enable(SPI_t *spi); + +/*! \brief Disables the SPI. + * + * Ensures that nothing is transferred while setting up buffers. + * + * \param spi Base address of the SPI instance. + * + * \warning This may cause data loss if used on a slave SPI. + */ +extern void spi_disable(SPI_t *spi); + + +/*! \brief Tests if the SPI is enabled. + * + * \param spi Base address of the SPI instance. + * + * \return \c 1 if the SPI is enabled, otherwise \c 0. + */ +extern bool spi_is_enabled(SPI_t *spi); + +/** + * \brief Select given device on the SPI bus + * + * Set device specific setting and calls board chip select. + * + * \param spi Base address of the SPI instance. + * \param device SPI device + * + */ +extern void spi_select_device(SPI_t *spi, struct spi_device *device); + +/** + * \brief Deselect given device on the SPI bus + * + * Calls board chip deselect. + * + * \param spi Base address of the SPI instance. + * \param device SPI device + * + * \pre SPI device must be selected with spi_select_device() first + */ +extern void spi_deselect_device(SPI_t *spi, struct spi_device *device); + +/*! \brief Write one byte to a SPI device. + * + * \param spi Base address of the SPI instance. + * \param data The data byte to be loaded + * + */ +__always_inline static void spi_write_single(SPI_t *spi, uint8_t data) +{ + spi_put(spi,data); +} + +/** + * \brief Send a sequence of bytes to a SPI device + * + * Received bytes on the SPI bus are discarded. + * + * \param spi Base address of the SPI instance. + * \param data data buffer to write + * \param len Length of data + * + * \pre SPI device must be selected with spi_select_device() first + */ +extern status_code_t spi_write_packet(SPI_t *spi,const uint8_t *data, size_t len); + + +/*! \brief Receive one byte from a SPI device. + * + * \param spi Base address of the SPI instance. + * \param data Pointer to the data byte where to store the received data. + * + */ +inline static void spi_read_single(SPI_t *spi, uint8_t *data) +{ + *data=spi_get(spi); +} + +/** + * \brief Receive a sequence of bytes from a SPI device + * + * All bytes sent out on SPI bus are sent as value 0. + * + * \param spi Base address of the SPI instance. + * \param data data buffer to read + * \param len Length of data + * + * \pre SPI device must be selected with spi_select_device() first + */ +extern status_code_t spi_read_packet(SPI_t *spi, uint8_t *data, size_t len); + +/*! \brief Checks if all transmissions are complete. + * + * \param spi Base address of the SPI instance. + * + * \return Status. + * \retval 1 All transmissions complete. + * \retval 0 Transmissions not complete. + */ +inline static bool spi_is_tx_empty(SPI_t *spi) +{ + return spi_is_tx_ok(spi); +} + +/*! \brief Checks if all transmissions is ready. + * + * \param spi Base address of the SPI instance. + * + * \return Status. + * \retval 1 All transmissions complete. + * \retval 0 Transmissions not complete. + */ +inline static bool spi_is_tx_ready(SPI_t *spi) +{ + return spi_is_tx_ok(spi); +} + +/*! \brief Tests if the SPI contains a received character. + * + * \param spi Base address of the SPI instance. + * + * \return \c 1 if the SPI Receive Holding Register is full, otherwise \c 0. + */ +inline static bool spi_is_rx_full(SPI_t *spi) +{ + return spi_is_tx_ok(spi); +} + +/*! \brief Checks if all reception is ready. + * + * \param spi Base address of the SPI instance. + * + * \return \c 1 if the SPI Receiver is ready, otherwise \c 0. + */ +inline static bool spi_is_rx_ready(SPI_t *spi) +{ + return spi_is_tx_ok(spi); +} + +//! @} + + + +#ifdef __cplusplus +} +#endif + +/** + * \page spi_master_xmega Quick start guide for SPI master on XMEGA devices + * + * \section spi_master_xmega_basic Basic setup for XMEGA devices + * The SPI module will be set up as master: + * - SPI on PORTD + * - 1MHz SPI clock speed + * - Slave Chip Select connected on PORTD pin 1 + * - SPI mode 0 (data on rising clock edge) + * + * \section spi_master_xmega_basic_setup Setup steps + * \subsection spi_master_xmega_basic_setup_code Example code + * Add to application C-file (e.g. main.c): + * \code + void spi_init_pins(void) + { + ioport_configure_port_pin(&PORTD, PIN1_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); + + ioport_configure_port_pin(&PORTD, PIN4_bm, IOPORT_PULL_UP | IOPORT_DIR_INPUT); + ioport_configure_port_pin(&PORTD, PIN5_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); + ioport_configure_port_pin(&PORTD, PIN6_bm, IOPORT_DIR_INPUT); + ioport_configure_port_pin(&PORTD, PIN7_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); + } + + void spi_init_module(void) + { + struct spi_device spi_device_conf = { + .id = IOPORT_CREATE_PIN(PORTD, 1) + }; + + spi_master_init(&SPID); + spi_master_setup_device(&SPID, &spi_device_conf, SPI_MODE_0, 1000000, 0); + spi_enable(&SPID); + } +\endcode + * + * \subsection spi_master_xmega_basic_setup Workflow + * -# Ensure that \ref conf_spi_master.h is present for the driver. + * - \note This file is only for the driver and should not be included by the + * user. In this example the file can be left empty. + * -# Initialize the pins used by the SPI interface (this initialization is for + * the ATxmega32A4U device). + * -# Set the pin used for slave select as output high: + * \code + ioport_configure_port_pin(&PORTD, PIN1_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); +\endcode + * -# Enable pull-up on own chip select (SS): + * \code + ioport_configure_port_pin(&PORTD, PIN4_bm, IOPORT_PULL_UP | IOPORT_DIR_INPUT); +\endcode + * \attention If this pin is pulled low the SPI module will go into slave mode. + * -# Set MOSI and SCL as output high, and set MISO as input: + * \code + ioport_configure_port_pin(&PORTD, PIN5_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); + ioport_configure_port_pin(&PORTD, PIN6_bm, IOPORT_DIR_INPUT); + ioport_configure_port_pin(&PORTD, PIN7_bm, IOPORT_INIT_HIGH | IOPORT_DIR_OUTPUT); +\endcode + * -# Define the SPI device configuration struct to describe which pin the + * slave select (slave chip select) is connected to, in this case the slave + * select pin has been connected to PORTD pin 1 (PD1): + * - \code + struct spi_device spi_device_conf = { + .id = IOPORT_CREATE_PIN(PORTD, 1) + }; +\endcode + * -# Initialize the SPI module, in this case SPI on PORTD has been chosen: + * - \code + spi_master_init(&SPID); +\endcode + * -# Setup the SPI master module for a specific device: + * - \code + spi_master_setup_device(&SPID, &spi_device_conf, SPI_MODE_0, 1000000, 0); +\endcode + * - \note The last argument, which is zero in this case, can be ignored and is + * only included for compatibility purposes. + * -# Then enable the SPI: + * - \code + spi_enable(&SPID); +\endcode + * + * \section spi_master_xmega_basic_usage Usage steps + * \subsection spi_master_xmega_basic_usage_code Example code + * Add to, e.g., the main loop in the application C-file: + * \code + uint8_t data_buffer[1] = {0xAA}; + + struct spi_device spi_device_conf = { + .id = IOPORT_CREATE_PIN(PORTD, 1) + }; + + spi_select_device(&SPID, &spi_device_conf); + + spi_write_packet(&SPID, data_buffer, 1); + spi_read_packet(&SPID, data_buffer, 1); + + spi_deselect_device(&SPID, &spi_device_conf); +\endcode + * + * \subsection spi_master_xmega_basic_usage_flow Workflow + * -# Create a buffer for data to be sent/received on the SPI bus, in this case + * a single byte buffer is used. The buffer can be of arbitrary size as long as + * there is space left in SRAM: + * - \code + uint8_t data_buffer[1] = {0xAA}; +\endcode + * -# Define the SPI device configuration struct to describe which pin the + * slave select (slave chip select) is connected to, in this case the slave + * select pin has been connected to PORTD pin 1 (PD1): + * - \code + struct spi_device spi_device_conf = { + .id = IOPORT_CREATE_PIN(PORTD, 1) + }; +\endcode + * - \note As this struct is the same for both the initializing part and the usage + * part it could be a good idea to make the struct global, and hence accessible + * for both the initializing part and usage part. Another solution could be to + * create the struct in the main function and pass the address of the struct to + * the spi_init_module() function, e.g.: + * \code + void spi_init_module(struct spi_device *spi_device_conf) + { + ... + + spi_master_setup_device(&SPID, spi_device_conf, SPI_MODE_0, 1000000, 0); + + ... + } +\endcode + * -# Write data to the SPI slave device, in this case write one byte from the + * data_buffer: + * - \code + spi_write_packet(&SPID, data_buffer, 1); +\endcode + * -# Read data from the SPI slave device, in this case read one byte and put it + * into the data_buffer: + * - \code + spi_read_packet(&SPID, data_buffer, 1); +\endcode + * - \attention As the SPI works as a shift register so that data is shifted in at + * the same time as data is shifted out a read operation will mean that a dummy + * byte \ref CONFIG_SPI_MASTER_DUMMY is written to the SPI bus. \ref CONFIG_SPI_MASTER_DUMMY + * defaults to 0xFF, but can be changed by defining it inside the \ref conf_spi_master.h + * file. + * -# When read and write operations is done de-select the slave: + * - \code + spi_deselect_device(&SPID, &spi_device_conf); +\endcode + * + */ + +#endif // _SPI_MASTER_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_spi/spi_master.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_spi/spi_master.h.REMOVED.git-id deleted file mode 100644 index 70cb4af8..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_spi/spi_master.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -12fc708809ef040b50a0ae09dfa31096af58f73a \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_usart_spi/usart_spi.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_usart_spi/usart_spi.c new file mode 100644 index 00000000..7a406d70 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_usart_spi/usart_spi.c @@ -0,0 +1,140 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#include "usart_spi.h" +#include "sysclk.h" + +void usart_spi_init(USART_t *usart) +{ +#ifdef USARTC0 + if((uint16_t)usart == (uint16_t)&USARTC0) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART0_bm); + } +#endif +#ifdef USARTC1 + else + if((uint16_t)usart == (uint16_t)&USARTC1) { + sysclk_enable_module(SYSCLK_PORT_C,PR_USART1_bm); + } +#endif +#ifdef USARTD0 + else + if((uint16_t)usart == (uint16_t)&USARTD0) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART0_bm); + } +#endif +#ifdef USARTD1 + else + if((uint16_t)usart == (uint16_t)&USARTD1) { + sysclk_enable_module(SYSCLK_PORT_D,PR_USART1_bm); + } +#endif +#ifdef USARTE0 + else + if((uint16_t)usart == (uint16_t)&USARTE0) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART0_bm); + } +#endif +#ifdef USARTE1 + else + if((uint16_t)usart == (uint16_t)&USARTE1) { + sysclk_enable_module(SYSCLK_PORT_E,PR_USART1_bm); + } +#endif +#ifdef USARTF0 + else + if((uint16_t)usart == (uint16_t)&USARTF0) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART0_bm); + } +#endif +#ifdef USARTF1 + else + if((uint16_t)usart == (uint16_t)&USARTF1) { + sysclk_enable_module(SYSCLK_PORT_F,PR_USART1_bm); + } +#endif +} + +void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id) +{ + usart_spi_options_t opt; + opt.baudrate=baud_rate; + opt.spimode=flags; + opt.data_order=false; + usart_init_spi(usart, &opt); +} + +status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len) +{ + size_t i=0; + while(len) { + usart_spi_transmit(usart,*(data+i)); + len--; + i++; + } + return STATUS_OK; +} + +status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len) +{ + while(len) { + *data = usart_spi_transmit(usart, CONFIG_USART_SPI_DUMMY); + len--; + data++; + } + return STATUS_OK; +} + +void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_low(device->id); +} + +void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device) +{ + ioport_set_pin_high(device->id); +} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_usart_spi/usart_spi.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_usart_spi/usart_spi.c.REMOVED.git-id deleted file mode 100644 index c360af51..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_usart_spi/usart_spi.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7a406d7089281b83780e00251f2b9a9591744e12 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_usart_spi/usart_spi.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_usart_spi/usart_spi.h new file mode 100644 index 00000000..d5d5a95f --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_usart_spi/usart_spi.h @@ -0,0 +1,279 @@ +/** + * \file + * + * \brief AVR XMEGA USART in SPI mode driver functions. + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _USART_SPI_H_ +#define _USART_SPI_H_ + +#include "compiler.h" +#include "status_codes.h" +#include "ioport.h" +#include "usart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \name USART in SPI mode Management Configuration + */ +//! @{ +#include "conf_usart_spi.h" + +//! Default Config Spi Master Dummy Field +#ifndef CONFIG_USART_SPI_DUMMY + #define CONFIG_USART_SPI_DUMMY 0xFF +#endif +//! @} + +/** + * \brief Clock phase + */ +#define SPI_CPHA (1 << 0) + +/** + * \brief Clock polarity + */ +#define SPI_CPOL (1 << 1) + +/** + * \brief SPI mode 0 + */ +#define SPI_MODE_0 0 +/** + * \brief SPI mode 1 + */ +#define SPI_MODE_1 (SPI_CPHA) +/** + * \brief SPI mode 2 + */ +#define SPI_MODE_2 (SPI_CPOL) +/** + * \brief SPI mode 3 + */ +#define SPI_MODE_3 (SPI_CPOL | SPI_CPHA) + +typedef uint8_t spi_flags_t; +typedef uint32_t board_spi_select_id_t; + +//! \brief Polled SPI device definition +struct usart_spi_device { + //! Board specific select id + port_pin_t id; +}; + +/*! \brief Initializes the USART in SPI master mode. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_init(USART_t *usart); + +/** + * \brief Setup a USART in SPI mode device. + * + * The returned device descriptor structure must be passed to the driver + * whenever that device should be used as current slave device. + * + * \param usart Base address of the USART instance. + * \param device Pointer to usart device struct that should be initialized. + * \param flags USART configuration flags. Common flags for all + * implementations are the usart modes SPI_MODE_0 ... + * SPI_MODE_3. + * \param baud_rate Baud rate for communication with slave device in Hz. + * \param sel_id Board specific select id + */ +extern void usart_spi_setup_device(USART_t *usart, struct usart_spi_device *device, + spi_flags_t flags, unsigned long baud_rate, + board_spi_select_id_t sel_id); + +/*! \brief Enables the USART for the specified USART in SPI mode. + * + * \param usart Base address of the USART instance. + */ +extern void usart_spi_enable(USART_t *usart); + +/*! \brief Disables the USART. + * + * Ensures that nothing is transferred while setting up buffers. + * + * \param usart Base address of the USART instance. + * + */ +extern void usart_spi_disable(USART_t *usart); + + +/*! \brief Tests if the USART in SPI mode is enabled. + * + * \param usart Base address of the usart instance. + * + * \return \c 1 if the usart is enabled, otherwise \c 0. + */ +extern bool usart_spi_is_enabled(USART_t *usart); + +/** + * \brief Select given device on the SPI bus + * + * Set device specific setting and calls board chip select. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + */ +extern void usart_spi_select_device(USART_t *usart, struct usart_spi_device *device); + +/** + * \brief Deselect given device on the SPI bus + * + * Calls board chip deselect. + * + * \param usart Base address of the USART instance. + * \param device SPI device + * + * \pre SPI device must be selected with usart_spi_select_device() first + */ +extern void usart_spi_deselect_device(USART_t *usart, struct usart_spi_device *device); + +/*! \brief Write one byte to a SPI device using USART in SPI mode + * + * \param usart Base address of the usart instance. + * \param data The data byte to be loaded + * + */ +__always_inline static void usart_spi_write_single(USART_t *usart, uint8_t data) +{ + usart_spi_transmit(usart, data); +} + +/** + * \brief Send a sequence of bytes to a SPI device using USART in SPI mode + * + * Received bytes on the USART in SPI mode are discarded. + * + * \param usart Base address of the USART instance. + * \param data Data buffer to write + * \param len Length of data + * + * \pre usart device must be selected with usart_spi_select_device() first + */ +extern status_code_t usart_spi_write_packet(USART_t *usart,const uint8_t *data, size_t len); + + +/*! \brief Receive one byte from a SPI device using USART in SPI mode + * + * \param usart Base address of the USART instance. + * \param data Pointer to the data byte where to store the received data. + * + */ +inline static void usart_spi_read_single(USART_t *usart, uint8_t *data) +{ + *data = usart_spi_transmit(usart, CONFIG_USART_SPI_DUMMY); +} + +/** + * \brief Receive a sequence of bytes from a USART in SPI mode device + * + * All bytes sent out on usart bus are sent as value 0. + * + * \param usart Base address of the usart instance. + * \param data data buffer to read + * \param len Length of data + * + * \pre usart device must be selected with usart_spi_select_device() first + */ +extern status_code_t usart_spi_read_packet(USART_t *usart, uint8_t *data, size_t len); + +/*! \brief Check whether there are data in Transmit Holding Register or + * Transmit Shift Register in SPI master mode. + * + * \param usart Base address of the USART instance. + * + * \retval 1 The two registers are empty. + * \retval 0 One of the two registers contains data. + */ +inline static bool usart_spi_is_tx_empty(USART_t *usart) +{ + return usart_data_register_is_empty(usart); +} + +/*! \brief Check whether the USART in SPI master mode contains a received character. + * + * \param usart Base address of the USART instance. + * + * \retval 1 Some data have been received. + * \retval 0 No data has been received. + */ +inline static bool usart_spi_is_rx_ready(USART_t *usart) +{ + return usart_rx_is_complete(usart); +} + +/*! \brief Check if the USART Transmit Register is empty. + * + * \param usart Base address of the USART instance. + * + * \retval 1 There is no data in the Transmit Holding Register. + * \retval 0 There are data in the Transmit Holding Register. + */ +inline static bool usart_spi_is_tx_ready(USART_t *usart) +{ + return usart_data_register_is_empty(usart); +} + +/*! \brief Tests if the USART in SPI mode contains a received character. + * + * \param usart Base address of the USART instance. + * + * \return \c 1 if the USART Receive Holding Register is full, otherwise \c 0. + */ +inline static bool usart_spi_is_rx_full(USART_t *usart) +{ + return usart_rx_is_complete(usart); +} + +#ifdef __cplusplus +} +#endif + +#endif // _USART_SPI_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_usart_spi/usart_spi.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_usart_spi/usart_spi.h.REMOVED.git-id deleted file mode 100644 index cc1d7612..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/spi/xmega_usart_spi/usart_spi.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d5d5a95f1ee6943e3286f8d2e9d936ea9b7c1de4 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.c new file mode 100644 index 00000000..fd035fe1 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.c @@ -0,0 +1,84 @@ +/** + * \file + * + * \brief User Interface + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include +#include "ui.h" + +void ui_init(void) +{ + return; +} + +void ui_powerdown(void) +{ + return; +} + +void ui_wakeup(void) +{ + return; +} + +void ui_loop_back_state(bool b_started) +{ + return; +} + +void ui_process(uint16_t framenumber) +{ + return; +} + + +/** + * \defgroup UI User Interface + * + * Human interface on XMEGA-A3BU Xplained: + * - Led green (close to USB connector) is on at power on + * - Led 0 is on when USB line is in IDLE mode, and off in SUSPEND mode + * - Led 1 blinks when USB host has checked and enabled vendor interface + * - Red LED (Led 2) close to USB connector is on when loopback is running + */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.c.REMOVED.git-id deleted file mode 100644 index 82a90d08..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/example/atxmega256a3bu_xmega_a3bu_xplained/ui.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fd035fe1de454228afb754f138e9a19216463ee0 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor.c new file mode 100644 index 00000000..bd1dfdd8 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor.c @@ -0,0 +1,295 @@ +/** + * \file + * + * \brief USB Vendor class interface. + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_vendor.h" +#include "udd.h" +#include "udc.h" +#include "udi_vendor.h" +#include + +// Configuration check +#ifndef UDI_VENDOR_ENABLE_EXT +# error UDI_VENDOR_ENABLE_EXT must be defined in conf_usb.h file. +#endif +#ifndef UDI_VENDOR_DISABLE_EXT +# error UDI_VENDOR_DISABLE_EXT must be defined in conf_usb.h file. +#endif + +/** + * \ingroup udi_vendor_group + * \defgroup udi_vendor_group_udc Interface with USB Device Core (UDC) + * + * Structures and functions required by UDC. + * + * @{ + */ +bool udi_vendor_enable(void); +void udi_vendor_disable(void); +bool udi_vendor_setup(void); +uint8_t udi_vendor_getsetting(void); + +//! Global structure which contains standard UDI API for UDC +UDC_DESC_STORAGE udi_api_t udi_api_vendor = { + .enable = udi_vendor_enable, + .disable = udi_vendor_disable, + .setup = udi_vendor_setup, + .getsetting = udi_vendor_getsetting, + .sof_notify = NULL, +}; +//@} + + +/** + * \ingroup udi_vendor_group + * \defgroup udi_vendor_group_internal Implementation of UDI Vendor Class + * + * Class internal implementation + * @{ + */ + +//! USB descriptor alternate setting used +static uint8_t udi_vendor_alternate_setting = 0; + +/** + * \name Internal routines + */ +//@{ +bool udi_vendor_enable(void) +{ + udi_vendor_alternate_setting = udc_get_interface_desc()->bAlternateSetting; + if (0 == udi_vendor_alternate_setting) { + // Call application callback + // to notify that interface is enabled + if (!UDI_VENDOR_ENABLE_EXT()) { + return false; + } + } + return true; +} + + +void udi_vendor_disable(void) +{ + if (1 == udi_vendor_alternate_setting) { + UDI_VENDOR_DISABLE_EXT(); + } +} + + +bool udi_vendor_setup(void) +{ + if (Udd_setup_is_in()) { + if ((Udd_setup_type() == USB_REQ_TYPE_VENDOR) + && (udd_g_ctrlreq.req.bRequest == 0)) { + return UDI_VENDOR_SETUP_IN_RECEIVED(); + } + } + if (Udd_setup_is_out()) { + if ((Udd_setup_type() == USB_REQ_TYPE_VENDOR) + && (udd_g_ctrlreq.req.bRequest == 0) + && (0 != udd_g_ctrlreq.req.wLength)) { + return UDI_VENDOR_SETUP_OUT_RECEIVED(); + } + } + return false; // Not supported request +} + +uint8_t udi_vendor_getsetting(void) +{ + return udi_vendor_alternate_setting; +} +//@} + +#if UDI_VENDOR_EPS_SIZE_INT_FS +/** + * \brief Start a transfer on interrupt IN + * + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_vendor_interrupt_in_run(uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback) +{ + return udd_ep_run(UDI_VENDOR_EP_INTERRUPT_IN, + false, + buf, + buf_size, + callback); +} + + +/** + * \brief Start a transfer on interrupt OUT + * + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_vendor_interrupt_out_run(uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback) +{ + return udd_ep_run(UDI_VENDOR_EP_INTERRUPT_OUT, + false, + buf, + buf_size, + callback); +} +#endif + +#if UDI_VENDOR_EPS_SIZE_BULK_FS +/** + * \brief Start a transfer on bulk IN + * + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_vendor_bulk_in_run(uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback) +{ + return udd_ep_run(UDI_VENDOR_EP_BULK_IN, + false, + buf, + buf_size, + callback); +} + + +/** + * \brief Start a transfer on bulk OUT + * + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_vendor_bulk_out_run(uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback) +{ + return udd_ep_run(UDI_VENDOR_EP_BULK_OUT, + false, + buf, + buf_size, + callback); +} +#endif + + +#if UDI_VENDOR_EPS_SIZE_ISO_FS +/** + * \brief Start a transfer on interrupt IN + * + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_vendor_iso_in_run(uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback) +{ + return udd_ep_run(UDI_VENDOR_EP_ISO_IN, + false, + buf, + buf_size, + callback); +} + +/** + * \brief Start a transfer on interrupt OUT + * + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_vendor_iso_out_run(uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback) +{ + return udd_ep_run(UDI_VENDOR_EP_ISO_OUT, + false, + buf, + buf_size, + callback); +} +#endif + +//@} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor.c.REMOVED.git-id deleted file mode 100644 index 8a4f14f0..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bd1dfdd8a732702bca11fac24cc351736f189726 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor.h new file mode 100644 index 00000000..2aaaac5d --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor.h @@ -0,0 +1,687 @@ +/** + * \file + * + * \brief USB Vendor class interface definitions. + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UDI_VENDOR_H_ +#define _UDI_VENDOR_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_vendor.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" +#include "globals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Configuration Full Speed check +#ifndef UDI_VENDOR_EPS_SIZE_INT_FS +# error UDI_VENDOR_EPS_SIZE_INT_FS must be defined in conf_usb.h file. +#endif +#ifndef UDI_VENDOR_EPS_SIZE_BULK_FS +# error UDI_VENDOR_EPS_SIZE_BULK_FS must be defined in conf_usb.h file. +#endif +#ifndef UDI_VENDOR_EPS_SIZE_ISO_FS +# error UDI_VENDOR_EPS_SIZE_ISO_FS must be defined in conf_usb.h file. +#endif + +// Configuration High Speed check +#ifdef USB_DEVICE_HS_SUPPORT +# ifndef UDI_VENDOR_EPS_SIZE_INT_HS +# error UDI_VENDOR_EPS_SIZE_INT_HS must be defined in conf_usb.h file. +# endif +# ifndef UDI_VENDOR_EPS_SIZE_BULK_HS +# error UDI_VENDOR_EPS_SIZE_BULK_HS must be defined in conf_usb.h file. +# endif +# ifndef UDI_VENDOR_EPS_SIZE_ISO_HS +# error UDI_VENDOR_EPS_SIZE_ISO_HS must be defined in conf_usb.h file. +# endif +#endif + +/** + * \addtogroup udi_vendor_group_udc + * @{ + */ +//! Global structure which contains standard UDI interface for UDC +extern UDC_DESC_STORAGE udi_api_t udi_api_vendor; +//@} + +/** + * \ingroup udi_vendor_group + * \defgroup udi_vendor_group_desc USB interface descriptors + * + * The following structures provide predefined USB interface descriptors. + * It must be used to define the final USB descriptors. + */ +//@{ + +/** + * \name Endpoint descriptors + * @{ + */ +#if UDI_VENDOR_EPS_SIZE_INT_FS +# define UDI_VENDOR_EPS_INT_DESC \ + .ep_interrupt_in.bLength = sizeof(usb_ep_desc_t),\ + .ep_interrupt_in.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_interrupt_in.bEndpointAddress = UDI_VENDOR_EP_INTERRUPT_IN,\ + .ep_interrupt_in.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep_interrupt_in.bInterval = 1,\ + .ep_interrupt_out.bLength = sizeof(usb_ep_desc_t),\ + .ep_interrupt_out.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_interrupt_out.bEndpointAddress = UDI_VENDOR_EP_INTERRUPT_OUT,\ + .ep_interrupt_out.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep_interrupt_out.bInterval = 1, + +# define UDI_VENDOR_EPS_INT_DESC_FS \ + .ep_interrupt_in.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_INT_FS),\ + .ep_interrupt_out.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_INT_FS), + +# define UDI_VENDOR_EPS_INT_DESC_HS \ + .ep_interrupt_in.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_INT_HS),\ + .ep_interrupt_out.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_INT_HS), + +#else +# define UDI_VENDOR_EPS_INT_DESC +# define UDI_VENDOR_EPS_INT_DESC_FS +# define UDI_VENDOR_EPS_INT_DESC_HS +#endif + +#if UDI_VENDOR_EPS_SIZE_BULK_FS +# define UDI_VENDOR_EPS_BULK_DESC \ + .ep_bulk_in.bLength = sizeof(usb_ep_desc_t),\ + .ep_bulk_in.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_bulk_in.bEndpointAddress = UDI_VENDOR_EP_BULK_IN,\ + .ep_bulk_in.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_bulk_in.bInterval = 0,\ + .ep_bulk_out.bLength = sizeof(usb_ep_desc_t),\ + .ep_bulk_out.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_bulk_out.bEndpointAddress = UDI_VENDOR_EP_BULK_OUT,\ + .ep_bulk_out.bmAttributes = USB_EP_TYPE_BULK,\ + .ep_bulk_out.bInterval = 0, + +# define UDI_VENDOR_EPS_BULK_DESC_FS \ + .ep_bulk_in.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_BULK_FS),\ + .ep_bulk_out.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_BULK_FS), + +# define UDI_VENDOR_EPS_BULK_DESC_HS \ + .ep_bulk_in.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_BULK_HS),\ + .ep_bulk_out.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_BULK_HS), + +#else +# define UDI_VENDOR_EPS_BULK_DESC +# define UDI_VENDOR_EPS_BULK_DESC_FS +# define UDI_VENDOR_EPS_BULK_DESC_HS +#endif + +#ifndef SINGLE_ENDPOINT_INTERFACE + + #if UDI_VENDOR_EPS_SIZE_ISO_FS + # define UDI_VENDOR_EPS_ISO_DESC \ + .ep_iso_in.bLength = sizeof(usb_ep_desc_t),\ + .ep_iso_in.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_iso_in.bEndpointAddress = UDI_VENDOR_EP_ISO_IN,\ + .ep_iso_in.bmAttributes = USB_EP_TYPE_ISOCHRONOUS,\ + .ep_iso_in.bInterval = 1,\ + .ep_iso_in2.bLength = sizeof(usb_ep_desc_t),\ + .ep_iso_in2.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_iso_in2.bEndpointAddress = UDI_VENDOR_EP_ISO_IN + 1,\ + .ep_iso_in2.bmAttributes = USB_EP_TYPE_ISOCHRONOUS,\ + .ep_iso_in2.bInterval = 1,\ + .ep_iso_in3.bLength = sizeof(usb_ep_desc_t),\ + .ep_iso_in3.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_iso_in3.bEndpointAddress = UDI_VENDOR_EP_ISO_IN + 2,\ + .ep_iso_in3.bmAttributes = USB_EP_TYPE_ISOCHRONOUS,\ + .ep_iso_in3.bInterval = 1,\ + .ep_iso_in4.bLength = sizeof(usb_ep_desc_t),\ + .ep_iso_in4.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_iso_in4.bEndpointAddress = UDI_VENDOR_EP_ISO_IN + 3,\ + .ep_iso_in4.bmAttributes = USB_EP_TYPE_ISOCHRONOUS,\ + .ep_iso_in4.bInterval = 1,\ + .ep_iso_in5.bLength = sizeof(usb_ep_desc_t),\ + .ep_iso_in5.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_iso_in5.bEndpointAddress = UDI_VENDOR_EP_ISO_IN + 4,\ + .ep_iso_in5.bmAttributes = USB_EP_TYPE_ISOCHRONOUS,\ + .ep_iso_in5.bInterval = 1,\ + .ep_iso_in6.bLength = sizeof(usb_ep_desc_t),\ + .ep_iso_in6.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_iso_in6.bEndpointAddress = UDI_VENDOR_EP_ISO_IN + 5,\ + .ep_iso_in6.bmAttributes = USB_EP_TYPE_ISOCHRONOUS,\ + .ep_iso_in6.bInterval = 1, + + //.ep_iso_out.bLength = sizeof(usb_ep_desc_t),\ + //.ep_iso_out.bDescriptorType = USB_DT_ENDPOINT,\ + //.ep_iso_out.bEndpointAddress = UDI_VENDOR_EP_ISO_OUT,\ + //.ep_iso_out.bmAttributes = USB_EP_TYPE_ISOCHRONOUS,\ + //.ep_iso_out.bInterval = 1, + + # define UDI_VENDOR_EPS_ISO_DESC_FS \ + .ep_iso_in.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_FS),\ + .ep_iso_in2.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_FS),\ + .ep_iso_in3.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_FS),\ + .ep_iso_in4.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_FS),\ + .ep_iso_in5.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_FS),\ + .ep_iso_in6.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_FS), + + //.ep_iso_out.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_FS), + + # define UDI_VENDOR_EPS_ISO_DESC_HS \ + .ep_iso_in.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_HS),\ + .ep_iso_in2.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_HS),\ + .ep_iso_in3.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_HS),\ + .ep_iso_in4.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_HS),\ + .ep_iso_in5.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_HS),\ + .ep_iso_in6.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_HS), + //.ep_iso_out.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_HS), + + #else + # define UDI_VENDOR_EPS_ISO_DESC + # define UDI_VENDOR_EPS_ISO_DESC_FS + # define UDI_VENDOR_EPS_ISO_DESC_HS + #endif + #else + # define UDI_VENDOR_EPS_ISO_DESC \ + .ep_iso_in.bLength = sizeof(usb_ep_desc_t),\ + .ep_iso_in.bDescriptorType = USB_DT_ENDPOINT,\ + .ep_iso_in.bEndpointAddress = UDI_VENDOR_EP_ISO_IN,\ + .ep_iso_in.bmAttributes = USB_EP_TYPE_ISOCHRONOUS,\ + .ep_iso_in.bInterval = 1, + + # define UDI_VENDOR_EPS_ISO_DESC_FS \ + .ep_iso_in.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_FS),\ + + # define UDI_VENDOR_EPS_ISO_DESC_HS \ + .ep_iso_in.wMaxPacketSize = LE16(UDI_VENDOR_EPS_SIZE_ISO_HS),\ + + #endif + +//@} + +//! Interface descriptor structure for vendor Class interface +typedef struct { + //usb_iface_desc_t iface0; + usb_iface_desc_t iface1; +#if UDI_VENDOR_EPS_SIZE_INT_FS + usb_ep_desc_t ep_interrupt_in; + usb_ep_desc_t ep_interrupt_out; +#endif +#if UDI_VENDOR_EPS_SIZE_BULK_FS + usb_ep_desc_t ep_bulk_in; + usb_ep_desc_t ep_bulk_out; +#endif +#if UDI_VENDOR_EPS_SIZE_ISO_FS + usb_ep_desc_t ep_iso_in; + #ifndef SINGLE_ENDPOINT_INTERFACE + usb_ep_desc_t ep_iso_in2; + usb_ep_desc_t ep_iso_in3; + usb_ep_desc_t ep_iso_in4; + usb_ep_desc_t ep_iso_in5; + usb_ep_desc_t ep_iso_in6; + #endif + //usb_ep_desc_t ep_iso_out; +#endif +} udi_vendor_desc_t; + +//! By default no string associated to this interface +#ifndef UDI_VENDOR_STRING_ID +#define UDI_VENDOR_STRING_ID 0 +#endif + +//! Maximum 6 endpoints used by vendor interface +#define UDI_VENDOR_EP_NB_INT ((UDI_VENDOR_EPS_SIZE_INT_FS)?2:0) +#define UDI_VENDOR_EP_NB_BULK ((UDI_VENDOR_EPS_SIZE_BULK_FS)?2:0) +#ifdef SINGLE_ENDPOINT_INTERFACE + #define UDI_VENDOR_EP_NB_ISO ((UDI_VENDOR_EPS_SIZE_ISO_FS)?1:0) //Used to be 2:0, back when there were only two EPs!! +#else + #define UDI_VENDOR_EP_NB_ISO ((UDI_VENDOR_EPS_SIZE_ISO_FS)?6:0) //Used to be 2:0, back when there were only two EPs!! +#endif +#define UDI_VENDOR_EP_NB (UDI_VENDOR_EP_NB_INT+UDI_VENDOR_EP_NB_BULK+UDI_VENDOR_EP_NB_ISO) + + +//! Content of vendor interface descriptor for all speeds +#define UDI_VENDOR_DESC \ + /*.iface0.bLength = sizeof(usb_iface_desc_t),\ + .iface0.bDescriptorType = USB_DT_INTERFACE,\ + .iface0.bInterfaceNumber = UDI_VENDOR_IFACE_NUMBER,\ + .iface0.bAlternateSetting = 0,\ + .iface0.bNumEndpoints = 0,\ + .iface0.bInterfaceClass = VENDOR_CLASS,\ + .iface0.bInterfaceSubClass = VENDOR_SUBCLASS,\ + .iface0.bInterfaceProtocol = VENDOR_PROTOCOL,\ + .iface0.iInterface = UDI_VENDOR_STRING_ID,\ + */.iface1.bLength = sizeof(usb_iface_desc_t),\ + .iface1.bDescriptorType = USB_DT_INTERFACE,\ + .iface1.bInterfaceNumber = UDI_VENDOR_IFACE_NUMBER,\ + .iface1.bAlternateSetting = 0,\ + .iface1.bNumEndpoints = UDI_VENDOR_EP_NB,\ + .iface1.bInterfaceClass = VENDOR_CLASS,\ + .iface1.bInterfaceSubClass = VENDOR_SUBCLASS,\ + .iface1.bInterfaceProtocol = VENDOR_PROTOCOL,\ + .iface1.iInterface = UDI_VENDOR_STRING_ID,\ + UDI_VENDOR_EPS_INT_DESC \ + UDI_VENDOR_EPS_BULK_DESC \ + UDI_VENDOR_EPS_ISO_DESC \ + +//! Content of vendor interface descriptor for full speed only +#define UDI_VENDOR_DESC_FS {\ + UDI_VENDOR_DESC \ + UDI_VENDOR_EPS_INT_DESC_FS \ + UDI_VENDOR_EPS_BULK_DESC_FS \ + UDI_VENDOR_EPS_ISO_DESC_FS \ + } + +//! Content of vendor interface descriptor for high speed only +#define UDI_VENDOR_DESC_HS {\ + UDI_VENDOR_DESC \ + UDI_VENDOR_EPS_INT_DESC_HS \ + UDI_VENDOR_EPS_BULK_DESC_HS \ + UDI_VENDOR_EPS_ISO_DESC_HS \ + } +//@} + + +/** + * \ingroup udi_group + * \defgroup udi_vendor_group USB Device Interface (UDI) for Vendor Class + * + * Common APIs used by high level application to use this USB class. + * + * These routines are used to transfer data to/from USB VENDOR endpoints. + * + * See \ref udi_vendor_quickstart. + * @{ + */ + +#if UDI_VENDOR_EPS_SIZE_INT_FS || defined(__DOXYGEN__) +/** + * \brief Start a transfer on interrupt IN + * + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_vendor_interrupt_in_run(uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); + +/** + * \brief Start a transfer on interrupt OUT + * + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_vendor_interrupt_out_run(uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); +#endif + +#if UDI_VENDOR_EPS_SIZE_BULK_FS || defined(__DOXYGEN__) +/** + * \brief Start a transfer on bulk IN + * + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_vendor_bulk_in_run(uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); + +/** + * \brief Start a transfer on bulk OUT + * + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_vendor_bulk_out_run(uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); +#endif + + +#if UDI_VENDOR_EPS_SIZE_ISO_FS || defined(__DOXYGEN__) +/** + * \brief Start a transfer on isochronous IN + * + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_vendor_iso_in_run(uint8_t * buf, iram_size_t buf_size, udd_callback_trans_t callback); + +/** + * \brief Start a transfer on isochronous OUT + * + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_vendor_iso_out_run(uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); +#endif + +//@} + +/** + * \page udi_vendor_quickstart Quick start guide for USB Device Vendor module (UDI Vendor) + * + * This is the quick start guide for the \ref udi_vendor_group + * "USB device interface Vendor module (UDI Vendor)" with step-by-step instructions on + * how to configure and use the modules in a selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * Also, you can refer to application note + * + * AVR4901: ASF - USB Device Vendor Class Application. + * + * \section udi_vendor_basic_use_case Basic use case + * In this basic use case, the "USB Vendor (Single Interface Device)" module is used. + * The "USB Vendor (Composite Device)" module usage is described in \ref udi_vendor_use_cases + * "Advanced use cases". + * + * \section udi_vendor_basic_use_case_setup Setup steps + * \subsection udi_vendor_basic_use_case_setup_prereq Prerequisites + * \copydetails udc_basic_use_case_setup_prereq + * \subsection udi_vendor_basic_use_case_setup_code Example code + * \copydetails udc_basic_use_case_setup_code + * \subsection udi_vendor_basic_use_case_setup_flow Workflow + * \copydetails udc_basic_use_case_setup_flow + * + * \section udi_vendor_basic_use_case_usage Usage steps + * + * \subsection udi_vendor_basic_use_case_usage_code Example code + * Content of conf_usb.h: + * \code + * #define UDI_VENDOR_ENABLE_EXT() my_callback_vendor_enable() + * extern bool my_callback_vendor_enable(void); + * #define UDI_VENDOR_DISABLE_EXT() my_callback_vendor_disable() + * extern void my_callback_vendor_disable(void); + * + * #define UDI_VENDOR_SETUP_OUT_RECEIVED() my_vendor_setup_out_received() + * extern bool my_vendor_setup_out_received(void); + * #define UDI_VENDOR_SETUP_IN_RECEIVED() my_vendor_setup_in_received() + * extern bool my_vendor_setup_in_received(void); + * + * #define UDI_VENDOR_EPS_SIZE_INT_FS 64 + * #define UDI_VENDOR_EPS_SIZE_BULK_FS 64 + * #define UDI_VENDOR_EPS_SIZE_ISO_FS 256 + * #define UDI_VENDOR_EPS_SIZE_INT_HS 64 + * #define UDI_VENDOR_EPS_SIZE_BULK_HS 512 + * #define UDI_VENDOR_EPS_SIZE_ISO_HS 64 + + * #include "udi_vendor_conf.h" // At the end of conf_usb.h file +\endcode + * + * Add to application C-file: + * \code + static bool my_flag_autorize_vendor_transfert = false; + bool my_callback_vendor_enable(void) + { + my_flag_autorize_vendor_transfert = true; + return true; + } + void my_callback_vendor_disable(void) + { + my_flag_autorize_vendor_transfert = false; + } + + uint8_t global_buffer[X]; + void task(void) + { + if (my_flag_autorize_vendor_transfert) { + // Enable a transfer on OUT interrupt endpoint + udi_vendor_interrupt_out_run( + global_buffer, + sizeof(global_buffer), + NULL); + // Enable a transfer on IN interrupt endpoint + udi_vendor_interrupt_in_run( + global_buffer, + sizeof(global_buffer), + NULL); + ... + } + } +\endcode + * + * \subsection udi_vendor_basic_use_case_setup_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the USB device Vendor configuration: + * - \code #define UDI_VENDOR_ENABLE_EXT() my_callback_vendor_enable() + extern bool my_callback_vendor_enable(void); \endcode + * \note After the device enumeration (detecting and identifying USB devices), + * the USB host starts the device configuration. When the USB Vendor interface + * from the device is accepted by the host, the USB host enables this interface and the + * UDI_VENDOR_ENABLE_EXT() callback function is called and return true. + * Thus, when this event is received, the Vendor transfers can start. + * - \code #define UDI_VENDOR_DISABLE_EXT() my_callback_vendor_disable() + extern void my_callback_vendor_disable(void); \endcode + * \note When the USB device is unplugged or is reset by the USB host, the USB + * interface is disabled and the UDI_VENDOR_DISABLE_EXT() callback function + * is called. Thus, it is recommended to disable the data Vendor transfer. + * - \code #define UDI_VENDOR_SETUP_OUT_RECEIVED() my_vendor_setup_out_received() + extern bool my_vendor_setup_out_received(void); + #define UDI_VENDOR_SETUP_IN_RECEIVED() my_vendor_setup_in_received() + extern bool my_vendor_setup_in_received(void); \endcode + * \note The control requests for the interface Vendor will be processed + * through these both callbacks. + * - \code #define UDI_VENDOR_EPS_SIZE_INT_FS 64 + #define UDI_VENDOR_EPS_SIZE_BULK_FS 64 + #define UDI_VENDOR_EPS_SIZE_ISO_FS 256 + #define UDI_VENDOR_EPS_SIZE_INT_HS 64 + #define UDI_VENDOR_EPS_SIZE_BULK_HS 512 + #define UDI_VENDOR_EPS_SIZE_ISO_HS 64 \endcode + * \note The endpoint size is defined by the final application, and can be + * disabled if the full speed size is zero. + * -# The Vendor transfers on interrupt, bulk and isochronous endpoints are + * done through these functions: + * - \code // Start a transfer on interrupt IN + udi_vendor_interrupt_in_run(); + // Start a transfer on interrupt OUT + udi_vendor_interrupt_out_run(); + // Start a transfer on bulk IN + udi_vendor_bulk_in_run(); + // Start a transfer on bulk OUT + udi_vendor_bulk_out_run(); + // Start a transfer on isochronous IN + udi_vendor_iso_in_run(); + // Start a transfer on isochronous OUT + udi_vendor_iso_out_run(); \endcode + * + * \section udi_vendor_use_cases Advanced use cases + * For more advanced use of the UDI Vendor module, see the following use cases: + * - \subpage udi_vendor_use_case_composite + * - \subpage udc_use_case_1 + * - \subpage udc_use_case_2 + * - \subpage udc_use_case_3 + * - \subpage udc_use_case_5 + * - \subpage udc_use_case_6 + */ + +/** + * \page udi_vendor_use_case_composite Vendor in a composite device + * + * A USB Composite Device is a USB Device which uses more than one USB class. + * In this use case, the "USB Vendor (Composite Device)" module is used to + * create a USB composite device. Thus, this USB module can be associated with + * another "Composite Device" module, like "USB HID Mouse (Composite Device)". + * + * Also, you can refer to application note + * + * AVR4902 ASF - USB Composite Device. + * + * \section udi_vendor_use_case_composite_setup Setup steps + * For the setup code of this use case to work, the + * \ref udi_vendor_basic_use_case "basic use case" must be followed. + * + * \section udi_vendor_use_case_composite_usage Usage steps + * + * \subsection udi_vendor_use_case_composite_usage_code Example code + * Content of conf_usb.h: + * \code + #define USB_DEVICE_EP_CTRL_SIZE 64 + #define USB_DEVICE_NB_INTERFACE (X+1) + #define USB_DEVICE_MAX_EP (X) to (X+6) + + #define UDI_VENDOR_EP_INTERRUPT_IN (1 | USB_EP_DIR_IN) + #define UDI_VENDOR_EP_INTERRUPT_OUT (2 | USB_EP_DIR_OUT) + #define UDI_VENDOR_EP_BULK_IN (3 | USB_EP_DIR_IN) + #define UDI_VENDOR_EP_BULK_OUT (4 | USB_EP_DIR_OUT) + #define UDI_VENDOR_EP_ISO_IN (5 | USB_EP_DIR_IN) + #define UDI_VENDOR_EP_ISO_OUT (6 | USB_EP_DIR_OUT) + + #define UDI_VENDOR_IFACE_NUMBER X + + #define UDI_COMPOSITE_DESC_T \ + udi_vendor_desc_t udi_vendor; \ + ... + #define UDI_COMPOSITE_DESC_FS \ + .udi_vendor = UDI_VENDOR_DESC, \ + ... + #define UDI_COMPOSITE_DESC_HS \ + .udi_vendor = UDI_VENDOR_DESC, \ + ... + #define UDI_COMPOSITE_API \ + &udi_api_vendor, \ + ... +\endcode + * + * \subsection udi_vendor_use_case_composite_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB composite device configuration: + * - \code // Endpoint control size, This must be: + // - 8, 16, 32 or 64 for full speed device (8 is recommended to save RAM) + // - 64 for a high speed device + #define USB_DEVICE_EP_CTRL_SIZE 64 + // Total Number of interfaces on this USB device. + // Add 1 for Vendor. + #define USB_DEVICE_NB_INTERFACE (X+1) + // Total number of endpoints on this USB device. + // This must include each endpoint for each interface. + // Add 0 to 6 for Vendor interface. + // The number depends on UDI_VENDOR_EPS_SIZE_..._FS defines. + #define USB_DEVICE_MAX_EP (X) to (X+6) \endcode + * -# Ensure that conf_usb.h contains the description of + * composite device: + * - \code // The endpoint numbers chosen by you for the Vendor. + // The endpoint numbers starting from 1. + #define UDI_VENDOR_EP_INTERRUPT_IN (1 | USB_EP_DIR_IN) + #define UDI_VENDOR_EP_INTERRUPT_OUT (2 | USB_EP_DIR_OUT) + #define UDI_VENDOR_EP_BULK_IN (3 | USB_EP_DIR_IN) + #define UDI_VENDOR_EP_BULK_OUT (4 | USB_EP_DIR_OUT) + #define UDI_VENDOR_EP_ISO_IN (5 | USB_EP_DIR_IN) + #define UDI_VENDOR_EP_ISO_OUT (6 | USB_EP_DIR_OUT) + // The interface index of an interface starting from 0 + #define UDI_VENDOR_IFACE_NUMBER X \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB composite device configuration: + * - \code // USB Interfaces descriptor structure + #define UDI_COMPOSITE_DESC_T \ + ... + udi_vendor_desc_t udi_vendor; \ + ... + // USB Interfaces descriptor value for Full Speed + #define UDI_COMPOSITE_DESC_FS \ + ... + .udi_vendor = UDI_VENDOR_DESC_FS, \ + ... + // USB Interfaces descriptor value for High Speed + #define UDI_COMPOSITE_DESC_HS \ + ... + .udi_vendor = UDI_VENDOR_DESC_HS, \ + ... + // USB Interface APIs + #define UDI_COMPOSITE_API \ + ... + &udi_api_vendor, \ + ... \endcode + * - \note The descriptors order given in the four lists above must be the + * same as the order defined by all interface indexes. The interface index + * orders are defined through UDI_X_IFACE_NUMBER defines. + */ + +#ifdef __cplusplus +} +#endif +#endif // _UDI_VENDOR_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor.h.REMOVED.git-id deleted file mode 100644 index a576d603..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2aaaac5d32de216c19d704aa822dbce60dbccc13 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor_conf.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor_conf.h new file mode 100644 index 00000000..e2fef15a --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor_conf.h @@ -0,0 +1,123 @@ +/** + * \file + * + * \brief Default Vendor class configuration for a USB Device + * with a single interface + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UDI_VENDOR_CONF_H_ +#define _UDI_VENDOR_CONF_H_ + +#include "conf_usb.h" + +/** + * \addtogroup udi_vendor_group_single_desc + * @{ + */ + +//! Control endpoint size +#define USB_DEVICE_EP_CTRL_SIZE 64 + +//! Endpoint numbers used by vendor interface. +//! Note: The order of endpoint can depend on USB hardware capability +//! when a specific mapping is used on USB DPRAM. +#if SAM3S || SAM4S || SAM4E +# define UDI_VENDOR_EP_INTERRUPT_IN (3 | USB_EP_DIR_IN) +# define UDI_VENDOR_EP_INTERRUPT_OUT (6 | USB_EP_DIR_OUT) +# define UDI_VENDOR_EP_BULK_IN (1 | USB_EP_DIR_IN) +# define UDI_VENDOR_EP_BULK_OUT (2 | USB_EP_DIR_OUT) +# define UDI_VENDOR_EP_ISO_IN (4 | USB_EP_DIR_IN) +# define UDI_VENDOR_EP_ISO_OUT (5 | USB_EP_DIR_OUT) +#elif SAM3U +# define UDI_VENDOR_EP_INTERRUPT_IN (3 | USB_EP_DIR_IN) +# define UDI_VENDOR_EP_INTERRUPT_OUT (4 | USB_EP_DIR_OUT) +# define UDI_VENDOR_EP_BULK_IN (1 | USB_EP_DIR_IN) +# define UDI_VENDOR_EP_BULK_OUT (2 | USB_EP_DIR_OUT) +# define UDI_VENDOR_EP_ISO_IN (5 | USB_EP_DIR_IN) +# define UDI_VENDOR_EP_ISO_OUT (6 | USB_EP_DIR_OUT) +#elif SAM3XA +# define UDI_VENDOR_EP_INTERRUPT_IN (3 | USB_EP_DIR_IN) +# define UDI_VENDOR_EP_INTERRUPT_OUT (4 | USB_EP_DIR_OUT) +# define UDI_VENDOR_EP_BULK_IN (5 | USB_EP_DIR_IN) +# define UDI_VENDOR_EP_BULK_OUT (6 | USB_EP_DIR_OUT) +# define UDI_VENDOR_EP_ISO_IN (1 | USB_EP_DIR_IN) +# define UDI_VENDOR_EP_ISO_OUT (2 | USB_EP_DIR_OUT) +#elif SAMG55 +#define UDI_VENDOR_EP_INTERRUPT_IN (1 | USB_EP_DIR_IN) +#define UDI_VENDOR_EP_INTERRUPT_OUT (2 | USB_EP_DIR_OUT) +#define UDI_VENDOR_EP_BULK_IN (3 | USB_EP_DIR_IN) +#define UDI_VENDOR_EP_BULK_OUT (4 | USB_EP_DIR_OUT) +#else +#define UDI_VENDOR_EP_INTERRUPT_IN (1 | USB_EP_DIR_IN) +#define UDI_VENDOR_EP_INTERRUPT_OUT (2 | USB_EP_DIR_OUT) +#define UDI_VENDOR_EP_BULK_IN ((((UDI_VENDOR_EPS_SIZE_INT_FS)?2:0)+1)\ + | USB_EP_DIR_IN) +#define UDI_VENDOR_EP_BULK_OUT ((((UDI_VENDOR_EPS_SIZE_INT_FS)?2:0)+2)\ + | USB_EP_DIR_OUT) +#define UDI_VENDOR_EP_ISO_IN ((((UDI_VENDOR_EPS_SIZE_INT_FS)?2:0)+ \ + ((UDI_VENDOR_EPS_SIZE_BULK_FS)?2:0)+1)\ + | USB_EP_DIR_IN) +#define UDI_VENDOR_EP_ISO_OUT ((((UDI_VENDOR_EPS_SIZE_INT_FS)?2:0)+ \ + ((UDI_VENDOR_EPS_SIZE_BULK_FS)?2:0)+2)\ + | USB_EP_DIR_OUT) +#endif + +//! Interface number is 0 because it is the unique interface +#define UDI_VENDOR_IFACE_NUMBER 0 + +/** + * \name UDD Configuration + */ +//@{ +//! Maximum 6 endpoints used by vendor interface +#define UDI_VENDOR_EP_NB_INT ((UDI_VENDOR_EPS_SIZE_INT_FS)?2:0) +#define UDI_VENDOR_EP_NB_BULK ((UDI_VENDOR_EPS_SIZE_BULK_FS)?2:0) +#define UDI_VENDOR_EP_NB_ISO ((UDI_VENDOR_EPS_SIZE_ISO_FS)?2:0) +#define USB_DEVICE_MAX_EP (UDI_VENDOR_EP_NB_INT+UDI_VENDOR_EP_NB_BULK+UDI_VENDOR_EP_NB_ISO) +//@} + +//@} + +#include "udi_vendor.h" + +#endif // _UDI_VENDOR_CONF_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor_conf.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor_conf.h.REMOVED.git-id deleted file mode 100644 index e9dadc8c..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor_conf.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e2fef15a41dd54b700f22ad9afb78714fed317e9 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.c new file mode 100644 index 00000000..ae0cc47d --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.c @@ -0,0 +1,190 @@ +/** + * \file + * + * \brief Default descriptors for a USB Device with a single vendor class + * interface + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "conf_usb.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi_vendor.h" + + +/** + * \defgroup udi_vendor_group_single_desc USB device descriptors for a single interface + * + * The following structures provide the USB device descriptors required for + * USB Device with a single interface Vendor Class. + * + * It is ready to use and do not require more definition. + * @{ + */ + +//! Only one interface for this device +#define USB_DEVICE_NB_INTERFACE 1 + +//! USB Device Descriptor +UDC_DATA(4) +UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { + .bLength = sizeof(usb_dev_desc_t), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = LE16(USB_V2_0), + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .idVendor = LE16(USB_DEVICE_VENDOR_ID), + .idProduct = LE16(USB_DEVICE_PRODUCT_ID), + .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) + | USB_DEVICE_MINOR_VERSION), +#ifdef USB_DEVICE_MANUFACTURE_NAME + .iManufacturer = 1, +#else + .iManufacturer = 0, // No manufacture string +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + .iProduct = 2, +#else + .iProduct = 0, // No product string +#endif +#ifdef USB_DEVICE_SERIAL_NAME + .iSerialNumber = 3, +#else + .iSerialNumber = 0, // No serial string +#endif + .bNumConfigurations = 1 +}; + + +#ifdef USB_DEVICE_HS_SUPPORT +//! USB Device Qualifier Descriptor for HS +UDC_DATA(4) +UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { + .bLength = sizeof(usb_dev_qual_desc_t), + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = LE16(USB_V2_0), + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .bNumConfigurations = 1 +}; +#endif + +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1) +typedef struct { + usb_conf_desc_t conf; + udi_vendor_desc_t udi_vendor; +} udc_desc_t; +COMPILER_PACK_RESET() + +//! USB Device Configuration Descriptor filled for FS +UDC_DATA(4) +UDC_DESC_STORAGE udc_desc_t udc_desc_fs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), + .udi_vendor = UDI_VENDOR_DESC_FS, +}; + +#ifdef USB_DEVICE_HS_SUPPORT +//! USB Device Configuration Descriptor filled for HS +UDC_DATA(4) +UDC_DESC_STORAGE udc_desc_t udc_desc_hs = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), + .udi_vendor = UDI_VENDOR_DESC_HS, +}; +#endif + + +/** + * \name UDC structures which contains all USB Device definitions + */ +//@{ + +//! Associate an UDI for each USB interface +UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { + &udi_api_vendor, +}; + +//! Add UDI with USB Descriptors FS +UDC_DESC_STORAGE udc_config_speed_t udc_config_lsfs[1] = {{ + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_fs, + .udi_apis = udi_apis, +}}; + +#ifdef USB_DEVICE_HS_SUPPORT +//! Add UDI with USB Descriptors HS +UDC_DESC_STORAGE udc_config_speed_t udc_config_hs[1] = {{ + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc_hs, + .udi_apis = udi_apis, +}}; +#endif + +//! Add all information about USB Device in global structure for UDC +UDC_DESC_STORAGE udc_config_t udc_config = { + .confdev_lsfs = &udc_device_desc, + .conf_lsfs = udc_config_lsfs, +#ifdef USB_DEVICE_HS_SUPPORT + .confdev_hs = &udc_device_desc, + .qualifier = &udc_device_qual, + .conf_hs = udc_config_hs, +#endif +}; + +//@} +//@} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.c.REMOVED.git-id deleted file mode 100644 index fdee5321..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/device/udi_vendor_desc.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ae0cc47dbb2e39a2716fb79cc891c859cd27e54d \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/usb_protocol_vendor.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/usb_protocol_vendor.h new file mode 100644 index 00000000..5a2df8bc --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/usb_protocol_vendor.h @@ -0,0 +1,69 @@ +/** + * \file + * + * \brief USB Vendor class protocol definitions. + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _USB_PROTOCOL_VENDOR_H_ +#define _USB_PROTOCOL_VENDOR_H_ + +/** + * \ingroup usb_protocol_group + * \defgroup usb_vendor_protocol USB Vendor Class definitions + * + * @{ + */ + +/** + * \name Vendor class values + */ +//@{ +#define VENDOR_CLASS 0xFF +#define VENDOR_SUBCLASS 0xFF +#define VENDOR_PROTOCOL 0xFF +//@} + + +//@} + +#endif // _USB_PROTOCOL_VENDOR_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/usb_protocol_vendor.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/usb_protocol_vendor.h.REMOVED.git-id deleted file mode 100644 index 5b8f6522..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/class/vendor/usb_protocol_vendor.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5a2df8bc08fc3f43624a6509b55e966415c901ec \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc.c b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc.c new file mode 100644 index 00000000..ea6e7ad4 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc.c @@ -0,0 +1,1276 @@ +/** + * \file + * + * \brief USB Device Controller (UDC) + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#include + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" +#include "udc.h" + +#include "globals.h" +#include "tiny_dma.h" +#include "tiny_adc.h" +#include "tiny_calibration.h" +#include "tiny_eeprom.h" +/** + * \ingroup udc_group + * \defgroup udc_group_interne Implementation of UDC + * + * Internal implementation + * @{ + */ + +//! \name Internal variables to manage the USB device +//! @{ + +//! Device status state (see enum usb_device_status in usb_protocol.h) +static le16_t udc_device_status; + +COMPILER_WORD_ALIGNED +//! Device interface setting value +static uint8_t udc_iface_setting = 0; + +//! Device Configuration number selected by the USB host +COMPILER_WORD_ALIGNED +static uint8_t udc_num_configuration = 0; + +//! Pointer on the selected speed device configuration +static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf; + +//! Pointer on interface descriptor used by SETUP request. +static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface; + +//! @} + + +//! \name Internal structure to store the USB device main strings +//! @{ + +/** + * \brief Language ID of USB device (US ID by default) + */ +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = { + .desc.bLength = sizeof(usb_str_lgid_desc_t), + .desc.bDescriptorType = USB_DT_STRING, + .string = {LE16(USB_LANGID_EN_US)} +}; + +/** + * \brief USB device manufacture name storage + * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_MANUFACTURE_NAME +static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME; +# define USB_DEVICE_MANUFACTURE_NAME_SIZE \ + (sizeof(udc_string_manufacturer_name)-1) +#else +# define USB_DEVICE_MANUFACTURE_NAME_SIZE 0 +#endif + +/** + * \brief USB device product name storage + * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_PRODUCT_NAME +static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME; +# define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1) +#else +# define USB_DEVICE_PRODUCT_NAME_SIZE 0 +#endif + +/** + * \brief Get USB device serial number + * + * Use the define USB_DEVICE_SERIAL_NAME to set static serial number. + * + * For dynamic serial number set the define USB_DEVICE_GET_SERIAL_NAME_POINTER + * to a suitable pointer. This will also require the serial number length + * define USB_DEVICE_GET_SERIAL_NAME_LENGTH. + */ +#if defined USB_DEVICE_GET_SERIAL_NAME_POINTER + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_GET_SERIAL_NAME_POINTER; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + USB_DEVICE_GET_SERIAL_NAME_LENGTH +#elif defined USB_DEVICE_SERIAL_NAME + static const uint8_t *udc_get_string_serial_name(void) + { + return (const uint8_t *)USB_DEVICE_SERIAL_NAME; + } +# define USB_DEVICE_SERIAL_NAME_SIZE \ + (sizeof(USB_DEVICE_SERIAL_NAME)-1) +#else +# define USB_DEVICE_SERIAL_NAME_SIZE 0 +#endif + +/** + * \brief USB device string descriptor + * Structure used to transfer ASCII strings to USB String descriptor structure. + */ +struct udc_string_desc_t { + usb_str_desc_t header; + le16_t string[Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \ + USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE)]; +}; +COMPILER_WORD_ALIGNED +static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = { + .header.bDescriptorType = USB_DT_STRING +}; +//! @} + +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void) +{ + return udc_ptr_iface; +} + +/** + * \brief Returns a value to check the end of USB Configuration descriptor + * + * \return address after the last byte of USB Configuration descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void) +{ + return (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) + udc_ptr_conf->desc + + le16_to_cpu(udc_ptr_conf->desc->wTotalLength)); +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Search specific descriptor in global interface descriptor + * + * \param desc Address of interface descriptor + * or previous specific descriptor found + * \param desc_id Descriptor ID to search + * + * \return address of specific descriptor found + * \return NULL if it is the end of global interface descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t + UDC_DESC_STORAGE * desc, uint8_t desc_id) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc; + + ptr_eof_desc = udc_get_eof_conf(); + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + // Check the end of configuration descriptor + while (ptr_eof_desc > desc) { + // If new interface descriptor is found, + // then it is the end of the current global interface descriptor + if (USB_DT_INTERFACE == desc->bDescriptorType) { + break; // End of global interface descriptor + } + if (desc_id == desc->bDescriptorType) { + return desc; // Specific descriptor found + } + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + } + return NULL; // No specific descriptor found +} +#endif + +/** + * \brief Search an interface descriptor + * This routine updates the internal pointer udc_ptr_iface. + * + * \param iface_num Interface number to find in Configuration Descriptor + * \param setting_num Setting number of interface to find + * + * \return 1 if found or 0 if not found + */ +static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc; + + if (0 == udc_num_configuration) { + return false; + } + + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Start at the beginning of configuration descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) + udc_ptr_conf->desc; + + // Check the end of configuration descriptor + ptr_end_desc = udc_get_eof_conf(); + while (ptr_end_desc > + (UDC_DESC_STORAGE usb_conf_desc_t *) udc_ptr_iface) { + if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) { + // A interface descriptor is found + // Check interface and alternate setting number + if ((iface_num == udc_ptr_iface->bInterfaceNumber) && + (setting_num == + udc_ptr_iface->bAlternateSetting)) { + return true; // Interface found + } + } + // Go to next descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) ( + (uint8_t *) udc_ptr_iface + + udc_ptr_iface->bLength); + } + return false; // Interface not found +} + +/** + * \brief Disables an usb device interface (UDI) + * This routine call the UDI corresponding to interface number + * + * \param iface_num Interface number to disable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_disable(uint8_t iface_num) +{ + udi_api_t UDC_DESC_STORAGE *udi_api; + + // Select first alternate setting of the interface + // to update udc_ptr_iface before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + +#if (0!=USB_DEVICE_MAX_EP) + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Start at the beginning of interface descriptor + { + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) + ep_desc, USB_DT_ENDPOINT); + if (NULL == ep_desc) { + break; + } + // Free the endpoint used by the interface + udd_ep_free(ep_desc->bEndpointAddress); + } + } +#endif + + // Disable interface + udi_api->disable(); + return true; +} + +/** + * \brief Enables an usb device interface (UDI) + * This routine calls the UDI corresponding + * to the interface and setting number. + * + * \param iface_num Interface number to enable + * \param setting_num Setting number to enable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num) +{ + // Select the interface descriptor + if (!udc_update_iface_desc(iface_num, setting_num)) { + return false; + } + +#if (0!=USB_DEVICE_MAX_EP) + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + + // Start at the beginning of the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) ep_desc, + USB_DT_ENDPOINT); + if (NULL == ep_desc) + break; + // Alloc the endpoint used by the interface + if (!udd_ep_alloc(ep_desc->bEndpointAddress, + ep_desc->bmAttributes, + le16_to_cpu + (ep_desc->wMaxPacketSize))) { + return false; + } + } +#endif + // Enable the interface + return udc_ptr_conf->udi_apis[iface_num]->enable(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void) +{ + udd_enable(); +} + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void) +{ + udd_disable(); + udc_reset(); +} + +/** + * \brief Reset the current configuration of the USB device, + * This routines can be called by UDD when a RESET on the USB line occurs. + */ +void udc_reset(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + udc_iface_disable(iface_num); + } + } + udc_num_configuration = 0; +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + if (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status) { + // Remote wakeup is enabled then disable it + UDC_REMOTEWAKEUP_DISABLE(); + } +#endif + udc_device_status = +#if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED) + CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED); +#else + CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED); +#endif +} + +void udc_sof_notify(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (udc_ptr_conf->udi_apis[iface_num]->sof_notify != NULL) { + udc_ptr_conf->udi_apis[iface_num]->sof_notify(); + } + } + } +} + +/** + * \brief Standard device request to get device status + * + * \return true if success + */ +static bool udc_req_std_dev_get_status(void) +{ + if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status)) { + return false; + } + + udd_set_setup_payload( (uint8_t *) & udc_device_status, + sizeof(udc_device_status)); + return true; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to get endpoint status + * + * \return true if success + */ +static bool udc_req_std_ep_get_status(void) +{ + static le16_t udc_ep_status; + + if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status)) { + return false; + } + + udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req. + wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0; + + udd_set_setup_payload( (uint8_t *) & udc_ep_status, + sizeof(udc_ep_status)); + return true; +} +#endif + +/** + * \brief Standard device request to change device status + * + * \return true if success + */ +static bool udc_req_std_dev_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) { + udc_device_status &= CPU_TO_LE16(~(uint32_t)USB_DEV_STATUS_REMOTEWAKEUP); +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + UDC_REMOTEWAKEUP_DISABLE(); +#endif + return true; + } + return false; +} + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to clear endpoint feature + * + * \return true if success + */ +static bool udc_req_std_ep_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Standard device request to set a feature + * + * \return true if success + */ +static bool udc_req_std_dev_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + switch (udd_g_ctrlreq.req.wValue) { + + case USB_DEV_FEATURE_REMOTE_WAKEUP: +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP); + UDC_REMOTEWAKEUP_ENABLE(); + return true; +#else + return false; +#endif + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DEV_FEATURE_TEST_MODE: + if (!udd_is_high_speed()) { + break; + } + if (udd_g_ctrlreq.req.wIndex & 0xff) { + break; + } + // Unconfigure the device, terminating all ongoing requests + udc_reset(); + switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) { + case USB_DEV_TEST_MODE_J: + udd_g_ctrlreq.callback = udd_test_mode_j; + return true; + + case USB_DEV_TEST_MODE_K: + udd_g_ctrlreq.callback = udd_test_mode_k; + return true; + + case USB_DEV_TEST_MODE_SE0_NAK: + udd_g_ctrlreq.callback = udd_test_mode_se0_nak; + return true; + + case USB_DEV_TEST_MODE_PACKET: + udd_g_ctrlreq.callback = udd_test_mode_packet; + return true; + + case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports + default: + break; + } + break; +#endif + default: + break; + } + return false; +} + +/** + * \brief Standard endpoint request to halt an endpoint + * + * \return true if success + */ +#if (0!=USB_DEVICE_MAX_EP) +static bool udc_req_std_ep_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + udd_ep_abort(udd_g_ctrlreq.req.wIndex & 0xFF); + return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Change the address of device + * Callback called at the end of request set address + */ +static void udc_valid_address(void) +{ + udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F); +} + +/** + * \brief Standard device request to set device address + * + * \return true if success + */ +static bool udc_req_std_dev_set_address(void) +{ + if (udd_g_ctrlreq.req.wLength) { + return false; + } + + // The address must be changed at the end of setup request after the handshake + // then we use a callback to change address + udd_g_ctrlreq.callback = udc_valid_address; + return true; +} + +/** + * \brief Standard device request to get device string descriptor + * + * \return true if success + */ +static bool udc_req_std_dev_get_str_desc(void) +{ + uint8_t i; + const uint8_t *str; + uint8_t str_length = 0; + + // Link payload pointer to the string corresponding at request + switch (udd_g_ctrlreq.req.wValue & 0xff) { + case 0: + udd_set_setup_payload((uint8_t *) &udc_string_desc_languageid, + sizeof(udc_string_desc_languageid)); + break; + +#ifdef USB_DEVICE_MANUFACTURE_NAME + case 1: + str_length = USB_DEVICE_MANUFACTURE_NAME_SIZE; + str = udc_string_manufacturer_name; + break; +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + case 2: + str_length = USB_DEVICE_PRODUCT_NAME_SIZE; + str = udc_string_product_name; + break; +#endif +#if defined USB_DEVICE_SERIAL_NAME || defined USB_DEVICE_GET_SERIAL_NAME_POINTER + case 3: + str_length = USB_DEVICE_SERIAL_NAME_SIZE; + str = udc_get_string_serial_name(); + break; +#endif + default: +#ifdef UDC_GET_EXTRA_STRING + if (UDC_GET_EXTRA_STRING()) { + break; + } +#endif + return false; + } + + if (str_length) { + for(i = 0; i < str_length; i++) { + udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]); + } + + udc_string_desc.header.bLength = 2 + (str_length) * 2; + udd_set_setup_payload( + (uint8_t *) &udc_string_desc, + udc_string_desc.header.bLength); + } + + return true; +} + +/** + * \brief Standard device request to get descriptors about USB device + * + * \return true if success + */ +static bool udc_req_std_dev_get_descriptor(void) +{ + uint8_t conf_num; + + conf_num = udd_g_ctrlreq.req.wValue & 0xff; + + // Check descriptor ID + switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + case USB_DT_DEVICE: + // Device descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (!udd_is_high_speed()) { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_hs, + udc_config.confdev_hs->bLength); + } else +#endif + { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_lsfs, + udc_config.confdev_lsfs->bLength); + } + break; + + case USB_DT_CONFIGURATION: + // Configuration descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else +#endif + { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_CONFIGURATION; + break; + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DT_DEVICE_QUALIFIER: + // Device qualifier descriptor requested + udd_set_setup_payload( (uint8_t *) udc_config.qualifier, + udc_config.qualifier->bLength); + break; + + case USB_DT_OTHER_SPEED_CONFIGURATION: + // Other configuration descriptor requested + if (!udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) { + return false; + } + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_OTHER_SPEED_CONFIGURATION; + break; +#endif + + case USB_DT_BOS: + // Device BOS descriptor requested + if (udc_config.conf_bos == NULL) { + return false; + } + udd_set_setup_payload( (uint8_t *) udc_config.conf_bos, + udc_config.conf_bos->wTotalLength); + break; + + case USB_DT_STRING: + // String descriptor requested + if (!udc_req_std_dev_get_str_desc()) { + return false; + } + break; + + default: + // Unknown descriptor requested + return false; + } + // if the descriptor is larger than length requested, then reduce it + if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) { + udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength; + } + return true; +} + +/** + * \brief Standard device request to get configuration number + * + * \return true if success + */ +static bool udc_req_std_dev_get_configuration(void) +{ + if (udd_g_ctrlreq.req.wLength != 1) { + return false; + } + + udd_set_setup_payload(&udc_num_configuration,1); + return true; +} + +/** + * \brief Standard device request to enable a configuration + * + * \return true if success + */ +static bool udc_req_std_dev_set_configuration(void) +{ + uint8_t iface_num; + + // Check request length + if (udd_g_ctrlreq.req.wLength) { + return false; + } + // Authorize configuration only if the address is valid + if (!udd_getaddress()) { + return false; + } + // Check the configuration number requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_hs->bNumConfigurations) { + return false; + } + } else +#endif + { + // FS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_lsfs->bNumConfigurations) { + return false; + } + } + + // Reset current configuration + udc_reset(); + + // Enable new configuration + udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF; + if (udc_num_configuration == 0) { + return true; // Default empty configuration requested + } + // Update pointer of the configuration descriptor +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1]; + } else +#endif + { + // FS descriptor + udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1]; + } + // Enable all interfaces of the selected configuration + for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (!udc_iface_enable(iface_num, 0)) { + return false; + } + } + return true; +} + +/** + * \brief Standard interface request + * to get the alternate setting number of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_get_setting(void) +{ + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (udd_g_ctrlreq.req.wLength != 1) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + // Check the interface number included in the request + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + // Select first alternate setting of the interface to update udc_ptr_iface + // before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Get alternate setting from UDI + udi_api = udc_ptr_conf->udi_apis[iface_num]; + udc_iface_setting = udi_api->getsetting(); + + // Link value to payload pointer of request + udd_set_setup_payload(&udc_iface_setting,1); + return true; +} + +/** + * \brief Standard interface request + * to set an alternate setting of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_set_setting(void) +{ + uint8_t iface_num, setting_num; + + if (udd_g_ctrlreq.req.wLength) { + return false; // Error in request + } + if (!udc_num_configuration) { + return false; // The device is not is configured state yet + } + + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + setting_num = udd_g_ctrlreq.req.wValue & 0xFF; + + // Disable current setting + if (!udc_iface_disable(iface_num)) { + return false; + } + + // Enable new setting + return udc_iface_enable(iface_num, setting_num); +} + +/** + * \brief Main routine to manage the standard USB SETUP request + * + * \return true if the request is supported + */ +static bool udc_reqstd(void) +{ + if (Udd_setup_is_in()) { + // GET Standard Requests + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error for USB host + } + + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Get Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_dev_get_status(); + case USB_REQ_GET_DESCRIPTOR: + return udc_req_std_dev_get_descriptor(); + case USB_REQ_GET_CONFIGURATION: + return udc_req_std_dev_get_configuration(); + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Get Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_INTERFACE: + return udc_req_std_iface_get_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Get Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_ep_get_status(); + default: + break; + } + } +#endif + } else { + // SET Standard Requests + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Set Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_ADDRESS: + return udc_req_std_dev_set_address(); + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_dev_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_dev_set_feature(); + case USB_REQ_SET_CONFIGURATION: + return udc_req_std_dev_set_configuration(); + case USB_REQ_SET_DESCRIPTOR: + /* Not supported (defined as optional by the USB 2.0 spec) */ + break; + default: + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Set Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_INTERFACE: + return udc_req_std_iface_set_setting(); + default: + break; + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Set Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_ep_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_ep_set_feature(); + default: + break; + } + } +#endif + } + return false; +} + +/** + * \brief Send the SETUP interface request to UDI + * + * \return true if the request is supported + */ +static bool udc_req_iface(void) +{ + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (0 == udc_num_configuration) { + return false; // The device is not is configured state yet + } + // Check interface number + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) { + return false; + } + + //* To update udc_ptr_iface with the selected interface in request + // Select first alternate setting of interface to update udc_ptr_iface + // before calling udi_api->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) { + return false; + } + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Send the SETUP request to the UDI corresponding to the interface number + return udi_api->setup(); +} + +/** + * \brief Send the SETUP interface request to UDI + * + * \return true if the request is supported + */ +static bool udc_req_ep(void) +{ + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (0 == udc_num_configuration) { + return false; // The device is not is configured state yet + } + // Send this request on all enabled interfaces + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) { + return false; + } + + // Send the SETUP request to the UDI + if (udi_api->setup()) { + return true; + } + } + return false; +} + +static bool udc_reqvend(void){ + switch (udd_g_ctrlreq.req.bRequest){ + case 0xa0: //Break! (Debug command) + debugOnNextEnd = 1; + uds.medianTrfcntL = median_TRFCNT & 0xff; + uds.medianTrfcntH = (median_TRFCNT >> 8) & 0xff; + uds.calValNeg = cali_value_negative_gradient; + uds.calValPos = cali_value_positive_gradient; + uds.CALA = DFLLRC2M.CALA; + uds.CALB = DFLLRC2M.CALB; + udd_set_setup_payload(&uds, udd_g_ctrlreq.req.wLength); + //asm("nop"); + return 1; + case 0xa1: //Receive waveform for signal gen + TC_DAC.CTRLA = 0x00; + TC_DAC.PERBUF = udd_g_ctrlreq.req.wValue; + TC_DAC.CTRLA = (unsigned char) udd_g_ctrlreq.req.wIndex & 0x0F; + udd_set_setup_payload(dacBuf_CH1, udd_g_ctrlreq.req.wLength); + if(dacBuf_len != udd_g_ctrlreq.req.wLength){ + dacBuf_len = udd_g_ctrlreq.req.wLength; + tiny_dma_delayed_set(global_mode); + } + return 1; + case 0xa2: //CH2 waveform + TC_AUXDAC.CTRLA = 0x00; + TC_AUXDAC.PERBUF = udd_g_ctrlreq.req.wValue; + TC_AUXDAC.CTRLA = (unsigned char) udd_g_ctrlreq.req.wIndex & 0x0F; + udd_set_setup_payload(dacBuf_CH2, udd_g_ctrlreq.req.wLength); + if(auxDacBufLen != udd_g_ctrlreq.req.wLength){ + auxDacBufLen = udd_g_ctrlreq.req.wLength; + tiny_dma_delayed_set(global_mode); + } + return 1; + case 0xa3: //PSU voltage control + TC_PSU.CCA = 0; + PSU_target = udd_g_ctrlreq.req.wValue; + return 1; + case 0xa4: //Triple mode + PORTB.OUT = udd_g_ctrlreq.req.wValue; + return 1; + case 0xa5: //Control Gain and Scope modes + switch(udd_g_ctrlreq.req.wValue){ + case 0: //Mode 0 + tiny_adc_setup(0, 0); + tiny_adc_ch0setup(udd_g_ctrlreq.req.wIndex); + tiny_dma_delayed_set(0); + break; + case 1: //Mode 1 + tiny_adc_setup(0, 0); + tiny_adc_ch0setup(udd_g_ctrlreq.req.wIndex); + tiny_dma_delayed_set(1); + break; + case 2: //Mode 2 + tiny_adc_setup(1, 1); + tiny_adc_ch0setup(udd_g_ctrlreq.req.wIndex); + tiny_adc_ch1setup(udd_g_ctrlreq.req.wIndex>>8); + tiny_dma_delayed_set(2); + break; + case 3: //Mode 3 + tiny_dma_delayed_set(3); + break; + case 4: //Mode 4 + tiny_dma_delayed_set(4); + break; + case 5: //Mode 5 + tiny_adc_setup(0, 0); + tiny_adc_ch0setup(udd_g_ctrlreq.req.wIndex); + tiny_dma_delayed_set(5); + break; + case 6: //Mode 6 + tiny_adc_setup(0, 1); + tiny_adc_ch0setup(udd_g_ctrlreq.req.wIndex); + tiny_dma_delayed_set(6); + break; + case 7: //Mode 7 + tiny_adc_setup(0, 2); + tiny_adc_ch0setup(udd_g_ctrlreq.req.wIndex | 0x80); + tiny_dma_delayed_set(7); + break; + default: + return 0; + } + return 1; + case 0xa6: //Digital out??? + PORTE.OUT = udd_g_ctrlreq.req.wValue; + return 1; + case 0xa7: //Soft Reset + //Fill EEPROM buffer with value + + if(udd_g_ctrlreq.req.wValue){ + eeprom_safe_read(); + memcpy(eeprom_buffer_write, eeprom_buffer_read, EEPROM_PAGE_SIZE); + eeprom_buffer_write[0] = 1; + eeprom_safe_write(); + eeprom_safe_read(); + } + + //Code here from SprinterSB + //http://www.avrfreaks.net/comment/872674 + //I don't understand it, but it seems to do the job + __asm volatile ("cli" "\n\t" + "out __CCP__, %[ccp]" "\n\t" + "st %a[rst], %[swrst]" + : + : [ccp] "r" ((uint8_t) CCP_IOREG_gc), + [swrst] "r" ((uint8_t) RST_SWRST_bm), + [rst] "e" (&RST.CTRL) + : "memory"); + __builtin_unreachable(); + case 0xa8: //Firmware Version Request + udd_set_setup_payload(&firmver, udd_g_ctrlreq.req.wLength); + return 1; + case 0xa9: //Variant Version Request + udd_set_setup_payload(&variant, udd_g_ctrlreq.req.wLength); + return 1; + default: + return 0; + } +} +/** + * \brief Main routine to manage the USB SETUP request. + * + * This function parses a USB SETUP request and submits an appropriate + * response back to the host or, in the case of SETUP OUT requests + * with data, sets up a buffer for receiving the data payload. + * + * The main standard requests defined by the USB 2.0 standard are handled + * internally. The interface requests are sent to UDI, and the specific request + * sent to a specific application callback. + * + * \return true if the request is supported, else the request is stalled by UDD + */ +bool udc_process_setup(void) +{ + // By default no data (receive/send) and no callbacks registered + udd_g_ctrlreq.payload_size = 0; + udd_g_ctrlreq.callback = NULL; + udd_g_ctrlreq.over_under_run = NULL; + + if (Udd_setup_is_in()) { + if (udd_g_ctrlreq.req.wLength == 0) { + return false; // Error from USB host + } + } + + if (Udd_setup_type() == USB_REQ_TYPE_VENDOR){ + if (udc_reqvend()) { + return true; + } + } + + // If standard request then try to decode it in UDC + if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { + if (udc_reqstd()) { + return true; + } + } + + // If interface request then try to decode it in UDI + if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) { + if (udc_req_iface()) { + return true; + } + } + + // If endpoint request then try to decode it in UDI + if (Udd_setup_recipient() == USB_REQ_RECIP_ENDPOINT) { + if (udc_req_ep()) { + return true; + } + } + + // Here SETUP request unknown by UDC and UDIs +#ifdef USB_DEVICE_SPECIFIC_REQUEST + // Try to decode it in specific callback + return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,... +#else + return false; +#endif +} + +//! @} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc.c.REMOVED.git-id deleted file mode 100644 index 50f24419..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ea6e7ad4969e07a1472ad1893273afa05b503593 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc.h new file mode 100644 index 00000000..edfe7078 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc.h @@ -0,0 +1,697 @@ +/** + * \file + * + * \brief Interface of the USB Device Controller (UDC) + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UDC_H_ +#define _UDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udc_desc.h" +#include "udd.h" + +#if USB_DEVICE_VENDOR_ID == 0 +# error USB_DEVICE_VENDOR_ID cannot be equal to 0 +#endif + +#if USB_DEVICE_PRODUCT_ID == 0 +# error USB_DEVICE_PRODUCT_ID cannot be equal to 0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udc_group USB Device Controller (UDC) + * + * The UDC provides a high-level abstraction of the usb device. + * You can use these functions to control the main device state + * (start/attach/wakeup). + * + * \section USB_DEVICE_CONF USB Device Custom configuration + * The following USB Device configuration must be included in the conf_usb.h + * file of the application. + * + * USB_DEVICE_VENDOR_ID (Word)
+ * Vendor ID provided by USB org (ATMEL 0x03EB). + * + * USB_DEVICE_PRODUCT_ID (Word)
+ * Product ID (Referenced in usb_atmel.h). + * + * USB_DEVICE_MAJOR_VERSION (Byte)
+ * Major version of the device + * + * USB_DEVICE_MINOR_VERSION (Byte)
+ * Minor version of the device + * + * USB_DEVICE_MANUFACTURE_NAME (string)
+ * ASCII name for the manufacture + * + * USB_DEVICE_PRODUCT_NAME (string)
+ * ASCII name for the product + * + * USB_DEVICE_SERIAL_NAME (string)
+ * ASCII name to enable and set a serial number + * + * USB_DEVICE_POWER (Numeric)
+ * (unit mA) Maximum device power + * + * USB_DEVICE_ATTR (Byte)
+ * USB attributes available: + * - USB_CONFIG_ATTR_SELF_POWERED + * - USB_CONFIG_ATTR_REMOTE_WAKEUP + * Note: if remote wake enabled then defines remotewakeup callbacks, + * see Table 5-2. External API from UDC - Callback + * + * USB_DEVICE_LOW_SPEED (Only defined)
+ * Force the USB Device to run in low speed + * + * USB_DEVICE_HS_SUPPORT (Only defined)
+ * Authorize the USB Device to run in high speed + * + * USB_DEVICE_MAX_EP (Byte)
+ * Define the maximum endpoint number used by the USB Device.
+ * This one is already defined in UDI default configuration. + * Ex: + * - When endpoint control 0x00, endpoint 0x01 and + * endpoint 0x82 is used then USB_DEVICE_MAX_EP=2 + * - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0 + * - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1
+ * (configuration not possible on USBB interface) + * @{ + */ + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + * + * \section udc_vbus_monitoring VBus monitoring used cases + * + * The VBus monitoring is used only for USB SELF Power application. + * + * - By default the USB device is automatically attached when Vbus is high + * or when USB is start for devices without internal Vbus monitoring. + * conf_usb.h file does not contains define USB_DEVICE_ATTACH_AUTO_DISABLE. + * \code //#define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode + * + * - Add custom VBUS monitoring. conf_usb.h file contains define + * USB_DEVICE_ATTACH_AUTO_DISABLE: + * \code #define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode + * User C file contains: + * \code + // Authorize VBUS monitoring + if (!udc_include_vbus_monitoring()) { + // Implement custom VBUS monitoring via GPIO or other + } + Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other + { + // Attach USB Device + udc_attach(); + } +\endcode + * + * - Case of battery charging. conf_usb.h file contains define + * USB_DEVICE_ATTACH_AUTO_DISABLE: + * \code #define USB_DEVICE_ATTACH_AUTO_DISABLE \endcode + * User C file contains: + * \code + Event VBUS present() // VBUS interrupt or GPIO interrupt or .. + { + // Authorize battery charging, but wait key press to start USB. + } + Event Key press() + { + // Stop batteries charging + // Start USB + udc_attach(); + } +\endcode + */ +static inline bool udc_include_vbus_monitoring(void) +{ + return udd_include_vbus_monitoring(); +} + +/*! \brief Start the USB Device stack + */ +void udc_start(void); + +/*! \brief Stop the USB Device stack + */ +void udc_stop(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +static inline void udc_attach(void) +{ + udd_attach(); +} + + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +static inline void udc_detach(void) +{ + udd_detach(); +} + + +/*! \brief The USB driver sends a resume signal called \e "Upstream Resume" + * This is authorized only when the remote wakeup feature is enabled by host. + */ +static inline void udc_remotewakeup(void) +{ + udd_send_remotewakeup(); +} + + +/** + * \brief Returns a pointer on the current interface descriptor + * + * \return pointer on the current interface descriptor. + */ +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void); + +//@} + +/** + * \ingroup usb_group + * \defgroup usb_device_group USB Stack Device + * + * This module includes USB Stack Device implementation. + * The stack is divided in three parts: + * - USB Device Controller (UDC) provides USB chapter 9 compliance + * - USB Device Interface (UDI) provides USB Class compliance + * - USB Device Driver (UDD) provides USB Driver for each Atmel MCU + + * Many USB Device applications can be implemented on Atmel MCU. + * Atmel provides many application notes for different applications: + * - AVR4900, provides general information about Device Stack + * - AVR4901, explains how to create a new class + * - AVR4902, explains how to create a composite device + * - AVR49xx, all device classes provided in ASF have an application note + * + * A basic USB knowledge is required to understand the USB Device + * Class application notes (HID,MS,CDC,PHDC,...). + * Then, to create an USB device with + * only one class provided by ASF, refer directly to the application note + * corresponding to this USB class. The USB Device application note for + * New Class and Composite is dedicated to advanced USB users. + * + * @{ + */ + +//! @} + +#ifdef __cplusplus +} +#endif + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_prereq USB Device Controller (UDC) - Prerequisites + * Common prerequisites for all USB devices. + * + * This module is based on USB device stack full interrupt driven, and supporting + * \ref sleepmgr_group sleepmgr. For AVR and SAM3/4 devices the \ref clk_group clock services + * is supported. For SAMD devices the \ref asfdoc_sam0_system_clock_group clock driver is supported. + * + * The following procedure must be executed to setup the project correctly: + * - Specify the clock configuration: + * - XMEGA USB devices need 48MHz clock input.\n + * XMEGA USB devices need CPU frequency higher than 12MHz.\n + * You can use either an internal RC48MHz auto calibrated by Start of Frames + * or an external OSC. + * - UC3 and SAM3/4 devices without USB high speed support need 48MHz clock input.\n + * You must use a PLL and an external OSC. + * - UC3 and SAM3/4 devices with USB high speed support need 12MHz clock input.\n + * You must use an external OSC. + * - UC3 devices with USBC hardware need CPU frequency higher than 25MHz. + * - SAMD devices without USB high speed support need 48MHz clock input.\n + * You should use DFLL with USBCRM. + * - In conf_board.h, the define CONF_BOARD_USB_PORT must be added to enable USB lines. + * (Not mandatory for all boards) + * - Enable interrupts + * - Initialize the clock service + * + * The usage of \ref sleepmgr_group sleepmgr service is optional, but recommended to reduce power + * consumption: + * - Initialize the sleep manager service + * - Activate sleep mode when the application is in IDLE state + * + * \subpage udc_conf_clock. + * + * for AVR and SAM3/4 devices, add to the initialization code: + * \code + sysclk_init(); + irq_initialize_vectors(); + cpu_irq_enable(); + board_init(); + sleepmgr_init(); // Optional +\endcode + * + * For SAMD devices, add to the initialization code: + * \code + system_init(); + irq_initialize_vectors(); + cpu_irq_enable(); + sleepmgr_init(); // Optional +\endcode + * Add to the main IDLE loop: + * \code + sleepmgr_enter_sleep(); // Optional +\endcode + * + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_code USB Device Controller (UDC) - Example code + * Common example code for all USB devices. + * + * Content of conf_usb.h: + * \code + #define USB_DEVICE_VENDOR_ID 0x03EB + #define USB_DEVICE_PRODUCT_ID 0xXXXX + #define USB_DEVICE_MAJOR_VERSION 1 + #define USB_DEVICE_MINOR_VERSION 0 + #define USB_DEVICE_POWER 100 + #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED +\endcode + * + * Add to application C-file: + * \code + void usb_init(void) + { + udc_start(); + } +\endcode + */ + +/** + * \ingroup udc_group + * \defgroup udc_basic_use_case_setup_flow USB Device Controller (UDC) - Workflow + * Common workflow for all USB devices. + * + * -# Ensure that conf_usb.h is available and contains the following configuration + * which is the main USB device configuration: + * - \code // Vendor ID provided by USB org (ATMEL 0x03EB) + #define USB_DEVICE_VENDOR_ID 0x03EB // Type Word + // Product ID (Atmel PID referenced in usb_atmel.h) + #define USB_DEVICE_PRODUCT_ID 0xXXXX // Type Word + // Major version of the device + #define USB_DEVICE_MAJOR_VERSION 1 // Type Byte + // Minor version of the device + #define USB_DEVICE_MINOR_VERSION 0 // Type Byte + // Maximum device power (mA) + #define USB_DEVICE_POWER 100 // Type 9-bits + // USB attributes to enable features + #define USB_DEVICE_ATTR USB_CONFIG_ATTR_BUS_POWERED // Flags \endcode + * -# Call the USB device stack start function to enable stack and start USB: + * - \code udc_start(); \endcode + * \note In case of USB dual roles (Device and Host) managed through USB OTG connector + * (USB ID pin), the call of udc_start() must be removed and replaced by uhc_start(). + * SeRefer to "AVR4950 section 6.1 Dual roles" for further information about dual roles. + */ + +/** + * \page udc_conf_clock conf_clock.h examples with USB support + * + * Content of XMEGA conf_clock.h: + * \code + // Configuration based on internal RC: + // USB clock need of 48Mhz + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC + #define CONFIG_OSC_RC32_CAL 48000000UL + #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + // CPU clock need of clock > 12MHz to run with USB (Here 24MHz) + #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ + #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 + #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 +\endcode + * + * Content of conf_clock.h for AT32UC3A0, AT32UC3A1, AT32UC3B devices (USBB): + * \code + // Configuration based on 12MHz external OSC: + #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + #define CONFIG_PLL1_MUL 8 + #define CONFIG_PLL1_DIV 2 + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) +\endcode + * + * Content of conf_clock.h for AT32UC3A3, AT32UC3A4 devices (USBB with high speed support): + * \code + // Configuration based on 12MHz external OSC: + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_OSC0 + #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) +\endcode + * + * Content of conf_clock.h for AT32UC3C, ATUCXXD, ATUCXXL3U, ATUCXXL4U devices (USBC): + * \code + // Configuration based on 12MHz external OSC: + #define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 + #define CONFIG_PLL1_MUL 8 + #define CONFIG_PLL1_DIV 2 + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + #define CONFIG_USBCLK_DIV 1 // Fusb = Fsys/(2 ^ USB_div) + // CPU clock need of clock > 25MHz to run with USBC + #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL1 +\endcode + * + * Content of conf_clock.h for SAM3S, SAM3SD, SAM4S devices (UPD: USB Peripheral Device): + * \code + // PLL1 (B) Options (Fpll = (Fclk * PLL_mul) / PLL_div) + #define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL + #define CONFIG_PLL1_MUL 16 + #define CONFIG_PLL1_DIV 2 + // USB Clock Source Options (Fusb = FpllX / USB_div) + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 + #define CONFIG_USBCLK_DIV 2 +\endcode + * + * Content of conf_clock.h for SAM3U device (UPDHS: USB Peripheral Device High Speed): + * \code + // USB Clock Source fixed at UPLL. +\endcode + * + * Content of conf_clock.h for SAM3X, SAM3A devices (UOTGHS: USB OTG High Speed): + * \code + // USB Clock Source fixed at UPLL. + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_UPLL + #define CONFIG_USBCLK_DIV 1 +\endcode + * + * Content of conf_clocks.h for SAMD devices (USB): + * \code + // System clock bus configuration + # define CONF_CLOCK_FLASH_WAIT_STATES 2 + + // USB Clock Source fixed at DFLL. + // SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop + # define CONF_CLOCK_DFLL_ENABLE true + # define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_USB_RECOVERY + # define CONF_CLOCK_DFLL_ON_DEMAND true + + // Set this to true to configure the GCLK when running clocks_init. + // If set to false, none of the GCLK generators will be configured in clocks_init(). + # define CONF_CLOCK_CONFIGURE_GCLK true + + // Configure GCLK generator 0 (Main Clock) + # define CONF_CLOCK_GCLK_0_ENABLE true + # define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY true + # define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_DFLL + # define CONF_CLOCK_GCLK_0_PRESCALER 1 + # define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false +\endcode + */ + +/** + * \page udc_use_case_1 Change USB speed + * + * In this use case, the USB device is used with different USB speeds. + * + * \section udc_use_case_1_setup Setup steps + * + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_1_usage Usage steps + * + * \subsection udc_use_case_1_usage_code Example code + * Content of conf_usb.h: + * \code + #if // Low speed + #define USB_DEVICE_LOW_SPEED + // #define USB_DEVICE_HS_SUPPORT + + #elif // Full speed + // #define USB_DEVICE_LOW_SPEED + // #define USB_DEVICE_HS_SUPPORT + + #elif // High speed + // #define USB_DEVICE_LOW_SPEED + #define USB_DEVICE_HS_SUPPORT + + #endif +\endcode + * + * \subsection udc_use_case_1_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required for a USB device low speed (1.5Mbit/s): + * - \code #define USB_DEVICE_LOW_SPEED + //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device full speed (12Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + //#define USB_DEVICE_HS_SUPPORT \endcode + * -# Ensure that conf_usb.h contains the following parameters + * required for a USB device high speed (480Mbit/s): + * - \code //#define USB_DEVICE_LOW_SPEED + #define USB_DEVICE_HS_SUPPORT \endcode + */ + +/** + * \page udc_use_case_2 Use USB strings + * + * In this use case, the usual USB strings is added in the USB device. + * + * \section udc_use_case_2_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_2_usage Usage steps + * + * \subsection udc_use_case_2_usage_code Example code + * Content of conf_usb.h: + * \code + #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" + #define USB_DEVICE_PRODUCT_NAME "Product name" + #define USB_DEVICE_SERIAL_NAME "12...EF" +\endcode + * + * \subsection udc_use_case_2_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable different USB strings: + * - \code // Static ASCII name for the manufacture + #define USB_DEVICE_MANUFACTURE_NAME "Manufacture name" \endcode + * - \code // Static ASCII name for the product + #define USB_DEVICE_PRODUCT_NAME "Product name" \endcode + * - \code // Static ASCII name to enable and set a serial number + #define USB_DEVICE_SERIAL_NAME "12...EF" \endcode + */ + +/** + * \page udc_use_case_3 Use USB remote wakeup feature + * + * In this use case, the USB remote wakeup feature is enabled. + * + * \section udc_use_case_3_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_3_usage Usage steps + * + * \subsection udc_use_case_3_usage_code Example code + * Content of conf_usb.h: + * \code + #define USB_DEVICE_ATTR \ + (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) + #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + extern void my_callback_remotewakeup_enable(void); + #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + extern void my_callback_remotewakeup_disable(void); +\endcode + * + * Add to application C-file: + * \code + void my_callback_remotewakeup_enable(void) + { + // Enable application wakeup events (e.g. enable GPIO interrupt) + } + void my_callback_remotewakeup_disable(void) + { + // Disable application wakeup events (e.g. disable GPIO interrupt) + } + + void my_interrupt_event(void) + { + udc_remotewakeup(); + } +\endcode + * + * \subsection udc_use_case_3_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable remote wakeup feature: + * - \code // Authorizes the remote wakeup feature + #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_REMOTE_WAKEUP | USB_CONFIG_ATTR_..._POWERED) \endcode + * - \code // Define callback called when the host enables the remotewakeup feature + #define UDC_REMOTEWAKEUP_ENABLE() my_callback_remotewakeup_enable() + extern void my_callback_remotewakeup_enable(void); \endcode + * - \code // Define callback called when the host disables the remotewakeup feature + #define UDC_REMOTEWAKEUP_DISABLE() my_callback_remotewakeup_disable() + extern void my_callback_remotewakeup_disable(void); \endcode + * -# Send a remote wakeup (USB upstream): + * - \code udc_remotewakeup(); \endcode + */ + +/** + * \page udc_use_case_5 Bus power application recommendations + * + * In this use case, the USB device BUS power feature is enabled. + * This feature requires a correct power consumption management. + * + * \section udc_use_case_5_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_5_usage Usage steps + * + * \subsection udc_use_case_5_usage_code Example code + * Content of conf_usb.h: + * \code + #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) + #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + extern void user_callback_suspend_action(void) + #define UDC_RESUME_EVENT() user_callback_resume_action() + extern void user_callback_resume_action(void) +\endcode + * + * Add to application C-file: + * \code + void user_callback_suspend_action(void) + { + // Disable hardware component to reduce power consumption + } + void user_callback_resume_action(void) + { + // Re-enable hardware component + } +\endcode + * + * \subsection udc_use_case_5_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters: + * - \code // Authorizes the BUS power feature + #define USB_DEVICE_ATTR (USB_CONFIG_ATTR_BUS_POWERED) \endcode + * - \code // Define callback called when the host suspend the USB line + #define UDC_SUSPEND_EVENT() user_callback_suspend_action() + extern void user_callback_suspend_action(void); \endcode + * - \code // Define callback called when the host or device resume the USB line + #define UDC_RESUME_EVENT() user_callback_resume_action() + extern void user_callback_resume_action(void); \endcode + * -# Reduce power consumption in suspend mode (max. 2.5mA on Vbus): + * - \code void user_callback_suspend_action(void) + { + turn_off_components(); + } \endcode + */ + +/** + * \page udc_use_case_6 USB dynamic serial number + * + * In this use case, the USB serial strings is dynamic. + * For a static serial string refer to \ref udc_use_case_2. + * + * \section udc_use_case_6_setup Setup steps + * Prior to implement this use case, be sure to have already + * apply the UDI module "basic use case". + * + * \section udc_use_case_6_usage Usage steps + * + * \subsection udc_use_case_6_usage_code Example code + * Content of conf_usb.h: + * \code + #define USB_DEVICE_SERIAL_NAME + #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number + #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 + extern uint8_t serial_number[]; +\endcode + * + * Add to application C-file: + * \code + uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + + void init_build_usb_serial_number(void) + { + serial_number[0] = 'A'; + serial_number[1] = 'B'; + ... + serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + } \endcode + * + * \subsection udc_use_case_6_usage_flow Workflow + * -# Ensure that conf_usb.h is available and contains the following parameters + * required to enable a USB serial number strings dynamically: + * - \code #define USB_DEVICE_SERIAL_NAME // Define this empty + #define USB_DEVICE_GET_SERIAL_NAME_POINTER serial_number // Give serial array pointer + #define USB_DEVICE_GET_SERIAL_NAME_LENGTH 12 // Give size of serial array + extern uint8_t serial_number[]; // Declare external serial array \endcode + * -# Before start USB stack, initialize the serial array + * - \code + uint8_t serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH]; + + void init_build_usb_serial_number(void) + { + serial_number[0] = 'A'; + serial_number[1] = 'B'; + ... + serial_number[USB_DEVICE_GET_SERIAL_NAME_LENGTH-1] = 'C'; + } \endcode + */ + + + +#endif // _UDC_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc.h.REMOVED.git-id deleted file mode 100644 index e62d6b98..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -edfe70788b075f89f1db3c17450ad33ca4916353 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc_desc.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc_desc.h new file mode 100644 index 00000000..88ed08a9 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc_desc.h @@ -0,0 +1,135 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UDC_DESC_H_ +#define _UDC_DESC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup udc_group + * \defgroup udc_desc_group USB Device Descriptor + * + * @{ + */ + +/** + * \brief Defines the memory's location of USB descriptors + * + * By default the Descriptor is stored in RAM + * (UDC_DESC_STORAGE is defined empty). + * + * If you have need to free RAM space, + * it is possible to put descriptor in flash in following case: + * - USB driver authorize flash transfer (USBB on UC3 and USB on Mega) + * - USB Device is not high speed (UDC no need to change USB descriptors) + * + * For UC3 application used "const". + * + * For Mega application used "code". + */ +#define UDC_DESC_STORAGE + // Descriptor storage in internal RAM +#if (defined UDC_DATA_USE_HRAM_SUPPORT) +# if defined(__GNUC__) +# define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0"))) +# define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0"))) +# elif defined(__ICCAVR32__) +# define UDC_DATA(x) COMPILER_ALIGNED(x) __data32 +# define UDC_BSS(x) COMPILER_ALIGNED(x) __data32 +# endif +#else +# define UDC_DATA(x) COMPILER_ALIGNED(x) +# define UDC_BSS(x) COMPILER_ALIGNED(x) +#endif + + + +/** + * \brief Configuration descriptor and UDI link for one USB speed + */ +typedef struct { + //! USB configuration descriptor + usb_conf_desc_t UDC_DESC_STORAGE *desc; + //! Array of UDI API pointer + udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE * udi_apis; +} udc_config_speed_t; + + +/** + * \brief All information about the USB Device + */ +typedef struct { + //! USB device descriptor for low or full speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs; + //! USB configuration descriptor and UDI API pointers for low or full speed + udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs; +#ifdef USB_DEVICE_HS_SUPPORT + //! USB device descriptor for high speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs; + //! USB device qualifier, only use in high speed mode + usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier; + //! USB configuration descriptor and UDI API pointers for high speed + udc_config_speed_t UDC_DESC_STORAGE *conf_hs; +#endif + usb_dev_bos_desc_t UDC_DESC_STORAGE *conf_bos; +} udc_config_t; + +//! Global variables of USB Device Descriptor and UDI links +extern UDC_DESC_STORAGE udc_config_t udc_config; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDC_DESC_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc_desc.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc_desc.h.REMOVED.git-id deleted file mode 100644 index ceea95ad..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udc_desc.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -88ed08a96118be1b177bd0edf0c4fabc11a46da5 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udd.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udd.h new file mode 100644 index 00000000..10807f43 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udd.h @@ -0,0 +1,396 @@ +/** + * \file + * + * \brief Common API for USB Device Drivers (UDD) + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UDD_H_ +#define _UDD_H_ + +#include "usb_protocol.h" +#include "udc_desc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udd_group USB Device Driver (UDD) + * + * The UDD driver provides a low-level abstraction of the device + * controller hardware. Most events coming from the hardware such as + * interrupts, which may cause the UDD to call into the UDC and UDI. + * + * @{ + */ + +//! \brief Endpoint identifier +typedef uint8_t udd_ep_id_t; + +//! \brief Endpoint transfer status +//! Returned in parameters of callback register via udd_ep_run routine. +typedef enum { + UDD_EP_TRANSFER_OK = 0, + UDD_EP_TRANSFER_ABORT = 1, +} udd_ep_status_t; + +/** + * \brief Global variable to give and record information of the setup request management + * + * This global variable allows to decode and response a setup request. + * It can be updated by udc_process_setup() from UDC or *setup() from UDIs. + */ +typedef struct { + //! Data received in USB SETUP packet + //! Note: The swap of "req.wValues" from uin16_t to le16_t is done by UDD. + usb_setup_req_t req; + + //! Point to buffer to send or fill with data following SETUP packet + //! This buffer must be word align for DATA IN phase (use prefix COMPILER_WORD_ALIGNED for buffer) + uint8_t *payload; + + //! Size of buffer to send or fill, and content the number of byte transfered + uint16_t payload_size; + + //! Callback called after reception of ZLP from setup request + void (*callback) (void); + + //! Callback called when the buffer given (.payload) is full or empty. + //! This one return false to abort data transfer, or true with a new buffer in .payload. + bool(*over_under_run) (void); +} udd_ctrl_request_t; +extern udd_ctrl_request_t udd_g_ctrlreq; + +//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer +#define Udd_setup_is_in() \ + (USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer +#define Udd_setup_is_out() \ + (USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) + +//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype. +#define Udd_setup_type() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK) + +//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient +#define Udd_setup_recipient() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK) + +/** + * \brief End of halt callback function type. + * Registered by routine udd_ep_wait_stall_clear() + * Callback called when endpoint stall is cleared. + */ +typedef void (*udd_callback_halt_cleared_t) (void); + +/** + * \brief End of transfer callback function type. + * Registered by routine udd_ep_run() + * Callback called by USB interrupt after data transfer or abort (reset,...). + * + * \param status UDD_EP_TRANSFER_OK, if transfer is complete + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param n number of data transfered + */ +typedef void (*udd_callback_trans_t) (udd_ep_status_t status, + iram_size_t nb_transfered, udd_ep_id_t ep); + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + */ +bool udd_include_vbus_monitoring(void); + +/** + * \brief Enables the USB Device mode + */ +void udd_enable(void); + +/** + * \brief Disables the USB Device mode + */ +void udd_disable(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +void udd_attach(void); + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +void udd_detach(void); + +/** + * \brief Test whether the USB Device Controller is running at high + * speed or not. + * + * \return \c true if the Device is running at high speed mode, otherwise \c false. + */ +bool udd_is_high_speed(void); + +/** + * \brief Changes the USB address of device + * + * \param address New USB address + */ +void udd_set_address(uint8_t address); + +/** + * \brief Returns the USB address of device + * + * \return USB address + */ +uint8_t udd_getaddress(void); + +/** + * \brief Returns the current start of frame number + * + * \return current start of frame number. + */ +uint16_t udd_get_frame_number(void); + +/** + * \brief Returns the current micro start of frame number + * + * \return current micro start of frame number required in high speed mode. + */ +uint16_t udd_get_micro_frame_number(void); + +/*! \brief The USB driver sends a resume signal called Upstream Resume + */ +void udd_send_remotewakeup(void); + +/** + * \brief Load setup payload + * + * \param payload Pointer on payload + * \param payload_size Size of payload + */ +void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ); + + +/** + * \name Endpoint Management + * + * The following functions allow drivers to create and remove + * endpoints, as well as set, clear and query their "halted" and + * "wedged" states. + */ +//@{ + +#if (USB_DEVICE_MAX_EP != 0) + +/** + * \brief Configures and enables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * \param bmAttributes Attributes of endpoint declared in the descriptor. + * \param MaxEndpointSize Endpoint maximum size + * + * \return \c 1 if the endpoint is enabled, otherwise \c 0. + */ +bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize); + +/** + * \brief Disables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + */ +void udd_ep_free(udd_ep_id_t ep); + +/** + * \brief Check if the endpoint \a ep is halted. + * + * \param ep The ID of the endpoint to check. + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_is_halted(udd_ep_id_t ep); + +/** + * \brief Set the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will result + * in a STALL handshake being sent. Any pending transactions will be + * performed first, however. + * + * \param ep The ID of the endpoint to be halted + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_set_halt(udd_ep_id_t ep); + +/** + * \brief Clear the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will + * be handled normally, i.e. a STALL handshake will not be sent, and + * the data toggle sequence will start at DATA0. + * + * \param ep The ID of the endpoint to be un-halted + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_clear_halt(udd_ep_id_t ep); + +/** + * \brief Registers a callback to call when endpoint halt is cleared + * + * \param ep The ID of the endpoint to use + * \param callback NULL or function to call when endpoint halt is cleared + * + * \warning if the endpoint is not halted then the \a callback is called immediately. + * + * \return \c 1 if the register is accepted, otherwise \c 0. + */ +bool udd_ep_wait_stall_clear(udd_ep_id_t ep, + udd_callback_halt_cleared_t callback); + +/** + * \brief Allows to receive or send data on an endpoint + * + * The driver uses a specific DMA USB to transfer data + * from internal RAM to endpoint, if this one is available. + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * Note: The control endpoint is not authorized. + * + * \param ep The ID of the endpoint to use + * \param b_shortpacket Enabled automatic short packet + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \warning About \a b_shortpacket, for IN endpoint it means that a short packet + * (or a Zero Length Packet) will be sent to the USB line to properly close the usb + * transfer at the end of the data transfer. + * For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer + * at the end of the data transfer (received short packet). + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, + uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); +/** + * \brief Aborts transfer on going on endpoint + * + * If a transfer is on going, then it is stopped and + * the callback registered is called to signal the end of transfer. + * Note: The control endpoint is not authorized. + * + * \param ep Endpoint to abort + */ +void udd_ep_abort(udd_ep_id_t ep); + +#endif + +//@} + + +/** + * \name High speed test mode management + * + * The following functions allow the device to jump to a specific test mode required in high speed mode. + */ +//@{ +void udd_test_mode_j(void); +void udd_test_mode_k(void); +void udd_test_mode_se0_nak(void); +void udd_test_mode_packet(void); +//@} + + +/** + * \name UDC callbacks to provide for UDD + * + * The following callbacks are used by UDD. + */ +//@{ + +/** + * \brief Decodes and manages a setup request + * + * The driver call it when a SETUP packet is received. + * The \c udd_g_ctrlreq contains the data of SETUP packet. + * If this callback accepts the setup request then it must + * return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data. + * + * \return \c 1 if the request is accepted, otherwise \c 0. + */ +extern bool udc_process_setup(void); + +/** + * \brief Reset the UDC + * + * The UDC must reset all configuration. + */ +extern void udc_reset(void); + +/** + * \brief To signal that a SOF is occurred + * + * The UDC must send the signal to all UDIs enabled + */ +extern void udc_sof_notify(void); + +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDD_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udd.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udd.h.REMOVED.git-id deleted file mode 100644 index 4f90b2c0..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udd.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -10807f43d79e2ad521e08c907e549df8ce64bd36 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udi.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udi.h new file mode 100644 index 00000000..1fc7ae5d --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udi.h @@ -0,0 +1,133 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UDI_H_ +#define _UDI_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udi_group USB Device Interface (UDI) + * The UDI provides a common API for all classes, + * and this is used by UDC for the main control of USB Device interface. + * @{ + */ + +/** + * \brief UDI API. + * + * The callbacks within this structure are called only by + * USB Device Controller (UDC) + * + * The udc_get_interface_desc() can be use by UDI to know the interface descriptor + * selected by UDC. + */ +typedef struct { + /** + * \brief Enable the interface. + * + * This function is called when the host selects a configuration + * to which this interface belongs through a Set Configuration + * request, and when the host selects an alternate setting of + * this interface through a Set Interface request. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ + bool(*enable) (void); + + /** + * \brief Disable the interface. + * + * This function is called when this interface is currently + * active, and + * - the host selects any configuration through a Set + * Configuration request, or + * - the host issues a USB reset, or + * - the device is detached from the host (i.e. Vbus is no + * longer present) + */ + void (*disable) (void); + + /** + * \brief Handle a control request directed at an interface. + * + * This function is called when this interface is currently + * active and the host sends a SETUP request + * with this interface as the recipient. + * + * Use udd_g_ctrlreq to decode and response to SETUP request. + * + * \return \c 1 if this interface supports the SETUP request, otherwise \c 0. + */ + bool(*setup) (void); + + /** + * \brief Returns the current setting of the selected interface. + * + * This function is called when UDC when know alternate setting of selected interface. + * + * \return alternate setting of selected interface + */ + uint8_t(*getsetting) (void); + + /** + * \brief To signal that a SOF is occurred + */ + void(*sof_notify) (void); +} udi_api_t; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udi.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udi.h.REMOVED.git-id deleted file mode 100644 index 66f5daad..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/udc/udi.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1fc7ae5d01a43eec2181fb52327d80f8edde0f74 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/usb_atmel.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/usb_atmel.h new file mode 100644 index 00000000..049459cc --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/usb_atmel.h @@ -0,0 +1,190 @@ +/** + * \file + * + * \brief All USB VIDs and PIDs from Atmel USB applications + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _USB_ATMEL_H_ +#define _USB_ATMEL_H_ + +/** + * \defgroup usb_group USB Stack + * + * This stack includes the USB Device Stack, USB Host Stack and common + * definitions. + * @{ + */ + +//! @} + +/** + * \ingroup usb_group + * \defgroup usb_atmel_ids_group Atmel USB Identifiers + * + * This module defines Atmel PID and VIDs constants. + * + * @{ + */ + +//! \name Vendor Identifier assigned by USB org to ATMEL +#define USB_VID_ATMEL 0x03EB + + +//! \name Product Identifier assigned by ATMEL to AVR applications +//! @{ + +//! \name The range from 2000h to 20FFh is reserved to the old PID for C51, MEGA, and others. +//! @{ +#define USB_PID_ATMEL_MEGA_HIDGENERIC 0x2013 +#define USB_PID_ATMEL_MEGA_HIDKEYBOARD 0x2017 +#define USB_PID_ATMEL_MEGA_CDC 0x2018 +#define USB_PID_ATMEL_MEGA_AUDIO_IN 0x2019 +#define USB_PID_ATMEL_MEGA_MS 0x201A +#define USB_PID_ATMEL_MEGA_AUDIO_IN_OUT 0x201B +#define USB_PID_ATMEL_MEGA_HIDMOUSE 0x201C +#define USB_PID_ATMEL_MEGA_HIDMOUSE_CERTIF_U4 0x201D +#define USB_PID_ATMEL_MEGA_CDC_MULTI 0x201E +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_USBKEY 0x2022 +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_STK525 0x2023 +#define USB_PID_ATMEL_MEGA_MS_2 0x2029 +#define USB_PID_ATMEL_MEGA_MS_HIDMS 0x202A +#define USB_PID_ATMEL_MEGA_MS_3 0x2032 +#define USB_PID_ATMEL_MEGA_LIBUSB 0x2050 +//! @} + +//! \name The range 2100h to 21FFh is reserved to PIDs for AVR Tools. +//! @{ +#define USB_PID_ATMEL_XPLAINED 0x2122 +#define USB_PID_ATMEL_XMEGA_USB_ZIGBIT_2_4GHZ 0x214A +#define USB_PID_ATMEL_XMEGA_USB_ZIGBIT_SUBGHZ 0x214B +//! @} + +//! \name The range 2300h to 23FFh is reserved to PIDs for demo from ASF1.7=> +//! @{ +#define USB_PID_ATMEL_UC3_ENUM 0x2300 +#define USB_PID_ATMEL_UC3_MS 0x2301 +#define USB_PID_ATMEL_UC3_MS_SDRAM_LOADER 0x2302 +#define USB_PID_ATMEL_UC3_EVK1100_CTRLPANEL 0x2303 +#define USB_PID_ATMEL_UC3_HID 0x2304 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID 0x2305 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID_MS 0x2306 +#define USB_PID_ATMEL_UC3_CDC 0x2307 +#define USB_PID_ATMEL_UC3_AUDIO_MICRO 0x2308 +#define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310 // Virtual Com (debug interface) on EVK11xx +#define USB_PID_ATMEL_UC3_AUDIO_SPEAKER_MICRO 0x2311 +#define USB_PID_ATMEL_UC3_CDC_MSC 0x2312 +//! @} + +//! \name The range 2400h to 24FFh is reserved to PIDs for ASF applications +//! @{ +#define USB_PID_ATMEL_ASF_HIDMOUSE 0x2400 +#define USB_PID_ATMEL_ASF_HIDKEYBOARD 0x2401 +#define USB_PID_ATMEL_ASF_HIDGENERIC 0x2402 +#define USB_PID_ATMEL_ASF_MSC 0x2403 +#define USB_PID_ATMEL_ASF_CDC 0x2404 +#define USB_PID_ATMEL_ASF_PHDC 0x2405 +#define USB_PID_ATMEL_ASF_MSC_HIDMOUSE 0x2420 +#define USB_PID_ATMEL_ASF_MSC_HIDS_CDC 0x2421 +#define USB_PID_ATMEL_ASF_MSC_HIDKEYBOARD 0x2422 +#define USB_PID_ATMEL_ASF_VENDOR_CLASS 0x2423 +#define USB_PID_ATMEL_ASF_MSC_CDC 0x2424 +#define USB_PID_ATMEL_ASF_TWO_CDC 0x2425 +#define USB_PID_ATMEL_ASF_SEVEN_CDC 0x2426 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_POWERONLY 0x2430 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TERMINAL 0x2431 +#define USB_PID_ATMEL_ASF_XPLAIN_BC_TOUCH 0x2432 +#define USB_PID_ATMEL_ASF_AUDIO_SPEAKER 0x2433 +#define USB_PID_ATMEL_ASF_XMEGA_B1_XPLAINED 0x2434 +//! @} + +//! \name The range 2F00h to 2FFFh is reserved to official PIDs for AVR bootloaders +//! Note, !!!! don't use this range for demos or examples !!!! +//! @{ +#define USB_PID_ATMEL_DFU_ATXMEGA64C3 0x2FD6 +#define USB_PID_ATMEL_DFU_ATXMEGA128C3 0x2FD7 +#define USB_PID_ATMEL_DFU_ATXMEGA16C4 0x2FD8 +#define USB_PID_ATMEL_DFU_ATXMEGA32C4 0x2FD9 +#define USB_PID_ATMEL_DFU_ATXMEGA256C3 0x2FDA +#define USB_PID_ATMEL_DFU_ATXMEGA384C3 0x2FDB +#define USB_PID_ATMEL_DFU_ATUCL3_L4 0x2FDC +#define USB_PID_ATMEL_DFU_ATXMEGA64A4U 0x2FDD +#define USB_PID_ATMEL_DFU_ATXMEGA128A4U 0x2FDE + +#define USB_PID_ATMEL_DFU_ATXMEGA64B3 0x2FDF +#define USB_PID_ATMEL_DFU_ATXMEGA128B3 0x2FE0 +#define USB_PID_ATMEL_DFU_ATXMEGA64B1 0x2FE1 +#define USB_PID_ATMEL_DFU_ATXMEGA256A3BU 0x2FE2 +#define USB_PID_ATMEL_DFU_ATXMEGA16A4U 0x2FE3 +#define USB_PID_ATMEL_DFU_ATXMEGA32A4U 0x2FE4 +#define USB_PID_ATMEL_DFU_ATXMEGA64A3U 0x2FE5 +#define USB_PID_ATMEL_DFU_ATXMEGA128A3U 0x2FE6 +#define USB_PID_ATMEL_DFU_ATXMEGA192A3U 0x2FE7 +#define USB_PID_ATMEL_DFU_ATXMEGA64A1U 0x2FE8 +#define USB_PID_ATMEL_DFU_ATUC3D 0x2FE9 +#define USB_PID_ATMEL_DFU_ATXMEGA128B1 0x2FEA +#define USB_PID_ATMEL_DFU_AT32UC3C 0x2FEB +#define USB_PID_ATMEL_DFU_ATXMEGA256A3U 0x2FEC +#define USB_PID_ATMEL_DFU_ATXMEGA128A1U 0x2FED +#define USB_PID_ATMEL_DFU_ATMEGA8U2 0x2FEE +#define USB_PID_ATMEL_DFU_ATMEGA16U2 0x2FEF +#define USB_PID_ATMEL_DFU_ATMEGA32U2 0x2FF0 +#define USB_PID_ATMEL_DFU_AT32UC3A3 0x2FF1 +#define USB_PID_ATMEL_DFU_ATMEGA32U6 0x2FF2 +#define USB_PID_ATMEL_DFU_ATMEGA16U4 0x2FF3 +#define USB_PID_ATMEL_DFU_ATMEGA32U4 0x2FF4 +#define USB_PID_ATMEL_DFU_AT32AP7200 0x2FF5 +#define USB_PID_ATMEL_DFU_AT32UC3B 0x2FF6 +#define USB_PID_ATMEL_DFU_AT90USB82 0x2FF7 +#define USB_PID_ATMEL_DFU_AT32UC3A 0x2FF8 +#define USB_PID_ATMEL_DFU_AT90USB64 0x2FF9 +#define USB_PID_ATMEL_DFU_AT90USB162 0x2FFA +#define USB_PID_ATMEL_DFU_AT90USB128 0x2FFB +// 2FFCh to 2FFFh used by C51 family products +//! @} + +//! @} + +//! @} + + +#endif // _USB_ATMEL_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/usb_atmel.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/usb_atmel.h.REMOVED.git-id deleted file mode 100644 index c48c06d6..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/usb_atmel.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -049459cc1040ae3651b953c3cf070c0a3cea6224 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/usb_protocol.h b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/usb_protocol.h new file mode 100644 index 00000000..0b532938 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/usb_protocol.h @@ -0,0 +1,505 @@ +/** + * \file + * + * \brief USB protocol definitions. + * + * This file contains the USB definitions and data structures provided by the + * USB 2.0 specification. + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _USB_PROTOCOL_H_ +#define _USB_PROTOCOL_H_ + +#include "usb_atmel.h" + +/** + * \ingroup usb_group + * \defgroup usb_protocol_group USB Protocol Definitions + * + * This module defines constants and data structures provided by the USB + * 2.0 specification. + * + * @{ + */ + +//! Value for field bcdUSB +#define USB_V2_0 0x0200 //!< USB Specification version 2.00 +#define USB_V2_1 0x0201 //!< USB Specification version 2.01 + +/*! \name Generic definitions (Class, subclass and protocol) + */ +//! @{ +#define NO_CLASS 0x00 +#define CLASS_VENDOR_SPECIFIC 0xFF +#define NO_SUBCLASS 0x00 +#define NO_PROTOCOL 0x00 +//! @} + +//! \name IAD (Interface Association Descriptor) constants +//! @{ +#define CLASS_IAD 0xEF +#define SUB_CLASS_IAD 0x02 +#define PROTOCOL_IAD 0x01 +//! @} + +/** + * \brief USB request data transfer direction (bmRequestType) + */ +#define USB_REQ_DIR_OUT (0<<7) //!< Host to device +#define USB_REQ_DIR_IN (1<<7) //!< Device to host +#define USB_REQ_DIR_MASK (1<<7) //!< Mask + +/** + * \brief USB request types (bmRequestType) + */ +#define USB_REQ_TYPE_STANDARD (0<<5) //!< Standard request +#define USB_REQ_TYPE_CLASS (1<<5) //!< Class-specific request +#define USB_REQ_TYPE_VENDOR (2<<5) //!< Vendor-specific request +#define USB_REQ_TYPE_MASK (3<<5) //!< Mask + +/** + * \brief USB recipient codes (bmRequestType) + */ +#define USB_REQ_RECIP_DEVICE (0<<0) //!< Recipient device +#define USB_REQ_RECIP_INTERFACE (1<<0) //!< Recipient interface +#define USB_REQ_RECIP_ENDPOINT (2<<0) //!< Recipient endpoint +#define USB_REQ_RECIP_OTHER (3<<0) //!< Recipient other +#define USB_REQ_RECIP_MASK (0x1F) //!< Mask + +/** + * \brief Standard USB requests (bRequest) + */ +enum usb_reqid { + USB_REQ_GET_STATUS = 0, + USB_REQ_CLEAR_FEATURE = 1, + USB_REQ_SET_FEATURE = 3, + USB_REQ_SET_ADDRESS = 5, + USB_REQ_GET_DESCRIPTOR = 6, + USB_REQ_SET_DESCRIPTOR = 7, + USB_REQ_GET_CONFIGURATION = 8, + USB_REQ_SET_CONFIGURATION = 9, + USB_REQ_GET_INTERFACE = 10, + USB_REQ_SET_INTERFACE = 11, + USB_REQ_SYNCH_FRAME = 12, +}; + +/** + * \brief Standard USB device status flags + * + */ +enum usb_device_status { + USB_DEV_STATUS_BUS_POWERED = 0, + USB_DEV_STATUS_SELF_POWERED = 1, + USB_DEV_STATUS_REMOTEWAKEUP = 2 +}; + +/** + * \brief Standard USB Interface status flags + * + */ +enum usb_interface_status { + USB_IFACE_STATUS_RESERVED = 0 +}; + +/** + * \brief Standard USB endpoint status flags + * + */ +enum usb_endpoint_status { + USB_EP_STATUS_HALTED = 1, +}; + +/** + * \brief Standard USB device feature flags + * + * \note valid for SetFeature request. + */ +enum usb_device_feature { + USB_DEV_FEATURE_REMOTE_WAKEUP = 1, //!< Remote wakeup enabled + USB_DEV_FEATURE_TEST_MODE = 2, //!< USB test mode + USB_DEV_FEATURE_OTG_B_HNP_ENABLE = 3, + USB_DEV_FEATURE_OTG_A_HNP_SUPPORT = 4, + USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5 +}; + +/** + * \brief Test Mode possible on HS USB device + * + * \note valid for USB_DEV_FEATURE_TEST_MODE request. + */ +enum usb_device_hs_test_mode { + USB_DEV_TEST_MODE_J = 1, + USB_DEV_TEST_MODE_K = 2, + USB_DEV_TEST_MODE_SE0_NAK = 3, + USB_DEV_TEST_MODE_PACKET = 4, + USB_DEV_TEST_MODE_FORCE_ENABLE = 5, +}; + +/** + * \brief Standard USB endpoint feature/status flags + */ +enum usb_endpoint_feature { + USB_EP_FEATURE_HALT = 0, +}; + +/** + * \brief Standard USB Test Mode Selectors + */ +enum usb_test_mode_selector { + USB_TEST_J = 0x01, + USB_TEST_K = 0x02, + USB_TEST_SE0_NAK = 0x03, + USB_TEST_PACKET = 0x04, + USB_TEST_FORCE_ENABLE = 0x05, +}; + +/** + * \brief Standard USB descriptor types + */ +enum usb_descriptor_type { + USB_DT_DEVICE = 1, + USB_DT_CONFIGURATION = 2, + USB_DT_STRING = 3, + USB_DT_INTERFACE = 4, + USB_DT_ENDPOINT = 5, + USB_DT_DEVICE_QUALIFIER = 6, + USB_DT_OTHER_SPEED_CONFIGURATION = 7, + USB_DT_INTERFACE_POWER = 8, + USB_DT_OTG = 9, + USB_DT_IAD = 0x0B, + USB_DT_BOS = 0x0F, + USB_DT_DEVICE_CAPABILITY = 0x10, +}; + +/** + * \brief USB Device Capability types + */ +enum usb_capability_type { + USB_DC_USB20_EXTENSION = 0x02, +}; + +/** + * \brief USB Device Capability - USB 2.0 Extension + * To fill bmAttributes field of usb_capa_ext_desc_t structure. + */ +enum usb_capability_extension_attr { + USB_DC_EXT_LPM = 0x00000002, + USB_DC_EXT_BESL = 0x00000004, + USB_DC_EXT_BESL_BASELINE_VALID = 0x00000008, + USB_DC_EXT_BESL_DEEP_VALID = 0x00000010, +}; +#define USB_DC_EXT_BESL_DEEP_OFFSET 8 +#define USB_DC_EXT_BESL_DEEP(besl) ((besl & 0xF) << USB_DC_EXT_BESL_DEEP_OFFSET) +#define USB_DC_EXT_BESL_BASELINE_OFFSET 12 +#define USB_DC_EXT_BESL_BASELINE(besl) ((besl & 0xF) << USB_DC_EXT_BESL_BASELINE_OFFSET) + +#define BESL_125_US 0 +#define BESL_150_US 1 +#define BESL_200_US 2 +#define BESL_300_US 3 +#define BESL_400_US 4 +#define BESL_500_US 5 +#define BESL_1000_US 6 +#define BESL_2000_US 7 +#define BESL_3000_US 8 +#define BESL_4000_US 9 +#define BESL_5000_US 10 +#define BESL_6000_US 11 +#define BESL_7000_US 12 +#define BESL_8000_US 13 +#define BESL_9000_US 14 +#define BESL_10000_US 15 + +/** Fields definition from a LPM TOKEN */ +#define USB_LPM_ATTRIBUT_BLINKSTATE_MASK (0xF << 0) +#define USB_LPM_ATTRIBUT_BESL_MASK (0xF << 4) +#define USB_LPM_ATTRIBUT_REMOTEWAKE_MASK (1 << 8) +#define USB_LPM_ATTRIBUT_BLINKSTATE(value) ((value & 0xF) << 0) +#define USB_LPM_ATTRIBUT_BESL(value) ((value & 0xF) << 4) +#define USB_LPM_ATTRIBUT_REMOTEWAKE(value) ((value & 1) << 8) +#define USB_LPM_ATTRIBUT_BLINKSTATE_L1 USB_LPM_ATTRIBUT_BLINKSTATE(1) + +/** + * \brief Standard USB endpoint transfer types + */ +enum usb_ep_type { + USB_EP_TYPE_CONTROL = 0x00, + USB_EP_TYPE_ISOCHRONOUS = 0x01, + USB_EP_TYPE_BULK = 0x02, + USB_EP_TYPE_INTERRUPT = 0x03, + USB_EP_TYPE_MASK = 0x03, +}; + +/** + * \brief Standard USB language IDs for string descriptors + */ +enum usb_langid { + USB_LANGID_EN_US = 0x0409, //!< English (United States) +}; + +/** + * \brief Mask selecting the index part of an endpoint address + */ +#define USB_EP_ADDR_MASK 0x0f + +//! \brief USB address identifier +typedef uint8_t usb_add_t; + +/** + * \brief Endpoint transfer direction is IN + */ +#define USB_EP_DIR_IN 0x80 + +/** + * \brief Endpoint transfer direction is OUT + */ +#define USB_EP_DIR_OUT 0x00 + +//! \brief Endpoint identifier +typedef uint8_t usb_ep_t; + +/** + * \brief Maximum length in bytes of a USB descriptor + * + * The maximum length of a USB descriptor is limited by the 8-bit + * bLength field. + */ +#define USB_MAX_DESC_LEN 255 + +/* + * 2-byte alignment requested for all USB structures. + */ +COMPILER_PACK_SET(1) + +/** + * \brief A USB Device SETUP request + * + * The data payload of SETUP packets always follows this structure. + */ +typedef struct { + uint8_t bmRequestType; + uint8_t bRequest; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_setup_req_t; + +/** + * \brief Standard USB device descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + le16_t idVendor; + le16_t idProduct; + le16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} usb_dev_desc_t; + +/** + * \brief Standard USB device qualifier descriptor structure + * + * This descriptor contains information about the device when running at + * the "other" speed (i.e. if the device is currently operating at high + * speed, this descriptor can be used to determine what would change if + * the device was operating at full speed.) + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} usb_dev_qual_desc_t; + +/** + * \brief USB Device BOS descriptor structure + * + * The BOS descriptor (Binary device Object Store) defines a root + * descriptor that is similar to the configuration descriptor, and is + * the base descriptor for accessing a family of related descriptors. + * A host can read a BOS descriptor and learn from the wTotalLength field + * the entire size of the device-level descriptor set, or it can read in + * the entire BOS descriptor set of device capabilities. + * The host accesses this descriptor using the GetDescriptor() request. + * The descriptor type in the GetDescriptor() request is set to BOS. + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t wTotalLength; + uint8_t bNumDeviceCaps; +} usb_dev_bos_desc_t; + + +/** + * \brief USB Device Capabilities - USB 2.0 Extension Descriptor structure + * + * Defines the set of USB 1.1-specific device level capabilities. + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; + le32_t bmAttributes; +} usb_dev_capa_ext_desc_t; + +/** + * \brief USB Device LPM Descriptor structure + * + * The BOS descriptor and capabilities descriptors for LPM. + */ +typedef struct { + usb_dev_bos_desc_t bos; + usb_dev_capa_ext_desc_t capa_ext; +} usb_dev_lpm_desc_t; + +/** + * \brief Standard USB Interface Association Descriptor structure + */ +typedef struct { + uint8_t bLength; //!< size of this descriptor in bytes + uint8_t bDescriptorType; //!< INTERFACE descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_association_desc_t; + + +/** + * \brief Standard USB configuration descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} usb_conf_desc_t; + + +#define USB_CONFIG_ATTR_MUST_SET (1 << 7) //!< Must always be set +#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) //!< Bus-powered +#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) //!< Self-powered +#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported + +#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA + +/** + * \brief Standard USB association descriptor structure + */ +typedef struct { + uint8_t bLength; //!< Size of this descriptor in bytes + uint8_t bDescriptorType; //!< Interface descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_iad_desc_t; + +/** + * \brief Standard USB interface descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} usb_iface_desc_t; + +/** + * \brief Standard USB endpoint descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + le16_t wMaxPacketSize; + uint8_t bInterval; +} usb_ep_desc_t; + + +/** + * \brief A standard USB string descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; +} usb_str_desc_t; + +typedef struct { + usb_str_desc_t desc; + le16_t string[1]; +} usb_str_lgid_desc_t; + +COMPILER_PACK_RESET() + +//! @} + +#endif /* _USB_PROTOCOL_H_ */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/usb_protocol.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/usb_protocol.h.REMOVED.git-id deleted file mode 100644 index cb7e03ae..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/services/usb/usb_protocol.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0b532938d869768db918ec20ab880c0db3a2335b \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/utils/interrupt.h b/AVR Code/USB_BULK_TEST/src/ASF/common/utils/interrupt.h new file mode 100644 index 00000000..80401572 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/utils/interrupt.h @@ -0,0 +1,142 @@ +/** + * \file + * + * \brief Global interrupt management for 8- and 32-bit AVR + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef UTILS_INTERRUPT_H +#define UTILS_INTERRUPT_H + +#include + +#if XMEGA || MEGA || TINY +# include "interrupt/interrupt_avr8.h" +#elif UC3 +# include "interrupt/interrupt_avr32.h" +#elif SAM +# include "interrupt/interrupt_sam_nvic.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup interrupt_group Global interrupt management + * + * This is a driver for global enabling and disabling of interrupts. + * + * @{ + */ + +#if defined(__DOXYGEN__) +/** + * \def CONFIG_INTERRUPT_FORCE_INTC + * \brief Force usage of the ASF INTC driver + * + * Predefine this symbol when preprocessing to force the use of the ASF INTC driver. + * This is useful to ensure compatibility across compilers and shall be used only when required + * by the application needs. + */ +# define CONFIG_INTERRUPT_FORCE_INTC +#endif + +//! \name Global interrupt flags +//@{ +/** + * \typedef irqflags_t + * \brief Type used for holding state of interrupt flag + */ + +/** + * \def cpu_irq_enable + * \brief Enable interrupts globally + */ + +/** + * \def cpu_irq_disable + * \brief Disable interrupts globally + */ + +/** + * \fn irqflags_t cpu_irq_save(void) + * \brief Get and clear the global interrupt flags + * + * Use in conjunction with \ref cpu_irq_restore. + * + * \return Current state of interrupt flags. + * + * \note This function leaves interrupts disabled. + */ + +/** + * \fn void cpu_irq_restore(irqflags_t flags) + * \brief Restore global interrupt flags + * + * Use in conjunction with \ref cpu_irq_save. + * + * \param flags State to set interrupt flag to. + */ + +/** + * \fn bool cpu_irq_is_enabled_flags(irqflags_t flags) + * \brief Check if interrupts are globally enabled in supplied flags + * + * \param flags Currents state of interrupt flags. + * + * \return True if interrupts are enabled. + */ + +/** + * \def cpu_irq_is_enabled + * \brief Check if interrupts are globally enabled + * + * \return True if interrupts are enabled. + */ +//@} + +//! @} + +/** + * \ingroup interrupt_group + * \defgroup interrupt_deprecated_group Deprecated interrupt definitions + */ + +#endif /* UTILS_INTERRUPT_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/utils/interrupt.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/utils/interrupt.h.REMOVED.git-id deleted file mode 100644 index f5ac3ef7..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/utils/interrupt.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8040157237414e1f5865d2c638c7d15ef621dd5f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/utils/interrupt/interrupt_avr8.h b/AVR Code/USB_BULK_TEST/src/ASF/common/utils/interrupt/interrupt_avr8.h new file mode 100644 index 00000000..1c55fb29 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/utils/interrupt/interrupt_avr8.h @@ -0,0 +1,148 @@ +/** + * \file + * + * \brief Global interrupt management for 8-bit AVR + * + * Copyright (C) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef UTILS_INTERRUPT_INTERRUPT_H +#define UTILS_INTERRUPT_INTERRUPT_H + +#include +#include + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +#ifdef ISR_CUSTOM_H +# include ISR_CUSTOM_H +#else + +/** + * \def ISR + * \brief Define service routine for specified interrupt vector + * + * Usage: + * \code + ISR(FOO_vect) + { + ... + } +\endcode + * + * \param vect Interrupt vector name as found in the device header files. + */ +#if defined(__DOXYGEN__) +# define ISR(vect) +#elif defined(__GNUC__) +# include +#elif defined(__ICCAVR__) +# define __ISR(x) _Pragma(#x) +# define ISR(vect) __ISR(vector=vect) __interrupt void handler_##vect(void) +#endif +#endif // ISR_CUSTOM_H + +#if XMEGA +/** + * \brief Initialize interrupt vectors + * Enables all interrupt levels, with vectors located in the application section + * and fixed priority scheduling. + */ +#define irq_initialize_vectors() \ + PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm; +#elif MEGA_RF +#define irq_initialize_vectors() +#endif + +#ifdef __GNUC__ +# define cpu_irq_enable() sei() +# define cpu_irq_disable() cli() +#else +# define cpu_irq_enable() __enable_interrupt() +# define cpu_irq_disable() __disable_interrupt() +#endif + +typedef uint8_t irqflags_t; + +static inline irqflags_t cpu_irq_save(void) +{ + irqflags_t flags = SREG; + cpu_irq_disable(); + return flags; +} + +static inline void cpu_irq_restore(irqflags_t flags) +{ + barrier(); + SREG = flags; +} + +static inline bool cpu_irq_is_enabled_flags(irqflags_t flags) +{ +#if XMEGA +# ifdef __GNUC__ + return flags & CPU_I_bm; +# else + return flags & I_bm; +# endif +#elif MEGA || TINY + return flags & (1 << SREG_I); +#endif +} + +#define cpu_irq_is_enabled() cpu_irq_is_enabled_flags(SREG) + +//! @} + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ +// Deprecated definitions. +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() +//! @} + +#endif /* UTILS_INTERRUPT_INTERRUPT_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/utils/interrupt/interrupt_avr8.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/utils/interrupt/interrupt_avr8.h.REMOVED.git-id deleted file mode 100644 index e5d6c122..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/utils/interrupt/interrupt_avr8.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1c55fb290d29fa6f8a5a8dd0ace44842db9ab27b \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/utils/make/Makefile.avr.in b/AVR Code/USB_BULK_TEST/src/ASF/common/utils/make/Makefile.avr.in new file mode 100644 index 00000000..5d9a8375 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/utils/make/Makefile.avr.in @@ -0,0 +1,483 @@ +# List of available make goals: +# +# all Default target, builds the project +# clean Clean up the project +# rebuild Rebuild the project +# +# doc Build the documentation +# cleandoc Clean up the documentation +# rebuilddoc Rebuild the documentation +# +# +# Copyright (c) 2009 - 2013 Atmel Corporation. All rights reserved. +# +# \asf_license_start +# +# \page License +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. The name of Atmel may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# 4. This software may only be redistributed and used in connection with an +# Atmel microcontroller product. +# +# THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE +# EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# \asf_license_stop +# + +# Include the config.mk file from the current working path, e.g., where the +# user called make. +include config.mk + +# Tool to use to generate documentation from the source code +DOCGEN ?= doxygen + +# Look for source files relative to the top-level source directory +VPATH := $(PRJ_PATH) + +# Output target file +target := $(TARGET) + +# Output project name (target name minus suffix) +project := $(basename $(target)) + +# Output target file (typically ELF or static library) +ifeq ($(suffix $(target)),.a) +target_type := lib +else +ifeq ($(suffix $(target)),.elf) +target_type := elf +else +$(error "Target type $(target_type) is not supported") +endif +endif + +# Allow override of operating system detection. The user can add OS=Linux or +# OS=Windows on the command line to explicit set the host OS. +# +# This allows to work around broken uname utility on certain systems. +ifdef OS + ifeq ($(strip $(OS)), Linux) + os_type := Linux + endif + ifeq ($(strip $(OS)), Windows) + os_type := windows32_64 + endif +endif + +os_type ?= $(strip $(shell uname)) + +ifeq ($(os_type),windows32) +os := Windows +else +ifeq ($(os_type),windows64) +os := Windows +else +ifeq ($(os_type),windows32_64) +os ?= Windows +else +ifeq ($(os_type),) +os := Windows +else +# Default to Linux style operating system. Both Cygwin and mingw are fully +# compatible (for this Makefile) with Linux. +os := Linux +endif +endif +endif +endif + +# Output documentation directory and configuration file. +docdir := ../doxygen/html +doccfg := ../doxygen/doxyfile.doxygen + +CROSS ?= avr- +AR := $(CROSS)ar +AS := $(CROSS)as +CC := $(CROSS)gcc +CPP := $(CROSS)gcc -E +CXX := $(CROSS)g++ +LD := $(CROSS)gcc +NM := $(CROSS)nm +OBJCOPY := $(CROSS)objcopy +OBJDUMP := $(CROSS)objdump +SIZE := $(CROSS)size + +RM := rm +ifeq ($(os),Windows) +RMDIR := rmdir /S /Q +else +RMDIR := rmdir -p --ignore-fail-on-non-empty +endif + +# On Windows, we need to override the shell to force the use of cmd.exe +ifeq ($(os),Windows) +SHELL := cmd +endif + +# Strings for beautifying output +MSG_CLEAN_FILES = "RM *.o *.d" +MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))" +MSG_CLEAN_DOC = "RMDIR $(docdir)" +MSG_MKDIR = "MKDIR $(dir $@)" + +MSG_INFO = "INFO " +MSG_PREBUILD = "PREBUILD $(PREBUILD_CMD)" +MSG_POSTBUILD = "POSTBUILD $(POSTBUILD_CMD)" + +MSG_ARCHIVING = "AR $@" +MSG_ASSEMBLING = "AS $@" +MSG_BINARY_IMAGE = "OBJCOPY $@" +MSG_COMPILING = "CC $@" +MSG_COMPILING_CXX = "CXX $@" +MSG_EEPROM_IMAGE = "OBJCOPY $@" +MSG_EXTENDED_LISTING = "OBJDUMP $@" +MSG_IHEX_IMAGE = "OBJCOPY $@" +MSG_LINKING = "LN $@" +MSG_PREPROCESSING = "CPP $@" +MSG_SIZE = "SIZE $@" +MSG_SYMBOL_TABLE = "NM $@" + +MSG_GENERATING_DOC = "DOXYGEN $(docdir)" + +# Don't use make's built-in rules and variables +MAKEFLAGS += -rR + +# Don't print 'Entering directory ...' +MAKEFLAGS += --no-print-directory + +# Function for reversing the order of a list +reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1)) + +# Hide command output by default, but allow the user to override this +# by adding V=1 on the command line. +# +# This is inspired by the Kbuild system used by the Linux kernel. +ifdef V + ifeq ("$(origin V)", "command line") + VERBOSE = $(V) + endif +endif +ifndef VERBOSE + VERBOSE = 0 +endif + +ifeq ($(VERBOSE), 1) + Q = +else + Q = @ +endif + +arflags-gnu-y := $(ARFLAGS) +asflags-gnu-y := $(ASFLAGS) +cflags-gnu-y := $(CFLAGS) +cxxflags-gnu-y := $(CXXFLAGS) +cppflags-gnu-y := $(CPPFLAGS) +cpuflags-gnu-y := +dbgflags-gnu-y := $(DBGFLAGS) +libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB)) +ldflags-gnu-y := $(LDFLAGS) +flashflags-gnu-y := $(FLASHFLAGS) +eepromflags-gnu-y := $(EEPROMFLAGS) +clean-files := +clean-dirs := + +clean-files += $(wildcard $(target) $(project).map) +clean-files += $(wildcard $(project).hex $(project).eep) +clean-files += $(wildcard $(project).lss $(project).sym) +clean-files += $(wildcard $(build)) + +# Use pipes instead of temporary files for communication between processes +cflags-gnu-y += -pipe +asflags-gnu-y += -pipe +ldflags-gnu-y += -pipe + +# Archiver flags. +arflags-gnu-y += rcs + +# Always enable warnings. And be very careful about implicit +# declarations. +cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes +cflags-gnu-y += -Werror-implicit-function-declaration +cxxflags-gnu-y += -Wall +# IAR doesn't allow arithmetic on void pointers, so warn about that. +cflags-gnu-y += -Wpointer-arith +cxxflags-gnu-y += -Wpointer-arith + +# Preprocessor flags. +cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC)) +asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)') + +# CPU specific flags. +cpuflags-gnu-y += -mmcu=$(MCU) + +# Dependency file flags. +depflags = -MD -MP -MQ $@ + +# Debug specific flags. +ifdef BUILD_DEBUG_LEVEL +dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL) +else +dbgflags-gnu-y += -gdwarf-2 +endif + +# Optimization specific flags. +ifdef BUILD_OPTIMIZATION +optflags-gnu-y = -O$(BUILD_OPTIMIZATION) +else +optflags-gnu-y = $(OPTIMIZATION) +endif + +# Relax compilation and linking. +cflags-gnu-y += -mrelax +cxxflags-gnu-y += -mrelax +asflags-gnu-y += -mrelax +ldflags-gnu-y += -Wl,--relax + +# Always preprocess assembler files. +asflags-gnu-y += -x assembler-with-cpp +# Compile C files using the GNU99 standard. +cflags-gnu-y += -std=gnu99 +# Compile C++ files using the GNU++98 standard. +cxxflags-gnu-y += -std=gnu++98 + +# Use unsigned character type when compiling. +cflags-gnu-y += -funsigned-char +cxxflags-gnu-y += -funsigned-char + +# Don't use strict aliasing (very common in embedded applications). +cflags-gnu-y += -fno-strict-aliasing +cxxflags-gnu-y += -fno-strict-aliasing + +# Separate each function and data into its own separate section to allow +# garbage collection of unused sections. +cflags-gnu-y += -ffunction-sections -fdata-sections +cxxflags-gnu-y += -ffunction-sections -fdata-sections + +# Garbage collect unreferred sections when linking. +ldflags-gnu-y += -Wl,--gc-sections + +# Output a link map file and a cross reference table +ldflags-gnu-y += -Wl,-Map=$(project).map,--cref + +# Add library search paths relative to the top level directory. +ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH)) + +a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__ +c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y) +cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y) +l_flags = $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y) +ar_flags = $(arflags-gnu-y) + +# Intel Hex file production flags +flashflags-gnu-y += -R .eeprom -R .usb_descriptor_table + +# Eeprom file production flags +eepromflags-gnu-y += -j .eeprom +eepromflags-gnu-y += --set-section-flags=.eeprom="alloc,load" +eepromflags-gnu-y += --change-section-lma .eeprom=0 + +# Source files list and part informations must already be included before +# running this makefile + +# If a custom build directory is specified, use it -- force trailing / in directory name. +ifdef BUILD_DIR + build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/) +else + build-dir = +endif + +# Create object files list from source files list. +obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS)))) + +# Create dependency files list from source files list. +dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d)) + +clean-files += $(wildcard $(obj-y)) +clean-files += $(dep-files) + +clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y))))) + +# Default target. +.PHONY: all +ifeq ($(target_type),lib) +all: $(target) $(project).lss $(project).sym +else +ifeq ($(target_type),elf) +all: prebuild $(target) $(project).lss $(project).sym $(project).hex $(project).bin postbuild +endif +endif + +prebuild: +ifneq ($(strip $(PREBUILD_CMD)),) + @echo $(MSG_PREBUILD) + $(Q)$(PREBUILD_CMD) +endif + +postbuild: +ifneq ($(strip $(POSTBUILD_CMD)),) + @echo $(MSG_POSTBUILD) + $(Q)$(POSTBUILD_CMD) +endif + +# Clean up the project. +.PHONY: clean +clean: + @$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES)) + $(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),) + @$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS)) +# Remove created directories, and make sure we only remove existing +# directories, since recursive rmdir might help us a bit on the way. +ifeq ($(os),Windows) + $(Q)$(if $(strip $(clean-dirs)), \ + $(RMDIR) $(strip $(subst /,\,$(clean-dirs)))) +else + $(Q)$(if $(strip $(clean-dirs)), \ + for directory in $(strip $(clean-dirs)); do \ + if [ -d "$$directory" ]; then \ + $(RMDIR) $$directory; \ + fi \ + done \ + ) +endif + +# Rebuild the project. +.PHONY: rebuild +rebuild: clean all + +.PHONY: objfiles +objfiles: $(obj-y) + +# Create object files from C source files. +$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING) + $(Q)$(CC) $(c_flags) -c $< -o $@ + +# Create object files from C++ source files. +$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING_CXX) + $(Q)$(CXX) $(cxx_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.s $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Include all dependency files to add depedency to all header files in use. +include $(dep-files) + +ifeq ($(target_type),lib) +# Archive object files into an archive +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_ARCHIVING) + $(Q)$(AR) $(ar_flags) $@ $(obj-y) + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Bxt $@ +else +ifeq ($(target_type),elf) +# Link the object files into an ELF file. Also make sure the target is rebuilt +# if the common Makefile.avr.in or project config.mk is changed. +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_LINKING) + $(Q)$(LD) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@ + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Ax $@ + $(Q)$(SIZE) -Bx $@ +endif +endif + +# Create extended function listing from target output file. +%.lss: $(target) + @echo $(MSG_EXTENDED_LISTING) + $(Q)$(OBJDUMP) -h -S $< > $@ + +# Create symbol table from target output file. +%.sym: $(target) + @echo $(MSG_SYMBOL_TABLE) + $(Q)$(NM) -n $< > $@ + +# Create Intel HEX image from ELF output file. +%.hex: $(target) + @echo $(MSG_IHEX_IMAGE) + $(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@ + +# Create EEPROM Intel HEX image from ELF output file. +%.eep: $(target) + @echo $(MSG_EEPROM_IMAGE) + $(Q)$(OBJCOPY) $(eepromflags-gnu-y) -O ihex $< $@ || exit 0 + +# Create binary image from ELF output file. +%.bin: $(target) + @echo $(MSG_BINARY_IMAGE) + $(Q)$(OBJCOPY) -O binary $< $@ + +# Provide information about the detected host operating system. +.SECONDARY: info-os +info-os: + @echo $(MSG_INFO)$(os) build host detected + +# Build Doxygen generated documentation. +.PHONY: doc +doc: + @echo $(MSG_GENERATING_DOC) + $(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg)) + +# Clean Doxygen generated documentation. +.PHONY: cleandoc +cleandoc: + @$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC)) + $(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir)) + +# Rebuild the Doxygen generated documentation. +.PHONY: rebuilddoc +rebuilddoc: cleandoc doc diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/utils/make/Makefile.avr.in.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/utils/make/Makefile.avr.in.REMOVED.git-id deleted file mode 100644 index fd0ff90e..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/utils/make/Makefile.avr.in.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5d9a83754735b62ce6f57c15c478be32f708c33b \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/utils/parts.h b/AVR Code/USB_BULK_TEST/src/ASF/common/utils/parts.h new file mode 100644 index 00000000..b0ddbdf4 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/common/utils/parts.h @@ -0,0 +1,1292 @@ +/** + * \file + * + * \brief Atmel part identification macros + * + * Copyright (C) 2012-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef ATMEL_PARTS_H +#define ATMEL_PARTS_H + +/** + * \defgroup part_macros_group Atmel part identification macros + * + * This collection of macros identify which series and families that the various + * Atmel parts belong to. These can be used to select part-dependent sections of + * code at compile time. + * + * @{ + */ + +/** + * \name Convenience macros for part checking + * @{ + */ +/* ! Check GCC and IAR part definition for 8-bit AVR */ +#define AVR8_PART_IS_DEFINED(part) \ + (defined(__ ## part ## __) || defined(__AVR_ ## part ## __)) + +/* ! Check GCC and IAR part definition for 32-bit AVR */ +#define AVR32_PART_IS_DEFINED(part) \ + (defined(__AT32 ## part ## __) || defined(__AVR32_ ## part ## __)) + +/* ! Check GCC and IAR part definition for SAM */ +#define SAM_PART_IS_DEFINED(part) (defined(__ ## part ## __)) +/** @} */ + +/** + * \defgroup uc3_part_macros_group AVR UC3 parts + * @{ + */ + +/** + * \name AVR UC3 A series + * @{ + */ +#define UC3A0 ( \ + AVR32_PART_IS_DEFINED(UC3A0128) || \ + AVR32_PART_IS_DEFINED(UC3A0256) || \ + AVR32_PART_IS_DEFINED(UC3A0512) \ + ) + +#define UC3A1 ( \ + AVR32_PART_IS_DEFINED(UC3A1128) || \ + AVR32_PART_IS_DEFINED(UC3A1256) || \ + AVR32_PART_IS_DEFINED(UC3A1512) \ + ) + +#define UC3A3 ( \ + AVR32_PART_IS_DEFINED(UC3A364) || \ + AVR32_PART_IS_DEFINED(UC3A364S) || \ + AVR32_PART_IS_DEFINED(UC3A3128) || \ + AVR32_PART_IS_DEFINED(UC3A3128S) || \ + AVR32_PART_IS_DEFINED(UC3A3256) || \ + AVR32_PART_IS_DEFINED(UC3A3256S) \ + ) + +#define UC3A4 ( \ + AVR32_PART_IS_DEFINED(UC3A464) || \ + AVR32_PART_IS_DEFINED(UC3A464S) || \ + AVR32_PART_IS_DEFINED(UC3A4128) || \ + AVR32_PART_IS_DEFINED(UC3A4128S) || \ + AVR32_PART_IS_DEFINED(UC3A4256) || \ + AVR32_PART_IS_DEFINED(UC3A4256S) \ + ) +/** @} */ + +/** + * \name AVR UC3 B series + * @{ + */ +#define UC3B0 ( \ + AVR32_PART_IS_DEFINED(UC3B064) || \ + AVR32_PART_IS_DEFINED(UC3B0128) || \ + AVR32_PART_IS_DEFINED(UC3B0256) || \ + AVR32_PART_IS_DEFINED(UC3B0512) \ + ) + +#define UC3B1 ( \ + AVR32_PART_IS_DEFINED(UC3B164) || \ + AVR32_PART_IS_DEFINED(UC3B1128) || \ + AVR32_PART_IS_DEFINED(UC3B1256) || \ + AVR32_PART_IS_DEFINED(UC3B1512) \ + ) +/** @} */ + +/** + * \name AVR UC3 C series + * @{ + */ +#define UC3C0 ( \ + AVR32_PART_IS_DEFINED(UC3C064C) || \ + AVR32_PART_IS_DEFINED(UC3C0128C) || \ + AVR32_PART_IS_DEFINED(UC3C0256C) || \ + AVR32_PART_IS_DEFINED(UC3C0512C) \ + ) + +#define UC3C1 ( \ + AVR32_PART_IS_DEFINED(UC3C164C) || \ + AVR32_PART_IS_DEFINED(UC3C1128C) || \ + AVR32_PART_IS_DEFINED(UC3C1256C) || \ + AVR32_PART_IS_DEFINED(UC3C1512C) \ + ) + +#define UC3C2 ( \ + AVR32_PART_IS_DEFINED(UC3C264C) || \ + AVR32_PART_IS_DEFINED(UC3C2128C) || \ + AVR32_PART_IS_DEFINED(UC3C2256C) || \ + AVR32_PART_IS_DEFINED(UC3C2512C) \ + ) +/** @} */ + +/** + * \name AVR UC3 D series + * @{ + */ +#define UC3D3 ( \ + AVR32_PART_IS_DEFINED(UC64D3) || \ + AVR32_PART_IS_DEFINED(UC128D3) \ + ) + +#define UC3D4 ( \ + AVR32_PART_IS_DEFINED(UC64D4) || \ + AVR32_PART_IS_DEFINED(UC128D4) \ + ) +/** @} */ + +/** + * \name AVR UC3 L series + * @{ + */ +#define UC3L0 ( \ + AVR32_PART_IS_DEFINED(UC3L016) || \ + AVR32_PART_IS_DEFINED(UC3L032) || \ + AVR32_PART_IS_DEFINED(UC3L064) \ + ) + +#define UC3L0128 ( \ + AVR32_PART_IS_DEFINED(UC3L0128) \ + ) + +#define UC3L0256 ( \ + AVR32_PART_IS_DEFINED(UC3L0256) \ + ) + +#define UC3L3 ( \ + AVR32_PART_IS_DEFINED(UC64L3U) || \ + AVR32_PART_IS_DEFINED(UC128L3U) || \ + AVR32_PART_IS_DEFINED(UC256L3U) \ + ) + +#define UC3L4 ( \ + AVR32_PART_IS_DEFINED(UC64L4U) || \ + AVR32_PART_IS_DEFINED(UC128L4U) || \ + AVR32_PART_IS_DEFINED(UC256L4U) \ + ) + +#define UC3L3_L4 (UC3L3 || UC3L4) +/** @} */ + +/** + * \name AVR UC3 families + * @{ + */ +/** AVR UC3 A family */ +#define UC3A (UC3A0 || UC3A1 || UC3A3 || UC3A4) + +/** AVR UC3 B family */ +#define UC3B (UC3B0 || UC3B1) + +/** AVR UC3 C family */ +#define UC3C (UC3C0 || UC3C1 || UC3C2) + +/** AVR UC3 D family */ +#define UC3D (UC3D3 || UC3D4) + +/** AVR UC3 L family */ +#define UC3L (UC3L0 || UC3L0128 || UC3L0256 || UC3L3_L4) +/** @} */ + +/** AVR UC3 product line */ +#define UC3 (UC3A || UC3B || UC3C || UC3D || UC3L) + +/** @} */ + +/** + * \defgroup xmega_part_macros_group AVR XMEGA parts + * @{ + */ + +/** + * \name AVR XMEGA A series + * @{ + */ +#define XMEGA_A1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1) \ + ) + +#define XMEGA_A3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3) \ + ) + +#define XMEGA_A3B ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3B) \ + ) + +#define XMEGA_A4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA AU series + * @{ + */ +#define XMEGA_A1U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1U) \ + ) + +#define XMEGA_A3U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3U) \ + ) + +#define XMEGA_A3BU ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3BU) \ + ) + +#define XMEGA_A4U ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega64A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A4U) \ + ) +/** @} */ + +/** + * \name AVR XMEGA B series + * @{ + */ +#define XMEGA_B1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B1) || \ + AVR8_PART_IS_DEFINED(ATxmega128B1) \ + ) + +#define XMEGA_B3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B3) || \ + AVR8_PART_IS_DEFINED(ATxmega128B3) \ + ) +/** @} */ + +/** + * \name AVR XMEGA C series + * @{ + */ +#define XMEGA_C3 ( \ + AVR8_PART_IS_DEFINED(ATxmega384C3) || \ + AVR8_PART_IS_DEFINED(ATxmega256C3) || \ + AVR8_PART_IS_DEFINED(ATxmega192C3) || \ + AVR8_PART_IS_DEFINED(ATxmega128C3) || \ + AVR8_PART_IS_DEFINED(ATxmega64C3) || \ + AVR8_PART_IS_DEFINED(ATxmega32C3) \ + ) + +#define XMEGA_C4 ( \ + AVR8_PART_IS_DEFINED(ATxmega32C4) || \ + AVR8_PART_IS_DEFINED(ATxmega16C4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA D series + * @{ + */ +#define XMEGA_D3 ( \ + AVR8_PART_IS_DEFINED(ATxmega32D3) || \ + AVR8_PART_IS_DEFINED(ATxmega64D3) || \ + AVR8_PART_IS_DEFINED(ATxmega128D3) || \ + AVR8_PART_IS_DEFINED(ATxmega192D3) || \ + AVR8_PART_IS_DEFINED(ATxmega256D3) || \ + AVR8_PART_IS_DEFINED(ATxmega384D3) \ + ) + +#define XMEGA_D4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16D4) || \ + AVR8_PART_IS_DEFINED(ATxmega32D4) || \ + AVR8_PART_IS_DEFINED(ATxmega64D4) || \ + AVR8_PART_IS_DEFINED(ATxmega128D4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA E series + * @{ + */ +#define XMEGA_E5 ( \ + AVR8_PART_IS_DEFINED(ATxmega8E5) || \ + AVR8_PART_IS_DEFINED(ATxmega16E5) || \ + AVR8_PART_IS_DEFINED(ATxmega32E5) \ + ) +/** @} */ + + +/** + * \name AVR XMEGA families + * @{ + */ +/** AVR XMEGA A family */ +#define XMEGA_A (XMEGA_A1 || XMEGA_A3 || XMEGA_A3B || XMEGA_A4) + +/** AVR XMEGA AU family */ +#define XMEGA_AU (XMEGA_A1U || XMEGA_A3U || XMEGA_A3BU || XMEGA_A4U) + +/** AVR XMEGA B family */ +#define XMEGA_B (XMEGA_B1 || XMEGA_B3) + +/** AVR XMEGA C family */ +#define XMEGA_C (XMEGA_C3 || XMEGA_C4) + +/** AVR XMEGA D family */ +#define XMEGA_D (XMEGA_D3 || XMEGA_D4) + +/** AVR XMEGA E family */ +#define XMEGA_E (XMEGA_E5) +/** @} */ + + +/** AVR XMEGA product line */ +#define XMEGA (XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E) + +/** @} */ + +/** + * \defgroup mega_part_macros_group megaAVR parts + * + * \note These megaAVR groupings are based on the groups in AVR Libc for the + * part header files. They are not names of official megaAVR device series or + * families. + * + * @{ + */ + +/** + * \name ATmegaxx0/xx1 subgroups + * @{ + */ +#define MEGA_XX0 ( \ + AVR8_PART_IS_DEFINED(ATmega640) || \ + AVR8_PART_IS_DEFINED(ATmega1280) || \ + AVR8_PART_IS_DEFINED(ATmega2560) \ + ) + +#define MEGA_XX1 ( \ + AVR8_PART_IS_DEFINED(ATmega1281) || \ + AVR8_PART_IS_DEFINED(ATmega2561) \ + ) +/** @} */ + +/** + * \name megaAVR groups + * @{ + */ +/** ATmegaxx0/xx1 group */ +#define MEGA_XX0_1 (MEGA_XX0 || MEGA_XX1) + +/** ATmegaxx4 group */ +#define MEGA_XX4 ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) || \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxx4 group */ +#define MEGA_XX4_A ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) \ + ) + +/** ATmegaxx8 group */ +#define MEGA_XX8 ( \ + AVR8_PART_IS_DEFINED(ATmega48) || \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx8A/P/PA group */ +#define MEGA_XX8_A ( \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx group */ +#define MEGA_XX ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxxA/P/PA group */ +#define MEGA_XX_A ( \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) +/** ATmegaxxRFA1 group */ +#define MEGA_RFA1 ( \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxxRFR2 group */ +#define MEGA_RFR2 ( \ + AVR8_PART_IS_DEFINED(ATmega64RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega128RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega644RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega1284RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega2564RFR2) \ + ) + + +/** ATmegaxxRFxx group */ +#define MEGA_RF (MEGA_RFA1 || MEGA_RFR2) + +/** + * \name ATmegaxx_un0/un1/un2 subgroups + * @{ + */ +#define MEGA_XX_UN0 ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN1 ( \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN2 ( \ + AVR8_PART_IS_DEFINED(ATmega169P) || \ + AVR8_PART_IS_DEFINED(ATmega169PA) || \ + AVR8_PART_IS_DEFINED(ATmega329P) || \ + AVR8_PART_IS_DEFINED(ATmega329PA) \ + ) + +/** Devices added to complete megaAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define MEGA_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(AT90CAN128) || \ + AVR8_PART_IS_DEFINED(AT90CAN32) || \ + AVR8_PART_IS_DEFINED(AT90CAN64) || \ + AVR8_PART_IS_DEFINED(AT90PWM1) || \ + AVR8_PART_IS_DEFINED(AT90PWM216) || \ + AVR8_PART_IS_DEFINED(AT90PWM2B) || \ + AVR8_PART_IS_DEFINED(AT90PWM316) || \ + AVR8_PART_IS_DEFINED(AT90PWM3B) || \ + AVR8_PART_IS_DEFINED(AT90PWM81) || \ + AVR8_PART_IS_DEFINED(AT90USB1286) || \ + AVR8_PART_IS_DEFINED(AT90USB1287) || \ + AVR8_PART_IS_DEFINED(AT90USB162) || \ + AVR8_PART_IS_DEFINED(AT90USB646) || \ + AVR8_PART_IS_DEFINED(AT90USB647) || \ + AVR8_PART_IS_DEFINED(AT90USB82) || \ + AVR8_PART_IS_DEFINED(ATmega1284) || \ + AVR8_PART_IS_DEFINED(ATmega162) || \ + AVR8_PART_IS_DEFINED(ATmega164P) || \ + AVR8_PART_IS_DEFINED(ATmega165A) || \ + AVR8_PART_IS_DEFINED(ATmega165P) || \ + AVR8_PART_IS_DEFINED(ATmega165PA) || \ + AVR8_PART_IS_DEFINED(ATmega168P) || \ + AVR8_PART_IS_DEFINED(ATmega169A) || \ + AVR8_PART_IS_DEFINED(ATmega16M1) || \ + AVR8_PART_IS_DEFINED(ATmega16U2) || \ + AVR8_PART_IS_DEFINED(ATmega16U4) || \ + AVR8_PART_IS_DEFINED(ATmega256RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega324P) || \ + AVR8_PART_IS_DEFINED(ATmega325) || \ + AVR8_PART_IS_DEFINED(ATmega3250) || \ + AVR8_PART_IS_DEFINED(ATmega3250A) || \ + AVR8_PART_IS_DEFINED(ATmega3250P) || \ + AVR8_PART_IS_DEFINED(ATmega3250PA) || \ + AVR8_PART_IS_DEFINED(ATmega325A) || \ + AVR8_PART_IS_DEFINED(ATmega325P) || \ + AVR8_PART_IS_DEFINED(ATmega325PA) || \ + AVR8_PART_IS_DEFINED(ATmega329) || \ + AVR8_PART_IS_DEFINED(ATmega3290) || \ + AVR8_PART_IS_DEFINED(ATmega3290A) || \ + AVR8_PART_IS_DEFINED(ATmega3290P) || \ + AVR8_PART_IS_DEFINED(ATmega3290PA) || \ + AVR8_PART_IS_DEFINED(ATmega329A) || \ + AVR8_PART_IS_DEFINED(ATmega32M1) || \ + AVR8_PART_IS_DEFINED(ATmega32U2) || \ + AVR8_PART_IS_DEFINED(ATmega32U4) || \ + AVR8_PART_IS_DEFINED(ATmega48P) || \ + AVR8_PART_IS_DEFINED(ATmega644P) || \ + AVR8_PART_IS_DEFINED(ATmega645) || \ + AVR8_PART_IS_DEFINED(ATmega6450) || \ + AVR8_PART_IS_DEFINED(ATmega6450A) || \ + AVR8_PART_IS_DEFINED(ATmega6450P) || \ + AVR8_PART_IS_DEFINED(ATmega645A) || \ + AVR8_PART_IS_DEFINED(ATmega645P) || \ + AVR8_PART_IS_DEFINED(ATmega649) || \ + AVR8_PART_IS_DEFINED(ATmega6490) || \ + AVR8_PART_IS_DEFINED(ATmega6490A) || \ + AVR8_PART_IS_DEFINED(ATmega6490P) || \ + AVR8_PART_IS_DEFINED(ATmega649A) || \ + AVR8_PART_IS_DEFINED(ATmega649P) || \ + AVR8_PART_IS_DEFINED(ATmega64M1) || \ + AVR8_PART_IS_DEFINED(ATmega64RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega8) || \ + AVR8_PART_IS_DEFINED(ATmega8515) || \ + AVR8_PART_IS_DEFINED(ATmega8535) || \ + AVR8_PART_IS_DEFINED(ATmega88P) || \ + AVR8_PART_IS_DEFINED(ATmega8A) || \ + AVR8_PART_IS_DEFINED(ATmega8U2) \ + ) + +/** Unspecified group */ +#define MEGA_UNSPECIFIED (MEGA_XX_UN0 || MEGA_XX_UN1 || MEGA_XX_UN2 || \ + MEGA_UNCATEGORIZED) + +/** @} */ + +/** megaAVR product line */ +#define MEGA (MEGA_XX0_1 || MEGA_XX4 || MEGA_XX8 || MEGA_XX || MEGA_RF || \ + MEGA_UNSPECIFIED) + +/** @} */ + +/** + * \defgroup tiny_part_macros_group tinyAVR parts + * + * @{ + */ + +/** + * \name tinyAVR groups + * @{ + */ + +/** Devices added to complete tinyAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define TINY_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(ATtiny10) || \ + AVR8_PART_IS_DEFINED(ATtiny13) || \ + AVR8_PART_IS_DEFINED(ATtiny13A) || \ + AVR8_PART_IS_DEFINED(ATtiny1634) || \ + AVR8_PART_IS_DEFINED(ATtiny167) || \ + AVR8_PART_IS_DEFINED(ATtiny20) || \ + AVR8_PART_IS_DEFINED(ATtiny2313) || \ + AVR8_PART_IS_DEFINED(ATtiny2313A) || \ + AVR8_PART_IS_DEFINED(ATtiny24) || \ + AVR8_PART_IS_DEFINED(ATtiny24A) || \ + AVR8_PART_IS_DEFINED(ATtiny25) || \ + AVR8_PART_IS_DEFINED(ATtiny26) || \ + AVR8_PART_IS_DEFINED(ATtiny261) || \ + AVR8_PART_IS_DEFINED(ATtiny261A) || \ + AVR8_PART_IS_DEFINED(ATtiny4) || \ + AVR8_PART_IS_DEFINED(ATtiny40) || \ + AVR8_PART_IS_DEFINED(ATtiny4313) || \ + AVR8_PART_IS_DEFINED(ATtiny43U) || \ + AVR8_PART_IS_DEFINED(ATtiny44) || \ + AVR8_PART_IS_DEFINED(ATtiny44A) || \ + AVR8_PART_IS_DEFINED(ATtiny45) || \ + AVR8_PART_IS_DEFINED(ATtiny461) || \ + AVR8_PART_IS_DEFINED(ATtiny461A) || \ + AVR8_PART_IS_DEFINED(ATtiny48) || \ + AVR8_PART_IS_DEFINED(ATtiny5) || \ + AVR8_PART_IS_DEFINED(ATtiny828) || \ + AVR8_PART_IS_DEFINED(ATtiny84) || \ + AVR8_PART_IS_DEFINED(ATtiny84A) || \ + AVR8_PART_IS_DEFINED(ATtiny85) || \ + AVR8_PART_IS_DEFINED(ATtiny861) || \ + AVR8_PART_IS_DEFINED(ATtiny861A) || \ + AVR8_PART_IS_DEFINED(ATtiny87) || \ + AVR8_PART_IS_DEFINED(ATtiny88) || \ + AVR8_PART_IS_DEFINED(ATtiny9) \ + ) + +/** @} */ + +/** tinyAVR product line */ +#define TINY (TINY_UNCATEGORIZED) + +/** @} */ + +/** + * \defgroup sam_part_macros_group SAM parts + * @{ + */ + +/** + * \name SAM3S series + * @{ + */ +#define SAM3S1 ( \ + SAM_PART_IS_DEFINED(SAM3S1A) || \ + SAM_PART_IS_DEFINED(SAM3S1B) || \ + SAM_PART_IS_DEFINED(SAM3S1C) \ + ) + +#define SAM3S2 ( \ + SAM_PART_IS_DEFINED(SAM3S2A) || \ + SAM_PART_IS_DEFINED(SAM3S2B) || \ + SAM_PART_IS_DEFINED(SAM3S2C) \ + ) + +#define SAM3S4 ( \ + SAM_PART_IS_DEFINED(SAM3S4A) || \ + SAM_PART_IS_DEFINED(SAM3S4B) || \ + SAM_PART_IS_DEFINED(SAM3S4C) \ + ) + +#define SAM3S8 ( \ + SAM_PART_IS_DEFINED(SAM3S8B) || \ + SAM_PART_IS_DEFINED(SAM3S8C) \ + ) + +#define SAM3SD8 ( \ + SAM_PART_IS_DEFINED(SAM3SD8B) || \ + SAM_PART_IS_DEFINED(SAM3SD8C) \ + ) +/** @} */ + +/** + * \name SAM3U series + * @{ + */ +#define SAM3U1 ( \ + SAM_PART_IS_DEFINED(SAM3U1C) || \ + SAM_PART_IS_DEFINED(SAM3U1E) \ + ) + +#define SAM3U2 ( \ + SAM_PART_IS_DEFINED(SAM3U2C) || \ + SAM_PART_IS_DEFINED(SAM3U2E) \ + ) + +#define SAM3U4 ( \ + SAM_PART_IS_DEFINED(SAM3U4C) || \ + SAM_PART_IS_DEFINED(SAM3U4E) \ + ) +/** @} */ + +/** + * \name SAM3N series + * @{ + */ +#define SAM3N00 ( \ + SAM_PART_IS_DEFINED(SAM3N00A) || \ + SAM_PART_IS_DEFINED(SAM3N00B) \ + ) + +#define SAM3N0 ( \ + SAM_PART_IS_DEFINED(SAM3N0A) || \ + SAM_PART_IS_DEFINED(SAM3N0B) || \ + SAM_PART_IS_DEFINED(SAM3N0C) \ + ) + +#define SAM3N1 ( \ + SAM_PART_IS_DEFINED(SAM3N1A) || \ + SAM_PART_IS_DEFINED(SAM3N1B) || \ + SAM_PART_IS_DEFINED(SAM3N1C) \ + ) + +#define SAM3N2 ( \ + SAM_PART_IS_DEFINED(SAM3N2A) || \ + SAM_PART_IS_DEFINED(SAM3N2B) || \ + SAM_PART_IS_DEFINED(SAM3N2C) \ + ) + +#define SAM3N4 ( \ + SAM_PART_IS_DEFINED(SAM3N4A) || \ + SAM_PART_IS_DEFINED(SAM3N4B) || \ + SAM_PART_IS_DEFINED(SAM3N4C) \ + ) +/** @} */ + +/** + * \name SAM3X series + * @{ + */ +#define SAM3X4 ( \ + SAM_PART_IS_DEFINED(SAM3X4C) || \ + SAM_PART_IS_DEFINED(SAM3X4E) \ + ) + +#define SAM3X8 ( \ + SAM_PART_IS_DEFINED(SAM3X8C) || \ + SAM_PART_IS_DEFINED(SAM3X8E) || \ + SAM_PART_IS_DEFINED(SAM3X8H) \ + ) +/** @} */ + +/** + * \name SAM3A series + * @{ + */ +#define SAM3A4 ( \ + SAM_PART_IS_DEFINED(SAM3A4C) \ + ) + +#define SAM3A8 ( \ + SAM_PART_IS_DEFINED(SAM3A8C) \ + ) +/** @} */ + +/** + * \name SAM4S series + * @{ + */ +#define SAM4S2 ( \ + SAM_PART_IS_DEFINED(SAM4S2A) || \ + SAM_PART_IS_DEFINED(SAM4S2B) || \ + SAM_PART_IS_DEFINED(SAM4S2C) \ + ) + +#define SAM4S4 ( \ + SAM_PART_IS_DEFINED(SAM4S4A) || \ + SAM_PART_IS_DEFINED(SAM4S4B) || \ + SAM_PART_IS_DEFINED(SAM4S4C) \ + ) + +#define SAM4S8 ( \ + SAM_PART_IS_DEFINED(SAM4S8B) || \ + SAM_PART_IS_DEFINED(SAM4S8C) \ + ) + +#define SAM4S16 ( \ + SAM_PART_IS_DEFINED(SAM4S16B) || \ + SAM_PART_IS_DEFINED(SAM4S16C) \ + ) + +#define SAM4SA16 ( \ + SAM_PART_IS_DEFINED(SAM4SA16B) || \ + SAM_PART_IS_DEFINED(SAM4SA16C) \ + ) + +#define SAM4SD16 ( \ + SAM_PART_IS_DEFINED(SAM4SD16B) || \ + SAM_PART_IS_DEFINED(SAM4SD16C) \ + ) + +#define SAM4SD32 ( \ + SAM_PART_IS_DEFINED(SAM4SD32B) || \ + SAM_PART_IS_DEFINED(SAM4SD32C) \ + ) +/** @} */ + +/** + * \name SAM4L series + * @{ + */ +#define SAM4LS ( \ + SAM_PART_IS_DEFINED(SAM4LS2A) || \ + SAM_PART_IS_DEFINED(SAM4LS2B) || \ + SAM_PART_IS_DEFINED(SAM4LS2C) || \ + SAM_PART_IS_DEFINED(SAM4LS4A) || \ + SAM_PART_IS_DEFINED(SAM4LS4B) || \ + SAM_PART_IS_DEFINED(SAM4LS4C) || \ + SAM_PART_IS_DEFINED(SAM4LS8A) || \ + SAM_PART_IS_DEFINED(SAM4LS8B) || \ + SAM_PART_IS_DEFINED(SAM4LS8C) \ + ) + +#define SAM4LC ( \ + SAM_PART_IS_DEFINED(SAM4LC2A) || \ + SAM_PART_IS_DEFINED(SAM4LC2B) || \ + SAM_PART_IS_DEFINED(SAM4LC2C) || \ + SAM_PART_IS_DEFINED(SAM4LC4A) || \ + SAM_PART_IS_DEFINED(SAM4LC4B) || \ + SAM_PART_IS_DEFINED(SAM4LC4C) || \ + SAM_PART_IS_DEFINED(SAM4LC8A) || \ + SAM_PART_IS_DEFINED(SAM4LC8B) || \ + SAM_PART_IS_DEFINED(SAM4LC8C) \ + ) +/** @} */ + +/** + * \name SAMD20 series + * @{ + */ +#define SAMD20J ( \ + SAM_PART_IS_DEFINED(SAMD20J14) || \ + SAM_PART_IS_DEFINED(SAMD20J15) || \ + SAM_PART_IS_DEFINED(SAMD20J16) || \ + SAM_PART_IS_DEFINED(SAMD20J17) || \ + SAM_PART_IS_DEFINED(SAMD20J18) \ + ) + +#define SAMD20G ( \ + SAM_PART_IS_DEFINED(SAMD20G14) || \ + SAM_PART_IS_DEFINED(SAMD20G15) || \ + SAM_PART_IS_DEFINED(SAMD20G16) || \ + SAM_PART_IS_DEFINED(SAMD20G17) || \ + SAM_PART_IS_DEFINED(SAMD20G17U) || \ + SAM_PART_IS_DEFINED(SAMD20G18) || \ + SAM_PART_IS_DEFINED(SAMD20G18U) \ + ) + +#define SAMD20E ( \ + SAM_PART_IS_DEFINED(SAMD20E14) || \ + SAM_PART_IS_DEFINED(SAMD20E15) || \ + SAM_PART_IS_DEFINED(SAMD20E16) || \ + SAM_PART_IS_DEFINED(SAMD20E17) || \ + SAM_PART_IS_DEFINED(SAMD20E18) || \ + SAM_PART_IS_DEFINED(SAMD20E1F) \ + ) +/** @} */ + +/** + * \name SAMD21 series + * @{ + */ +#define SAMD21J ( \ + SAM_PART_IS_DEFINED(SAMD21J15A) || \ + SAM_PART_IS_DEFINED(SAMD21J16A) || \ + SAM_PART_IS_DEFINED(SAMD21J17A) || \ + SAM_PART_IS_DEFINED(SAMD21J18A) || \ + SAM_PART_IS_DEFINED(SAMD21J15B) || \ + SAM_PART_IS_DEFINED(SAMD21J16B) \ + ) + +#define SAMD21G ( \ + SAM_PART_IS_DEFINED(SAMD21G15A) || \ + SAM_PART_IS_DEFINED(SAMD21G16A) || \ + SAM_PART_IS_DEFINED(SAMD21G17A) || \ + SAM_PART_IS_DEFINED(SAMD21G17AU) || \ + SAM_PART_IS_DEFINED(SAMD21G18A) || \ + SAM_PART_IS_DEFINED(SAMD21G18AU) || \ + SAM_PART_IS_DEFINED(SAMD21G15B) || \ + SAM_PART_IS_DEFINED(SAMD21G16B) \ + ) + +#define SAMD21E ( \ + SAM_PART_IS_DEFINED(SAMD21E15A) || \ + SAM_PART_IS_DEFINED(SAMD21E16A) || \ + SAM_PART_IS_DEFINED(SAMD21E17A) || \ + SAM_PART_IS_DEFINED(SAMD21E18A) || \ + SAM_PART_IS_DEFINED(SAMD21E15B) || \ + SAM_PART_IS_DEFINED(SAMD21E15BU) || \ + SAM_PART_IS_DEFINED(SAMD21E16B) || \ + SAM_PART_IS_DEFINED(SAMD21E16BU) || \ + SAM_PART_IS_DEFINED(SAMD21E15L) || \ + SAM_PART_IS_DEFINED(SAMD21E16L) \ + ) +/** @} */ + +/** + * \name SAMR21 series + * @{ + */ +#define SAMR21G ( \ + SAM_PART_IS_DEFINED(SAMR21G16A) || \ + SAM_PART_IS_DEFINED(SAMR21G17A) || \ + SAM_PART_IS_DEFINED(SAMR21G18A) \ + ) + +#define SAMR21E ( \ + SAM_PART_IS_DEFINED(SAMR21E16A) || \ + SAM_PART_IS_DEFINED(SAMR21E17A) || \ + SAM_PART_IS_DEFINED(SAMR21E18A) \ + ) +/** @} */ + +/** + * \name SAMD10 series + * @{ + */ +#define SAMD10C ( \ + SAM_PART_IS_DEFINED(SAMD10C12A) || \ + SAM_PART_IS_DEFINED(SAMD10C13A) || \ + SAM_PART_IS_DEFINED(SAMD10C14A) \ + ) + +#define SAMD10DS ( \ + SAM_PART_IS_DEFINED(SAMD10D12AS) || \ + SAM_PART_IS_DEFINED(SAMD10D13AS) || \ + SAM_PART_IS_DEFINED(SAMD10D14AS) \ + ) + +#define SAMD10DM ( \ + SAM_PART_IS_DEFINED(SAMD10D12AM) || \ + SAM_PART_IS_DEFINED(SAMD10D13AM) || \ + SAM_PART_IS_DEFINED(SAMD10D14AM) \ + ) +/** @} */ + +/** + * \name SAMD11 series + * @{ + */ +#define SAMD11C ( \ + SAM_PART_IS_DEFINED(SAMD11C14A) \ + ) + +#define SAMD11DS ( \ + SAM_PART_IS_DEFINED(SAMD11D14AS) \ + ) + +#define SAMD11DM ( \ + SAM_PART_IS_DEFINED(SAMD11D14AM) \ + ) +/** @} */ + +/** + * \name SAML21 series + * @{ + */ +#define SAML21E ( \ + SAM_PART_IS_DEFINED(SAML21E15A) || \ + SAM_PART_IS_DEFINED(SAML21E16A) || \ + SAM_PART_IS_DEFINED(SAML21E17A) || \ + SAM_PART_IS_DEFINED(SAML21E18A) \ + ) + +#define SAML21G ( \ + SAM_PART_IS_DEFINED(SAML21G16A) || \ + SAM_PART_IS_DEFINED(SAML21G17A) || \ + SAM_PART_IS_DEFINED(SAML21G18A) \ + ) + +#define SAML21J ( \ + SAM_PART_IS_DEFINED(SAML21J16A) || \ + SAM_PART_IS_DEFINED(SAML21J17A) || \ + SAM_PART_IS_DEFINED(SAML21J18A) \ + ) +/** @} */ + +/** + * \name SAM4E series + * @{ + */ +#define SAM4E8 ( \ + SAM_PART_IS_DEFINED(SAM4E8C) || \ + SAM_PART_IS_DEFINED(SAM4E8E) \ + ) + +#define SAM4E16 ( \ + SAM_PART_IS_DEFINED(SAM4E16C) || \ + SAM_PART_IS_DEFINED(SAM4E16E) \ + ) +/** @} */ + +/** + * \name SAM4N series + * @{ + */ +#define SAM4N8 ( \ + SAM_PART_IS_DEFINED(SAM4N8A) || \ + SAM_PART_IS_DEFINED(SAM4N8B) || \ + SAM_PART_IS_DEFINED(SAM4N8C) \ + ) + +#define SAM4N16 ( \ + SAM_PART_IS_DEFINED(SAM4N16B) || \ + SAM_PART_IS_DEFINED(SAM4N16C) \ + ) +/** @} */ + +/** + * \name SAM4C series + * @{ + */ +#define SAM4C8_0 ( \ + SAM_PART_IS_DEFINED(SAM4C8C_0) \ + ) + +#define SAM4C8_1 ( \ + SAM_PART_IS_DEFINED(SAM4C8C_1) \ + ) + +#define SAM4C8 (SAM4C8_0 || SAM4C8_1) + +#define SAM4C16_0 ( \ + SAM_PART_IS_DEFINED(SAM4C16C_0) \ + ) + +#define SAM4C16_1 ( \ + SAM_PART_IS_DEFINED(SAM4C16C_1) \ + ) + +#define SAM4C16 (SAM4C16_0 || SAM4C16_1) + +#define SAM4C32_0 ( \ + SAM_PART_IS_DEFINED(SAM4C32C_0) ||\ + SAM_PART_IS_DEFINED(SAM4C32E_0) \ + ) + +#define SAM4C32_1 ( \ + SAM_PART_IS_DEFINED(SAM4C32C_1) ||\ + SAM_PART_IS_DEFINED(SAM4C32E_1) \ + ) + + +#define SAM4C32 (SAM4C32_0 || SAM4C32_1) + +/** @} */ + +/** + * \name SAM4CM series + * @{ + */ +#define SAM4CMP8_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMP8C_0) \ + ) + +#define SAM4CMP8_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMP8C_1) \ + ) + +#define SAM4CMP8 (SAM4CMP8_0 || SAM4CMP8_1) + +#define SAM4CMP16_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMP16C_0) \ + ) + +#define SAM4CMP16_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMP16C_1) \ + ) + +#define SAM4CMP16 (SAM4CMP16_0 || SAM4CMP16_1) + +#define SAM4CMP32_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMP32C_0) \ + ) + +#define SAM4CMP32_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMP32C_1) \ + ) + +#define SAM4CMP32 (SAM4CMP32_0 || SAM4CMP32_1) + +#define SAM4CMS8_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMS8C_0) \ + ) + +#define SAM4CMS8_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMS8C_1) \ + ) + +#define SAM4CMS8 (SAM4CMS8_0 || SAM4CMS8_1) + +#define SAM4CMS16_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMS16C_0) \ + ) + +#define SAM4CMS16_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMS16C_1) \ + ) + +#define SAM4CMS16 (SAM4CMS16_0 || SAM4CMS16_1) + +#define SAM4CMS32_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMS32C_0) \ + ) + +#define SAM4CMS32_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMS32C_1) \ + ) + +#define SAM4CMS32 (SAM4CMS32_0 || SAM4CMS32_1) + +/** @} */ + +/** + * \name SAM4CP series + * @{ + */ +#define SAM4CP16_0 ( \ + SAM_PART_IS_DEFINED(SAM4CP16B_0) \ + ) + +#define SAM4CP16_1 ( \ + SAM_PART_IS_DEFINED(SAM4CP16B_1) \ + ) + +#define SAM4CP16 (SAM4CP16_0 || SAM4CP16_1) +/** @} */ + +/** + * \name SAMG series + * @{ + */ +#define SAMG51 ( \ + SAM_PART_IS_DEFINED(SAMG51G18) \ + ) + +#define SAMG53 ( \ + SAM_PART_IS_DEFINED(SAMG53G19) ||\ + SAM_PART_IS_DEFINED(SAMG53N19) \ + ) + +#define SAMG54 ( \ + SAM_PART_IS_DEFINED(SAMG54G19) ||\ + SAM_PART_IS_DEFINED(SAMG54J19) ||\ + SAM_PART_IS_DEFINED(SAMG54N19) \ + ) + +#define SAMG55 ( \ + SAM_PART_IS_DEFINED(SAMG55G18) ||\ + SAM_PART_IS_DEFINED(SAMG55G19) ||\ + SAM_PART_IS_DEFINED(SAMG55J18) ||\ + SAM_PART_IS_DEFINED(SAMG55J19) ||\ + SAM_PART_IS_DEFINED(SAMG55N19) \ + ) +/** @} */ +/** + * \name SAM families + * @{ + */ +/** SAM3S Family */ +#define SAM3S (SAM3S1 || SAM3S2 || SAM3S4 || SAM3S8 || SAM3SD8) + +/** SAM3U Family */ +#define SAM3U (SAM3U1 || SAM3U2 || SAM3U4) + +/** SAM3N Family */ +#define SAM3N (SAM3N00 || SAM3N0 || SAM3N1 || SAM3N2 || SAM3N4) + +/** SAM3XA Family */ +#define SAM3XA (SAM3X4 || SAM3X8 || SAM3A4 || SAM3A8) + +/** SAM4S Family */ +#define SAM4S (SAM4S2 || SAM4S4 || SAM4S8 || SAM4S16 || SAM4SA16 || SAM4SD16 || SAM4SD32) + +/** SAM4L Family */ +#define SAM4L (SAM4LS || SAM4LC) + +/** SAMD20 Family */ +#define SAMD20 (SAMD20J || SAMD20G || SAMD20E) + +/** SAMD21 Family */ +#define SAMD21 (SAMD21J || SAMD21G || SAMD21E) + +/** SAMD10 Family */ +#define SAMD10 (SAMD10C || SAMD10DS || SAMD10DM) + +/** SAMD11 Family */ +#define SAMD11 (SAMD11C || SAMD11DS || SAMD11DM) + +/** SAMD Family */ +#define SAMD (SAMD20 || SAMD21 || SAMD10 || SAMD11) + +/** SAMR21 Family */ +#define SAMR21 (SAMR21G || SAMR21E) + +/** SAML21 Family */ +#define SAML21 (SAML21J || SAML21G || SAML21E) + +/** SAM4E Family */ +#define SAM4E (SAM4E8 || SAM4E16) + +/** SAM4N Family */ +#define SAM4N (SAM4N8 || SAM4N16) + +/** SAM4C Family */ +#define SAM4C_0 (SAM4C8_0 || SAM4C16_0 || SAM4C32_0) +#define SAM4C_1 (SAM4C8_1 || SAM4C16_1 || SAM4C32_1) +#define SAM4C (SAM4C8 || SAM4C16 || SAM4C32) + +/** SAM4CM Family */ +#define SAM4CM_0 (SAM4CMP8_0 || SAM4CMP16_0 || SAM4CMP32_0 || SAM4CMS8_0 || \ + SAM4CMS16_0 || SAM4CMS32_0) +#define SAM4CM_1 (SAM4CMP8_1 || SAM4CMP16_1 || SAM4CMP32_1 || SAM4CMS8_1 || \ + SAM4CMS16_1 || SAM4CMS32_1) +#define SAM4CM (SAM4CMP8 || SAM4CMP16 || SAM4CMP32 || SAM4CMS8 || \ + SAM4CMS16 || SAM4CMS32) + +/** SAM4CP Family */ +#define SAM4CP_0 (SAM4CP16_0) +#define SAM4CP_1 (SAM4CP16_1) +#define SAM4CP (SAM4CP16) + +/** SAMG Family */ +#define SAMG (SAMG51 || SAMG53 || SAMG54 || SAMG55) + +/** SAM0 product line (cortex-m0+) */ +#define SAM0 (SAMD20 || SAMD21 || SAMR21 || SAMD10 || SAMD11 || SAML21) + +/** @} */ + +/** SAM product line */ +#define SAM (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4L || SAM4E || \ + SAM0 || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG) + +/** @} */ + +/** @} */ + +/** @} */ + +#endif /* ATMEL_PARTS_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/common/utils/parts.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/common/utils/parts.h.REMOVED.git-id deleted file mode 100644 index ad358fbe..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/common/utils/parts.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b0ddbdf452609855bc00ead95bd72eff266ac6be \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/init.c b/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/init.c new file mode 100644 index 00000000..571692ee --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/init.c @@ -0,0 +1,163 @@ +/** + * \file + * + * \brief XMEGA-A3BU Xplained board init. + * + * This file contains board initialization function. + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#include +#include +#include + +/** + * \addtogroup xmega_a3bu_xplained_group + * @{ + */ + +void board_init(void) +{ + ioport_configure_pin(LED0_GPIO, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH); + ioport_configure_pin(LED1_GPIO, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH); + ioport_configure_pin(LED2_GPIO, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH); + ioport_configure_pin(LED3_GPIO, IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW + | IOPORT_INV_ENABLED); + + ioport_configure_pin(GPIO_PUSH_BUTTON_0, IOPORT_DIR_INPUT + | IOPORT_LEVEL | IOPORT_PULL_UP); + ioport_configure_pin(GPIO_PUSH_BUTTON_1, IOPORT_DIR_INPUT + | IOPORT_LEVEL | IOPORT_PULL_UP); + ioport_configure_pin(GPIO_PUSH_BUTTON_2, IOPORT_DIR_INPUT + | IOPORT_LEVEL | IOPORT_PULL_UP); + +#ifdef CONF_BOARD_C12832A1Z + ioport_configure_pin(NHD_C12832A1Z_SPI_SCK, IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(NHD_C12832A1Z_SPI_MOSI, IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(NHD_C12832A1Z_CSN, IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(NHD_C12832A1Z_REGISTER_SELECT, IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(NHD_C12832A1Z_RESETN, IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(NHD_C12832A1Z_BACKLIGHT, IOPORT_DIR_OUTPUT + | IOPORT_INIT_LOW); +#endif + +#ifdef CONF_BOARD_AT45DBX + ioport_configure_pin(AT45DBX_MASTER_SCK, IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(AT45DBX_MASTER_MOSI, IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(AT45DBX_MASTER_MISO, IOPORT_DIR_INPUT); + ioport_configure_pin(AT45DBX_CS, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH); +#endif + +#ifdef CONF_BOARD_ENABLE_MXT143E_XPLAINED + ioport_configure_pin(MXT143E_XPLAINED_SCK, IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(MXT143E_XPLAINED_MOSI, IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(MXT143E_XPLAINED_MISO, IOPORT_DIR_INPUT); + ioport_configure_pin(MXT143E_XPLAINED_CS, IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(MXT143E_XPLAINED_CHG, IOPORT_DIR_INPUT); + ioport_configure_pin(MXT143E_XPLAINED_DC, IOPORT_DIR_OUTPUT + | IOPORT_INIT_LOW); + #ifndef MXT143E_XPLAINED_BACKLIGHT_DISABLE + ioport_configure_pin(MXT143E_XPLAINED_BACKLIGHT, IOPORT_DIR_OUTPUT + | IOPORT_INIT_LOW); + #endif + ioport_configure_pin(MXT143E_XPLAINED_LCD_RESET, IOPORT_DIR_OUTPUT + | IOPORT_INIT_LOW); +#endif + +#ifdef CONF_BOARD_ENABLE_AC_PINS + ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 0), IOPORT_DIR_INPUT); + ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 2), IOPORT_DIR_INPUT); + ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 1), IOPORT_DIR_INPUT); +#endif + +#ifdef CONF_BOARD_ENABLE_USARTC0 + ioport_configure_pin(IOPORT_CREATE_PIN(PORTC, 3), IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(IOPORT_CREATE_PIN(PORTC, 2), IOPORT_DIR_INPUT); +#endif + +#ifdef CONF_BOARD_ENABLE_USARTD0 + ioport_configure_pin(IOPORT_CREATE_PIN(PORTD, 3), IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(IOPORT_CREATE_PIN(PORTD, 2), IOPORT_DIR_INPUT); +#endif + +#ifdef CONF_BOARD_ENABLE_USARTE0 + ioport_configure_pin(IOPORT_CREATE_PIN(PORTE, 3), IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(IOPORT_CREATE_PIN(PORTE, 2), IOPORT_DIR_INPUT); +#endif + +#if defined (SENSORS_XPLAINED_BOARD) + /* Configure the Xplained Sensor extension board, if any, after + * the platform Xplained board has configured basic clock settings, + * GPIO pin mapping, interrupt controller options, etc. + */ + sensor_board_init (); +#endif + +#ifdef CONF_BOARD_AT86RFX + ioport_configure_pin(AT86RFX_SPI_SCK, IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(AT86RFX_SPI_MOSI, IOPORT_DIR_OUTPUT + | IOPORT_INIT_HIGH); + ioport_configure_pin(AT86RFX_SPI_MISO, IOPORT_DIR_INPUT); + ioport_configure_pin(AT86RFX_SPI_CS, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH); + + /* Initialize TRX_RST and SLP_TR as GPIO. */ + ioport_configure_pin(AT86RFX_RST_PIN, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH); + ioport_configure_pin(AT86RFX_SLP_PIN, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH); +#endif +} + +/** + * @} + */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/init.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/init.c.REMOVED.git-id deleted file mode 100644 index beaf1c89..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/init.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -571692eecb0d2c5e207b7bbb547de6e5ea0c3d79 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/led.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/led.h new file mode 100644 index 00000000..702e895f --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/led.h @@ -0,0 +1,83 @@ +/** + * \file + * + * \brief XMEGA-A3BU board LEDs support package. + * + * This file contains definitions and services related to the LED features of + * the XMEGA-A3BU Xplained board. + * + * To use this board, define BOARD=XMEGA_A3BU_XPLAINED. + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef _LED_H_ +#define _LED_H_ + +#include "gpio.h" + +/** + * \brief Turns off the specified LEDs. + * + * \param led_gpio LED to turn off (LEDx_GPIO). + * + * \note The pins of the specified LEDs are set to GPIO output mode. + */ +#define LED_Off(led_gpio) gpio_set_pin_high(led_gpio) + +/** + * \brief Turns on the specified LEDs. + * + * \param led_gpio LED to turn on (LEDx_GPIO). + * + * \note The pins of the specified LEDs are set to GPIO output mode. + */ +#define LED_On(led_gpio) gpio_set_pin_low(led_gpio) + +/** + * \brief Toggles the specified LEDs. + * + * \param led_gpio LED to toggle (LEDx_GPIO). + * + * \note The pins of the specified LEDs are set to GPIO output mode. + */ +#define LED_Toggle(led_gpio) gpio_toggle_pin(led_gpio) + +#endif /* _LED_H_ */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/led.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/led.h.REMOVED.git-id deleted file mode 100644 index bdabf7e2..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/led.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -702e895f177e913969bfd5223c93d3ed2fbe05b7 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/xmega_a3bu_xplained.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/xmega_a3bu_xplained.h new file mode 100644 index 00000000..e8165188 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/xmega_a3bu_xplained.h @@ -0,0 +1,417 @@ +/** + * \file + * + * \brief XMEGA-A3BU-XPLAINED board header file. + * + * This file contains definitions and services related to the features of the + * XMEGA-A3BU Xplained board. + * + * To use this board define BOARD=XMEGA_A3BU_XPLAINED. + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef _XMEGA_A3BU_XPLAINED_H_ +#define _XMEGA_A3BU_XPLAINED_H_ + +#include + +#define MCU_SOC_NAME "ATxmega256A3BU" +#define BOARD_NAME "XMEGA-A3BU-XPLAINED" +/** + * \defgroup xmega_a3bu_xplained_group XMEGA-A3BU Xplained board + * @{ + */ + +/** + * \defgroup xmega_a3bu_xplained_feature_group Feature definitions + * @{ + */ + +//! \name Miscellaneous data +//@{ +//! Validate board support for the common sensor service. +#define COMMON_SENSOR_PLATFORM +//@} + +/** + * \name LEDs + * + * LED0 and LED1 are single yellow LEDs that are active low.. + * LED2 and LED3 are inside one package (Led red and green close + * to USB connector) but can be controlled individually. + * LED2 has a red color and is active low. This LED can be + * used for general purposes. + * LED3 has a green color and is active high. By default this + * LED is on since it shall indicate that power is applied to the + * board. By pulling the gate of a N-FET low it is possible to + * turn off the LED if needed. + */ +//@{ +#define LED0_GPIO IOPORT_CREATE_PIN(PORTR, 0) +#define LED1_GPIO IOPORT_CREATE_PIN(PORTR, 1) +#define LED2_GPIO IOPORT_CREATE_PIN(PORTD, 4) +#define LED3_GPIO IOPORT_CREATE_PIN(PORTD, 5) +#define LED0 LED0_GPIO +#define LED1 LED1_GPIO +#define LED2 LED2_GPIO +#define LED3 LED3_GPIO +//! Number of LEDs. +#define LED_COUNT 4 +//@} + +//! \name Push buttons +//@{ +#define GPIO_PUSH_BUTTON_0 IOPORT_CREATE_PIN(PORTE, 5) +#define GPIO_PUSH_BUTTON_1 IOPORT_CREATE_PIN(PORTF, 1) +#define GPIO_PUSH_BUTTON_2 IOPORT_CREATE_PIN(PORTF, 2) +//@} + +//! \name QTouch button +//! This button requires the software QTouch library +//@{ +#define QTOUCH_BUTTON_SNS IOPORT_CREATE_PIN(PORTF, 6) +#define QTOUCH_BUTTON_SNSK IOPORT_CREATE_PIN(PORTF, 7) +//@} + +//! \name Light sensor +//@{ +#define LIGHT_SENSOR_ADC_MODULE ADCA +#define LIGHT_SENSOR_ADC_INPUT ADCCH_POS_PIN0 +#define LIGHT_SENSOR_SIGNAL_PIN IOPORT_CREATE_PIN(PORTA, 0) +//@} + +//! \name Temperature sensor (NTC) +//@{ +#define TEMPERATURE_SENSOR_ADC_MODULE ADCA +#define TEMPERATURE_SENSOR_ADC_INPUT ADCCH_POS_PIN1 +#define TEMPERATURE_SENSOR_SIGNAL_PIN IOPORT_CREATE_PIN(PORTA, 1) +//@} + +//! \name Analog filter (lowpass RC @ 159 Hz) +//@{ +#define FILTER_INPUT_SIGNAL_PIN IOPORT_CREATE_PIN(PORTF, 0) +#define FILTER_OUTPUT_ADC_MODULE ADCA +#define FILTER_OUTPUT_ADC_INPUT ADCCH_POS_PIN2 +#define FILTER_OUTPUT_SIGNAL_PIN IOPORT_CREATE_PIN(PORTA, 2) +//@} + +//! \name LCD backlight +//@{ +#define LCD_BACKLIGHT_ENABLE_PIN IOPORT_CREATE_PIN(PORTE, 4) +#define LCD_BACKLIGHT_ENABLE_LEVEL true +//@} + +//! \name LCD controller (NHD-C12832A1Z-FSW-FBW-3V3) +//@{ +#define NHD_C12832A1Z_SPI &USARTD0 +#define NHD_C12832A1Z_SPI_SCK IOPORT_CREATE_PIN(PORTD, 1) +#define NHD_C12832A1Z_SPI_MOSI IOPORT_CREATE_PIN(PORTD, 3) +#define NHD_C12832A1Z_CSN IOPORT_CREATE_PIN(PORTF, 3) +//! If this signal is set high display data is sent otherwise commands +#define NHD_C12832A1Z_REGISTER_SELECT IOPORT_CREATE_PIN(PORTD, 0) +#define NHD_C12832A1Z_RESETN IOPORT_CREATE_PIN(PORTA, 3) +//! The backlight is active high +#define NHD_C12832A1Z_BACKLIGHT IOPORT_CREATE_PIN(PORTE, 4) +//@} + +//! \name LCD dimensions +//@{ +#define LCD_WIDTH_PIXELS (128) +#define LCD_HEIGHT_PIXELS (32) +//@} + +//! \name DataFlash memory (AT45DBX) +//@{ +#define AT45DBX_SPI &USARTD0 +#define AT45DBX_CS IOPORT_CREATE_PIN(PORTF, 4) +//! SCK pin +#define AT45DBX_MASTER_SCK IOPORT_CREATE_PIN(PORTD, 1) +//! MOSI pin +#define AT45DBX_MASTER_MOSI IOPORT_CREATE_PIN(PORTD, 3) +//! MISO pin +#define AT45DBX_MASTER_MISO IOPORT_CREATE_PIN(PORTD, 2) +//@} + +//! \name MXT143E Xplained top module +//@{ +#define MXT143E_XPLAINED_TWI &TWIC +#define MXT143E_XPLAINED_USART_SPI &USARTC1 +#define MXT143E_XPLAINED_CS IOPORT_CREATE_PIN(PORTC, 4) +#define MXT143E_XPLAINED_SCK IOPORT_CREATE_PIN(PORTC, 7) +#define MXT143E_XPLAINED_MOSI IOPORT_CREATE_PIN(PORTC, 5) +#define MXT143E_XPLAINED_MISO IOPORT_CREATE_PIN(PORTC, 6) +#define MXT143E_XPLAINED_CHG IOPORT_CREATE_PIN(PORTC, 2) +#define MXT143E_XPLAINED_DC IOPORT_CREATE_PIN(PORTC, 3) +#define MXT143E_XPLAINED_BACKLIGHT IOPORT_CREATE_PIN(PORTA, 4) +#define MXT143E_XPLAINED_LCD_RESET IOPORT_CREATE_PIN(PORTA, 6) +//@} + +/** + * \name External oscillator + * + * \todo Need to measure the actual startup time on the hardware. + */ +//@{ +#define BOARD_XOSC_HZ 32768 +#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ +#define BOARD_XOSC_STARTUP_US 1000000 +//@} + +//! \name Communication interfaces on header J1 +//@{ +#define TWIC_SDA IOPORT_CREATE_PIN(PORTC, 0) +#define TWIC_SCL IOPORT_CREATE_PIN(PORTC, 1) +#define USARTC0_RXD IOPORT_CREATE_PIN(PORTC, 2) +#define USARTC0_TXD IOPORT_CREATE_PIN(PORTC, 3) +#define SPIC_SS IOPORT_CREATE_PIN(PORTC, 4) +#define SPIC_MOSI IOPORT_CREATE_PIN(PORTC, 5) +#define SPIC_MISO IOPORT_CREATE_PIN(PORTC, 6) +#define SPIC_SCK IOPORT_CREATE_PIN(PORTC, 7) +//@} + + +/*! \name Connections of the AT86RFX transceiver + */ +//! @{ +#define AT86RFX_SPI &SPIC +#define AT86RFX_RST_PIN IOPORT_CREATE_PIN(PORTC, 0) +#define AT86RFX_MISC_PIN IOPORT_CREATE_PIN(PORTC, 1) +#define AT86RFX_IRQ_PIN IOPORT_CREATE_PIN(PORTC, 2) +#define AT86RFX_SLP_PIN IOPORT_CREATE_PIN(PORTC, 3) +#define AT86RFX_SPI_CS IOPORT_CREATE_PIN(PORTC, 4) +#define AT86RFX_SPI_MOSI IOPORT_CREATE_PIN(PORTC, 5) +#define AT86RFX_SPI_MISO IOPORT_CREATE_PIN(PORTC, 6) +#define AT86RFX_SPI_SCK IOPORT_CREATE_PIN(PORTC, 7) + +#define AT86RFX_INTC_INIT() ioport_configure_pin(AT86RFX_IRQ_PIN, IOPORT_DIR_INPUT); \ + PORTC.PIN2CTRL = PORT_ISC0_bm; \ + PORTC.INT0MASK = PIN2_bm; \ + PORTC.INTFLAGS = PORT_INT0IF_bm; + +#define AT86RFX_ISR() ISR(PORTC_INT0_vect) + +/** Enables the transceiver main interrupt. */ +#define ENABLE_TRX_IRQ() (PORTC.INTCTRL |= PORT_INT0LVL_gm) + +/** Disables the transceiver main interrupt. */ +#define DISABLE_TRX_IRQ() (PORTC.INTCTRL &= ~PORT_INT0LVL_gm) + +/** Clears the transceiver main interrupt. */ +#define CLEAR_TRX_IRQ() (PORTC.INTFLAGS = PORT_INT0IF_bm) + +/* + * This macro saves the trx interrupt status and disables the trx interrupt. + */ +#define ENTER_TRX_REGION() { uint8_t irq_mask = PORTC.INTCTRL; PORTC.INTCTRL &= ~PORT_INT0LVL_gm + +/* + * This macro restores the transceiver interrupt status + */ +#define LEAVE_TRX_REGION() PORTC.INTCTRL = irq_mask; } + +//! @} + + +/** + * \name Pin connections on header J1 + * + * The whole port C is directly connected to J1. + * + * \note For the TWI lines there are footprints for pull up resistors, which + * are by default not mounted on the board. + */ +//@{ +#define J1_PIN0 IOPORT_CREATE_PIN(PORTC, 0) +#define J1_PIN1 IOPORT_CREATE_PIN(PORTC, 1) +#define J1_PIN2 IOPORT_CREATE_PIN(PORTC, 2) +#define J1_PIN3 IOPORT_CREATE_PIN(PORTC, 3) +#define J1_PIN4 IOPORT_CREATE_PIN(PORTC, 4) +#define J1_PIN5 IOPORT_CREATE_PIN(PORTC, 5) +#define J1_PIN6 IOPORT_CREATE_PIN(PORTC, 6) +#define J1_PIN7 IOPORT_CREATE_PIN(PORTC, 7) +//@} + +/** + * \name Pin connections on header J2 + * + * The lower half of port B is connected to the lower pins of J2 while the + * upper half of port A is connected to the upper pins of J2. + * + * The port pins are connected directly to this header and are not shared with + * any on-board functionality. + */ +//@{ +#define J2_PIN0 IOPORT_CREATE_PIN(PORTB, 0) +#define J2_PIN1 IOPORT_CREATE_PIN(PORTB, 1) +#define J2_PIN2 IOPORT_CREATE_PIN(PORTB, 2) +#define J2_PIN3 IOPORT_CREATE_PIN(PORTB, 3) +#define J2_PIN4 IOPORT_CREATE_PIN(PORTA, 4) +#define J2_PIN5 IOPORT_CREATE_PIN(PORTA, 5) +#define J2_PIN6 IOPORT_CREATE_PIN(PORTA, 6) +#define J2_PIN7 IOPORT_CREATE_PIN(PORTA, 7) +//@} + +/** + * \name Pin connections on header J3 + * + * The lower half of port A is connected to the lower pins of J3 while the + * upper half of port B is connected to the upper pins of J3. + * + * Following pins are shared with on-board functionality: + * - J3_PIN0 Light sensor output (can be disconnected via scratch pad) + * - J3_PIN1 NTC sensor output (can be disconnected via scratch pad) + * - J3_PIN2 Filter output (can be disconnected via scratch pad) + * - J3_PIN3 Display reset input (can't be used when display is in use) + * - J3_PIN4 JTAG TMS (pin can't be used while JTAG device connected) + * - J3_PIN5 JTAG TDI (pin can't be used while JTAG device connected) + * - J3_PIN6 JTAG TCK (pin can't be used while JTAG device connected) + * - J3_PIN7 JTAG TDO & PID DATA (pin can't be used while JTAG/PDI device is + * connected) + */ +//@{ +#define J3_PIN0 IOPORT_CREATE_PIN(PORTA, 0) +#define J3_PIN1 IOPORT_CREATE_PIN(PORTA, 1) +#define J3_PIN2 IOPORT_CREATE_PIN(PORTA, 2) +#define J3_PIN3 IOPORT_CREATE_PIN(PORTA, 3) +#define J3_PIN4 IOPORT_CREATE_PIN(PORTB, 4) +#define J3_PIN5 IOPORT_CREATE_PIN(PORTB, 5) +#define J3_PIN6 IOPORT_CREATE_PIN(PORTB, 6) +#define J3_PIN7 IOPORT_CREATE_PIN(PORTB, 7) +//@} + +/** + * \name Pin connections on header J4 + * + * The lower half of port E is connected to the lower pins of J4 and the lower + * half of port D is connected to the upper pins of J4. + */ +//@{ +#define J4_PIN0 IOPORT_CREATE_PIN(PORTE, 0) +#define J4_PIN1 IOPORT_CREATE_PIN(PORTE, 1) +#define J4_PIN2 IOPORT_CREATE_PIN(PORTE, 2) +#define J4_PIN3 IOPORT_CREATE_PIN(PORTE, 3) +#define J4_PIN4 IOPORT_CREATE_PIN(PORTD, 0) +#define J4_PIN5 IOPORT_CREATE_PIN(PORTD, 3) +#define J4_PIN6 IOPORT_CREATE_PIN(PORTD, 2) +#define J4_PIN7 IOPORT_CREATE_PIN(PORTD, 1) +//@} + +/** + * @} + */ + +/** + * \defgroup xmega_a3bu_xplained_config_group Configuration options + * @{ + */ + +#if defined(__DOXYGEN__) + +/** + * \name Initialization + * \note Define these symbols in \ref conf_board.h to enable the corresponding + * features. + */ +//@{ + +/** + * \def CONF_BOARD_C12832A1Z + * \brief Initialize SPI and control pins for C12832A1Z LCD controller + */ +# if !defined(CONF_BOARD_C12832A1Z) +# define CONF_BOARD_C12832A1Z +# endif + +/** + * \def CONF_BOARD_AT45DBX + * \brief Initialize SPI pins for AT45DBX DataFlash + */ +# if !defined(CONF_BOARD_AT45DBX) +# define CONF_BOARD_AT45DBX +# endif + +/** + * \def CONF_BOARD_ENABLE_AC_PINS + * \brief Initialize IO pins for Analog Comparator + * + * \note This initializes pins PA0, PA2 and PB1 as inputs. + */ +# if !defined(CONF_BOARD_ENABLE_AC_PINS) +# define CONF_BOARD_ENABLE_AC_PINS +# endif + +/** + * \def CONF_BOARD_ENABLE_USARTC0 + * \brief Initialize IO pins for USART 0 on port C + */ +# if !defined(CONF_BOARD_ENABLE_USARTC0) +# define CONF_BOARD_ENABLE_USARTC0 +# endif + +/** + * \def CONF_BOARD_ENABLE_USARTD0 + * \brief Initialize IO pins for USART 0 on port D + */ +# if !defined(CONF_BOARD_ENABLE_USARTD0) +# define CONF_BOARD_ENABLE_USARTD0 +# endif + +/** + * \def CONF_BOARD_ENABLE_USARTE0 + * \brief Initialize IO pins for USART 0 on port E + */ +# if !defined(CONF_BOARD_ENABLE_USARTE0) +# define CONF_BOARD_ENABLE_USARTE0 +# endif + +//@} + +#endif // __DOXYGEN__ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* _XMEGA_A3BU_XPLAINED_H_ */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/xmega_a3bu_xplained.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/xmega_a3bu_xplained.h.REMOVED.git-id deleted file mode 100644 index 26826736..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/boards/xmega_a3bu_xplained/xmega_a3bu_xplained.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e81651885cd903ea6df1218a89ae12ec2b063f97 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/ccp.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/ccp.h new file mode 100644 index 00000000..1e929a4d --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/ccp.h @@ -0,0 +1,123 @@ +/** + * \file + * + * \brief Configuration Change Protection write functions + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef CPU_CCP_H +#define CPU_CCP_H +#include + +/** + * \defgroup ccp_group Configuration Change Protection + * + * See \ref xmega_ccp_quickstart. + * + * Function for writing to protected IO registers. + * @{ + */ + +#if defined(__DOXYGEN__) +//! \name IAR Memory Model defines. +//@{ + +/** + * \def CONFIG_MEMORY_MODEL_TINY + * \brief Configuration symbol to enable 8 bit pointers. + * + */ +# define CONFIG_MEMORY_MODEL_TINY + +/** + * \def CONFIG_MEMORY_MODEL_SMALL + * \brief Configuration symbol to enable 16 bit pointers. + * \note If no memory model is defined, SMALL is default. + * + */ +# define CONFIG_MEMORY_MODEL_SMALL + + +/** + * \def CONFIG_MEMORY_MODEL_LARGE + * \brief Configuration symbol to enable 24 bit pointers. + * + */ +# define CONFIG_MEMORY_MODEL_LARGE + +//@} +#endif + + +/** + * \brief Write to a CCP-protected 8-bit I/O register + * + * \param addr Address of the I/O register + * \param value Value to be written + * + * \note Using IAR Embedded workbench, the choice of memory model has an impact + * on calling convention. The memory model is not visible to the + * preprocessor, so it must be defined in the Assembler preprocessor directives. + */ +extern void ccp_write_io(void *addr, uint8_t value); + +/** @} */ + +/** + * \page xmega_ccp_quickstart Quick start guide for CCP driver + * + * This is the quick start guide for the \ref ccp_group + * "Configuration Change Protection (CCP) driver", with step-by-step + * instructions on how to use the driver. + * + * The use case contains a code fragment, and this can be copied into, e.g., + * the main application function. + * + * \section ccp_basic_use_case Basic use case + * In this use case, the CCP is used to write to the protected XMEGA Clock + * Control register. + * + * \subsection ccp_basic_use_case_setup_flow Workflow + * -# call CCP write io to change system clock selection: + * - \code ccp_write_io((uint8_t *)&CLK.CTRL, CLK_SCLKSEL_RC32M_gc); \endcode + */ + +#endif /* CPU_CCP_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/ccp.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/ccp.h.REMOVED.git-id deleted file mode 100644 index eb519662..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/ccp.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1e929a4d4c2e69ef282a2f86e8509e8c259199eb \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/ccp.s b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/ccp.s new file mode 100644 index 00000000..91f8fb02 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/ccp.s @@ -0,0 +1,100 @@ +/** + * \file + * + * \brief Configuration Change Protection + * + * Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#include + +//! Value to write to CCP for access to protected IO registers. +#define CCP_IOREG 0xd8 + + /* + * GNU and IAR use different calling conventions. Since this is + * a very small and simple function to begin with, it's easier + * to implement it twice than to deal with the differences + * within a single implementation. + * + * Interrupts are disabled by hardware during the timed + * sequence, so there's no need to save/restore interrupt state. + */ + + PUBLIC_FUNCTION(ccp_write_io) + +#if defined(__GNUC__) + + out RAMPZ, r1 // Reset bits 23:16 of Z + movw r30, r24 // Load addr into Z + ldi r18, CCP_IOREG // Load magic CCP value + out CCP, r18 // Start CCP handshake + st Z, r22 // Write value to I/O register + ret // Return to caller + +#elif defined(__IAR_SYSTEMS_ASM__) + +# if !defined(CONFIG_MEMORY_MODEL_TINY) && !defined(CONFIG_MEMORY_MODEL_SMALL) \ + && !defined(CONFIG_MEMORY_MODEL_LARGE) +# define CONFIG_MEMORY_MODEL_SMALL +# endif + ldi r20, 0 + out RAMPZ, r20 // Reset bits 23:16 of Z +# if defined(CONFIG_MEMORY_MODEL_TINY) + mov r31, r20 // Reset bits 8:15 of Z + mov r30, r16 // Load addr into Z +# else + movw r30, r16 // Load addr into Z +# endif + ldi r21, CCP_IOREG // Load magic CCP value + out CCP, r21 // Start CCP handshake +# if defined(CONFIG_MEMORY_MODEL_TINY) + st Z, r17 // Write value to I/O register +# elif defined(CONFIG_MEMORY_MODEL_SMALL) + st Z, r18 // Write value to I/O register +# elif defined(CONFIG_MEMORY_MODEL_LARGE) + st Z, r19 // Write value to I/O register +# else +# error Unknown memory model in use, no idea how registers should be accessed +# endif + ret +#else +# error Unknown assembler +#endif + + END_FUNC(ccp_write_io) + END_FILE() diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/ccp.s.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/ccp.s.REMOVED.git-id deleted file mode 100644 index b2a0c386..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/ccp.s.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -91f8fb02cea7897ca035b5aee8786df8b20b9ab4 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/xmega_reset_cause.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/xmega_reset_cause.h new file mode 100644 index 00000000..ff6840a8 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/xmega_reset_cause.h @@ -0,0 +1,108 @@ +/** + * \file + * + * \brief Chip-specific reset cause functions + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef XMEGA_DRIVERS_CPU_RESET_CAUSE_H +#define XMEGA_DRIVERS_CPU_RESET_CAUSE_H + +#include "compiler.h" +#include "ccp.h" + +/** + * \ingroup reset_cause_group + * \defgroup xmega_reset_cause_group XMEGA reset cause + * + * See \ref reset_cause_quickstart + * + * @{ + */ + +/** + * \brief Chip-specific reset cause type capable of holding all chip reset + * causes. Typically reflects the size of the reset cause register. + */ +typedef uint8_t reset_cause_t; + +//! \internal \name Chip-specific reset causes +//@{ +//! \internal External reset cause +#define CHIP_RESET_CAUSE_EXTRST RST_EXTRF_bm +//! \internal brown-out detected reset cause, same as for CPU +#define CHIP_RESET_CAUSE_BOD_IO RST_BORF_bm +//! \internal Brown-out detected reset cause, same as for I/O +#define CHIP_RESET_CAUSE_BOD_CPU RST_BORF_bm +//! \internal On-chip debug system reset cause +#define CHIP_RESET_CAUSE_OCD RST_PDIRF_bm +//! \internal Power-on-reset reset cause +#define CHIP_RESET_CAUSE_POR RST_PORF_bm +//! \internal Software reset reset cause +#define CHIP_RESET_CAUSE_SOFT RST_SRF_bm +//! \internal Spike detected reset cause +#define CHIP_RESET_CAUSE_SPIKE RST_SDRF_bm +//! \internal Watchdog timeout reset cause +#define CHIP_RESET_CAUSE_WDT RST_WDRF_bm +//@} + +static inline reset_cause_t reset_cause_get_causes(void) +{ + return (reset_cause_t)RST.STATUS; +} + +static inline void reset_cause_clear_causes(reset_cause_t causes) +{ + RST.STATUS = causes; +} + +static inline void reset_do_soft_reset(void) +{ + ccp_write_io((void *)&RST.CTRL, RST_SWRST_bm); + + while (1) { + /* Intentionally empty. */ + } +} + +//! @} + +#endif /* XMEGA_DRIVERS_CPU_RESET_CAUSE_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/xmega_reset_cause.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/xmega_reset_cause.h.REMOVED.git-id deleted file mode 100644 index d00af4e6..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/cpu/xmega_reset_cause.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ff6840a8acaefc471367ba8fe3e39bba11aedeaf \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/nvm/nvm.c b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/nvm/nvm.c new file mode 100644 index 00000000..61455202 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/nvm/nvm.c @@ -0,0 +1,710 @@ +/** + * \file + * + * \brief Non Volatile Memory controller driver + * + * Copyright (C) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#include "compiler.h" +#include "ccp.h" +#include "nvm.h" +#include + +/** + * \weakgroup nvm_signature_group + * @{ + */ + +/** + * \brief Read the device serial + * + * This function returns the device serial stored in the device. + * + * \note This function is modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not + * the program space reads will be corrupted. + * + * \retval storage Pointer to the structure where to store the device serial + */ +void nvm_read_device_serial(struct nvm_device_serial *storage) +{ + storage->lotnum0 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM0)); + storage->lotnum1 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM1)); + storage->lotnum2 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM2)); + storage->lotnum3 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM3)); + storage->lotnum4 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM4)); + storage->lotnum5 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(LOTNUM5)); + + storage->wafnum = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(WAFNUM)); + + storage->coordx0 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(COORDX0)); + storage->coordx1 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(COORDX1)); + storage->coordy0 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(COORDY0)); + storage->coordy1 = nvm_read_production_signature_row( + nvm_get_production_signature_row_offset(COORDY1)); +} + +//! @} + +/** + * \weakgroup nvm_eeprom_group + * @{ + */ + +/** + * \brief Read one byte from EEPROM using mapped access. + * + * This function reads one byte from EEPROM using mapped access. + * + * \param addr EEPROM address, between 0 and EEPROM_SIZE + * + * \return Byte value read from EEPROM. + */ +uint8_t nvm_eeprom_read_byte(eeprom_addr_t addr) +{ + uint8_t data; + Assert(addr <= EEPROM_SIZE); + + /* Wait until NVM is ready */ + nvm_wait_until_ready(); + eeprom_enable_mapping(); + data = *(uint8_t*)(addr + MAPPED_EEPROM_START), + eeprom_disable_mapping(); + return data; +} + +/** + * \brief Read buffer within the eeprom + * + * \param address the address to where to read + * \param buf pointer to the data + * \param len the number of bytes to read + */ +void nvm_eeprom_read_buffer(eeprom_addr_t address, void *buf, uint16_t len) +{ + nvm_wait_until_ready(); + eeprom_enable_mapping(); + memcpy( buf,(void*)(address+MAPPED_EEPROM_START), len ); + eeprom_disable_mapping(); +} + + +/** + * \brief Write one byte to EEPROM using IO mapping. + * + * This function writes one byte to EEPROM using IO-mapped access. + * This function will cancel all ongoing EEPROM page buffer loading + * operations, if any. + * + * \param address EEPROM address (max EEPROM_SIZE) + * \param value Byte value to write to EEPROM. + */ +void nvm_eeprom_write_byte(eeprom_addr_t address, uint8_t value) +{ + uint8_t old_cmd; + + Assert(address <= EEPROM_SIZE); + /* Flush buffer to make sure no unintentional data is written and load + * the "Page Load" command into the command register. + */ + old_cmd = NVM.CMD; + nvm_eeprom_flush_buffer(); + // Wait until NVM is ready + nvm_wait_until_ready(); + nvm_eeprom_load_byte_to_buffer(address, value); + + // Set address to write to + NVM.ADDR2 = 0x00; + NVM.ADDR1 = (address >> 8) & 0xFF; + NVM.ADDR0 = address & 0xFF; + + /* Issue EEPROM Atomic Write (Erase&Write) command. Load command, write + * the protection signature and execute command. + */ + NVM.CMD = NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc; + nvm_exec(); + NVM.CMD = old_cmd; +} + +/** + * \brief Write buffer within the eeprom + * + * \param address the address to where to write + * \param buf pointer to the data + * \param len the number of bytes to write + */ +void nvm_eeprom_erase_and_write_buffer(eeprom_addr_t address, const void *buf, uint16_t len) +{ + while (len) { + if (((address%EEPROM_PAGE_SIZE)==0) && (len>=EEPROM_PAGE_SIZE)) { + // A full page can be written + nvm_eeprom_load_page_to_buffer((uint8_t*)buf); + nvm_eeprom_atomic_write_page(address/EEPROM_PAGE_SIZE); + address += EEPROM_PAGE_SIZE; + buf = (uint8_t*)buf + EEPROM_PAGE_SIZE; + len -= EEPROM_PAGE_SIZE; + } else { + nvm_eeprom_write_byte(address++, *(uint8_t*)buf); + buf = (uint8_t*)buf + 1; + len--; + } + } +} + + +/** + * \brief Flush temporary EEPROM page buffer. + * + * This function flushes the EEPROM page buffers. This function will cancel + * any ongoing EEPROM page buffer loading operations, if any. + * This function also works for memory mapped EEPROM access. + * + * \note An EEPROM write operations will automatically flush the buffer for you. + * \note The function does not preserve the value of the NVM.CMD register + */ +void nvm_eeprom_flush_buffer(void) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + // Flush EEPROM page buffer if necessary + if ((NVM.STATUS & NVM_EELOAD_bm) != 0) { + NVM.CMD = NVM_CMD_ERASE_EEPROM_BUFFER_gc; + nvm_exec(); + } +} + +/** + * \brief Load single byte into temporary page buffer. + * + * This function loads one byte into the temporary EEPROM page buffers. + * If memory mapped EEPROM is enabled, this function will not work. + * Make sure that the buffer is flushed before starting to load bytes. + * Also, if multiple bytes are loaded into the same location, they will + * be ANDed together, thus 0x55 and 0xAA will result in 0x00 in the buffer. + * + * \note Only one page buffer exist, thus only one page can be loaded with + * data and programmed into one page. If data needs to be written to + * different pages, the loading and writing needs to be repeated. + * + * \param byte_addr EEPROM Byte address, between 0 and EEPROM_PAGE_SIZE. + * \param value Byte value to write to buffer. + */ +void nvm_eeprom_load_byte_to_buffer(uint8_t byte_addr, uint8_t value) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + eeprom_enable_mapping(); + *(uint8_t*)(byte_addr + MAPPED_EEPROM_START) = value; + eeprom_disable_mapping(); +} + + +/** + * \brief Load entire page into temporary EEPROM page buffer. + * + * This function loads an entire EEPROM page from an SRAM buffer to + * the EEPROM page buffers. If memory mapped EEPROM is enabled, this + * function will not work. Make sure that the buffer is flushed before + * starting to load bytes. + * + * \note Only the lower part of the address is used to address the buffer. + * Therefore, no address parameter is needed. In the end, the data + * is written to the EEPROM page given by the address parameter to the + * EEPROM write page operation. + * + * \param values Pointer to SRAM buffer containing an entire page. + */ +void nvm_eeprom_load_page_to_buffer(const uint8_t *values) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + // Load multiple bytes into page buffer + uint8_t i; + for (i = 0; i < EEPROM_PAGE_SIZE; ++i) { + nvm_eeprom_load_byte_to_buffer(i, *values); + ++values; + } +} + +/** + * \brief Erase and write bytes from page buffer into EEPROM. + * + * This function writes the contents of an already loaded EEPROM page + * buffer into EEPROM memory. + * + * As this is an atomic write, the page in EEPROM will be erased + * automatically before writing. Note that only the page buffer locations + * that have been loaded will be used when writing to EEPROM. Page buffer + * locations that have not been loaded will be left untouched in EEPROM. + * + * \param page_addr EEPROM Page address, between 0 and EEPROM_SIZE/EEPROM_PAGE_SIZE + */ +void nvm_eeprom_atomic_write_page(uint8_t page_addr) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + // Calculate page address + uint16_t address = (uint16_t)(page_addr * EEPROM_PAGE_SIZE); + + Assert(address <= EEPROM_SIZE); + + // Set address + NVM.ADDR2 = 0x00; + NVM.ADDR1 = (address >> 8) & 0xFF; + NVM.ADDR0 = address & 0xFF; + + // Issue EEPROM Atomic Write (Erase&Write) command + nvm_issue_command(NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc); +} + +/** + * \brief Write (without erasing) EEPROM page. + * + * This function writes the contents of an already loaded EEPROM page + * buffer into EEPROM memory. + * + * As this is a split write, the page in EEPROM will _not_ be erased + * before writing. + * + * \param page_addr EEPROM Page address, between 0 and EEPROM_SIZE/EEPROM_PAGE_SIZE + */ +void nvm_eeprom_split_write_page(uint8_t page_addr) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + // Calculate page address + uint16_t address = (uint16_t)(page_addr * EEPROM_PAGE_SIZE); + + Assert(address <= EEPROM_SIZE); + + // Set address + NVM.ADDR2 = 0x00; + NVM.ADDR1 = (address >> 8) & 0xFF; + NVM.ADDR0 = address & 0xFF; + + // Issue EEPROM Split Write command + nvm_issue_command(NVM_CMD_WRITE_EEPROM_PAGE_gc); +} + +/** + * \brief Fill temporary EEPROM page buffer with value. + * + * This fills the the EEPROM page buffers with a given value. + * If memory mapped EEPROM is enabled, this function will not work. + * + * \note Only the lower part of the address is used to address the buffer. + * Therefore, no address parameter is needed. In the end, the data + * is written to the EEPROM page given by the address parameter to the + * EEPROM write page operation. + * + * \param value Value to copy to the page buffer. + */ +void nvm_eeprom_fill_buffer_with_value(uint8_t value) +{ + nvm_eeprom_flush_buffer(); + // Wait until NVM is ready + nvm_wait_until_ready(); + // Load multiple bytes into page buffer + uint8_t i; + for (i = 0; i < EEPROM_PAGE_SIZE; ++i) { + nvm_eeprom_load_byte_to_buffer(i, value); + } +} + +/** + * \brief Erase bytes from EEPROM page. + * + * This function erases bytes from one EEPROM page, so that every location + * written to in the page buffer reads 0xFF. + * + * \param page_addr EEPROM Page address, between 0 and EEPROM_SIZE/EEPROM_PAGE_SIZE + */ +void nvm_eeprom_erase_bytes_in_page(uint8_t page_addr) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + // Calculate page address + uint16_t address = (uint16_t)(page_addr * EEPROM_PAGE_SIZE); + + Assert(address <= EEPROM_SIZE); + + // Set address + NVM.ADDR2 = 0x00; + NVM.ADDR1 = (address >> 8) & 0xFF; + NVM.ADDR0 = address & 0xFF; + + // Issue EEPROM Erase command + nvm_issue_command(NVM_CMD_ERASE_EEPROM_PAGE_gc); +} + +/** + * \brief Erase EEPROM page. + * + * This function erases one EEPROM page, so that every location reads 0xFF. + * + * \param page_addr EEPROM Page address, between 0 and EEPROM_SIZE/EEPROM_PAGE_SIZE + */ +void nvm_eeprom_erase_page(uint8_t page_addr) +{ + // Mark all addresses to be deleted + nvm_eeprom_fill_buffer_with_value(0xff); + // Erase bytes + nvm_eeprom_erase_bytes_in_page(page_addr); +} + + +/** + * \brief Erase bytes from all EEPROM pages. + * + * This function erases bytes from all EEPROM pages, so that every location + * written to in the page buffer reads 0xFF. + */ +void nvm_eeprom_erase_bytes_in_all_pages(void) +{ + // Wait until NVM is ready + nvm_wait_until_ready(); + + // Issue EEPROM Erase All command + nvm_issue_command(NVM_CMD_ERASE_EEPROM_gc); +} + +/** + * \brief Erase entire EEPROM memory. + * + * This function erases the entire EEPROM memory block to 0xFF. + */ +void nvm_eeprom_erase_all(void) +{ + // Mark all addresses to be deleted + nvm_eeprom_fill_buffer_with_value(0xff); + // Erase all pages + nvm_eeprom_erase_bytes_in_all_pages(); +} + +//! @} + + +//! @} + + +/** + * \weakgroup nvm_flash_group + * @{ + */ + +/** + * \brief Issue flash range CRC command + * + * This function sets the FLASH range CRC command in the NVM.CMD register. + * It then loads the start and end byte address of the part of FLASH to + * generate a CRC-32 for into the ADDR and DATA registers and finally performs + * the execute command. + * + * \note Should only be called from the CRC module. The function saves and + * restores the NVM.CMD register, but if this + * function is called from an interrupt, interrupts must be disabled + * before this function is called. + * + * \param start_addr end byte address + * \param end_addr start byte address + */ +void nvm_issue_flash_range_crc(flash_addr_t start_addr, flash_addr_t end_addr) +{ + uint8_t old_cmd; + // Save current nvm command + old_cmd = NVM.CMD; + + // Load the NVM CMD register with the Flash Range CRC command + NVM.CMD = NVM_CMD_FLASH_RANGE_CRC_gc; + + // Load the start byte address in the NVM Address Register + NVM.ADDR0 = start_addr & 0xFF; + NVM.ADDR1 = (start_addr >> 8) & 0xFF; +#if (FLASH_SIZE >= 0x10000UL) + NVM.ADDR2 = (start_addr >> 16) & 0xFF; +#endif + + // Load the end byte address in NVM Data Register + NVM.DATA0 = end_addr & 0xFF; + NVM.DATA1 = (end_addr >> 8) & 0xFF; +#if (FLASH_SIZE >= 0x10000UL) + NVM.DATA2 = (end_addr >> 16) & 0xFF; +#endif + + // Execute command + ccp_write_io((uint8_t *)&NVM.CTRLA, NVM_CMDEX_bm); + + // Restore command register + NVM.CMD = old_cmd; +} + +/** + * \brief Read buffer within the application section + * + * \param address the address to where to read + * \param buf pointer to the data + * \param len the number of bytes to read + */ +void nvm_flash_read_buffer(flash_addr_t address, void *buf, uint16_t len) +{ +#if (FLASH_SIZE>0x10000) + uint32_t opt_address = address; +#else + uint16_t opt_address = (uint16_t)address; +#endif + nvm_wait_until_ready(); + while ( len ) { + *(uint8_t*)buf = nvm_flash_read_byte(opt_address); + buf=(uint8_t*)buf+1; + opt_address++; + len--; + } +} + +/** + * \brief Read buffer within the user section + * + * \param address the address to where to read + * \param buf pointer to the data + * \param len the number of bytes to read + */ +void nvm_user_sig_read_buffer(flash_addr_t address, void *buf, uint16_t len) +{ + uint16_t opt_address = (uint16_t)address&(FLASH_PAGE_SIZE-1); + while ( len ) { + *(uint8_t*)buf = nvm_read_user_signature_row(opt_address); + buf=(uint8_t*)buf+1; + opt_address++; + len--; + } +} + +/** + * \brief Write specific parts of user flash section + * + * \param address the address to where to write + * \param buf pointer to the data + * \param len the number of bytes to write + * \param b_blank_check if True then the page flash is checked before write + * to run or not the erase page command. + * + * Set b_blank_check to false if all application flash is erased before. + */ +void nvm_user_sig_write_buffer(flash_addr_t address, const void *buf, + uint16_t len, bool b_blank_check) +{ + uint16_t w_value; + uint16_t page_pos; + uint16_t opt_address = (uint16_t)address; + bool b_flag_erase = false; + + while ( len ) { + for (page_pos=0; page_pos0x10000) + uint32_t page_address; + uint32_t opt_address = address; +#else + uint16_t page_address; + uint16_t opt_address = (uint16_t)address; +#endif + + // Compute the start of the page to be modified + page_address = opt_address-(opt_address%FLASH_PAGE_SIZE); + + // For each page + while ( len ) { + b_flag_erase = false; + + nvm_wait_until_ready(); + for (page_pos=0; page_posAtmel Support + */ +#ifndef NVM_H +#define NVM_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup nvm_group NVM driver + * + * See \ref xmega_nvm_quickstart + * + * \brief Low-level driver implementation for the AVR XMEGA Non Volatile + * Memory Controller (NVM). + * + * The XMEGA NVM controller interfaces the internal non-volatile memories + * in the XMEGA devices. Program memory, EEPROM and signature row is can be + * interfaced by the module. See the documentation of each sub-module for + * more information. + * + * \note If using GCC and the flash sub-module, remember to configure + * the boot section in the make file. More information in the sub-module + * documentation. + * + * \section xmega_nvm_quickstart_section Quick Start Guide + * See \ref xmega_nvm_quickstart + */ + +/** + * \defgroup nvm_generic_group NVM driver generic module handling + * \ingroup nvm_group + * \brief Support functions for the NVM driver. + * + * These functions are helper functions for the functions of the + * \ref nvm_group "NVM driver". + * + * @{ + */ + +/** + * \brief Wait for any NVM access to finish. + * + * This function is blocking and waits for any NVM access to finish. + * Use this function before any NVM accesses, if you are not certain that + * any previous operations are finished yet. + */ +static inline void nvm_wait_until_ready( void ) +{ + do { + // Block execution while waiting for the NVM to be ready + } while ((NVM.STATUS & NVM_NVMBUSY_bm) == NVM_NVMBUSY_bm); +} + +/** + * \brief Non-Volatile Memory Execute Command + * + * This function sets the CCP register before setting the CMDEX bit in the + * NVM.CTRLA register. + * + * \note The correct NVM command must be set in the NVM.CMD register before + * calling this function. + */ +static inline void nvm_exec(void) +{ + ccp_write_io((uint8_t *)&NVM.CTRLA, NVM_CMDEX_bm); +} + +/** + * \brief Non-Volatile Memory Execute Specific Command + * + * This function sets a command in the NVM.CMD register, then performs an + * execute command by writing the CMDEX bit to the NVM.CTRLA register. + * + * \note The function saves and restores the NVM.CMD register, but if this + * function is called from an interrupt, interrupts must be disabled + * before this function is called. + * + * \param nvm_command NVM Command to execute. + */ +static inline void nvm_issue_command(NVM_CMD_t nvm_command) +{ + uint8_t old_cmd; + + old_cmd = NVM.CMD; + NVM.CMD = nvm_command; + ccp_write_io((uint8_t *)&NVM.CTRLA, NVM_CMDEX_bm); + NVM.CMD = old_cmd; +} + +/** + * \brief Read one byte using the LDI instruction + * \internal + * + * This function sets the specified NVM_CMD, reads one byte using at the + * specified byte address with the LPM instruction. NVM_CMD is restored after + * use. + * + * \note Interrupts should be disabled before running this function + * if program memory/NVM controller is accessed from ISRs. + * + * \param nvm_cmd NVM command to load before running LPM + * \param address Byte offset into the signature row + */ +uint8_t nvm_read_byte(uint8_t nvm_cmd, uint16_t address); + + +/** + * \brief Perform SPM write + * \internal + * + * This function sets the specified NVM_CMD, sets CCP and then runs the SPM + * instruction to write to flash. + * + * \note Interrupts should be disabled before running this function + * if program memory/NVM controller is accessed from ISRs. + * + * \param addr Address to perform the SPM on. + * \param nvm_cmd NVM command to use in the NVM_CMD register + */ +void nvm_common_spm(uint32_t addr, uint8_t nvm_cmd); + +//! @} + +/** + * \defgroup nvm_signature_group NVM driver signature handling + * \ingroup nvm_group + * \brief Handling of signature rows + * + * Functions for handling signature rows. The following is supported: + * - Reading values from production and user signature row + * - Reading device id + * - Reading device revision + * - Reading device serial + * + * \note Some of these functions are modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not, + * the program space reads will be corrupted. See documentation for + * each individual function. + * \note Do not use the functions of this module in an interrupt service + * routine (ISR), since the functions can take several milliseconds to + * complete and hence block the interrupt for several milliseconds. + * In addition the functions of this module are modifying the page buffer + * which will corrupt any ongoing EEPROM handing used outside an ISR. + * @{ + */ + +/** + * \brief Structure containing the device ID + * + * This structure can be used to store the device ID of a device. + */ +struct nvm_device_id { + union { + struct { + uint8_t devid0; + uint8_t devid1; + uint8_t devid2; + }; + uint8_t byte[3]; + }; +}; + +/** + * \brief Structure containing the device serial + * + * This structure can be used to store the serial number of a device. + */ +struct nvm_device_serial { + union { + struct { + uint8_t lotnum0; + uint8_t lotnum1; + uint8_t lotnum2; + uint8_t lotnum3; + uint8_t lotnum4; + uint8_t lotnum5; + uint8_t wafnum; + uint8_t coordx0; + uint8_t coordx1; + uint8_t coordy0; + uint8_t coordy1; + }; + uint8_t byte[11]; + }; +}; + +/** + * \brief Get offset of calibration bytes in the production signature row + * + * \param regname Name of register within the production signature row + * \retval Offset of register into the production signature row + */ +#if defined(__GNUC__) +# define nvm_get_production_signature_row_offset(regname) \ + offsetof(NVM_PROD_SIGNATURES_t, regname) +#elif defined(__ICCAVR__) +# define nvm_get_production_signature_row_offset(regname) (regname##_offset) +#else +# error Unknown compiler +#endif + + +/** + * \brief Read one byte from the production signature row + * + * This function reads one byte from the production signature row of the device + * at the given address. + * + * \note This function is modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not + * the program space reads will be corrupted. + * + * \param address Byte offset into the signature row + */ +static inline uint8_t nvm_read_production_signature_row(uint8_t address) +{ + return nvm_read_byte(NVM_CMD_READ_CALIB_ROW_gc, address); +} + +/** + * \brief Read one byte from the user signature row + * + * This function reads one byte from the user signature row of the device + * at the given address. + * + * \note This function is modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not + * the program space reads will be corrupted. + * + * \param address Byte offset into the signature row + */ +static inline uint8_t nvm_read_user_signature_row(uint16_t address) +{ + return nvm_read_byte(NVM_CMD_READ_USER_SIG_ROW_gc, address); +} + +/** + * \brief Read the device id + * + * This function returns the device ID stored in the device. + * + * \retval storage Pointer to the structure where to store the device id + */ +static inline void nvm_read_device_id(struct nvm_device_id *storage) +{ + storage->devid0 = MCU.DEVID0; + storage->devid1 = MCU.DEVID1; + storage->devid2 = MCU.DEVID2; +} + +/** + * \brief Read the device revision + * + * This function returns the device revision stored in the device. + * + * \retval unsigned 8 bit value with the current device revision. + */ +static inline uint8_t nvm_read_device_rev(void) +{ + return MCU.REVID; +} + +void nvm_read_device_serial(struct nvm_device_serial *storage); + +//! @} + + +/** + * \defgroup nvm_eeprom_group NVM driver EEPROM handling + * \ingroup nvm_group + * \brief Functions for handling internal EEPROM memory. + * + * The internal EEPROM can be used to store data that will persist after + * power is removed. This can typically be used to store calibration data, + * application state, encryption keys or other data that need to be preserved + * when power is removed. + * + * The functions in this module uses IO register access to manipulate the + * EEPROM. + * + * \note The functions in this module are modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not + * the program space reads will be corrupted. + * @{ + */ + +#ifndef EEPROM_PAGE_SIZE +# if XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E +# define EEPROM_PAGE_SIZE 32 +# else +# error Unknown EEPROM page size +# endif +#endif + +#ifndef CONFIG_NVM_IGNORE_XMEGA_A3_D3_REVB_ERRATA +# if XMEGA_A3 || XMEGA_D3 +# error This NVM driver does not support rev B of XMEGA A3/D3 devices. \ + Set CONFIG_NVM_IGNORE_XMEGA_A3_D3_REVB_ERRATA to disable this message +# endif +#endif + +/** + * Data type for holding eeprom memory addresses. + */ +typedef uint16_t eeprom_addr_t; + + +/*! \brief Enable EEPROM mapping into data space. + * + * This macro enables mapping of EEPROM into data space. + * EEPROM starts at EEPROM_START in data memory. Read access + * can be done similar to ordinary SRAM access. + * + * \note This disables IO-mapped access to EEPROM, although page erase and + * write operations still needs to be done through IO register. + */ +static inline void eeprom_enable_mapping(void) +{ +#if !XMEGA_E + NVM_CTRLB = NVM_CTRLB | NVM_EEMAPEN_bm; +#endif +} + + +/*! \brief Disable EEPROM mapping into data space. + * + * This macro disables mapping of EEPROM into data space. + * IO mapped access is now enabled. + */ +static inline void eeprom_disable_mapping(void) +{ +#if !XMEGA_E + NVM_CTRLB = NVM_CTRLB & ~NVM_EEMAPEN_bm; +#endif +} + + +uint8_t nvm_eeprom_read_byte(eeprom_addr_t addr); +void nvm_eeprom_write_byte(eeprom_addr_t address, uint8_t value); +void nvm_eeprom_read_buffer(eeprom_addr_t address, void *buf, uint16_t len); +void nvm_eeprom_erase_and_write_buffer(eeprom_addr_t address, const void *buf, uint16_t len); + +void nvm_eeprom_flush_buffer(void); +void nvm_eeprom_load_byte_to_buffer(uint8_t byte_addr, uint8_t value); +void nvm_eeprom_load_page_to_buffer(const uint8_t *values); +void nvm_eeprom_atomic_write_page(uint8_t page_addr); +void nvm_eeprom_split_write_page(uint8_t page_addr); +void nvm_eeprom_fill_buffer_with_value(uint8_t value); +void nvm_eeprom_erase_bytes_in_page(uint8_t page_addr); +void nvm_eeprom_erase_page(uint8_t page_addr); +void nvm_eeprom_erase_bytes_in_all_pages(void); +void nvm_eeprom_erase_all(void); + +//! @} + +/** + * \defgroup nvm_flash_group NVM driver flash handling + * \ingroup nvm_group + * \brief Functions for handling internal flash memory. + * + * The internal flash memory on the XMEGA devices consists of the application + * section, the application table section and the bootloader section. + * All these sections can store program code for the MCU, but if there is + * available space, they can be used for storing other persistent data. + * + * Writing the flash memory can only be done one page at a time. It consists + * of loading the data to the internal page buffer and then running one of + * the write commands. If the page has not been erased before writing, the + * data will not be written correctly. + * + * In order to be able to write to flash memory the programming commands need + * to be run from the boot section. + * - When using IAR this is handled automatically by the linker script. + * - When using GCC this needs to be specified manually in the make files. For + * example the ATxmega128A1 has the boot section at the word address 0x10000 + * the corresponding byte address of 0x20000 needs to be added to the + * config.mk makefile: + * LDFLAGS += -Wl,--section-start=.BOOT=0x20000 + * See the device datasheet for the correct address for other devices. + * + * \note If using GCC and the flash sub-module, remember to configure + * the boot section in the make file. + * + * \note The functions in this module are modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not + * the program space reads will be corrupted. + * @{ + */ + +/** + * \brief Size of a flash page in bytes + * + * The page size in bytes taken from the toolchain header files. + * + * \note Page size is currently missing from the IAR header files, so it needs + * to be defined in the driver until it is fixed. + */ +#ifdef __DOXYGEN__ +# define FLASH_SIZE +# define FLASH_PAGE_SIZE +#else + +// 8K devices +# if AVR8_PART_IS_DEFINED(ATxmega8E5) +# define FLASH_SIZE (8*1024L) +# define FLASH_PAGE_SIZE (128) + +// 16K devices +# elif AVR8_PART_IS_DEFINED(ATxmega16A4) | \ + AVR8_PART_IS_DEFINED(ATxmega16A4U) | \ + AVR8_PART_IS_DEFINED(ATxmega16D4) | \ + AVR8_PART_IS_DEFINED(ATxmega16C4) +# define FLASH_SIZE (16*1024L) +# define FLASH_PAGE_SIZE (256) + +# elif AVR8_PART_IS_DEFINED(ATxmega16E5) +# define FLASH_SIZE (16*1024L) +# define FLASH_PAGE_SIZE (128) + +// 32K devices +# elif AVR8_PART_IS_DEFINED(ATxmega32A4) | \ + AVR8_PART_IS_DEFINED(ATxmega32A4U) | \ + AVR8_PART_IS_DEFINED(ATxmega32D4) | \ + AVR8_PART_IS_DEFINED(ATxmega32C4) +# define FLASH_SIZE (32*1024L) +# define FLASH_PAGE_SIZE (256) + +# elif AVR8_PART_IS_DEFINED(ATxmega32E5) +# define FLASH_SIZE (32*1024L) +# define FLASH_PAGE_SIZE (128) + +// 64K devices +# elif AVR8_PART_IS_DEFINED(ATxmega64A1) | \ + AVR8_PART_IS_DEFINED(ATxmega64A1U) | \ + AVR8_PART_IS_DEFINED(ATxmega64A3) | \ + AVR8_PART_IS_DEFINED(ATxmega64A3U) | \ + AVR8_PART_IS_DEFINED(ATxmega64A4U) | \ + AVR8_PART_IS_DEFINED(ATxmega64B1) | \ + AVR8_PART_IS_DEFINED(ATxmega64B3) | \ + AVR8_PART_IS_DEFINED(ATxmega64C3) | \ + AVR8_PART_IS_DEFINED(ATxmega64D3) | \ + AVR8_PART_IS_DEFINED(ATxmega64D4) +# define FLASH_SIZE (64*1024L) +# define FLASH_PAGE_SIZE (256) + +// 128K devices +# elif AVR8_PART_IS_DEFINED(ATxmega128A1) | \ + AVR8_PART_IS_DEFINED(ATxmega128A1U) | \ + AVR8_PART_IS_DEFINED(ATxmega128A3) | \ + AVR8_PART_IS_DEFINED(ATxmega128A3U) | \ + AVR8_PART_IS_DEFINED(ATxmega128C3) | \ + AVR8_PART_IS_DEFINED(ATxmega128D3) | \ + AVR8_PART_IS_DEFINED(ATxmega128D4) +# define FLASH_SIZE (128*1024L) +# define FLASH_PAGE_SIZE (512) + +# elif AVR8_PART_IS_DEFINED(ATxmega128A4U) | \ + AVR8_PART_IS_DEFINED(ATxmega128B1) | \ + AVR8_PART_IS_DEFINED(ATxmega128B3) +# define FLASH_SIZE (128*1024L) +# define FLASH_PAGE_SIZE (256) + +// 192K devices +# elif AVR8_PART_IS_DEFINED(ATxmega192A3U) | \ + AVR8_PART_IS_DEFINED(ATxmega192C3) | \ + AVR8_PART_IS_DEFINED(ATxmega192D3) +# define FLASH_SIZE (192*1024L) +# define FLASH_PAGE_SIZE (512) + +// 256K devices +# elif AVR8_PART_IS_DEFINED(ATxmega256A3) | \ + AVR8_PART_IS_DEFINED(ATxmega256A3U) | \ + AVR8_PART_IS_DEFINED(ATxmega256A3B) | \ + AVR8_PART_IS_DEFINED(ATxmega256A3BU) | \ + AVR8_PART_IS_DEFINED(ATxmega256C3) | \ + AVR8_PART_IS_DEFINED(ATxmega256D3) +# define FLASH_SIZE (256*1024L) +# define FLASH_PAGE_SIZE (512) + +// 384K devices +# elif AVR8_PART_IS_DEFINED(ATxmega384C3) +# define FLASH_SIZE (384*1024L) +# define FLASH_PAGE_SIZE (512) +# elif AVR8_PART_IS_DEFINED(ATxmega384D3) +# define FLASH_SIZE (384*1024L) +# define FLASH_PAGE_SIZE (512) +# else +# error Flash page size needs to be defined. +# endif +#endif + +/** + * Data type for holding flash memory addresses. + * + */ +#if (FLASH_SIZE >= 0x10000UL) // Note: Xmega with 64KB of flash have 4KB boot flash +typedef uint32_t flash_addr_t; +#else +typedef uint16_t flash_addr_t; +#endif + +/** + * Flash pointer type to use for accessing flash memory with IAR + */ +#if (FLASH_SIZE >= 0x10000UL) // Note: Xmega with 64KB of flash have 4KB boot flash +# define IAR_FLASH_PTR __farflash +#else +# define IAR_FLASH_PTR __flash +#endif + +/** + * \brief Load byte from flash memory + * + * Load one word of flash using byte addressing. IAR has __flash pointers + * and GCC have pgm_read_byte_xx functions which load data from flash memory. + * This function used for compatibility between the compilers. + * + * \param addr Byte address to load + * \return Byte from program memory + */ +static inline uint8_t nvm_flash_read_byte(flash_addr_t addr) +{ +#if defined(__GNUC__) + return pgm_read_byte_far(addr); +#elif defined(__ICCAVR__) + uint8_t IAR_FLASH_PTR *flashptr = (uint8_t IAR_FLASH_PTR *)addr; + return *flashptr; +#else +# error Unknown compiler +#endif +} + +/** + * \brief Load word from flash memory + * + * Load one word of flash using byte addressing. IAR has __flash pointers + * and GCC have pgm_read_byte_xx functions which load data from flash memory. + * This function used for compatibility between the compilers. + * + * \param addr Byte address to load (last bit is ignored) + * \return Word from program memory + */ +static inline uint16_t nvm_flash_read_word(flash_addr_t addr) +{ +#if defined(__GNUC__) + return pgm_read_word_far(addr); +#elif defined(__ICCAVR__) + uint16_t IAR_FLASH_PTR *flashptr = (uint16_t IAR_FLASH_PTR *)addr; + return *flashptr; +#endif +} + + +/** + * \brief Flush flash page buffer + * + * Clear the NVM controller page buffer for flash. This needs to be called + * before using \ref nvm_flash_load_word_to_buffer if it has not already been + * cleared. + * + */ +static inline void nvm_flash_flush_buffer(void) +{ + nvm_wait_until_ready(); + nvm_common_spm(0, NVM_CMD_ERASE_FLASH_BUFFER_gc); +} + + +/** + * \brief Load word into flash page buffer + * + * Clear the NVM controller page buffer for flash. This needs to be called + * before using \ref nvm_flash_load_word_to_buffer if it has not already been + * cleared. + * + * \param word_addr Address to store data. The upper bits beyond the page size + * is ignored. \ref FLASH_PAGE_SIZE + * \param data Data word to load into the page buffer + */ +void nvm_flash_load_word_to_buffer(uint32_t word_addr, uint16_t data); + + +/** + * \brief Erase entire application section + * + * Erase all of the application section. + */ +static inline void nvm_flash_erase_app(void) +{ + nvm_wait_until_ready(); + nvm_common_spm(0, NVM_CMD_ERASE_APP_gc); +} + +/** + * \brief Erase a page within the application section + * + * Erase one page within the application section + * + * \param page_addr Byte address to the page to delete + */ +static inline void nvm_flash_erase_app_page(flash_addr_t page_addr) +{ + nvm_wait_until_ready(); + nvm_common_spm(page_addr, NVM_CMD_ERASE_APP_PAGE_gc); +} + +/** + * \brief Write a page within the application section + * + * Write a page within the application section with the data stored in the + * page buffer. The page needs to be erased before the write to avoid + * corruption of the data written. + * + * \param page_addr Byte address to the page to delete + */ +static inline void nvm_flash_split_write_app_page(flash_addr_t page_addr) +{ + nvm_wait_until_ready(); + nvm_common_spm(page_addr, NVM_CMD_WRITE_APP_PAGE_gc); +} + +/** + * \brief Erase and write a page within the application section + * + * Erase and the write a page within the application section with the data + * stored in the page buffer. Erase and write is done in an atomic operation. + * + * \param page_addr Byte address to the page to delete + */ +static inline void nvm_flash_atomic_write_app_page(flash_addr_t page_addr) +{ + nvm_wait_until_ready(); + nvm_common_spm(page_addr, NVM_CMD_ERASE_WRITE_APP_PAGE_gc); +} + +void nvm_issue_flash_range_crc(flash_addr_t start_addr, flash_addr_t end_addr); + +void nvm_flash_read_buffer(flash_addr_t address, void *buf, uint16_t len); + +void nvm_flash_erase_and_write_buffer(flash_addr_t address, const void *buf, + uint16_t len, bool b_blank_check); + +/** + * \brief Erase a page within the boot section + * + * Erase one page within the boot section + * + * \param page_addr Byte address to the page to delete + */ +static inline void nvm_flash_erase_boot_page(flash_addr_t page_addr) +{ + nvm_wait_until_ready(); + nvm_common_spm(page_addr, NVM_CMD_ERASE_BOOT_PAGE_gc); +} + +/** + * \brief Write a page within the boot section + * + * Write a page within the boot section with the data stored in the + * page buffer. The page needs to be erased before the write to avoid + * corruption of the data written. + * + * \param page_addr Byte address to the page to delete + */ +static inline void nvm_flash_split_write_boot_page(flash_addr_t page_addr) +{ + nvm_wait_until_ready(); + nvm_common_spm(page_addr, NVM_CMD_WRITE_BOOT_PAGE_gc); +} + +/** + * \brief Erase and write a page within the boot section + * + * Erase and the write a page within the boot section with the data + * stored in the page buffer. Erase and write is done in an atomic operation. + * + * \param page_addr Byte address to the page to delete + */ +static inline void nvm_flash_atomic_write_boot_page(flash_addr_t page_addr) +{ + nvm_wait_until_ready(); + nvm_common_spm(page_addr, NVM_CMD_ERASE_WRITE_BOOT_PAGE_gc); +} + +void nvm_user_sig_read_buffer(flash_addr_t address, void *buf, uint16_t len); +void nvm_user_sig_write_buffer(flash_addr_t address, const void *buf, + uint16_t len, bool b_blank_check); + +/** + * \brief Erase the user calibration section page + * + * Erase the user calibration section page. There is only one page, so no + * parameters are needed. + */ +static inline void nvm_flash_erase_user_section(void) +{ + nvm_wait_until_ready(); + nvm_common_spm(0, NVM_CMD_ERASE_USER_SIG_ROW_gc); +} + +/** + * \brief Write the user calibration section page + * + * Write a the user calibration section page with the data stored in the + * page buffer. The page needs to be erased before the write to avoid + * corruption of the data written. There is only one page, so no + * parameters are needed. + */ +static inline void nvm_flash_write_user_page(void) +{ + nvm_wait_until_ready(); + nvm_common_spm(0, NVM_CMD_WRITE_USER_SIG_ROW_gc); +} + +//! @} + +/** + * \defgroup nvm_fuse_lock_group NVM driver fuse and lock bits handling + * \ingroup nvm_group + * \brief Functions for reading fuses and writing lock bits. + * + * The Fuses are used to set important system functions and can only be written + * from an external programming interface. The application software can read + * the fuses. The fuses are used to configure reset sources such as Brown-out + * Detector and Watchdog, Start-up configuration, JTAG enable and JTAG user ID. + * + * The Lock bits are used to set protection level on the different flash + * sections. They are used to block read and/or write on the different flash + * sections. Lock bits can be written from en external programmer and from the + * application software to set a more strict protection level, but not to set a + * less strict protection level. Chip erase is the only way to erase the lock + * bits. The lock bits are erased after the rest of the flash memory is erased. + * An unprogrammed fuse or lock bit will have the value one, while a programmed + * fuse or lock bit will have the value zero. + * Both fuses and lock bits are reprogrammable like the Flash Program memory. + * + * \note The functions in this module are modifying the NVM.CMD register. + * If the application are using program space access in interrupts + * (__flash pointers in IAR EW or pgm_read_byte in GCC) interrupts + * needs to be disabled when running EEPROM access functions. If not + * the program space reads will be corrupted. + * @{ + */ + +// The different fuse bytes +enum fuse_byte_t { + FUSEBYTE0 = 0, + FUSEBYTE1 = 1, + FUSEBYTE2 = 2, + FUSEBYTE3 = 3, // not used on current devices + FUSEBYTE4 = 4, + FUSEBYTE5 = 5, +}; + +uint8_t nvm_fuses_read(enum fuse_byte_t fuse); + +/** + * \brief Program the lock bits. + * + * Program the lock bits to the given values. Lock bits can only be programmed + * to a more secure setting than previously programmed. To clear lock bits, a + * flash erase has to be issued. + * + * \param blbb_lock Boot loader section lock bits to program + * \param blba_lock Application section lock bits to program + * \param blbat_lock Application table section lock bits to program + * \param lb_lock Flash/eeprom lock bits to program + */ +static inline void nvm_lock_bits_write(enum NVM_BLBB_enum blbb_lock, + enum NVM_BLBA_enum blba_lock, enum NVM_BLBAT_enum blbat_lock, + enum NVM_LB_enum lb_lock) +{ + nvm_wait_until_ready(); + NVM.DATA0 = (uint8_t)blbb_lock | (uint8_t)blba_lock | (uint8_t)blbat_lock | + (uint8_t)lb_lock; + nvm_issue_command(NVM_CMD_WRITE_LOCK_BITS_gc); +} + +/** + * \brief Program the BLBB lock bits. + * + * Program the lock bits for the boot loader section (BLBB). Other lock bits + * (BLBA, BLBAT and LB) are not altered (ie. programmed to NOLOCK). + * + * \param blbb_lock Boot loader section lock bits to program + */ +static inline void nvm_blbb_lock_bits_write(enum NVM_BLBB_enum blbb_lock) +{ + nvm_lock_bits_write(blbb_lock, NVM_BLBA_NOLOCK_gc, NVM_BLBAT_NOLOCK_gc, + NVM_LB_NOLOCK_gc); +} + +/** + * \brief Program the BLBA lock bits. + * + * Program the lock bits for the application section (BLBA). Other lock bits + * (BLBB, BLBAT and LB) are not altered (ie. programmed to NOLOCK). + * + * \param blba_lock Application section lock bits to program + */ +static inline void nvm_blba_lock_bits_write(enum NVM_BLBA_enum blba_lock) +{ + nvm_lock_bits_write(NVM_BLBB_NOLOCK_gc, blba_lock, NVM_BLBAT_NOLOCK_gc, + NVM_LB_NOLOCK_gc); +} + +/** + * \brief Program the BLBAT lock bits. + * + * Program the lock bits for the application table section (BLBAT). Other lock + * bits (BLBB, BLBA and LB) are not altered (ie. programmed to NOLOCK). + * + * \param blbat_lock Application table section lock bits to program + */ +static inline void nvm_blbat_lock_bits_write(enum NVM_BLBAT_enum blbat_lock) +{ + nvm_lock_bits_write(NVM_BLBB_NOLOCK_gc, NVM_BLBA_NOLOCK_gc, blbat_lock, + NVM_LB_NOLOCK_gc); +} + +/** + * \brief Program the LB lock bits. + * + * Program the lock bits for the flash and eeprom (LB). Other lock bits + * (BLBB, BLBA and BLBAT) are not altered (ie. programmed to NOLOCK). + * + * \param lb_lock Flash/eeprom lock bits to program + */ +static inline void nvm_lb_lock_bits_write(enum NVM_LB_enum lb_lock) +{ + nvm_lock_bits_write(NVM_BLBB_NOLOCK_gc, NVM_BLBA_NOLOCK_gc, + NVM_BLBAT_NOLOCK_gc, lb_lock); +} + +//! @} + +/** + * \page xmega_nvm_quickstart Quick Start Guide for the XMEGA NVM Driver + * + * This is the quick start guide for the \ref nvm_group "NVM Driver", with + * step-by-step instructions on how to configure and use the driver for + * specific use cases. + * + * The section described below can be compiled into e.g. the main application + * loop or any other function that will need to interface non-volatile memory. + * + * \section xmega_nvm_quickstart_basic Basic usage of the NVM driver + * This section will present three use cases of the NVM driver. The first will + * write a page to EEPROM and verify that it has been written, the second will + * access the BOD-level fuse to verify that the level is correctly set, and the + * third will read a chunk from the user signature row. + * + * \section xmega_nvm_quickstart_eeprom_case Use case 1: EEPROM + * + * The NVM driver has functions for interfacing many types of non-volatile + * memory, including flash, EEPROM, fuses and lock bits. The example code + * below will write a page to the internal EEPROM, and read it back to verify, + * using memory mapped I/O. + * + * \section xmega_nvm_quickstart_eeprom_case_setup_steps Setup steps + * There are no setup steps required for this use case. + * + * \subsection nvm_quickstart_eeprom_case_example_code Example code + * + * \code + #define EXAMPLE_PAGE 2 + #define EXAMPLE_ADDR EXAMPLE_PAGE * EEPROM_PAGE_SIZE + + uint8_t write_page[EEPROM_PAGE_SIZE]; + uint8_t read_page[EEPROM_PAGE_SIZE]; + + fill_page_with_known_data(write_page); + fill_page_with_zeroes(read_page); + + nvm_eeprom_load_page_to_buffer(write_page); + nvm_eeprom_atomic_write_page(EXAMPLE_PAGE); + + nvm_eeprom_read_buffer(EXAMPLE_ADDR, + read_page, EEPROM_PAGE_SIZE); + + check_if_pages_are_equal(write_page, read_page); +\endcode + * + * \subsection nvm_quickstart_eeprom_case_workflow Workflow + * + * -# We define where we would like to store our data, and we arbitrarily + * choose page 2 of EEPROM: + * - \code + #define EXAMPLE_PAGE 2 + #define EXAMPLE_ADDR EXAMPLE_PAGE * EEPROM_PAGE_SIZE +\endcode + * -# Define two tables, one which contains the data which we will write, + * and one which we will read the data into: + * - \code + uint8_t write_page[EEPROM_PAGE_SIZE]; + uint8_t read_page[EEPROM_PAGE_SIZE]; +\endcode + * -# Fill the tables with our data, and zero out the read table: + * - \code + fill_page_with_known_data(write_page); + fill_page_with_zeroes(read_page); +\endcode + * - \note These functions are undeclared, you should replace them with + * your own appropriate functions. + * -# We load our page into a temporary EEPROM page buffer: + * - \code + nvm_eeprom_load_page_to_buffer(write_page); +\endcode + * - \attention The function used above will not work if memory mapping + * is enabled. + * -# Do an atomic write of the page from buffer into the specified page: + * - \code + nvm_eeprom_atomic_write_page(EXAMPLE_PAGE); +\endcode + * - \note The function \ref nvm_eeprom_atomic_write_page() erases the + * page before writing the new one. For non-atomic (split) + * writing without deleting, see \ref nvm_eeprom_split_write_page() + * -# Read the page back into our read_page[] table: + * - \code + nvm_eeprom_read_buffer(EXAMPLE_ADDR, + read_page, EEPROM_PAGE_SIZE); +\endcode + * -# Verify that the page is equal to the one that was written earlier: + * - \code + check_if_pages_are_equal(write_page, read_page); +\endcode + * - \note This function is not declared, you should replace it with your + * own appropriate function. + * + * \section xmega_nvm_quickstart_fuse_case Use case 2: Fuses + * + * The NVM driver has functions for reading fuses. + * See \ref nvm_fuse_lock_group. + * + * We would like to check whether the Brown-out Detection level is set to + * 2.1V. This is set by programming the fuses when the chip is connected + * to a suitable programmer. The fuse is a part of FUSEBYTE5. If the BODLVL + * is correct, we turn on LED0. + * + * \section xmega_nvm_quickstart_fuse_case_setup_steps Setup steps + * There are no setup steps required for this use case. + * + * \subsection nvm_quickstart_fuse_case_example_code Example code + * \code + uint8_t fuse_value; + fuse_value = nvm_fuses_read(FUSEBYTE5); + + if ((fuse_value & NVM_FUSES_BODLVL_gm) == BODLVL_2V1_gc) { + gpio_set_pin_low(LED0_GPIO); + } +\endcode + * + * \subsection nvm_quickstart_fuse_case_workflow Workflow + * + * -# Create a variable to store the fuse contents: + * - \code + uint8_t fuse_value; +\endcode + * -# The fuse value we are interested in, BODLVL, is stored in FUSEBYTE5. + * We call the function \ref nvm_fuses_read() to read the fuse into our + * variable: + * - \code + fuse_value = nvm_fuses_read(FUSEBYTE5); +\endcode + * -# This ends the reading portion, but we would like to see whether the + * BOD-level is correct, and if it is, light up an LED: + * - \code + if ((fuse_value & NVM_FUSES_BODLVL_gm) == BODLVL_2V1_gc) { + gpio_set_pin_low(LED0_GPIO); + } +\endcode + * + * \section xmega_nvm_quickstart_signature_case Use case 3: Signature row + * + * The NVM driver has functions for reading the signature row of the device. + * Here we will simply read 16 bytes from the user signature row, assuming + * we need what is stored there. + * + * \section xmega_nvm_quickstart_signature_row_setup_steps Setup steps + * There are no setup steps required for this use case. + * + * \subsection xmega_nvm_quickstart_signature_row_example_code Example code + * + * \code + #define START_ADDR 0x10 + #define DATA_LENGTH 16 + + uint8_t values[LENGTH]; + uint8_t i; + + for (i = 0; i < DATA_LENGTH; i++) { + values[i] = nvm_read_user_signature_row(START_ADDR + i); + } +\endcode + * + * \subsection nvm_quickstart_signature_case_workflow Workflow + * + * -# Define starting address and length of data segment, and create + * variables needed to store and process the data: + * - \code + #define START_ADDR 0x10 + #define DATA_LENGTH 16 + + uint8_t values[LENGTH]; + uint8_t i; +\endcode + * -# Iterate through the user signature row, and store our desired data: + * - \code + for (i = 0; i < DATA_LENGTH; i++) { + values[i] = nvm_read_user_signature_row(START_ADDR + i); + } +\endcode + * + */ + +#ifdef __cplusplus +} +#endif + +#endif /* NVM_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/nvm/nvm.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/nvm/nvm.h.REMOVED.git-id deleted file mode 100644 index 968a6054..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/nvm/nvm.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1e52ffc957556eff30f0ad3fd285ee180a9bd1ec \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/nvm/nvm_asm.s b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/nvm/nvm_asm.s new file mode 100644 index 00000000..6d74e08e --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/nvm/nvm_asm.s @@ -0,0 +1,197 @@ +/** + * \file + * + * \brief Non Volatile Memory controller driver + * + * Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#include + +#if defined(__GNUC__) +//! Value to write to CCP for access to protected IO registers. +# define CCP_SPM_gc 0x9D + +//! NVM busy flag +# define NVM_NVMBUSY_bp 7 + +//! NVM command for loading flash buffer +# define NVM_CMD_LOAD_FLASH_BUFFER_gc 0x23 +#elif defined(__IAR_SYSTEMS_ASM__) +// All values are defined for IAR +#else +# error Unknown assembler +#endif + +#ifndef __DOXYGEN__ + PUBLIC_FUNCTION(nvm_read_byte) +#if defined(__GNUC__) + lds r20, NVM_CMD ; Store NVM command register + mov ZL, r22 ; Load byte index into low byte of Z. + mov ZH, r23 ; Load high byte into Z. + sts NVM_CMD, r24 ; Load prepared command into NVM Command register. + lpm r24, Z ; Perform an LPM to read out byte + sts NVM_CMD, r20 ; Restore NVM command register +#elif defined(__IAR_SYSTEMS_ASM__) + lds r20, NVM_CMD ; Store NVM command register + mov ZL, r18 ; Load byte index into low byte of Z. + mov ZH, r19 ; Load high byte into Z. + sts NVM_CMD, r16 ; Load prepared command into NVM Command register. + lpm r16, Z ; Perform an LPM to read out byte + sts NVM_CMD, r20 ; Restore NVM command register +#endif + + ret + + END_FUNC(nvm_read_byte) + +// IAR forgets about include files after each module, so need to include again +#if defined(__IAR_SYSTEMS_ASM__) +# include +#endif + + /** + * \brief Perform SPM command + */ + PUBLIC_FUNCTION_SEGMENT(nvm_common_spm, BOOT) + +#if defined(__GNUC__) + /** + * For GCC: + * \param address uint32_t r22:r25 + * \param nvm_cmd uint8_t r20 + */ + in r25, RAMPZ ; Store RAMPZ. Highest address byte is ignored, so using that + out RAMPZ, r24 ; Load R24 into RAMPZ + movw ZL, r22 ; Load R22:R23 into Z. + lds r24, NVM_CMD ; Store NVM command register (r24 is no longer needed) + sts NVM_CMD, r20 ; Load prepared command into NVM Command register. + ldi r23, CCP_SPM_gc ; Prepare Protect SPM signature (r23 is no longer needed) + sts CCP, r23 ; Enable SPM operation (this disables interrupts for 4 cycles). + spm ; Self-program. + sts NVM_CMD, r24 ; Restore NVM command register + out RAMPZ, r25 ; Restore RAMPZ register. +#elif defined(__IAR_SYSTEMS_ASM__) + /** + * For IAR: + * \param address uint32_t r16:r19 + * \param nvm_cmd uint8_t r20 + */ + in r19, RAMPZ ; Store RAMPZ. Highest address byte is ignored, so using that + out RAMPZ, r18 ; Load R18 into RAMPZ + movw ZL, r16 ; Load R16:R17 into Z. + lds r18, NVM_CMD ; Store NVM command register (r18 is no longer needed) + sts NVM_CMD, r20 ; Load prepared command into NVM Command register. + ldi r19, CCP_SPM_gc ; Prepare Protect SPM signature (r19 is no longer needed) + sts CCP, r19 ; Enable SPM operation (this disables interrupts for 4 cycles). + spm ; Self-program. + sts NVM_CMD, r18 ; Restore NVM command register + out RAMPZ, r19 ; Restore RAMPZ register. +#endif + + ret + + END_FUNC(nvm_common_spm) + +// IAR forgets about include files after each module, so need to include again +#if defined(__IAR_SYSTEMS_ASM__) +# include +#endif + + /** + * \brief Load byte to page buffer + * + */ + PUBLIC_FUNCTION_SEGMENT(nvm_flash_load_word_to_buffer, BOOT) + +#if defined(__GNUC__) + /** + * For GCC: + * \param word_addr uint32_t r22:r25 + * \param data uint16_t r20:r21 + */ +wait_nvm: + lds r18, NVM_STATUS + sbrc r18, NVM_NVMBUSY_bp + rjmp wait_nvm + + in r25, RAMPZ ; Store RAMPZ. Highest address byte is ignored, so using that + out RAMPZ, r24 ; Load R24 into RAMPZ + movw ZL, r22 ; Load R22:R23 into Z. + + lds r24, NVM_CMD ; Store NVM command register (r24 is no longer needed) + ldi r18, NVM_CMD_LOAD_FLASH_BUFFER_gc + sts NVM_CMD, r18 ; Load prepared command into NVM Command register. + + movw r0, r20 ; Load R20:R21 into R0:R1 + spm ; Self-program. + + clr r1 ; Clear R1 for GCC _zero_reg_ to function properly. + sts NVM_CMD, r24 ; Restore NVM command register + out RAMPZ, r25 ; Restore RAMPZ register. +#elif defined(__IAR_SYSTEMS_ASM__) + /** + * For IAR: + * \param word_addr uint32_t r16:r19 + * \param data uint16_t r20:r21 + */ +wait_nvm: + lds r19, NVM_STATUS + sbrc r19, NVM_NVMBUSY_bp + rjmp wait_nvm + + in r19, RAMPZ ; Store RAMPZ. Highest byte is ignored, so using that + out RAMPZ, r18 ; Load R18 into RAMPZ + movw ZL, r16 ; Load R16:R17 into Z. + + lds r18, NVM_CMD ; Store NVM command register (r18 is no longer needed) + ldi r17, NVM_CMD_LOAD_FLASH_BUFFER_gc + sts NVM_CMD, r17 ; Load prepared command into NVM Command register. + + movw r0, r20 ; Load R20:R21 into R0:R1 + spm ; Self-program. + + sts NVM_CMD, r18 ; Restore NVM command register + out RAMPZ, r19 ; Restore RAMPZ register. +#endif + + ret + + END_FUNC(nvm_flash_load_word_to_buffer) + + END_FILE() +#endif // __DOXYGEN__ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/nvm/nvm_asm.s.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/nvm/nvm_asm.s.REMOVED.git-id deleted file mode 100644 index 478f3b03..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/nvm/nvm_asm.s.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6d74e08e518a7172e2adf9a19654fbfe95d1c7af \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/pmic/pmic.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/pmic/pmic.h new file mode 100644 index 00000000..81f56157 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/pmic/pmic.h @@ -0,0 +1,352 @@ +/** + * \file + * + * \brief Programmable Multilevel Interrupt Controller driver + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef PMIC_H +#define PMIC_H + +#include +#include + +/** + * \defgroup pmic_group Programmable Multilevel Interrupt Controller + * + * See \ref xmega_pmic_quickstart. + * + * This is a low-level driver implementation for the AVR XMEGA Programmable + * Multilevel Interrupt Controller. + * + * \note If these functions are used in interrupt service routines (ISRs), any + * non-ISR code or ISR code for lower level interrupts must ensure that the + * operations are atomic, i.e., by disabling interrupts during the function + * calls. + * @{ + */ + +/** + * \brief Interrupt level bitmasks + * + * \note These may be OR'ed, e.g., if multiple levels are to be enabled or + * disabled. + */ +enum pmic_level { + PMIC_LVL_LOW = PMIC_LOLVLEN_bm, //!< Low-level interrupts + PMIC_LVL_MEDIUM = PMIC_MEDLVLEN_bm, //!< Medium-level interrupts + PMIC_LVL_HIGH = PMIC_HILVLEN_bm, //!< High-level interrupts + /** + * \brief Non-maskable interrupts + * \note These cannot be enabled nor disabled. + */ + PMIC_LVL_NMI = PMIC_NMIEX_bp, +}; + +//! Interrupt vector locations +enum pmic_vector { + PMIC_VEC_APPLICATION, //!< Application section + PMIC_VEC_BOOT, //!< Boot section + PMIC_NR_OF_VECTORS, //!< Number of interrupt vector locations +}; + +//! Interrupt scheduling schemes +enum pmic_schedule { + PMIC_SCH_FIXED_PRIORITY, //!< Default, fixed priority scheduling + PMIC_SCH_ROUND_ROBIN, //!< Round-robin scheduling + PMIC_NR_OF_SCHEDULES, //!< Number of interrupt scheduling schemes +}; + +/** + * \brief Initialize the PMIC + * + * Enables all interrupt levels, with vectors located in the application section + * and fixed priority scheduling. + */ +static inline void pmic_init(void) +{ + PMIC.CTRL = PMIC_LVL_LOW | PMIC_LVL_MEDIUM | + PMIC_LVL_HIGH; +} + +/** + * \brief Enable interrupts with specified \a level(s). + * + * \param level Interrupt level(s) to enable. + */ +static inline void pmic_enable_level(enum pmic_level level) +{ + Assert((level & PMIC_LVL_NMI)); + + PMIC.CTRL |= level; +} + +/** + * \brief Disable interrupts with specified \a level(s). + * + * \param level Interrupt level(s) to disable. + */ +static inline void pmic_disable_level(enum pmic_level level) +{ + Assert((level & PMIC_LVL_NMI)); + + PMIC.CTRL &= ~level; +} + +/** + * \brief Check if specified interrupt \a level(s) is enabled. + * + * \param level Interrupt level(s) to check. + * + * \return True if interrupt level(s) is enabled. + */ +static inline bool pmic_level_is_enabled(enum pmic_level level) +{ + Assert((level & PMIC_LVL_NMI)); + + return PMIC.CTRL & level; +} + +/** + * \brief Get currently enabled level(s) + * + * \return Bitmask with currently enabled levels. + */ +static inline enum pmic_level pmic_get_enabled_levels(void) +{ + return (enum pmic_level)(PMIC.CTRL & (PMIC_LVL_LOW | PMIC_LVL_MEDIUM + | PMIC_LVL_HIGH)); +} + +/** + * \brief Check if an interrupt level(s) is currently executing. + * + * \param level Interrupt level(s) to check. + * + * \return True if interrupt level(s) is currently executing. + */ +static inline bool pmic_level_is_executing(enum pmic_level level) +{ + return PMIC.STATUS & level; +} + +/** + * \brief Set interrupt scheduling for low-level interrupts. + * + * \param schedule Interrupt scheduling method to set. + * + * \note The low-priority vector, INTPRI, must be set to 0 when round-robin + * scheduling is disabled to return to default interrupt priority order. + */ +static inline void pmic_set_scheduling(enum pmic_schedule schedule) +{ + Assert(schedule < PMIC_NR_OF_SCHEDULES); + + switch (schedule) { + case PMIC_SCH_FIXED_PRIORITY: + PMIC.CTRL &= ~PMIC_RREN_bm; + PMIC.INTPRI = 0; + break; + + case PMIC_SCH_ROUND_ROBIN: + PMIC.CTRL |= PMIC_RREN_bm; + break; + + default: + break; + }; +} + +/** + * \brief Set location of interrupt vectors. + * + * \param vector Location to use for interrupt vectors. + */ +static inline void pmic_set_vector_location(enum pmic_vector vector) +{ + uint8_t ctrl = PMIC.CTRL; + + Assert(vector < PMIC_NR_OF_VECTORS); + + switch (vector) { + case PMIC_VEC_APPLICATION: + ctrl &= ~PMIC_IVSEL_bm; + break; + + case PMIC_VEC_BOOT: + ctrl |= PMIC_IVSEL_bm; + break; + + default: + break; + } + + ccp_write_io((uint8_t*)&PMIC.CTRL, ctrl); +} + +//! @} + +/** + * \page xmega_pmic_quickstart Quick start guide for PMIC driver + * + * This is the quick start guide for the \ref pmic_group "PMIC driver" and + * the closely related \ref interrupt_group "global interrupt driver", with + * step-by-step instructions on how to configure and use the drivers in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section pmic_basic_use_case Basic use case + * In this basic use case, the PMIC is configured for: + * - all interrupt levels enabled + * - round-robin scheduling + * + * This will allow for interrupts from other modules being used. + * + * \section pmic_basic_use_case_setup Setup steps + * + * \subsection pmic_basic_use_case_setup_prereq Prerequisites + * For the setup code of this use case to work, the following must + * be added to the project: + * -# Interrupts for the module requiring the PMIC module have to be + * enabled. + * -# An Interrupt Service Routine (ISR) for a given interrupt vector has to be + * defined, where the interrupt vectors available are defined by toolchain and + * listed in the subsection 'Interrupt Vector Summary' in the data sheet. + * \code + ISR(interrupt_vector){ + //Interrupt Service Routine + } +\endcode + * + * \subsection pmic_basic_use_case_setup_code Example code + * Add to the initialization code: + * \code + pmic_init(); + pmic_set_scheduling(PMIC_SCH_ROUND_ROBIN); + cpu_irq_enable(); +\endcode + * + * \subsection pmic_basic_use_case_setup_flow Workflow + * -# call the PMIC driver's own init function to enable all interrupt levels: + * - \code pmic_init(); \endcode + * -# enable round-robin instead of fixed priority interrupt scheduling: + * - \code pmic_set_scheduling(PMIC_SCH_ROUND_ROBIN); \endcode + * -# enable interrupts globally: + * - \code cpu_irq_enable(); \endcode + * - \attention Interrupts will not trigger without this step. + * + * \section pmic_use_cases Advanced use cases + * For more advanced use of the PMIC driver, see the following use cases: + * - \subpage pmic_use_case_1 : atomic operations + */ + +/** + * \page pmic_use_case_1 Use case #1 + * + * In this use case, the PMIC is configured for: + * - all interrupt levels enabled + * + * This will allow for interrupts from other modules being used. + * + * This use case shows how to make an operation which consists of multiple + * instructions uninterruptible, i.e., into an atomic operation. This is often + * necessary if there is a risk that data can be accessed by interrupt handlers + * while other code is accessing it, and at least one of them modifies it. + * + * \section pmic_use_case_1_setup Setup steps + * + * \subsection pmic_basic_use_case_setup_prereq Prerequisites + * For the setup code of this use case to work, the following must + * be added to the project: + * -# Interrupts for the module requiring the PMIC module have to be + * enabled. + * -# An Interrupt Service Routine (ISR) for a given interrupt vector has to be + * defined, where the interrupt vectors available are defined by toolchain and + * listed in the subsection 'Interrupt Vector Summary' in the data sheet. + * \code + ISR(interrupt_vector){ + //Interrupt Service Routine + } +\endcode + * + * \subsection pmic_use_case_1_setup_code Example code + * Add to application initialization: + * \code + pmic_init(); + cpu_irq_enable(); +\endcode + * + * \subsection pmic_use_case_1_setup_flow Workflow + * -# call the PMIC driver's own init function to enable all interrupt levels: + * - \code pmic_init(); \endcode + * -# set global interrupt enable flag: + * - \code cpu_irq_enable(); \endcode + * + * \section pmic_use_case_1_usage Usage steps + * + * \subsection pmic_use_case_1_usage_code Example code + * \code + Add to application: + void atomic_operation(void) + { + irqflags_t flags; + + flags = cpu_irq_save(); + + // Uninterruptible block of code + + cpu_irq_restore(flags); + } +\endcode + * + * \subsection pmic_use_case_1_usage_flow Workflow + * -# allocate temporary storage for interrupt enable: + * - \code irqflags_t flags; \endcode + * -# clear global interrupt enable flag while saving its previous state: + * - \code flags = cpu_irq_save(); \endcode + * -# restore the previous state of global interrupt flag after operation: + * - \code cpu_irq_restore(flags); \endcode + */ + +#endif /* PMIC_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/pmic/pmic.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/pmic/pmic.h.REMOVED.git-id deleted file mode 100644 index caf8cb34..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/pmic/pmic.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -81f561576ef6063862e73b77d32c30cb53e766f6 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/sleep/sleep.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/sleep/sleep.h new file mode 100644 index 00000000..8a218c41 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/sleep/sleep.h @@ -0,0 +1,169 @@ +/** + * \file + * + * \brief Sleep controller driver + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef SLEEP_H +#define SLEEP_H + +#include + +/** + * \defgroup sleep_group Sleep controller driver + * + * This is a low-level driver implementation for the AVR XMEGA sleep controller. + * + * \note To minimize the code overhead, these functions do not feature + * interrupt-protected access since they are likely to be called inside + * interrupt handlers or in applications where such protection is not + * necessary. If such protection is needed, it must be ensured by the calling + * code. + * + * \section xmega_sleep_quickstart_section Quick Start Guide + * See \ref xmega_sleep_quickstart + * @{ + */ + +#if defined(__ICCAVR__) || defined(__DOXYGEN__) +# include +//! Macro for issuing the sleep instruction. +# define sleep_enter() __sleep() + +/** + * \brief Enable sleep + */ +static inline void sleep_enable(void) +{ + SLEEP.CTRL |= SLEEP_SEN_bm; +} + +/** + * \brief Disable sleep + */ +static inline void sleep_disable(void) +{ + SLEEP.CTRL &= ~SLEEP_SEN_bm; +} + +#elif defined(__GNUC__) +# include +# define sleep_enter() sleep_cpu() + +#else +# error Unsupported compiler. +#endif + +/** + * \brief Set new sleep mode + * + * \param mode Sleep mode, from the device IO header file. + */ +static inline void sleep_set_mode(enum SLEEP_SMODE_enum mode) +{ + SLEEP.CTRL = mode | (SLEEP.CTRL & ~SLEEP_SMODE_gm); +} + +//! @} + +/** + * \page xmega_sleep_quickstart Quick Start Guide for the XMEGA Sleep Driver + * + * This is the quick start guide for the \ref sleep_group "Sleep Driver", with + * step-by-step instructions on how to configure and use the driver for a + * specific use case. + * + * The section described below can be copied into, e.g. the main application + * loop or any other function that will need to control and execute different + * sleep modes on the device. + * + * \section xmega_sleep_quickstart_basic Basic usage of the sleep driver + * This use case will prepare the device to enter the Power Down sleep mode and + * then enter the sleep mode. After waking up it will disable sleep. + * + * \section xmega_sleep_basic_usage Usage steps + * \subsection xmega_sleep_basic_usage_code Example code + * Add to, e.g., the main loop in the application C-file: + * \code + sleep_set_mode(SLEEP_SMODE_PDOWN_gc); + sleep_enable(); + sleep_enter(); + sleep_disable(); +\endcode + * + * \subsection xmega_sleep_basic_usage Workflow + * -# Set what sleep mode to use, the different sleep modes can be found in the + * device header file under the enum definition SLEEP_SMODE_enum: + * - \code sleep_set_mode(SLEEP_SMODE_PDOWN_gc); \endcode + * -# Enable that the device are allowed to go to sleep: + * - \code sleep_enable(); \endcode + * - \note This function has to be called in order for the device to go to + * sleep. This is a safety feature to stop the device to go to sleep + * unintentionally, even though it is possible to have this enabled at all times + * it is recommended to enable sleep mode only when you intend to go to sleep + * within a few clock cycles. + * -# Enter sleep mode: + * - \code sleep_enter(); \endcode + * - \attention Make sure to enable global interrupt and the interrupt you + * plan to use as wake-up source for your device, do also pay special + * attention to what wake-up sources are available for the different sleep + * modes. Failing to enable interrupts may result in indefinite sleep until + * power is cycled! + * -# When the device is woken from sleep it will execute the interrupt handler + * related to the wakeup-source (interrupt source) and continue on the next line + * of code after the \ref sleep_enter() call. Make sure to disable sleep when + * waking up. + * - \code sleep_disable(); \endcode + * + * \subsection xmega_sleep_basic_sleep_modes Sleep Modes + * Possible sleep modes depend on the device that is used. Please refer to the + * device datasheet and header file to find these definitions. + * + * As an example the ATxmega32A4U device has the following sleep modes: + * - Idle sleep: SLEEP_SMODE_IDLE_gc + * - Power Down: SLEEP_SMODE_PDOWN_gc + * - Power Save: SLEEP_SMODE_PSAVE_gc + * - Standby: SLEEP_SMODE_STDBY_gc + * - Extended standby: SLEEP_SMODE_ESTDBY_gc + */ + +#endif /* SLEEP_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/sleep/sleep.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/sleep/sleep.h.REMOVED.git-id deleted file mode 100644 index e3396990..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/sleep/sleep.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8a218c4125a7db6afbdb3f22235b7b8d33f74d09 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/spi/spi.c b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/spi/spi.c new file mode 100644 index 00000000..37511077 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/spi/spi.c @@ -0,0 +1,119 @@ +/***************************************************************************** + * + * \file + * + * \brief SPI software driver functions. + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + *****************************************************************************/ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "spi.h" + +/*! \brief Calculates the SPI baudrate divider. + * + * \param baudrate The expected baudrate on the SPI. + * \param clkper_hz SPI module input clock frequency (Peripheral clock, Hz). + * \param spi The SPI module address + * + * \return Status of operation. + * \retval >=0 Success. + * \retval <0 Error. + */ +int8_t spi_xmega_set_baud_div(SPI_t *spi, uint32_t baudrate, uint32_t clkper_hz) +{ + uint32_t divisor; + uint8_t divisor_8bit; + uint8_t ctrl; + + // Sanity check, requested baudrate is lower than system clock + Assert(clkper_hz > baudrate); + + /* + * Get wanted divisor rounded up so we don't get speed higher than + * requested baudrate. + */ + divisor = (clkper_hz + baudrate - 1) / baudrate; + + if (divisor > 128) { + /* + * Highest possible divisor is 128 so fail since we can't get + * low enough baudrate. + */ + return -1; + } + + /* + * We now know that the divisor is 128 or lower so move it into a 8-bit + * variable to make sure the following comparison is more optimized. + */ + divisor_8bit = divisor; + + /* + * For divisor values between the possible ones round up to the closest + * higher one to avoid higher baudrate than requested. + */ + if (divisor_8bit > 64) { + ctrl = SPI_PRESCALER_DIV128_gc; + } + else if (divisor_8bit > 32) { + ctrl = SPI_PRESCALER_DIV64_gc; + } + else if (divisor_8bit > 16) { + ctrl = SPI_CLK2X_bm | SPI_PRESCALER_DIV64_gc; + } + else if (divisor_8bit > 8) { + ctrl = SPI_PRESCALER_DIV16_gc; + } + else if (divisor_8bit > 4) { + ctrl = SPI_CLK2X_bm | SPI_PRESCALER_DIV16_gc; + } + else if (divisor_8bit > 2) { + ctrl = SPI_PRESCALER_DIV4_gc; + } + else { + ctrl = SPI_CLK2X_bm | SPI_PRESCALER_DIV4_gc; + } + + // Update register and make sure to clear out any leftover bits + spi->CTRL = (spi->CTRL & ~(SPI_CLK2X_bm | SPI_PRESCALER_gm)) | ctrl; + + return 1; +} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/spi/spi.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/spi/spi.c.REMOVED.git-id deleted file mode 100644 index 9addfaf2..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/spi/spi.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -37511077cee6a54bab360f1040f13599b55910b1 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/spi/spi.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/spi/spi.h new file mode 100644 index 00000000..766f6329 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/spi/spi.h @@ -0,0 +1,166 @@ +/***************************************************************************** + * + * \file + * + * \brief SPI driver for AVR. + * + * This file defines a useful set of functions for the SPI interface on AVR + * devices. + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + ******************************************************************************/ +/* + * Support and FAQ: visit Atmel Support + */ + + +#ifndef _SPI_H_ +#define _SPI_H_ + +/** + * \defgroup group_xmega_drivers_spi SPI - Serial Peripheral Interface + * + * Driver for the Serial Peripheral Interface (SPI). + * Provides functions for configuring and using the SPI. + * + * \{ + */ + +#include "compiler.h" +#include "status_codes.h" +#include "ioport.h" + +/*! \brief Calculates the SPI baudrate divider. + * + * \param baudrate The expected baudrate on the SPI. + * \param clkper_hz SPI module input clock frequency (Peripheral clock, Hz). + * \param spi The SPI module address + * + * \return Divider or error code. + * \retval >=0 Success. + * \retval <0 Error. + */ +int8_t spi_xmega_set_baud_div(SPI_t *spi, uint32_t baudrate, uint32_t clkper_hz); + +/*! \brief Enables the SPI. + * + * \param spi Base address of the SPI instance. + */ +static inline void spi_enable(SPI_t *spi) +{ + spi->CTRL |= SPI_ENABLE_bm; +} + +/*! \brief Disables the SPI. + * + * Ensures that nothing is transferred while setting up buffers. + * + * \param spi Base address of the SPI instance. + * + * \warning This may cause data loss if used on a slave SPI. + */ +static inline void spi_disable(SPI_t *spi) +{ + spi->CTRL &= ~SPI_ENABLE_bm; +} + +/*! \brief Tests if the SPI is enabled. + * + * \param spi Base address of the SPI instance. + * + * \return \c 1 if the SPI is enabled, otherwise \c 0. + */ +static inline bool spi_is_enabled(SPI_t *spi) +{ + return spi->CTRL & SPI_ENABLE_bm ? true : false; +} + +/*! \brief Put one data byte to a SPI peripheral. + * + * \param spi Base address of the SPI instance. + * \param data The data byte to be loaded + * + */ +static inline void spi_put(SPI_t *spi, uint8_t data) +{ + spi->DATA = data; +} + +/*! \brief Get one data byte to a SPI peripheral. + * + * \param spi Base address of the SPI instance. + * \return The data byte + * + */ +static inline uint8_t spi_get(SPI_t *spi) +{ + return spi->DATA; +} + +/*! \brief Tests if the SPI contains a received character. + * + * \param spi Base address of the SPI instance. + * + * \return \c 1 if the SPI Receive Holding Register is full, otherwise \c 0. + */ +static inline bool spi_is_tx_ok(SPI_t *spi) +{ + return spi->STATUS & SPI_IF_bm ? true : false; +} + +/*! \brief Activate SPI master mode of a SPI peripheral + * + * \param spi Base address of the SPI instance. + * + * \warning This may cause data loss if used on a slave SPI. + */ +static inline void spi_enable_master_mode(SPI_t *spi) +{ + spi->CTRL |= SPI_MASTER_bm; +} + +/*! \name Part Specific SPI Driver + */ +//! @{ +//! @} + +/** + * \} + */ + +#endif // _SPI_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/spi/spi.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/spi/spi.h.REMOVED.git-id deleted file mode 100644 index 4f6d4ba3..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/spi/spi.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -766f6329505a0c34e22436ae8defc789672a8ffc \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usart/usart.c b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usart/usart.c new file mode 100644 index 00000000..a4bc1421 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usart/usart.c @@ -0,0 +1,467 @@ +/** + * \file + * + * \brief USART driver for AVR XMEGA. + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#include +#include "compiler.h" +#include "usart.h" +#include "sysclk.h" +#include "ioport.h" +#include "status_codes.h" + +/* + * Fix XMEGA header files + * USART.CTRLC bit masks and bit positions + */ +#ifndef USART_UCPHA_bm +# define USART_UCPHA_bm 0x02 +#endif +#ifndef USART_DORD_bm +# define USART_DORD_bm 0x04 +#endif + +/** + * \brief Initialize USART in RS232 mode. + * + * This function initializes the USART module in RS232 mode using the + * usart_rs232_options_t configuration structure and CPU frequency. + * + * \param usart The USART module. + * \param opt The RS232 configuration option. + * + * \retval true if the initialization was successfull + * \retval false if the initialization failed (error in baud rate calculation) + */ +bool usart_init_rs232(USART_t *usart, const usart_rs232_options_t *opt) +{ + bool result; + sysclk_enable_peripheral_clock(usart); + usart_set_mode(usart, USART_CMODE_ASYNCHRONOUS_gc); + usart_format_set(usart, opt->charlength, opt->paritytype, + opt->stopbits); + result = usart_set_baudrate(usart, opt->baudrate, sysclk_get_per_hz()); + usart_tx_enable(usart); + usart_rx_enable(usart); + + return result; +} + +/** + * \brief Initialize USART in SPI master mode. + * + * This function initializes the USART module in SPI master mode using the + * usart_spi_options_t configuration structure and CPU frequency. + * + * \param usart The USART module. + * \param opt The RS232 configuration option. + */ +void usart_init_spi(USART_t *usart, const usart_spi_options_t *opt) +{ + ioport_pin_t sck_pin; + bool invert_sck; + + sysclk_enable_peripheral_clock(usart); + + usart_rx_disable(usart); + + /* configure Clock polarity using INVEN bit of the correct SCK I/O port **/ + invert_sck = (opt->spimode == 2) || (opt->spimode == 3); + UNUSED(invert_sck); + +#ifdef USARTC0 + if ((uint16_t)usart == (uint16_t)&USARTC0) { +# ifdef PORT_USART0_bm + if (PORTC.REMAP & PORT_USART0_bm) { + sck_pin = IOPORT_CREATE_PIN(PORTC, 5); + } else { + sck_pin = IOPORT_CREATE_PIN(PORTC, 1); + } +# else + sck_pin = IOPORT_CREATE_PIN(PORTC, 1); +# endif + } +#endif +#ifdef USARTC1 + if ((uint16_t)usart == (uint16_t)&USARTC1) { + sck_pin = IOPORT_CREATE_PIN(PORTC, 5); + } +#endif +#ifdef USARTD0 + if ((uint16_t)usart == (uint16_t)&USARTD0) { +# ifdef PORT_USART0_bm + if (PORTD.REMAP & PORT_USART0_bm) { + sck_pin = IOPORT_CREATE_PIN(PORTD, 5); + } else { + sck_pin = IOPORT_CREATE_PIN(PORTD, 1); + } +# else + sck_pin = IOPORT_CREATE_PIN(PORTD, 1); +# endif + } +#endif +#ifdef USARTD1 + if ((uint16_t)usart == (uint16_t)&USARTD1) { + sck_pin = IOPORT_CREATE_PIN(PORTD, 5); + } +#endif +#ifdef USARTE0 + if ((uint16_t)usart == (uint16_t)&USARTE0) { +# ifdef PORT_USART0_bm + if(PORTE.REMAP & PORT_USART0_bm) { + sck_pin = IOPORT_CREATE_PIN(PORTE, 5); + } else { + sck_pin = IOPORT_CREATE_PIN(PORTE, 1); + } +# else + sck_pin = IOPORT_CREATE_PIN(PORTE, 1); +# endif + } +#endif +#ifdef USARTE1 + if ((uint16_t)usart == (uint16_t)&USARTE1) { + sck_pin = IOPORT_CREATE_PIN(PORTE, 5); + } +#endif +#ifdef USARTF0 + if ((uint16_t)usart == (uint16_t)&USARTF0) { +# ifdef PORT_USART0_bm + if(PORTF.REMAP & PORT_USART0_bm) { + sck_pin = IOPORT_CREATE_PIN(PORTF, 5); + } else { + sck_pin = IOPORT_CREATE_PIN(PORTF, 1); + } +# else + sck_pin = IOPORT_CREATE_PIN(PORTF, 1); +# endif + } +#endif +#ifdef USARTF1 + if ((uint16_t)usart == (uint16_t)&USARTF1) { + sck_pin = IOPORT_CREATE_PIN(PORTF, 5); + } +#endif + + /* Configure the USART output pin */ + ioport_set_pin_dir(sck_pin, IOPORT_DIR_OUTPUT); + ioport_set_pin_mode(sck_pin, + IOPORT_MODE_TOTEM | (invert_sck? IOPORT_MODE_INVERT_PIN : 0)); + ioport_set_pin_level(sck_pin, IOPORT_PIN_LEVEL_HIGH); + + usart_set_mode(usart, USART_CMODE_MSPI_gc); + + if (opt->spimode == 1 || opt->spimode == 3) { + usart->CTRLC |= USART_UCPHA_bm; + } else { + usart->CTRLC &= ~USART_UCPHA_bm; + } + if (opt->data_order) { + (usart)->CTRLC |= USART_DORD_bm; + } else { + (usart)->CTRLC &= ~USART_DORD_bm; + } + + usart_spi_set_baudrate(usart, opt->baudrate, sysclk_get_per_hz()); + usart_tx_enable(usart); + usart_rx_enable(usart); +} + +/** + * \brief Send a data with the USART module + * + * This function outputs a data using the USART module. + * + * \param usart The USART module. + * \param c The data to send. + * + * \return STATUS_OK + */ +enum status_code usart_putchar(USART_t *usart, uint8_t c) +{ + while (usart_data_register_is_empty(usart) == false) { + } + + (usart)->DATA = c; + return STATUS_OK; +} + +/** + * \brief Receive a data with the USART module + * + * This function returns the received data from the USART module. + * + * \param usart The USART module. + * + * \return The received data. + */ +uint8_t usart_getchar(USART_t *usart) +{ + while (usart_rx_is_complete(usart) == false) { + } + + return ((uint8_t)(usart)->DATA); +} + +/** + * \brief Get the offset for lookup in the baudrate table + * + * \param baud The requested baudrate + * + * \return The baudrate offset in PROGMEM table + * \retval USART_BAUD_UNDEFINED for baudrates not in lookup table + */ +static uint8_t usart_get_baud_offset(uint32_t baud) +{ + switch (baud) { + case 1200: + return (uint8_t)USART_BAUD_1200; + + case 2400: + return (uint8_t)USART_BAUD_2400; + + case 4800: + return (uint8_t)USART_BAUD_4800; + + case 9600: + return (uint8_t)USART_BAUD_9600; + + case 19200: + return (uint8_t)USART_BAUD_19200; + + case 38400: + return (uint8_t)USART_BAUD_38400; + + case 57600: + return (uint8_t)USART_BAUD_57600; + + default: + return (uint8_t)USART_BAUD_UNDEFINED; + } +} + +/** + * \brief Set the baudrate by setting the BSEL and BSCALE values in the USART + * + * This function sets the selected BSEL and BSCALE value in the BAUDCTRL + * registers with BSCALE 0. For calculation options, see table 21-1 in XMEGA A + * manual. + * + * \param usart The USART module. + * \param bsel Calculated BSEL value. + * \param bscale Calculated BSEL value. + * + */ +void usart_set_bsel_bscale_value(USART_t *usart, uint16_t bsel, uint8_t bscale) +{ + (usart)->BAUDCTRLA = (uint8_t)(bsel); + (usart)->BAUDCTRLB = (uint8_t)(((bsel >> 8) & 0X0F) | (bscale << 4)); +} + +/** + * \brief Set the baudrate using precalculated BAUDCTRL values from PROGMEM + * + * \note This function only works for cpu_hz 2Mhz or 32Mhz and baudrate values + * 1200, 2400, 4800, 9600, 19200, 38400 and 57600. + * + * \param usart The USART module. + * \param baud The baudrate. + * \param cpu_hz The CPU frequency. + * + */ +void usart_set_baudrate_precalculated(USART_t *usart, uint32_t baud, + uint32_t cpu_hz) +{ + uint8_t baud_offset; + uint16_t baudctrl = 0; + + baud_offset = usart_get_baud_offset(baud); + + if (cpu_hz == 2000000UL) { + baudctrl = PROGMEM_READ_WORD(baudctrl_2mhz + baud_offset); + } else if (cpu_hz == 32000000UL) { + baudctrl = PROGMEM_READ_WORD(baudctrl_32mhz + baud_offset); + } else { + /* Error, system clock speed or USART baud rate is not supported + * by the look-up table */ + Assert(false); + } + + if (baud_offset != USART_BAUD_UNDEFINED) { + (usart)->BAUDCTRLB = (uint8_t)((uint16_t)baudctrl); + (usart)->BAUDCTRLA = (uint8_t)((uint16_t)baudctrl >> 8); + } +} + +/** + * \brief Set the baudrate value in the USART module + * + * This function sets the baudrate register with scaling regarding the CPU + * frequency and makes sure the baud rate is supported by the hardware. + * The function can be used if you don't want to calculate the settings + * yourself or changes to baudrate at runtime is required. + * + * \param usart The USART module. + * \param baud The baudrate. + * \param cpu_hz The CPU frequency. + * + * \retval true if the hardware supports the baud rate + * \retval false if the hardware does not support the baud rate (i.e. it's + * either too high or too low.) + */ +bool usart_set_baudrate(USART_t *usart, uint32_t baud, uint32_t cpu_hz) +{ + int8_t exp; + uint32_t div; + uint32_t limit; + uint32_t ratio; + uint32_t min_rate; + uint32_t max_rate; + + /* + * Check if the hardware supports the given baud rate + */ + /* 8 = (2^0) * 8 * (2^0) = (2^BSCALE_MIN) * 8 * (BSEL_MIN) */ + max_rate = cpu_hz / 8; + /* 4194304 = (2^7) * 8 * (2^12) = (2^BSCALE_MAX) * 8 * (BSEL_MAX+1) */ + min_rate = cpu_hz / 4194304; + + if (!((usart)->CTRLB & USART_CLK2X_bm)) { + max_rate /= 2; + min_rate /= 2; + } + + if ((baud > max_rate) || (baud < min_rate)) { + return false; + } + + /* Check if double speed is enabled. */ + if (!((usart)->CTRLB & USART_CLK2X_bm)) { + baud *= 2; + } + + /* Find the lowest possible exponent. */ + limit = 0xfffU >> 4; + ratio = cpu_hz / baud; + + for (exp = -7; exp < 7; exp++) { + if (ratio < limit) { + break; + } + + limit <<= 1; + + if (exp < -3) { + limit |= 1; + } + } + + /* + * Depending on the value of exp, scale either the input frequency or + * the target baud rate. By always scaling upwards, we never introduce + * any additional inaccuracy. + * + * We are including the final divide-by-8 (aka. right-shift-by-3) in + * this operation as it ensures that we never exceeed 2**32 at any + * point. + * + * The formula for calculating BSEL is slightly different when exp is + * negative than it is when exp is positive. + */ + if (exp < 0) { + /* We are supposed to subtract 1, then apply BSCALE. We want to + * apply BSCALE first, so we need to turn everything inside the + * parenthesis into a single fractional expression. + */ + cpu_hz -= 8 * baud; + + /* If we end up with a left-shift after taking the final + * divide-by-8 into account, do the shift before the divide. + * Otherwise, left-shift the denominator instead (effectively + * resulting in an overall right shift.) + */ + if (exp <= -3) { + div = ((cpu_hz << (-exp - 3)) + baud / 2) / baud; + } else { + baud <<= exp + 3; + div = (cpu_hz + baud / 2) / baud; + } + } else { + /* We will always do a right shift in this case, but we need to + * shift three extra positions because of the divide-by-8. + */ + baud <<= exp + 3; + div = (cpu_hz + baud / 2) / baud - 1; + } + + (usart)->BAUDCTRLB = (uint8_t)(((div >> 8) & 0X0F) | (exp << 4)); + (usart)->BAUDCTRLA = (uint8_t)div; + + return true; +} + +/** + * \brief Set the baudrate value in the USART_SPI module + * + * This function sets the baudrate register regarding the CPU frequency. + * + * \param usart The USART(SPI) module. + * \param baud The baudrate. + * \param cpu_hz The CPU frequency. + */ +void usart_spi_set_baudrate(USART_t *usart, uint32_t baud, uint32_t cpu_hz) +{ + uint16_t bsel_value; + + /* Check if baudrate is less than the maximim limit specified in + * datasheet */ + if (baud < (cpu_hz / 2)) { + bsel_value = (cpu_hz / (baud * 2)) - 1; + } else { + /* If baudrate is not within the specfication in datasheet, + * assign maximum baudrate possible for the current CPU frequency */ + bsel_value = 0; + } + + (usart)->BAUDCTRLB = (uint8_t)((~USART_BSCALE_gm) & (bsel_value >> 8)); + (usart)->BAUDCTRLA = (uint8_t)(bsel_value); +} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usart/usart.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usart/usart.c.REMOVED.git-id deleted file mode 100644 index a106d2d3..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usart/usart.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a4bc1421538c0809a45eafa36373c24a2deddb0e \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usart/usart.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usart/usart.h new file mode 100644 index 00000000..8a3cb986 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usart/usart.h @@ -0,0 +1,558 @@ +/** + * \file + * + * \brief USART driver for AVR XMEGA. + * + * This file contains basic functions for the AVR XMEGA USART, with support for all + * modes, settings and clock speeds. + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef _USART_H_ +#define _USART_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "compiler.h" +#include "pmic.h" + +/** + * \defgroup usart_group USART module (USART) + * + * See \ref xmega_usart_quickstart. + * + * This is a driver for configuring, enabling, disabling and use of the on-chip + * USART. + * + * \section dependencies Dependencies + * + * The USART module depends on the following modules: + * - \ref sysclk_group for peripheral clock control. + * - \ref port_driver_group for peripheral io port control. + * + * @{ + */ + +//! Offset in lookup table for baudrate 1200 +#define USART_BAUD_1200 0x00 +//! Offset in lookup table for baudrate 2400 +#define USART_BAUD_2400 0x01 +//! Offset in lookup table for baudrate 4800 +#define USART_BAUD_4800 0x02 +//! Offset in lookup table for baudrate 9600 +#define USART_BAUD_9600 0x03 +//! Offset in lookup table for baudrate 19200 +#define USART_BAUD_19200 0x04 +//! Offset in lookup table for baudrate 38400 +#define USART_BAUD_38400 0x05 +//! Offset in lookup table for baudrate 57600 +#define USART_BAUD_57600 0x06 +//! Baudrate not in lookup table +#define USART_BAUD_UNDEFINED 0xFF + +//! Lookup table containing baudctrl values for CPU frequency 2 Mhz +static PROGMEM_DECLARE(uint16_t, baudctrl_2mhz[]) = { + 0xE5BC, // Baud: 1200 + 0xC5AC, // Baud: 2400 + 0x859C, // Baud: 4800 + 0x0396, // Baud: 9600 + 0xC192, // Baud: 19200 + 0x2191, // Baud: 38400 + 0x9690, // Baud: 57600 +}; + +//! Lookup table containing baudctrl values for CPU frequency 32 Mhz +static PROGMEM_DECLARE(uint16_t, baudctrl_32mhz[]) = { + 0x031D, // Baud: 1200 + 0x01ED, // Baud: 2400 + 0xFDDC, // Baud: 4800 + 0xF5CC, // Baud: 9600 + 0xE5BC, // Baud: 19200 + 0xC5AC, // Baud: 38400 + 0x6EA8, // Baud: 57600 +}; + + +//! Input parameters when initializing RS232 and similar modes. +typedef struct usart_rs232_options { + //! Set baud rate of the USART (unused in slave modes). + uint32_t baudrate; + + //! Number of bits to transmit as a character (5 to 9). + USART_CHSIZE_t charlength; + + //! Parity type: USART_PMODE_DISABLED_gc, USART_PMODE_EVEN_gc, + //! USART_PMODE_ODD_gc. + USART_PMODE_t paritytype; + + //! Number of stop bits between two characters: + //! true: 2 stop bits + //! false: 1 stop bit + bool stopbits; + +} usart_rs232_options_t; + +//! Input parameters when initializing SPI master mode. +typedef struct usart_spi_options { + //! Set baud rate of the USART in SPI mode. + uint32_t baudrate; + + //! SPI transmission mode. + uint8_t spimode; + + uint8_t data_order; +} usart_spi_options_t; + +//! USART interrupt levels +enum usart_int_level_t { + USART_INT_LVL_OFF = 0x00, + USART_INT_LVL_LO = 0x01, + USART_INT_LVL_MED = 0x02, + USART_INT_LVL_HI = 0x03, +}; + +/** + * \brief Enable USART receiver. + * + * \param usart Pointer to the USART module + */ +static inline void usart_rx_enable(USART_t *usart) +{ + (usart)->CTRLB |= USART_RXEN_bm; +} + +/** + * \brief Disable USART receiver. + * + * \param usart Pointer to the USART module. + */ +static inline void usart_rx_disable(USART_t *usart) +{ + (usart)->CTRLB &= ~USART_RXEN_bm; +} + +/** + * \brief Configure the USART frame format. + * + * Sets the frame format, Frame Size, parity mode and number of stop bits. + * + * \param usart Pointer to the USART module + * \param charSize The character size. Use USART_CHSIZE_t type. + * \param parityMode The parity Mode. Use USART_PMODE_t type. + * \param twoStopBits Enable two stop bit mode. Use bool type. + */ +static inline void usart_format_set(USART_t *usart, USART_CHSIZE_t charSize, + USART_PMODE_t parityMode, bool twoStopBits) +{ + (usart)->CTRLC = (uint8_t)charSize | parityMode + | (twoStopBits ? USART_SBMODE_bm : 0); +} + +/** + * \brief Enable USART transmitter. + * + * \param usart Pointer to the USART module. + */ +static inline void usart_tx_enable(USART_t *usart) +{ + (usart)->CTRLB |= USART_TXEN_bm; +} + +/** + * \brief Disable USART transmitter. + * + * \param usart Pointer to the USART module. + */ +static inline void usart_tx_disable(USART_t *usart) +{ + (usart)->CTRLB &= ~USART_TXEN_bm; +} + +/** + * \brief Set USART RXD interrupt level. + * + * Sets the interrupt level on RX Complete interrupt. + * + * \param usart Pointer to the USART module. + * \param level Interrupt level of the RXD interrupt. + */ +static inline void usart_set_rx_interrupt_level(USART_t *usart, + enum usart_int_level_t level) +{ + (usart)->CTRLA = ((usart)->CTRLA & ~USART_RXCINTLVL_gm) | + (level << USART_RXCINTLVL_gp); +} + +/** + * \brief Set USART TXD interrupt level. + * + * Sets the interrupt level on TX Complete interrupt. + * + * \param usart Pointer to the USART module. + * \param level Interrupt level of the TXD interrupt. + */ +static inline void usart_set_tx_interrupt_level(USART_t *usart, + enum usart_int_level_t level) +{ + (usart)->CTRLA = ((usart)->CTRLA & ~USART_TXCINTLVL_gm) | + (level << USART_TXCINTLVL_gp); +} + +/** + * \brief Set USART DRE interrupt level. + * + * Sets the interrupt level on Data Register interrupt. + * + * \param usart Pointer to the USART module. + * \param level Interrupt level of the DRE interrupt. + * Use USART_DREINTLVL_t type. + */ +static inline void usart_set_dre_interrupt_level(USART_t *usart, + enum usart_int_level_t level) +{ + (usart)->CTRLA = ((usart)->CTRLA & ~USART_DREINTLVL_gm) | + (level << USART_DREINTLVL_gp); +} + +/** + * \brief Set the mode the USART run in. + * + * Set the mode the USART run in. The default mode is asynchronous mode. + * + * \param usart Pointer to the USART module register section. + * \param usartmode Selects the USART mode. Use USART_CMODE_t type. + * + * USART modes: + * - 0x0 : Asynchronous mode. + * - 0x1 : Synchronous mode. + * - 0x2 : IrDA mode. + * - 0x3 : Master SPI mode. + */ +static inline void usart_set_mode(USART_t *usart, USART_CMODE_t usartmode) +{ + (usart)->CTRLC = ((usart)->CTRLC & (~USART_CMODE_gm)) | usartmode; +} + +/** + * \brief Check if data register empty flag is set. + * + * \param usart The USART module. + */ +static inline bool usart_data_register_is_empty(USART_t * usart) +{ + return (usart)->STATUS & USART_DREIF_bm; +} + +/** + * \brief Checks if the RX complete interrupt flag is set. + * + * Checks if the RX complete interrupt flag is set. + * + * \param usart The USART module. + */ +static inline bool usart_rx_is_complete(USART_t * usart) +{ + return (usart)->STATUS & USART_RXCIF_bm; +} + +/** + * \brief Checks if the TX complete interrupt flag is set. + * + * Checks if the TX complete interrupt flag is set. + * + * \param usart The USART module. + */ +static inline bool usart_tx_is_complete(USART_t * usart) +{ + return (usart)->STATUS & USART_TXCIF_bm; +} + +/** + * \brief Clear TX complete interrupt flag. + * + * \param usart The USART module. + */ +static inline void usart_clear_tx_complete(USART_t * usart) +{ + (usart)->STATUS = USART_TXCIF_bm; +} + +/** + * \brief Clear RX complete interrupt flag. + * + * \param usart The USART module. + */ +static inline void usart_clear_rx_complete(USART_t *usart) +{ + (usart)->STATUS = USART_RXCIF_bm; +} + +/** + * \brief Write a data to the USART data register. + * + * \param usart The USART module. + * \param txdata The data to be transmitted. + */ +static inline void usart_put(USART_t * usart, uint8_t txdata) +{ + (usart)->DATA = txdata; +} + +/** + * \brief Read a data to the USART data register. + * + * \param usart The USART module. + * + * \return The received data + */ +static inline uint8_t usart_get(USART_t * usart) +{ + return (usart)->DATA; +} + +/** + * \brief Performs a data transfer on the USART in SPI mode. + * + * \param usart The USART module. + * \param txdata The data to be transmitted. + * + * \return The received data + */ +static inline uint8_t usart_spi_transmit(USART_t * usart, + uint8_t txdata) +{ + while (usart_data_register_is_empty(usart) == false); + usart_put(usart, txdata); + while (!usart_tx_is_complete(usart)); + usart_clear_tx_complete(usart); + return usart_get(usart); +} + +bool usart_init_rs232(USART_t *usart, const usart_rs232_options_t *opt); +void usart_init_spi(USART_t * usart, const usart_spi_options_t * opt); + +enum status_code usart_putchar(USART_t * usart, uint8_t c); +uint8_t usart_getchar(USART_t * usart); + +void usart_set_bsel_bscale_value(USART_t *usart, uint16_t bsel, uint8_t bscale); +void usart_set_baudrate_precalculated(USART_t *usart, uint32_t baud, + uint32_t cpu_hz); +bool usart_set_baudrate(USART_t *usart, uint32_t baud, uint32_t cpu_hz); +void usart_spi_set_baudrate(USART_t * usart, uint32_t baud, uint32_t cpu_hz); +//! @} + +#ifdef __cplusplus +} +#endif + +/** + * \page xmega_usart_quickstart Quick start guide for USART module + * + * This is the quick start guide for the \ref usart_group "USART module", with + * step-by-step instructions on how to configure and use the driver in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section usart_basic_use_case Basic use case + * \section usart_use_cases USART use cases + * - \ref usart_basic_use_case + * - \subpage usart_use_case_1 + * + * \section usart_basic_use_case Basic use case - transmit a character + * In this use case, the USART module is configured for: + * - Using USARTD0 + * - Baudrate: 9600 + * - Character length: 8 bit + * - Parity mode: Disabled + * - Stop bit: None + * - RS232 mode + * + * \section usart_basic_use_case_setup Setup steps + * + * \subsection usart_basic_use_case_setup_prereq Prerequisites + * -# \ref sysclk_group + * \subsection usart_basic_use_case_setup_code Example code + * The following configuration must be added to the project (typically to a + * conf_usart.h file, but it can also be added to your main application file.) + * \code + #define USART_SERIAL &USARTD0 + #define USART_SERIAL_BAUDRATE 9600 + #define USART_SERIAL_CHAR_LENGTH USART_CHSIZE_8BIT_gc + #define USART_SERIAL_PARITY USART_PMODE_DISABLED_gc + #define USART_SERIAL_STOP_BIT false +\endcode + * + * Add to application initialization: + * \code + sysclk_init(); + static usart_rs232_options_t USART_SERIAL_OPTIONS = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; + sysclk_enable_module(SYSCLK_PORT_D, PR_USART0_bm); + usart_init_rs232(USART_SERIAL, &USART_SERIAL_OPTIONS); +\endcode + * + * \subsection usart_basic_use_case_setup_flow Workflow + * -# Initialize system clock: + * - \code sysclk_init(); \endcode + * - \note Not always required, but since the \ref usart_group driver is + * dependent on \ref sysclk_group it is good practise to initialize + * this module. + * -# Create USART options struct: + * - \code + static usart_rs232_options_t USART_SERIAL_OPTIONS = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; +\endcode + * -# Enable the clock for the USART module: + * - \code sysclk_enable_module(SYSCLK_PORT_D, PR_USART0_bm); \endcode + * -# Initialize in RS232 mode: + * - \code usart_init_rs232(USART_SERIAL, &USART_SERIAL_OPTIONS); +\endcode + * + * \section usart_basic_use_case_usage Usage steps + * + * \subsection usart_basic_use_case_usage_code Example code + * Add to application C-file: + * \code + usart_putchar(USART_SERIAL, 'a'); +\endcode + * + * \subsection usart_basic_use_case_usage_flow Workflow + * -# Send an 'a' character via USART + * - \code usart_putchar(USART_SERIAL, 'a'); \endcode + */ + +/** + * \page usart_use_case_1 USART receive character and echo back + * + * In this use case, the USART module is configured for: + * - Using USARTD0 + * - Baudrate: 9600 + * - Character length: 8 bit + * - Parity mode: Disabled + * - Stop bit: None + * - RS232 mode + * + * The use case waits for a received character on the configured USART and + * echoes the character back to the same USART. + * + * \section usart_use_case_1_setup Setup steps + * + * \subsection usart_use_case_1_setup_prereq Prerequisites + * -# \ref sysclk_group + * + * \subsection usart_use_case_1_setup_code Example code + * -# The following configuration must be added to the project (typically to a + * conf_usart.h file, but it can also be added to your main application file.): + * \code + #define USART_SERIAL &USARTD0 + #define USART_SERIAL_BAUDRATE 9600 + #define USART_SERIAL_CHAR_LENGTH USART_CHSIZE_8BIT_gc + #define USART_SERIAL_PARITY USART_PMODE_DISABLED_gc + #define USART_SERIAL_STOP_BIT false +\endcode + * + * A variable for the received byte must be added: + * \code uint8_t received_byte; \endcode + * + * Add to application initialization: + * \code + sysclk_init(); + static usart_rs232_options_t USART_SERIAL_OPTIONS = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; + sysclk_enable_module(SYSCLK_PORT_D, PR_USART0_bm); + usart_init_rs232(USART_SERIAL, &USART_SERIAL_OPTIONS); +\endcode + * + * \subsection usart_use_case_1_setup_flow Workflow + * -# Initialize system clock: + * - \code sysclk_init(); \endcode + * - \note Not always required, but since the \ref usart_group driver is + * dependent on \ref sysclk_group it is good practise to initialize + * this module. + * -# Create USART options struct: + * - \code + static usart_rs232_options_t USART_SERIAL_OPTIONS = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; +\endcode + * -# Enable the clock for the USART module: + * - \code sysclk_enable_module(SYSCLK_PORT_D, PR_USART0_bm); \endcode + * -# Initialize in RS232 mode: + * - \code usart_init_rs232(USART_SERIAL, &USART_SERIAL_OPTIONS); +\endcode + * + * \section usart_use_case_1_usage Usage steps + * + * \subsection usart_use_case_1_usage_code Example code + * Add to, e.g., main loop in application C-file: + * \code + received_byte = usart_getchar(USART_SERIAL); + usart_putchar(USART_SERIAL, received_byte); +\endcode + * + * \subsection usart_use_case_1_usage_flow Workflow + * -# Wait for reception of a character: + * - \code received_byte = usart_getchar(USART_SERIAL); \endcode + * -# Echo the character back: + * - \code usart_putchar(USART_SERIAL, received_byte); \endcode + */ + +#endif // _USART_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usart/usart.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usart/usart.h.REMOVED.git-id deleted file mode 100644 index 0dacd37d..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usart/usart.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8a3cb98638b9d0e769d90a18e60674f3aa3c2b49 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usb/usb_device.c b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usb/usb_device.c new file mode 100644 index 00000000..a0b77ded --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usb/usb_device.c @@ -0,0 +1,1460 @@ +/** + * \file + * + * \brief USB Device driver + * Compliance with common driver UDD + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#include "conf_usb.h" + +// Read Modify Write opcode is implemented after IAR AVR 5.51 +#ifdef __ICCAVR__ +# if (__VER__ <= 551 || (__VER__ <= 611 && XMEGA_A1U) ) +# undef USB_WORKAROUND_DO_NOT_USE_RMW +# define USB_WORKAROUND_DO_NOT_USE_RMW +# endif +#endif + +#include "sysclk.h" +#include "udd.h" +#include "usb_device.h" +#include + +#ifndef UDD_NO_SLEEP_MGR +#include "sleepmgr.h" +#endif + +#ifndef UDD_USB_INT_LEVEL +// By default USB interrupt have low priority +# define UDD_USB_INT_LEVEL USB_INTLVL_MED_gc +#endif + + + +#ifdef USB_DEVICE_HS_SUPPORT +#error This product does not support high speed mode, please remove define USB_DEVICE_HS_SUPPORT in conf_usb.h +#endif + +//////////////////////////////////////////////////// +// USBB Device low-level driver (UDD) +//////////////////////////////////////////////////// +/** + * \ingroup udd_group + * \defgroup udd_xmega_usb_group Xmega USB Device Driver + * + * \section USBB_CONF USBB Custom configuration + * The following USBB driver configuration must be included in the conf_usb.h + * file of the application. + * + * UDD_USB_INT_LEVEL
+ * Option to change the interrupt priority (USB_INTLVL_x_gc) + * by default USB_INTLVL_LO_gc (recommended). + * + * \section Callbacks management + * The USB driver is fully managed by interrupt and does not request periodic + * task. Thereby, the USB events use callbacks to transfer the information. + * The callbacks are declared in static during compilation or in variable during + * code execution. + * + * Static declarations defined in conf_usb.h: + * - UDC_VBUS_EVENT(bool b_present)
+ * To signal Vbus level change + * - UDC_SUSPEND_EVENT()
+ * Called when USB bus enter in suspend mode + * - UDC_RESUME_EVENT()
+ * Called when USB bus is wakeup + * - UDC_SOF_EVENT()
+ * Called for each received SOF, Note: Each 1ms in HS/FS mode only. + * + * Dynamic callbacks, called "endpoint job" , are registered + * in udd_ep_job_t structure via the following functions: + * - udd_ep_run()
+ * To call it when a transfer is finish + * - udd_ep_wait_stall_clear()
+ * To call it when a endpoint halt is disabled + * + * \section Power mode management + * The Sleep modes authorized : + * - in USB IDLE state, the USB needs of USB clock and authorizes up to IDLE mode + * - in USB SUSPEND state, the USB no needs USB clock but requests a minimum + * clock restart timing. Thus, it authorizes up to POWER_DOWN or STANDBY mode. + * + * The USB_SLEEP_MODE_USB_IDLE equals SLEEPMGR_IDLE. + * + * The USB_SLEEP_MODE_USB_SUSPEND depends on USB clock startup timing: + * | Clock Startup | Sleep mode authorized | + * | >10ms | SLEEPMGR_STDBY | + * | <=10ms | SLEEPMGR_PDOWN | + * + * @{ + */ + + +// Check USB Device configuration +#ifndef USB_DEVICE_EP_CTRL_SIZE +# error USB_DEVICE_EP_CTRL_SIZE not defined +#endif +#ifndef USB_DEVICE_MAX_EP +# error USB_DEVICE_MAX_EP not defined +#endif + + +/** + * \name Power management routine. + */ +//@{ + + +#ifndef UDD_NO_SLEEP_MGR + +//! Definition of sleep levels +#if ((defined USB_DEVICE_HS_SUPPORT) && (USBCLK_STARTUP_TIMEOUT>3000)) \ + || ((!defined USB_DEVICE_HS_SUPPORT) && (USBCLK_STARTUP_TIMEOUT>10000)) +# define USBC_SLEEP_MODE_USB_SUSPEND SLEEPMGR_IDLE +#else +# define USBC_SLEEP_MODE_USB_SUSPEND SLEEPMGR_PDOWN +#endif +#define USBC_SLEEP_MODE_USB_IDLE SLEEPMGR_IDLE + +//! State of USB line +static bool udd_b_idle; + + +/*! \brief Authorize or not the CPU powerdown mode + * + * \param b_enable true to authorize powerdown mode + */ +static void udd_sleep_mode(bool b_idle) +{ + if (!b_idle && udd_b_idle) { + sleepmgr_unlock_mode(USBC_SLEEP_MODE_USB_IDLE); + } + if (b_idle && !udd_b_idle) { + sleepmgr_lock_mode(USBC_SLEEP_MODE_USB_IDLE); + } + udd_b_idle = b_idle; +} +#else + +static void udd_sleep_mode(bool b_idle) { +} +#endif // UDD_NO_SLEEP_MGR + +//@} + +/** + * \brief USB SRAM data about fifo, endpoint descriptor table and frame number + * + * The content of the USB SRAM can be: + * - modified by USB hardware by interface to signal endpoint status. + * Thereby, it is read by software. + * - modified by USB software to control endpoint. + * Thereby, it is read by hardware. + * This data section is volatile and the specific opcode read/modify/write must be used. + * + * @{ + */ +struct udd_sram_data { +#if XMEGA_A1U +# if (0!=((USB_DEVICE_MAX_EP+1)%4)) + uint8_t padding_align[16 - ((USB_DEVICE_MAX_EP + 1) * + sizeof(uint32_t)) % 16]; +# endif +#endif + uint32_t fifo[USB_DEVICE_MAX_EP + 1]; + USB_EP_t ep_ctrl[2 * (USB_DEVICE_MAX_EP + 1)]; + uint16_t frame_number; +}; +#if XMEGA_A1U +COMPILER_ALIGNED(16) +#else +COMPILER_ALIGNED(4) //! Caution seems GCC does not handle 2 alignment properly +#endif +static volatile struct udd_sram_data udd_sram; +#define UDD_EP_t USB_EP_t volatile + +// @} + +/** + * \name initialization of endpoint + */ +//@{ +/** + * \brief Configures and enables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * \param bmAttributes Attribute of endpoint declared in descriptor. + * \param MaxEndpointSize Endpoint size maximum + */ +static void udd_ep_init(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize); + +/** + * \brief Returns a pointer on endpoint control SRAM corresponding at endpoint number + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * + * \return endpoint descriptor index + */ +static UDD_EP_t *udd_ep_get_ctrl(udd_ep_id_t ep); +//@} + + +/** + * \name Control endpoint low level management routine. + * + * This function performs control endpoint management. + * It handle the SETUP/DATA/HANDSHAKE phases of a control transaction. + */ +//@{ + +//! Global variable to give and record information about setup request management +udd_ctrl_request_t udd_g_ctrlreq; + +//! Bit definitions about endpoint control state machine for udd_ep_control_state +typedef enum { + UDD_EPCTRL_SETUP = 0, //!< Wait a SETUP packet + UDD_EPCTRL_DATA_OUT = 1, //!< Wait a OUT data packet + UDD_EPCTRL_DATA_IN = 2, //!< Wait a IN data packet + UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP = 3, //!< Wait a IN ZLP packet + UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP = 4, //!< Wait a OUT ZLP packet + UDD_EPCTRL_STALL_REQ = 5, //!< STALL enabled on IN & OUT packet +} udd_ctrl_ep_state_t; + +//! State of the endpoint control management +static udd_ctrl_ep_state_t udd_ep_control_state; +//! Total number of data received/sent during data packet phase with previous payload buffers +static uint16_t udd_ctrl_prev_payload_nb_trans; +//! Number of data received/sent to/from udd_g_ctrlreq.payload buffer +static uint16_t udd_ctrl_payload_nb_trans; + +/** + * \brief Buffer to store the data received on control endpoint (SETUP/OUT endpoint 0) + * + * Used to avoid a RAM buffer overflow in case of the payload buffer + * is smaller than control endpoint size + */ +static uint8_t udd_ctrl_buffer[USB_DEVICE_EP_CTRL_SIZE]; + +/** + * \brief Reset control endpoint management + * + * Called after a USB line reset or at the end of SETUP request (after ZLP) + */ +static void udd_ctrl_init(void); + +//! \brief Managed reception of SETUP packet on control endpoint +static void udd_ctrl_setup_received(void); + +//! \brief Managed reception of IN packet on control endpoint +static void udd_ctrl_in_sent(void); + +//! \brief Managed reception of OUT packet on control endpoint +static void udd_ctrl_out_received(void); + +//! \brief Managed underflow event of IN packet on control endpoint +//! It is used to detect a DATA phase stopped by the host via a ZLP request. +//! This is mandatory for chapter 8 compliance +static void udd_ctrl_underflow(void); + +//! \brief Managed overflow event of OUT packet on control endpoint +//! It is used to detect a DATA phase stopped by the host via a ZLP request. +//! This is mandatory for chapter 8 compliance +static void udd_ctrl_overflow(void); + +//! \brief Managed stall event of IN/OUT packet on control endpoint +static void udd_ctrl_stall_data(void); + +//! \brief Send a ZLP IN on control endpoint +static void udd_ctrl_send_zlp_in(void); + +//! \brief Send a ZLP OUT on control endpoint +static void udd_ctrl_send_zlp_out(void); + +//! \brief Call callback associated to setup request +static void udd_ctrl_endofrequest(void); + +/** + * \brief Sub interrupt routine to manage error on control endpoint + * + * \return \c 1 if an error about control endpoint is occurred, otherwise \c 0. + */ +static bool udd_ctrl_interrupt_error(void); + +/** + * \brief Sub interrupt routine to manage a SETUP transfer complete on control endpoint + * + * \return \c 1 if an SETUP transfer complete about control endpoint is occurred, + * otherwise \c 0. + */ +static bool udd_ctrl_interrupt_tc_setup(void); + +//@} + + +/** + * \name Management of bulk/interrupt/isochronous endpoints + * + * The UDD manages the data transfer on endpoints: + * - Start data transfer on endpoint with USB Device DMA + * - Send a ZLP packet if requested + * - Call callback registered to signal end of transfer + * The transfer abort and stall feature are supported. + */ +//@{ +#if (0!=USB_DEVICE_MAX_EP) + +//! Structure definition about job registered on an endpoint +typedef struct { + //! A job is registered on this endpoint + uint8_t busy:1; + //! A short packet is requested for this job on endpoint IN + uint8_t b_shortpacket:1; + //! The cache buffer is currently used on endpoint OUT + uint8_t b_use_out_cache_buffer:1; + //! Buffer located in internal RAM to send or fill during job + uint8_t *buf; + //! Size of buffer to send or fill + iram_size_t buf_size; + //! Total number of data transfered on endpoint + iram_size_t nb_trans; + union { + //! Callback to call at the end of transfer + udd_callback_trans_t call_trans; + //! Callback to call when the endpoint halt is cleared + udd_callback_halt_cleared_t call_nohalt; + }; +} udd_ep_job_t; + +//! Array to register a job on bulk/interrupt/isochronous endpoint +static udd_ep_job_t udd_ep_job[USB_DEVICE_MAX_EP * 2]; + +/** + * \brief Buffer to store the data received on bulk/interrupt endpoints + * + * Used to avoid a RAM buffer overflow in case of the user buffer + * is smaller than endpoint size + * + * \warning The isochronous endpoint is not protected by this system + * and the user must always use a buffer corresponding at endpoint size + */ +#ifdef USB_DEVICE_LOW_SPEED +static uint8_t udd_ep_out_cache_buffer[USB_DEVICE_MAX_EP][8]; +#else +static uint8_t udd_ep_out_cache_buffer[USB_DEVICE_MAX_EP][64]; +#endif + + +/** + * \brief Checks endpoint number + * + * \param ep endpoint number + */ +bool udd_ep_is_valid(udd_ep_id_t ep); + +/** + * \brief Manages transfer complete on bulk/interrupt/isochronous endpoints + * + * \param ep endpoint number to manage + */ +static void udd_ep_trans_complet(udd_ep_id_t ep); + +/** + * \brief Returns the size of endpoint + * + * \return the size of current selected endpoint + */ +static uint16_t udd_ep_get_size(UDD_EP_t * ep_ctrl); + +/** + * \brief Returns a pointer on endpoint job corresponding at endpoint number + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + */ +static udd_ep_job_t *udd_ep_get_job(udd_ep_id_t ep); + +#endif // (0!=USB_DEVICE_MAX_EP) +//@} + + +void udd_enable(void) +{ + uint8_t i; + irqflags_t flags; + + // Sanity check Silicon revision +#if AVR8_PART_IS_DEFINED(ATxmega128A1U) + // The part ATxmega128A1U Rev. J is not supported, please use new silicon revision. + Assert(!(MCU_REVID < 0x0A)); +#endif + +#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC +# if CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC == OSC_ID_USBSOF + // RC oscillator calibration via USB Start Of Frame is not available + // in low speed mode. + // Thus, the calibration is disabled + // when USB interface start in low speed mode + DFLLRC32M.CTRL = 0; +# endif +#endif + +#ifdef USB_DEVICE_LOW_SPEED + // The USB hardware need of 6MHz in low speed mode + sysclk_enable_usb(6); + udd_set_low_speed(); +#else + // The USB hardware need of 48MHz in full speed mode + sysclk_enable_usb(48); + udd_set_full_speed(); +#endif + +// The XMEGA_A1U does not support the RC calibration through Keepalive (Low speed). +#if (!defined USB_DEVICE_LOW_SPEED) || (!XMEGA_A1U) +# ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC +# if CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC == OSC_ID_USBSOF + // The SOF calibration can be enabled + DFLLRC32M.CTRL = DFLL_ENABLE_bm; +# endif +# endif +#endif + + flags = cpu_irq_save(); + + // Reset endpoints table + for (i = 0; i < ((USB_DEVICE_MAX_EP + 1) * 2); i++) { + udd_sram.ep_ctrl[i].CTRL = 0; + } +#if (0!=USB_DEVICE_MAX_EP) + // Reset internal variables + for (i = 0; i < (USB_DEVICE_MAX_EP * 2); i++) { + udd_ep_job[i].busy = false; + } +#endif + + //** Enable USB hardware + usb_pad_init(); + udd_set_nb_max_ep(USB_DEVICE_MAX_EP); + udd_enable_interface(); + udd_enable_store_frame_number(); +#if XMEGA_A1U + Assert(((uint16_t)(&udd_sram) & 0x0F) == 0); /* check align on 16bit */ +#else + Assert(((uint16_t)(&udd_sram) & 0x01) == 0); /* check align on WORD */ +#endif + udd_set_ep_table_addr(udd_sram.ep_ctrl); + // Enable TC fifo management + udd_enable_fifo(); + udd_reset_fifo(); + // Enable Interrupt USB Device + udd_enable_interrupt(UDD_USB_INT_LEVEL); + +#ifndef UDD_NO_SLEEP_MGR + // Initialize the sleep mode authorized for the USB suspend mode + udd_b_idle = false; + sleepmgr_lock_mode(USBC_SLEEP_MODE_USB_SUSPEND); +#endif + +#ifndef USB_DEVICE_ATTACH_AUTO_DISABLE + udd_attach(); +#endif + cpu_irq_restore(flags); +} + + +void udd_disable(void) +{ + irqflags_t flags; + flags = cpu_irq_save(); + udd_detach_device(); + // Disable interface + USB_CTRLA = 0; + USB_CTRLB = 0; + sysclk_disable_usb(); + udd_sleep_mode(false); +#ifndef UDD_NO_SLEEP_MGR + sleepmgr_unlock_mode(USBC_SLEEP_MODE_USB_SUSPEND); +#endif + cpu_irq_restore(flags); +} + +bool udd_include_vbus_monitoring(void) +{ + return false; // No Vbus monitoring +} + +void udd_attach(void) +{ + irqflags_t flags; + flags = cpu_irq_save(); + + // At startup the USB bus state is unknown, + // therefore the state is considered IDLE to not miss any USB event + udd_sleep_mode(true); + + udd_ack_suspend_event(); + udd_ack_resume_event(); + udd_attach_device(); + // Enable main USB interrupts + udd_enable_tc_interrupt(); + udd_enable_busevt_interrupt(); + udd_enable_setup_interrupt(); + udd_enable_start_of_frame_interrupt(); + + cpu_irq_restore(flags); +} + +void udd_detach(void) +{ + // Detach device from the bus + udd_detach_device(); +} + +bool udd_is_high_speed(void) +{ + return false; +} + +void udd_set_address(uint8_t address) +{ + udd_set_device_address(address); +} + +uint8_t udd_getaddress(void) +{ + return udd_get_device_address(); +} + +uint16_t udd_get_frame_number(void) +{ + return udd_sram.frame_number; +} + +uint16_t udd_get_micro_frame_number(void) +{ + return 0; +} + +void udd_send_remotewakeup(void) +{ +#ifndef UDD_NO_SLEEP_MGR + if (!udd_b_idle) +#endif + { + udd_sleep_mode(true); // Enter in IDLE mode + udd_send_remote_wake_up(); + } +} + +void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ) +{ + udd_g_ctrlreq.payload = payload; + udd_g_ctrlreq.payload_size = payload_size; +} + +#if (0!=USB_DEVICE_MAX_EP) +bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize) +{ + UDD_EP_t *ep_ctrl; + Assert(udd_ep_is_valid(ep)); + + ep_ctrl = udd_ep_get_ctrl(ep); + if (udd_endpoint_is_enable(ep_ctrl)) { + return false; // Already allocated + } + udd_ep_init(ep, bmAttributes, MaxEndpointSize); + +/* + // Do not use multipacket mode with isochronous 1023 bytes endpoint + if (udd_endpoint_get_type(ep_ctrl)==USB_EP_TYPE_ISOCHRONOUS_gc + && (udd_endpoint_get_size_field(ep_ctrl) + ==USB_EP_BUFSIZE_1023_gc)) { + return true; + }*/ + + udd_endpoint_set_multipacket(ep_ctrl); + return true; +} + +void udd_ep_free(udd_ep_id_t ep) +{ + UDD_EP_t *ep_ctrl; + Assert(udd_ep_is_valid(ep)); + + udd_ep_abort(ep); + ep_ctrl = udd_ep_get_ctrl(ep); + udd_endpoint_disable(ep_ctrl); +} + +bool udd_ep_is_halted(udd_ep_id_t ep) +{ + UDD_EP_t *ep_ctrl; + Assert(udd_ep_is_valid(ep)); + + ep_ctrl = udd_ep_get_ctrl(ep); + return (udd_endpoint_is_stall(ep_ctrl)); +} + +bool udd_ep_set_halt(udd_ep_id_t ep) +{ + UDD_EP_t *ep_ctrl; + Assert(udd_ep_is_valid(ep)); + + ep_ctrl = udd_ep_get_ctrl(ep); + udd_endpoint_enable_stall(ep_ctrl); + udd_endpoint_clear_dtgl(ep_ctrl); + + udd_ep_abort(ep); + return true; +} + +bool udd_ep_clear_halt(udd_ep_id_t ep) +{ + udd_ep_job_t *ptr_job; + UDD_EP_t *ep_ctrl; + Assert(udd_ep_is_valid(ep)); + + ep_ctrl = udd_ep_get_ctrl(ep); + if (!udd_endpoint_is_stall(ep_ctrl)) { + return true; // No stall on going + } + udd_endpoint_disable_stall(ep_ctrl); + + // If a job is register on clear halt action + // then execute callback + ptr_job = udd_ep_get_job(ep); + if (ptr_job->busy == true) { + ptr_job->busy = false; + ptr_job->call_nohalt(); + } + return true; +} + +bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, uint8_t * buf, + iram_size_t buf_size, udd_callback_trans_t callback) +{ + udd_ep_job_t *ptr_job; + irqflags_t flags; + UDD_EP_t *ep_ctrl; + + Assert(udd_ep_is_valid(ep)); + + // Get control & job about this endpoint + ptr_job = udd_ep_get_job(ep); + ep_ctrl = udd_ep_get_ctrl(ep); + + if (!udd_endpoint_is_enable(ep_ctrl)) { + return false; // Endpoint not allocated + } + if (udd_endpoint_get_type(ep_ctrl)!=USB_EP_TYPE_ISOCHRONOUS_gc + && udd_endpoint_is_stall(ep_ctrl)) { + return false; // Endpoint is halted + } + flags = cpu_irq_save(); + if (ptr_job->busy == true) { + cpu_irq_restore(flags); + return false; // Job already on going + } + ptr_job->busy = true; + cpu_irq_restore(flags); + + + // Update Job information + ptr_job->buf = buf; + ptr_job->buf_size = buf_size; + ptr_job->nb_trans = 0; + ptr_job->call_trans = callback; + // Need to enable shortpacket to send a ZLP (buf_size==0) + ptr_job->b_shortpacket = b_shortpacket || (buf_size==0); + ptr_job->b_use_out_cache_buffer = false; + + // Initialize value to simulate a empty transfer + if (USB_EP_DIR_IN == (ep & USB_EP_DIR_IN)) { + udd_endpoint_in_reset_nb_sent(ep_ctrl); + } + else + { + if ((USB_EP_TYPE_ISOCHRONOUS_gc == udd_endpoint_get_type(ep_ctrl)) + && (0 != (buf_size % udd_ep_get_size(ep_ctrl)))) { + // The user must use a buffer size modulo endpoint size + ptr_job->busy = false; + return false; + } + udd_endpoint_out_reset_nb_received(ep_ctrl); + udd_endpoint_out_set_nbbyte(ep_ctrl, 0); + } + // Request next transfer + udd_ep_trans_complet(ep); + return true; +} + +void udd_ep_abort(udd_ep_id_t ep) +{ + UDD_EP_t *ep_ctrl; + udd_ep_job_t *ptr_job; + Assert(udd_ep_is_valid(ep)); + + ep_ctrl = udd_ep_get_ctrl(ep); + ptr_job = udd_ep_get_job(ep); + + // Stop transfer + udd_endpoint_set_NACK0(ep_ctrl); + if (ptr_job->busy == false) { + return; // No job on going + } + ptr_job->busy = false; + if (NULL != ptr_job->call_trans) { + ptr_job->call_trans(UDD_EP_TRANSFER_ABORT, + (ep & USB_EP_DIR_IN) ? + udd_endpoint_in_nb_sent(ep_ctrl) + : udd_endpoint_out_nb_receiv(ep_ctrl), + ep); + } +} + +bool udd_ep_wait_stall_clear(udd_ep_id_t ep, + udd_callback_halt_cleared_t callback) +{ + udd_ep_job_t *ptr_job; + UDD_EP_t *ep_ctrl; + Assert(udd_ep_is_valid(ep)); + + ep_ctrl = udd_ep_get_ctrl(ep); + ptr_job = udd_ep_get_job(ep); + + if (udd_endpoint_is_stall(ep_ctrl)) { + // Wait clear halt endpoint + if (ptr_job->busy == true) { + return false; // Job already on going + } + ptr_job->busy = true; + ptr_job->call_nohalt = callback; + } else { + // endpoint not halted then call directly callback + callback(); + } + return true; +} +#endif // (0!=USB_DEVICE_MAX_EP) + +//-------------------------------------------------------- +//--- INTERNAL ROUTINES TO MANAGED GLOBAL EVENTS + +/** + * \internal + * \brief Function called by USB bus event interrupt + * + * USB bus event interrupt includes : + * - USB line events SOF, reset, suspend, resume, wakeup + * - endpoint control errors underflow, overflow, stall + */ +ISR(USB_BUSEVENT_vect) +{ + if (udd_is_start_of_frame_event()) { + udd_ack_start_of_frame_event(); + udc_sof_notify(); +#ifdef UDC_SOF_EVENT + UDC_SOF_EVENT(); +#endif + goto udd_interrupt_bus_event_end; + } + + if (udd_ctrl_interrupt_error()) { + goto udd_interrupt_bus_event_end; + } + if (udd_is_reset_event()) { + udd_ack_reset_event(); +#if (0!=USB_DEVICE_MAX_EP) + // Abort all endpoint jobs on going + uint8_t i; + for (i = 1; i < USB_DEVICE_MAX_EP; i++) { + udd_ep_abort(i); + udd_ep_abort(i | USB_EP_DIR_IN); + } +#endif + udc_reset(); + + // Reset USB address to 0 + udd_set_device_address(0); + // Alloc and configure control endpoint + udd_ep_init(0, USB_EP_TYPE_CONTROL, USB_DEVICE_EP_CTRL_SIZE); + udd_ep_init(0 | USB_EP_DIR_IN, USB_EP_TYPE_CONTROL, + USB_DEVICE_EP_CTRL_SIZE); + udd_control_out_set_buf(&udd_ctrl_buffer); + // Reset endpoint control management + udd_ctrl_init(); + goto udd_interrupt_bus_event_end; + } + + if (udd_is_suspend_event()) { + udd_ack_suspend_event(); + udd_sleep_mode(false); // Enter in SUSPEND mode +#ifdef UDC_SUSPEND_EVENT + UDC_SUSPEND_EVENT(); +#endif + goto udd_interrupt_bus_event_end; + } + + if (udd_is_resume_event()) { + udd_ack_resume_event(); + udd_sleep_mode(true); // Enter in power reduction mode +#ifdef UDC_RESUME_EVENT + UDC_RESUME_EVENT(); +#endif + goto udd_interrupt_bus_event_end; + } + +udd_interrupt_bus_event_end: + return; +} + +/** + * \internal + * \brief Function called by USB transfer complete interrupt + * + * USB transfer complete interrupt includes events about endpoint transfer on all endpoints. + */ +ISR(USB_TRNCOMPL_vect) +{ +#if (0!=USB_DEVICE_MAX_EP) + uint8_t ep_index; + uint8_t i_fifo; + uint16_t ad; + uint16_t *p_ad; + int8_t rp; + UDD_EP_t *ep_ctrl; + udd_ep_id_t ep; +#endif + + if (!udd_is_tc_event()) { + // If no other transfer complete + // then check reception of SETUP packet on control endpoint + if (udd_ctrl_interrupt_tc_setup()) { + // Interrupt acked by control endpoint managed + goto udd_interrupt_tc_end; + } + Assert(false); + } + // Check IN/OUT transfer complete on all endpoints + udd_ack_tc_event(); + +#if (0!=USB_DEVICE_MAX_EP) + //** Decode TC FIFO + // Compute ep addr + rp = udd_get_fifo_rp(); + i_fifo = 2 * (1 + ~rp); + ad = ((uint16_t) udd_sram.ep_ctrl) - i_fifo; + p_ad = (uint16_t *) ad; + // Compute ep + ep_index = (((uint16_t) * p_ad - ((uint16_t) udd_sram.ep_ctrl)) >> 3); + ep = (ep_index / 2) + ((ep_index & 1) ? USB_EP_DIR_IN : 0); + Assert(USB_DEVICE_MAX_EP >= (ep & USB_EP_ADDR_MASK)); + + // Ack IT TC of endpoint + ep_ctrl = udd_ep_get_ctrl(ep); + if (!udd_endpoint_transfer_complete(ep_ctrl)) { + return; // Error, TC is generated by Multipacket transfer + } + udd_endpoint_ack_transfer_complete(ep_ctrl); + + // Check status on control endpoint + if (ep == 0) { + udd_ctrl_out_received(); + goto udd_interrupt_tc_end; // Interrupt acked by control endpoint managed + } + if (ep == (0 | USB_EP_DIR_IN)) { + udd_ctrl_in_sent(); + goto udd_interrupt_tc_end; // Interrupt acked by control endpoint managed + } + Assert(udd_ep_is_valid(ep)); + // Manage end of transfer on endpoint bulk/interrupt/isochronous + udd_ep_trans_complet(ep); + +#else + + udd_get_fifo_rp(); + if (udd_endpoint_transfer_complete(udd_ep_get_ctrl(0))) { + udd_endpoint_ack_transfer_complete(udd_ep_get_ctrl(0)); + udd_ctrl_out_received(); + }else{ + udd_endpoint_ack_transfer_complete(udd_ep_get_ctrl(0 | USB_EP_DIR_IN)); + udd_ctrl_in_sent(); + } +#endif + +udd_interrupt_tc_end: + return; +} + +//-------------------------------------------------------- +//--- INTERNAL ROUTINES TO INITIALIZE ENDPOINT + +static void udd_ep_init(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize) +{ + USB_EP_TYPE_t type; + USB_EP_BUFSIZE_t size; + UDD_EP_t *ep_ctrl; + +#if (0!=USB_DEVICE_MAX_EP) + // Translate USB attribute to hardware defines + switch (bmAttributes & USB_EP_TYPE_MASK) { + case USB_EP_TYPE_CONTROL: + type = USB_EP_TYPE_CONTROL_gc; + break; + case USB_EP_TYPE_ISOCHRONOUS: + type = USB_EP_TYPE_ISOCHRONOUS_gc; + break; + case USB_EP_TYPE_BULK: + case USB_EP_TYPE_INTERRUPT: //interrupt behaves as bulk + type = USB_EP_TYPE_BULK_gc; + break; + default: + Assert(false); // Wrong value + return; + } +#else + type = USB_EP_TYPE_CONTROL_gc; +#endif + + // Translate USB endpoint size to hardware defines + switch (MaxEndpointSize) { + default: + Assert(false); // Wrong value + case 8: + size = USB_EP_BUFSIZE_8_gc; + break; + case 16: + size = USB_EP_BUFSIZE_16_gc; + break; + case 32: + size = USB_EP_BUFSIZE_32_gc; + break; + case 64: + size = USB_EP_BUFSIZE_64_gc; + break; +#if (0!=USB_DEVICE_MAX_EP) + case 128: + size = USB_EP_BUFSIZE_128_gc; + break; + case 256: + size = USB_EP_BUFSIZE_256_gc; + break; + case 512: + size = USB_EP_BUFSIZE_512_gc; + break; + case 1023: + size =USB_EP_BUFSIZE_1023_gc; + break; +#endif + } + + // Enable endpoint + ep_ctrl = udd_ep_get_ctrl(ep); + udd_endpoint_disable(ep_ctrl); + udd_endpoint_clear_status(ep_ctrl); + udd_endpoint_set_control(ep_ctrl, (uint8_t) type | (uint8_t) size); +} + +static UDD_EP_t *udd_ep_get_ctrl(udd_ep_id_t ep) +{ + return &udd_sram.ep_ctrl[(2 * (ep & USB_EP_ADDR_MASK) + + ((ep & USB_EP_DIR_IN) ? 1 : 0))]; +} + + +//-------------------------------------------------------- +//--- INTERNAL ROUTINES TO MANAGED THE CONTROL ENDPOINT + +static void udd_ctrl_init(void) +{ + udd_disable_overflow_interrupt(); + udd_disable_underflow_interrupt(); + + // Clear status flag from control endpoints + // Mandatory for ATxmega128A1 Rev. K + udd_control_in_set_NACK0(); + udd_control_in_set_bytecnt(0); + udd_control_in_ack_tc(); + udd_control_ack_in_underflow(); + udd_control_out_ack_tc(); + udd_control_ack_out_overflow(); + + udd_g_ctrlreq.callback = NULL; + udd_g_ctrlreq.over_under_run = NULL; + udd_g_ctrlreq.payload_size = 0; + udd_ep_control_state = UDD_EPCTRL_SETUP; +} + +static void udd_ctrl_setup_received(void) +{ + if (UDD_EPCTRL_SETUP != udd_ep_control_state) { + if ((UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP == udd_ep_control_state) + || (UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP == udd_ep_control_state)) { + // Accept that ZLP event can be hidden by setup packet event + // in case of setup packet sending quickly after a ZLP + udd_ctrl_endofrequest(); + } + // Reinitializes control endpoint management + udd_ctrl_init(); + } + // Fill setup request structure + if (8 != udd_control_out_get_bytecnt()) + return; // Error data number don't correspond to SETUP packet + memcpy((uint8_t *) & udd_g_ctrlreq.req, udd_ctrl_buffer, 8); + + // To detect a protocol error on setup, enable nak interrupt on IN/OUT of control endpoint + udd_enable_overflow_interrupt(); + udd_enable_underflow_interrupt(); + + // Decode setup request + if (udc_process_setup() == false) { + // Setup request unknown then stall it + udd_ctrl_stall_data(); + return; + } + + if (Udd_setup_is_in()) { + udd_ctrl_prev_payload_nb_trans = 0; + udd_ctrl_payload_nb_trans = 0; + udd_ep_control_state = UDD_EPCTRL_DATA_IN; + udd_ctrl_in_sent(); // Send first data transfer + } else { + if (0 == udd_g_ctrlreq.req.wLength) { + // No data phase requested + // Send IN ZLP to ACK setup request + udd_ctrl_send_zlp_in(); + return; + } + // OUT data phase requested + udd_ctrl_prev_payload_nb_trans = 0; + udd_ctrl_payload_nb_trans = 0; + udd_ep_control_state = UDD_EPCTRL_DATA_OUT; + // Clear packet to receive first packet + udd_control_out_clear_NACK0(); + } +} + +static void udd_ctrl_in_sent(void) +{ + static bool b_shortpacket = false; + uint16_t nb_remain; + + if (UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP == udd_ep_control_state) { + // ZLP on IN is sent, then valid end of setup request + udd_ctrl_endofrequest(); + // Reinitializes control endpoint management + udd_ctrl_init(); + return; + } + Assert(udd_ep_control_state == UDD_EPCTRL_DATA_IN); + + nb_remain = udd_g_ctrlreq.payload_size - udd_ctrl_payload_nb_trans; + if (0 == nb_remain) { + // Update number of total data sending by previous playload buffer + udd_ctrl_prev_payload_nb_trans += udd_ctrl_payload_nb_trans; + if ((udd_g_ctrlreq.req.wLength == udd_ctrl_prev_payload_nb_trans) + || b_shortpacket) { + // All data requested are transfered or a short packet has been sent + // then it is the end of data phase. + // Generate an OUT ZLP for handshake phase. + udd_ctrl_send_zlp_out(); + return; + } + // Need of new buffer because the data phase is not complete + if ((!udd_g_ctrlreq.over_under_run) + || (!udd_g_ctrlreq.over_under_run())) { + // Underrun then send zlp on IN + // nb_remain == 0 allows to send a IN ZLP + } else { + // A new payload buffer is given + udd_ctrl_payload_nb_trans = 0; + nb_remain = udd_g_ctrlreq.payload_size; + } + } + // Continue transfer an send next data + if (nb_remain >= USB_DEVICE_EP_CTRL_SIZE) { + nb_remain = USB_DEVICE_EP_CTRL_SIZE; + b_shortpacket = false; + } else { + b_shortpacket = true; + } + udd_control_in_set_bytecnt(nb_remain); + + // Link payload buffer directly on USB hardware + udd_control_in_set_buf(udd_g_ctrlreq.payload + udd_ctrl_payload_nb_trans); + udd_ctrl_payload_nb_trans += nb_remain; + + // Valid and sent the data available in control endpoint buffer + udd_control_in_clear_NACK0(); +} + +static void udd_ctrl_out_received(void) +{ + uint16_t nb_data; + + if (UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP == udd_ep_control_state) { + // Valid end of setup request + udd_ctrl_endofrequest(); + // Reinitializes control endpoint management + udd_ctrl_init(); + return; + } + Assert(udd_ep_control_state == UDD_EPCTRL_DATA_OUT); + + // Read data received during OUT phase + nb_data = udd_control_out_get_bytecnt(); + + if (udd_g_ctrlreq.payload_size < (udd_ctrl_payload_nb_trans + nb_data)) { + // Payload buffer too small, ignore data remaining + nb_data = udd_g_ctrlreq.payload_size - udd_ctrl_payload_nb_trans; + } + + memcpy((uint8_t *) (udd_g_ctrlreq.payload + udd_ctrl_payload_nb_trans), + udd_ctrl_buffer, nb_data); + udd_ctrl_payload_nb_trans += nb_data; + + if ((USB_DEVICE_EP_CTRL_SIZE != nb_data) || (udd_g_ctrlreq.req.wLength + <= (udd_ctrl_prev_payload_nb_trans + + udd_ctrl_payload_nb_trans))) { + // End of reception because it is a short packet + // or all data are transfered + + // Before send ZLP, call intermediate callback + // in case of data receive generate a stall + udd_g_ctrlreq.payload_size = udd_ctrl_payload_nb_trans; + if (NULL != udd_g_ctrlreq.over_under_run) { + if (!udd_g_ctrlreq.over_under_run()) { + // Stall ZLP + udd_ctrl_stall_data(); + return; + } + } + // Send IN ZLP to ACK setup request + udd_ctrl_send_zlp_in(); + return; + } + + if (udd_g_ctrlreq.payload_size == udd_ctrl_payload_nb_trans) { + // Overrun then request a new payload buffer + if (!udd_g_ctrlreq.over_under_run) { + // No callback available to request a new payload buffer + udd_ctrl_stall_data(); + return; + } + if (!udd_g_ctrlreq.over_under_run()) { + // No new payload buffer delivered + udd_ctrl_stall_data(); + return; + } + // New payload buffer available + // Update number of total data received + udd_ctrl_prev_payload_nb_trans += udd_ctrl_payload_nb_trans; + // Reinit reception on payload buffer + udd_ctrl_payload_nb_trans = 0; + } + // Free buffer of OUT control endpoint to authorize next reception + udd_control_out_clear_NACK0(); +} + +static void udd_ctrl_underflow(void) +{ + if (udd_is_tc_event() || udd_ctrl_interrupt_tc_setup()) { + return; // underflow ignored if a transfer complete has been no processed + } + if (UDD_EPCTRL_DATA_OUT == udd_ep_control_state) { + // Host want to stop OUT transaction + // then stop to wait OUT data phase and wait IN ZLP handshake + udd_ctrl_send_zlp_in(); + } else if (UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP == udd_ep_control_state) { + // A OUT handshake is waiting by device, + // but host want extra IN data then stall extra IN data and following status stage + udd_control_in_enable_stall(); + udd_control_out_enable_stall(); + } +} + +static void udd_ctrl_overflow(void) +{ + if (udd_is_tc_event() || udd_ctrl_interrupt_tc_setup()) { + return; // overflow ignored if a transfer complete has been no processed + } + if (UDD_EPCTRL_DATA_IN == udd_ep_control_state) { + // Host want to stop IN transaction + // then stop to wait IN data phase and wait OUT ZLP handshake + udd_ctrl_send_zlp_out(); + } else if (UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP == udd_ep_control_state) { + // A IN handshake is waiting by device, + // but host want extra OUT data then stall extra OUT data and following status stage + udd_control_in_enable_stall(); + udd_control_out_enable_stall(); + } +} + +static void udd_ctrl_stall_data(void) +{ + // Stall all packets on IN & OUT control endpoint + udd_ep_control_state = UDD_EPCTRL_STALL_REQ; + udd_control_in_enable_stall(); + udd_control_out_enable_stall(); +} + +static void udd_ctrl_send_zlp_in(void) +{ + udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP; + // Valid and sent empty IN packet on control endpoint + udd_control_in_set_bytecnt(0); + udd_control_in_clear_NACK0(); +} + +static void udd_ctrl_send_zlp_out(void) +{ + udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP; + // Valid reception of OUT packet on control endpoint + udd_control_out_clear_NACK0(); +} + +static void udd_ctrl_endofrequest(void) +{ + // If a callback is registered then call it + if (udd_g_ctrlreq.callback) { + udd_g_ctrlreq.callback(); + } +} + +static bool udd_ctrl_interrupt_error(void) +{ + // Underflow only managed for control endpoint + if (udd_is_underflow_event()) { + udd_ack_underflow_event(); + if (udd_control_in_underflow()) { + udd_ctrl_underflow(); + } + return true; + } + // Overflow only managed for control endpoint + if (udd_is_overflow_event()) { + udd_ack_overflow_event(); + if (udd_control_out_overflow()) { + udd_ctrl_overflow(); + } + return true; + } + return false; +} + +static bool udd_ctrl_interrupt_tc_setup(void) +{ + if (!udd_is_setup_event()) { + return false; + } + udd_ack_setup_event(); + + // Clear eventually previous stall events + udd_control_out_ack_stall(); + udd_control_in_ack_stall(); + udd_ack_stall_event(); + + Assert(udd_control_setup()); // A setup must be received on control endpoint + + // Ack SETUP packet and decode request + udd_control_ack_setup(); + udd_ctrl_setup_received(); + return true; +} + + +//-------------------------------------------------------- +//--- INTERNAL ROUTINES TO MANAGED THE BULK/INTERRUPT/ISOCHRONOUS ENDPOINTS + +#if (0!=USB_DEVICE_MAX_EP) + +static uint16_t udd_ep_get_size(UDD_EP_t * ep_ctrl) +{ + // Translate hardware defines to USB endpoint size + switch (udd_endpoint_get_size_field(ep_ctrl)) { + default: + case USB_EP_BUFSIZE_8_gc: + return 8; + case USB_EP_BUFSIZE_16_gc: + return 16; + case USB_EP_BUFSIZE_32_gc: + return 32; + case USB_EP_BUFSIZE_64_gc: + return 64; + case USB_EP_BUFSIZE_128_gc: + return 128; + case USB_EP_BUFSIZE_256_gc: + return 256; + case USB_EP_BUFSIZE_512_gc: + return 512; + case USB_EP_BUFSIZE_1023_gc: + return 1023; + } +} + +static udd_ep_job_t *udd_ep_get_job(udd_ep_id_t ep) +{ + return &udd_ep_job[(2 * (ep & USB_EP_ADDR_MASK) + + ((ep & USB_EP_DIR_IN) ? 1 : 0)) - 2]; +} + +bool udd_ep_is_valid(udd_ep_id_t ep) +{ + ep &= USB_EP_ADDR_MASK; + if (ep == 0) { + return false; + } + return (USB_DEVICE_MAX_EP >= ep); +} + +static void udd_ep_trans_complet(udd_ep_id_t ep) +{ + UDD_EP_t *ep_ctrl; + udd_ep_job_t *ptr_job; + uint16_t ep_size, nb_trans; + iram_size_t next_trans; + + ptr_job = udd_ep_get_job(ep); + ep_ctrl = udd_ep_get_ctrl(ep); + ep_size = udd_ep_get_size(ep_ctrl); + + if (USB_EP_DIR_IN == (ep & USB_EP_DIR_IN)) { + // Transfer complete on IN + nb_trans = udd_endpoint_in_nb_sent(ep_ctrl); + + // Update number of data transfered + ptr_job->nb_trans += nb_trans; + + // Need to send other data + if (ptr_job->nb_trans != ptr_job->buf_size) { + next_trans = ptr_job->buf_size - ptr_job->nb_trans; + if (UDD_ENDPOINT_MAX_TRANS < next_trans) { + // The USB hardware support a maximum + // transfer size of UDD_ENDPOINT_MAX_TRANS Bytes + next_trans = UDD_ENDPOINT_MAX_TRANS - + (UDD_ENDPOINT_MAX_TRANS % ep_size); + } + // Need ZLP, if requested and last packet is not a short packet + ptr_job->b_shortpacket = ptr_job->b_shortpacket + && (0==(next_trans % ep_size)); + udd_endpoint_in_reset_nb_sent(ep_ctrl); + udd_endpoint_in_set_bytecnt(ep_ctrl, next_trans); + // Link the user buffer directly on USB hardware DMA + udd_endpoint_set_buf(ep_ctrl, &ptr_job->buf[ptr_job->nb_trans]); + udd_endpoint_clear_NACK0(ep_ctrl); + return; + } + + // Need to send a ZLP after all data transfer + if (ptr_job->b_shortpacket) { + ptr_job->b_shortpacket = false; + udd_endpoint_in_reset_nb_sent(ep_ctrl); + udd_endpoint_in_set_bytecnt(ep_ctrl, 0); + udd_endpoint_clear_NACK0(ep_ctrl); + return; + } + } + else + { + // Transfer complete on OUT + nb_trans = udd_endpoint_out_nb_receiv(ep_ctrl); + + // Can be necessary to copy data receive from cache buffer to user buffer + if (ptr_job->b_use_out_cache_buffer) { + memcpy(&ptr_job->buf[ptr_job->nb_trans] + , udd_ep_out_cache_buffer[ep - 1] + , ptr_job->buf_size % ep_size); + } + + // Update number of data transfered + ptr_job->nb_trans += nb_trans; + if (ptr_job->nb_trans > ptr_job->buf_size) { + ptr_job->nb_trans = ptr_job->buf_size; + } + + // If all previous data requested are received and user buffer not full + // then need to receive other data + if ((nb_trans == udd_endpoint_out_get_nbbyte_requested(ep_ctrl)) + && (ptr_job->nb_trans != ptr_job->buf_size)) { + next_trans = ptr_job->buf_size - ptr_job->nb_trans; + if (UDD_ENDPOINT_MAX_TRANS < next_trans) { + // The USB hardware support a maximum transfer size + // of UDD_ENDPOINT_MAX_TRANS Bytes + next_trans = UDD_ENDPOINT_MAX_TRANS + - (UDD_ENDPOINT_MAX_TRANS % ep_size); + } else { + next_trans -= next_trans % ep_size; + } + + udd_endpoint_out_reset_nb_received(ep_ctrl); + if (next_trans < ep_size) { + // Use the cache buffer for Bulk or Interrupt size endpoint + ptr_job->b_use_out_cache_buffer = true; + udd_endpoint_set_buf( ep_ctrl, + udd_ep_out_cache_buffer[ep - 1]); + udd_endpoint_out_set_nbbyte(ep_ctrl, ep_size); + } else { + // Link the user buffer directly on USB hardware DMA + udd_endpoint_set_buf(ep_ctrl, &ptr_job->buf[ptr_job->nb_trans]); + udd_endpoint_out_set_nbbyte(ep_ctrl, next_trans); + } + // Start transfer + udd_endpoint_clear_NACK0(ep_ctrl); + return; + } + } + + // Job complete then call callback + if (ptr_job->busy) { + ptr_job->busy = false; + if (NULL != ptr_job->call_trans) { + ptr_job->call_trans(UDD_EP_TRANSFER_OK, + ptr_job->nb_trans, + ep); + } + } + return; +} +#endif // (0!=USB_DEVICE_MAX_EP) +//@} diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usb/usb_device.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usb/usb_device.c.REMOVED.git-id deleted file mode 100644 index 84e5d494..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usb/usb_device.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a0b77ded8fb44bf7d4eb8b300363c7eff6c5591e \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usb/usb_device.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usb/usb_device.h new file mode 100644 index 00000000..351c0ef9 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usb/usb_device.h @@ -0,0 +1,390 @@ +/** + * \file + * + * \brief USB Driver header file for XMEGA products including USB interface. + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _USB_DEVICE_H_ +#define _USB_DEVICE_H_ + +#include + +/** + * \ingroup udd_group + * \defgroup udd_xmega_usb_group Xmega USB Device Driver + * USBC low-level driver for USB Device mode + * + * + * @{ + */ + +//! @name USB Device main management +//! @{ + +/** + * \brief Initializes the USB DP/DM buffers + * + * This functions initializes the USB buffer using the calibration value + * stored in production raw. + * If the calibration value is not found (0xFF) value, a default typical + * value is applied. + * Alternatively user can force calibration values using USB_PAD_USER_CAL0 + * and USB_PAD_USER_CAL1 + * + */ +static inline void usb_pad_init(void) +{ + uint8_t cal; + +#ifdef USB_PAD_USER_CAL0 + USB_CAL0 = USB_PAD_USER_CAL0; +#else + cal = nvm_read_production_signature_row + (nvm_get_production_signature_row_offset(USBCAL0)); + if (cal != 0xFF) { + USB_CAL0 = cal; + } else { + USB_CAL0 = 0x1F; + } +#endif + +#ifdef USB_PAD_USER_CAL1 + USB_CAL1 = USB_PAD_USER_CAL1; +#else + cal = nvm_read_production_signature_row + (nvm_get_production_signature_row_offset(USBCAL1)); + if (cal != 0xFF) { + USB_CAL1 = cal; + } else { + USB_CAL1 = 0x1F; + } +#endif +} + +#define udd_enable_interface() (USB_CTRLA |= USB_ENABLE_bm) +#define udd_disable_interface() (USB_CTRLA &= ~USB_ENABLE_bm) +#define udd_attach_device() (USB_CTRLB |= USB_ATTACH_bm) +#define udd_detach_device() (USB_CTRLB &= ~USB_ATTACH_bm) +#define udd_gnak_disable() (USB_CTRLB &= ~USB_GNACK_bm) +#define udd_gnak_enable() (USB_CTRLB |= USB_GNACK_bm) +#define udd_gnak_is_enable() (USB_CTRLB & USB_GNACK_bm) +#define udd_set_nb_max_ep(n) (USB_CTRLA |= n) +#define udd_enable_store_frame_number() (USB_CTRLA |= USB_STFRNUM_bm) +#define udd_disable_store_frame_number() (USB_CTRLA &= ~USB_STFRNUM_bm) +#define udd_set_full_speed() (USB_CTRLA |= USB_SPEED_bm) +#define udd_set_low_speed() (USB_CTRLA &= ~USB_SPEED_bm) +#define udd_set_ep_table_addr(n) (USB.EPPTR = (uint16_t)n) +#define udd_get_ep_table_addr() (USB.EPPTR) +#define udd_get_fifo_rp() (USB_FIFORP) +#define udd_reset_fifo() (USB_FIFORP=0xFF) +#define udd_enable_interrupt(level) (USB_INTCTRLA |= level&(USB_INTLVL1_bm|USB_INTLVL0_bm)) + +#define udd_set_device_address(n) (USB_ADDR=n) +#define udd_get_device_address() (USB_ADDR) +#define udd_enable_fifo() (USB_CTRLA |= USB_FIFOEN_bm) +#define udd_disable_fifo() (USB_CTRLA &= ~USB_FIFOEN_bm) + +#define udd_send_remote_wake_up() (USB_CTRLB &= ~USB_RWAKEUP_bm, USB_CTRLB |= USB_RWAKEUP_bm) +#define udd_set_global_nack() (USB_CTRLB |= USB_GNACK_bm) +#define udd_is_crc_event() (USB_INTFLAGSASET & USB_CRCIF_bm ? true : false) +#define udd_ack_crc_event() (USB_INTFLAGSACLR = USB_CRCIF_bm) +#define udd_set_crc_event() (USB_INTFLAGSASET = USB_CRCIF_bm) +#define udd_enable_crc_interrupt() (USB_INTCTRLA |= USB_CRCIE_bm) +#define udd_disable_crc_interrupt() (USB_INTCTRLA &= ~USB_CRCIE_bm) + +#define udd_is_start_of_frame_event() (USB_INTFLAGSASET & USB_SOFIF_bm ? true : false) +#define udd_ack_start_of_frame_event() (USB_INTFLAGSACLR = USB_SOFIF_bm) +#define udd_set_start_of_frame_event() (USB_INTFLAGSASET = USB_SOFIF_bm) +#define udd_enable_start_of_frame_interrupt() (USB_INTCTRLA |= USB_SOFIE_bm) +#define udd_disable_start_of_frame_interrupt() (USB_INTCTRLA &= ~USB_SOFIE_bm) +#define udd_is_enable_start_of_frame_interrupt() (0!=(USB_INTCTRLA|USB_SOFIE_bm)) + +#define udd_is_reset_event() (USB_INTFLAGSASET & USB_RSTIF_bm ? true : false) +#define udd_ack_reset_event() (USB_INTFLAGSACLR = USB_RSTIF_bm) +#define udd_set_reset_event() (USB_INTFLAGSASET = USB_RSTIF_bm) + +#define udd_is_suspend_event() (USB_INTFLAGSASET & USB_SUSPENDIF_bm ? true : false) +#define udd_ack_suspend_event() (USB_INTFLAGSACLR = USB_SUSPENDIF_bm) +#define udd_set_suspend_event() (USB_INTFLAGSASET = USB_SUSPENDIF_bm) + +#define udd_is_resume_event() (USB_INTFLAGSASET & USB_RESUMEIF_bm ? true : false) +#define udd_ack_resume_event() (USB_INTFLAGSACLR = USB_RESUMEIF_bm) +#define udd_set_resume_event() (USB_INTFLAGSASET = USB_RESUMEIF_bm) + +#define udd_enable_busevt_interrupt() (USB_INTCTRLA |= USB_BUSEVIE_bm) +#define udd_disable_busevt_interrupt() (USB_INTCTRLA &= ~USB_BUSEVIE_bm) + +#define udd_is_setup_event() (USB_INTFLAGSBCLR & USB_SETUPIF_bm ? true : false) +#define udd_ack_setup_event() (USB_INTFLAGSBCLR = USB_SETUPIF_bm) +#define udd_set_setup_event() (USB_INTFLAGSBSET = USB_SETUPIF_bm) +#define udd_enable_setup_interrupt() (USB_INTCTRLB |= USB_SETUPIE_bm) +#define udd_disable_setup_interrupt() (USB_INTCTRLB &= ~USB_SETUPIE_bm) + +#define udd_is_tc_event() (USB_INTFLAGSBCLR & USB_TRNIF_bm ? true : false) +#define udd_ack_tc_event() (USB_INTFLAGSBCLR = USB_TRNIF_bm) +#define udd_set_tc_event() (USB_INTFLAGSBSET = USB_TRNIF_bm) +#define udd_enable_tc_interrupt() (USB_INTCTRLB |= USB_TRNIE_bm) +#define udd_disable_tc_interrupt() (USB_INTCTRLB &= ~USB_TRNIE_bm) + +#define udd_is_overflow_event() (USB_INTFLAGSASET & USB_OVFIF_bm ? true : false) +#define udd_ack_overflow_event() (USB_INTFLAGSACLR = USB_OVFIF_bm) +#define udd_set_overflow_event() (USB_INTFLAGSASET = USB_OVFIF_bm) +#define udd_enable_overflow_interrupt() (USB_INTCTRLA |= USB_BUSERRIE_bm) +#define udd_disable_overflow_interrupt() (USB_INTCTRLA &= ~USB_BUSERRIE_bm) +#define udd_is_enable_overflow_interrupt() (USB_INTCTRLA&USB_BUSERRIE_bm ? true : false) + +#define udd_is_underflow_event() (USB_INTFLAGSASET & USB_UNFIF_bm ? true : false) +#define udd_ack_underflow_event() (USB_INTFLAGSACLR = USB_UNFIF_bm) +#define udd_set_underflow_event() (USB_INTFLAGSASET = USB_UNFIF_bm) +#define udd_enable_underflow_interrupt() (USB_INTCTRLA |= USB_BUSERRIE_bm) +#define udd_disable_underflow_interrupt() (USB_INTCTRLA &= ~USB_BUSERRIE_bm) +#define udd_is_enable_underflow_interrupt() (USB_INTCTRLA&USB_BUSERRIE_bm ? true : false) + +#define udd_is_stall_event() (USB_INTFLAGSASET & USB_STALLIF_bm ? true : false) +#define udd_ack_stall_event() (USB_INTFLAGSACLR = USB_STALLIF_bm) +#define udd_set_stall_event() (USB_INTFLAGSASET = USB_STALLIF_bm) +#define udd_enable_stall_interrupt() (USB_INTCTRLA |= USB_STALLIE_bm) +#define udd_disable_stall_interrupt() (USB_INTCTRLA &= ~USB_STALLIE_bm) +#define udd_is_enable_stall_interrupt() (USB_INTCTRLA&USB_STALLIE_bm ? true : false) +//! @} + +//! @name USB Device read/modify/write management +//! @{ +#ifndef USB_WORKAROUND_DO_NOT_USE_RMW +/* + * Read modify write new instructions for Xmega + * inline asm implementation with R16 register. + * This should be removed later on when the new instructions + * will be available within the compiler. + * + */ +// Load and Clear +#ifdef __GNUC__ +#define LACR16(addr,msk) \ + __asm__ __volatile__ ( \ + "ldi r16, %1" "\n\t" \ + ".dc.w 0x9306" "\n\t"\ + ::"z" (addr), "M" (msk):"r16") +#else +#define LACR16(addr,msk) __lac((unsigned char)msk,(unsigned char*)addr) +#endif + +// Load and Set +#ifdef __GNUC__ +#define LASR16(addr,msk) \ + __asm__ __volatile__ ( \ + "ldi r16, %1" "\n\t" \ + ".dc.w 0x9305" "\n\t"\ + ::"z" (addr), "M" (msk):"r16") +#else +#define LASR16(addr,msk) __las((unsigned char)msk,(unsigned char*)addr) +#endif + +// Exchange +#ifdef __GNUC__ +#define XCHR16(addr,msk) \ + __asm__ __volatile__ ( \ + "ldi r16, %1" "\n\t" \ + ".dc.w 0x9304" "\n\t"\ + ::"z" (addr), "M" (msk):"r16") +#else +#define XCHR16(addr,msk) __xch(msk,addr) +#endif + +// Load and toggle +#ifdef __GNUC__ +#define LATR16(addr,msk) \ + __asm__ __volatile__ ( \ + "ldi r16, %1" "\n\t" \ + ".dc.w 0x9307" "\n\t"\ + ::"z" (addr), "M" (msk):"r16") +#else +#define LATR16(addr,msk) __lat(msk,addr) +#endif + +#else + +// Load and Clear +#define LACR16(addr,msk) (*addr &= ~msk) +// Load and Set +#define LASR16(addr,msk)(*addr |= msk) + +#endif +//! @} + + +//! @name USB Device endpoints table management +//! @{ + +#define udd_endpoint_set_control(ep_ctrl,val) (ep_ctrl->CTRL=val) +#define udd_endpoint_get_control(ep_ctrl) (ep_ctrl->CTRL) + +#define udd_endpoint_disable(ep_ctrl) udd_endpoint_set_control(ep_ctrl,0) +#define udd_endpoint_is_enable(ep_ctrl) (USB_EP_TYPE_DISABLE_gc!=udd_endpoint_get_type(ep_ctrl)) + + +#define udd_endpoint_enable_stall(ep_ctrl) (ep_ctrl->CTRL |= USB_EP_STALL_bm) +#define udd_endpoint_disable_stall(ep_ctrl) (ep_ctrl->CTRL &= ~USB_EP_STALL_bm) +#define udd_endpoint_is_stall(ep_ctrl) (ep_ctrl->CTRL &USB_EP_STALL_bm ? true : false) +#define udd_endpoint_set_multipacket(ep_ctrl) (ep_ctrl->CTRL |= USB_EP_MULTIPKT_bm) +#define udd_endpoint_TC_int_disable(ep_ctrl) (ep_ctrl->CTRL |= USB_EP_INTDSBL_bm) +#define udd_endpoint_set_pingpong(ep_ctrl) (ep_ctrl->CTRL |= USB_EP_PINGPONG_bm) +#define udd_endpoint_get_size_field(ep_ctrl) (ep_ctrl->CTRL & USB_EP_BUFSIZE_gm) +#define udd_endpoint_get_type(ep_ctrl) (ep_ctrl->CTRL & USB_EP_TYPE_gm) + +#define udd_endpoint_get_status(ep_ctrl) (ep_ctrl->STATUS) +#define udd_endpoint_clear_status(ep_ctrl) (ep_ctrl->STATUS=USB_EP_BUSNACK0_bm|USB_EP_BUSNACK1_bm) + +#define udd_endpoint_setup_received(ep_ctrl) (ep_ctrl->STATUS&USB_EP_SETUP_bm ? true : false) +#define udd_endpoint_ack_setup_received(ep_ctrl) LACR16(&ep_ctrl->STATUS, USB_EP_SETUP_bm) + +#define udd_endpoint_transfer_complete(ep_ctrl) (ep_ctrl->STATUS&USB_EP_TRNCOMPL0_bm ? true : false) +#define udd_endpoint_ack_transfer_complete(ep_ctrl) LACR16(&(ep_ctrl->STATUS), USB_EP_TRNCOMPL0_bm) +#define udd_endpoint_transfer_complete_bank0(ep_ctrl) (ep_ctrl->STATUS&USB_EP_TRNCOMPL0_bm ? true : false) +#define udd_endpoint_ack_transfer_complete_bankO(ep_ctrl) LACR16(&ep_ctrl->STATUS, USB_EP_TRNCOMPL0_bm) +#define udd_endpoint_transfer_complete_bank1(ep_ctrl) (ep_ctrl->STATUS&USB_EP_SETUP_bm ? true : false) +#define udd_endpoint_ack_transfer_complete_bank1(ep_ctrl) LACR16(&ep_ctrl->STATUS, USB_EP_SETUP_bm) + +#define udd_endpoint_get_bank(ep_ctrl) (ep_ctrl->STATUS & USB_EP_BANK_bm ? true : false) +#define udd_endpoint_set_bank(ep_ctrl) LASR16(&ep_ctrl->STATUS, USB_EP_BANK_bm) +#define udd_endpoint_clear_bank(ep_ctrl) LACR16(&ep_ctrl->STATUS, USB_EP_BANK_bm) + +#define udd_endpoint_set_dtgl(ep_ctrl) LASR16(&ep_ctrl->STATUS,USB_EP_TOGGLE_bm) +#define udd_endpoint_clear_dtgl(ep_ctrl) LACR16(&ep_ctrl->STATUS, USB_EP_TOGGLE_bm ) +#define udd_endpoint_get_dtgl(ep_ctrl) ((ep_ctrl->STATUS)&USB_EP_TOGGLE_bm ? true : false) +#define udd_endpoint_toggle_dtgl(ep_ctrl) LATR16(&ep_ctrl->STATUS, USB_EP_TOGGLE_bm) + +#define udd_endpoint_set_NACK0(ep_ctrl) LASR16(&ep_ctrl->STATUS,USB_EP_BUSNACK0_bm) +#define udd_endpoint_set_NACK1(ep_ctrl) LASR16(&ep_ctrl->STATUS,USB_EP_BUSNACK1_bm) +#define udd_endpoint_clear_NACK0(ep_ctrl) LACR16(&ep_ctrl->STATUS, USB_EP_BUSNACK0_bm) +#define udd_endpoint_clear_NACK1(ep_ctrl) LACR16(&ep_ctrl->STATUS, USB_EP_BUSNACK1_bm) +#define udd_endpoint_get_NACK1(ep_ctrl) ((ep_ctrl->STATUS&USB_EP_BUSNACK1_bm) ? true : false) +#define udd_endpoint_get_NACK0(ep_ctrl) ((ep_ctrl->STATUS&USB_EP_BUSNACK0_bm) ? true : false) +#define udd_endpoint_overflow(ep_ctrl) (ep_ctrl->STATUS&USB_EP_OVF_bm ? true : false) +#define udd_endpoint_underflow(ep_ctrl) (ep_ctrl->STATUS&USB_EP_UNF_bm ? true : false) + +#define UDD_ENDPOINT_MAX_TRANS (0x3FF) + +#define udd_endpoint_out_nb_receiv(ep_ctrl) (ep_ctrl->CNT) +#define udd_endpoint_out_reset_nb_received(ep_ctrl) (ep_ctrl->CNT = 0) +#define udd_endpoint_in_set_bytecnt(ep_ctrl,n) (ep_ctrl->CNT = n) +#define udd_endpoint_set_azlp(ep_ctrl) (ep_ctrl->CNT |= 0x8000) +#define udd_endpoint_clear_azlp(ep_ctrl) (ep_ctrl->CNT &= ~0x8000) + +#define udd_endpoint_set_buf(ep_ctrl,buf) (ep_ctrl->DATAPTR = (uint16_t) buf) + +#define udd_endpoint_in_nb_sent(ep_ctrl) (ep_ctrl->AUXDATA) +#define udd_endpoint_in_reset_nb_sent(ep_ctrl) (ep_ctrl->AUXDATA = 0) +#define udd_endpoint_out_set_nbbyte(ep_ctrl,nb) (ep_ctrl->AUXDATA = nb) +#define udd_endpoint_out_get_nbbyte_requested(ep_ctrl) (ep_ctrl->AUXDATA) +#define udd_endpoint_set_aux(ep_ctrl,buf) (ep_ctrl->AUXDATA = (uint16_t) buf) +//! @} + + +//! @name USB Device endpoint control field management +//! @{ + +//! @name USB Device endpoint control setup field management +//! @{ +#define udd_control_setup() (udd_sram.ep_ctrl[0].STATUS&USB_EP_SETUP_bm ? true : false) +#define udd_control_ack_setup() LACR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_SETUP_bm) +//! @} + +//! @name USB Device endpoint control OUT field management +//! @{ +#define udd_control_out_is_enable_stall() (udd_sram.ep_ctrl[0].CTRL&USB_EP_STALL_bm ? true : false) +#define udd_control_out_enable_stall() LASR16(&udd_sram.ep_ctrl[0].CTRL,USB_EP_STALL_bm) +#define udd_control_out_disable_stall() LACR16(&udd_sram.ep_ctrl[0].CTRL,USB_EP_STALL_bm) +#define udd_control_out_is_stalled() (udd_sram.ep_ctrl[0].STATUS&USB_EP_STALLF_bm ? true : false) +#define udd_control_out_ack_stall() LACR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_STALLF_bm) +#define udd_control_out_set_NACK0() LASR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_BUSNACK0_bm) +#define udd_control_out_clear_NACK0() LACR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_BUSNACK0_bm) + +#define udd_control_out_overflow() (udd_sram.ep_ctrl[0].STATUS&USB_EP_OVF_bm ? true : false) +#define udd_control_ack_out_overflow() LACR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_OVF_bm) + +#define udd_control_out_tc() (udd_sram.ep_ctrl[0].STATUS&USB_EP_TRNCOMPL0_bm ? true : false) +#define udd_control_out_ack_tc() LACR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_TRNCOMPL0_bm) +#define udd_control_out_set_tc() LASR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_TRNCOMPL0_bm) + +#define udd_control_out_dt_get() (udd_sram.ep_ctrl[0].STATUS&USB_EP_TOGGLE_bm ? true : false) +#define udd_control_out_dt_set() LASR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_TOGGLE_bm ) +#define udd_control_out_dt_clear() LACR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_TOGGLE_bm ) +#define udd_control_out_dt_toggle() LATR16(&udd_sram.ep_ctrl[0].STATUS,USB_EP_TOGGLE_bm) + +#define udd_control_out_set_buf(buf) (udd_sram.ep_ctrl[0].DATAPTR = (uint16_t) buf) + +#define udd_control_out_get_bytecnt() (udd_sram.ep_ctrl[0].CNT) +//! @} + +//! @name USB Device endpoint control IN field management +//! @{ +#define udd_control_in_is_enable_stall() (udd_sram.ep_ctrl[1].CTRL&USB_EP_STALL_bm ? true : false) +#define udd_control_in_enable_stall() LASR16(&udd_sram.ep_ctrl[1].CTRL,USB_EP_STALL_bm) +#define udd_control_in_disable_stall() LACR16(&udd_sram.ep_ctrl[1].CTRL,USB_EP_STALL_bm) +#define udd_control_in_is_stalled() (udd_sram.ep_ctrl[1].STATUS&USB_EP_STALLF_bm ? true : false) +#define udd_control_in_ack_stall() LACR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_STALLF_bm) +#define udd_control_in_set_NACK0() LASR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_BUSNACK0_bm) +#define udd_control_in_clear_NACK0() LACR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_BUSNACK0_bm) + +#define udd_control_in_underflow() (udd_sram.ep_ctrl[1].STATUS&USB_EP_UNF_bm ? true : false) +#define udd_control_ack_in_underflow() LACR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_UNF_bm) + +#define udd_control_in_tc() (udd_sram.ep_ctrl[1].STATUS&USB_EP_TRNCOMPL0_bm ? true : false) +#define udd_control_in_ack_tc() LACR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_TRNCOMPL0_bm) +#define udd_control_in_set_tc() LASR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_TRNCOMPL0_bm) + +#define udd_control_in_dt_get() (udd_sram.ep_ctrl[1].STATUS&USB_EP_TOGGLE_bm ? true : false) +#define udd_control_in_dt_set() LASR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_TOGGLE_bm ) +#define udd_control_in_dt_clear() LACR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_TOGGLE_bm ) +#define udd_control_in_dt_toggle() LATR16(&udd_sram.ep_ctrl[1].STATUS,USB_EP_TOGGLE_bm) + +#define udd_control_in_set_buf(buf) (udd_sram.ep_ctrl[1].DATAPTR = (uint16_t) buf) + +#define udd_control_in_set_bytecnt(n) (udd_sram.ep_ctrl[1].CNT = n) +//! @} +//! @} + +//! @} + +#endif // _USB_DEVICE_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usb/usb_device.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usb/usb_device.h.REMOVED.git-id deleted file mode 100644 index cdd1739c..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/drivers/usb/usb_device.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -351c0ef90a7248c47453ee14be11805dcf0546b1 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/assembler.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/assembler.h new file mode 100644 index 00000000..8a2dfca0 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/assembler.h @@ -0,0 +1,159 @@ +/** + * \file + * + * \brief Assembler abstraction layer and utilities + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef ASSEMBLER_H_INCLUDED +#define ASSEMBLER_H_INCLUDED + +#if !defined(__ASSEMBLER__) && !defined(__IAR_SYSTEMS_ASM__) \ + && !defined(__DOXYGEN__) +# error This file may only be included from assembly files +#endif + +#if defined(__ASSEMBLER__) +# include "assembler/gas.h" +# include +#elif defined(__IAR_SYSTEMS_ASM__) +# include "assembler/iar.h" +# include +#endif + +/** + * \ingroup group_xmega_utils + * \defgroup assembler_group Assembler Support + * + * This group provides a good handful of macros intended to smooth out + * the differences between various assemblers, similar to what compiler.h does + * for compilers, except that assemblers tend to be much less standardized than + * compilers. + * + * @{ + */ + +//! \name Control Statements +//@{ +/** + * \def REPEAT(count) + * \brief Repeat the following statements \a count times + */ +/** + * \def END_REPEAT() + * \brief Mark the end of the statements to be repeated + */ +/** + * \def SET_LOC(offset) + * \brief Set the location counter to \a offset + */ +/** + * \def END_FILE() + * \brief Mark the end of the file + */ +//@} + +//! \name Data Objects +//@{ +/** + * \def FILL_BYTES(count) + * \brief Allocate space for \a count bytes + */ +//@} + +//! \name Symbol Definition +//@{ +/** + * \def L(name) + * \brief Turn \a name into a local symbol, if possible + */ +/** + * \def EXTERN_SYMBOL(name) + * \brief Declare \a name as an external symbol referenced by this file + */ +/** + * \def FUNCTION(name) + * \brief Define a file-local function called \a name + */ +/** + * \def PUBLIC_FUNCTION(name) + * \brief Define a globally visible function called \a name + */ +/** + * \def WEAK_FUNCTION(name) + * \brief Define a weak function called \a name + * + * Weak functions are only referenced if no strong definitions are found + */ +/** + * \def WEAK_FUNCTION_ALIAS(name, strong_name) + * \brief Define \a name as a weak alias for the function \a strong_name + * \sa WEAK_FUNCTION + */ +/** + * \def END_FUNC(name) + * \brief Mark the end of the function called \a name + */ +//@} + +//! \name Section Definition +//@{ +/** + * \def TEXT_SECTION(name) + * \brief Start a new section containing executable code + */ +/** + * \def RODATA_SECTION(name) + * \brief Start a new section containing read-only data + */ +/** + * \def DATA_SECTION(name) + * \brief Start a new section containing writeable initialized data + */ +/** + * \def BSS_SECTION(name) + * \brief Start a new section containing writeable zero-initialized data + */ +//@} + +//! @} + +#endif /* ASSEMBLER_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/assembler.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/assembler.h.REMOVED.git-id deleted file mode 100644 index ebc2824d..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/assembler.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8a2dfca03d5632ebb51fd8ad51301019cb536b4c \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/assembler/gas.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/assembler/gas.h new file mode 100644 index 00000000..58a54094 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/assembler/gas.h @@ -0,0 +1,124 @@ +/** + * \file + * + * \brief Assembler abstraction layer: GNU Assembler specifics + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef ASSEMBLER_GAS_H_INCLUDED +#define ASSEMBLER_GAS_H_INCLUDED + +#ifndef __DOXYGEN__ + + /* IAR doesn't accept dots in macro names */ + .macro ld_addr, reg, sym + lda.w \reg, \sym + .endm + + /* Define a function \a name that is either globally visible or only + * file-local. + */ + .macro gas_begin_func name, is_public + .if \is_public + .global \name + .endif + .section .text.\name, "ax", @progbits + .type \name, @function + \name : + .endm + + /* Define a function \a name that is either globally visible or only + * file-local in a given segment. + */ + .macro gas_begin_func_segm name, is_public, segment + .if \is_public + .global \name + .endif + .section .\segment, "ax", @progbits + .type \name, @function + \name : + .endm + + /* Define \a name as a weak alias for the function \a strong_name */ + .macro gas_weak_function_alias name, strong_name + .global \name + .weak \name + .type \name, @function + .set \name, \strong_name + .endm + + /* Define a weak function called \a name */ + .macro gas_weak_function name + .weak \name + gas_begin_func \name 1 + .endm + +#define REPEAT(count) .rept count +#define END_REPEAT() .endr +#define FILL_BYTES(count) .fill count +#define SET_LOC(offset) .org offset +#define L(name) .L##name +#define EXTERN_SYMBOL(name) + +#define TEXT_SECTION(name) \ + .section name, "ax", @progbits +#define RODATA_SECTION(name) \ + .section name, "a", @progbits +#define DATA_SECTION(name) \ + .section name, "aw", @progbits +#define BSS_SECTION(name) \ + .section name, "aw", @nobits + +#define FUNCTION(name) gas_begin_func name 0 +#define PUBLIC_FUNCTION(name) gas_begin_func name 1 +#define PUBLIC_FUNCTION_SEGMENT(name, segment) \ + gas_begin_func_segm name 1 segment +#define WEAK_FUNCTION(name) gas_weak_function name +#define WEAK_FUNCTION_ALIAS(name, strong_name) \ + gas_weak_function_alias name strong_name +#define END_FUNC(name) \ + .size name, . - name + +#define END_FILE() + +#endif /* __DOXYGEN__ */ + +#endif /* ASSEMBLER_GAS_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/assembler/gas.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/assembler/gas.h.REMOVED.git-id deleted file mode 100644 index 84fc8f77..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/assembler/gas.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -58a54094680ba9292dd92b8a87f1bfe4a1ae7d7e \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/bit_handling/clz_ctz.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/bit_handling/clz_ctz.h new file mode 100644 index 00000000..a58f1f4e --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/bit_handling/clz_ctz.h @@ -0,0 +1,215 @@ +/** + * \file + * + * \brief CLZ/CTZ C implementation. + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef CLZ_CTH_H +#define CLZ_CTH_H + +/** + * \brief Count leading zeros in unsigned integer + * + * This macro takes unsigned integers of any size, and evaluates to a call to + * the clz-function for its size. These functions count the number of zeros, + * starting with the MSB, before a one occurs in the integer. + * + * \param x Unsigned integer to count the leading zeros in. + * + * \return The number of leading zeros in \a x. + */ +#define clz(x) compiler_demux_size(sizeof(x), clz, (x)) + +/** + * \internal + * \brief Count leading zeros in unsigned, 8-bit integer + * + * \param x Unsigned byte to count the leading zeros in. + * + * \return The number of leading zeros in \a x. + */ +__always_inline static uint8_t clz8(uint8_t x) +{ + uint8_t bit = 0; + + if (x & 0xf0) { + x >>= 4; + } else { + bit += 4; + } + + if (x & 0x0c) { + x >>= 2; + } else { + bit += 2; + } + + if (!(x & 0x02)) { + bit++; + } + + return bit; + +} + +/** + * \internal + * \brief Count leading zeros in unsigned, 16-bit integer + * + * \param x Unsigned word to count the leading zeros in. + * + * \return The number of leading zeros in \a x. + */ +__always_inline static uint8_t clz16(uint16_t x) +{ + uint8_t bit = 0; + + if (x & 0xff00) { + x >>= 8; + } else { + bit += 8; + } + + return bit + clz8(x); +} + +/** + * \internal + * \brief Count leading zeros in unsigned, 32-bit integer + * + * \param x Unsigned double word to count the leading zeros in. + * + * \return The number of leading zeros in \a x. + */ +__always_inline static uint8_t clz32(uint32_t x) +{ + uint8_t bit = 0; + + if (x & 0xffff0000) { + x >>= 16; + } else { + bit += 16; + } + + return bit + clz16(x); +} + +/** + * \brief Count trailing zeros in unsigned integer + * + * This macro takes unsigned integers of any size, and evaluates to a call to + * the ctz-function for its size. These functions count the number of zeros, + * starting with the LSB, before a one occurs in the integer. + * + * \param x Unsigned integer to count the trailing zeros in. + * + * \return The number of trailing zeros in \a x. + */ +#define ctz(x) compiler_demux_size(sizeof(x), ctz, (x)) + +/** + * \internal + * \brief Count trailing zeros in unsigned, 8-bit integer + * + * \param x Unsigned byte to count the trailing zeros in. + * + * \return The number of leading zeros in \a x. + */ +__always_inline static uint8_t ctz8(uint8_t x) +{ + uint8_t bit = 0; + + if (!(x & 0x0f)) { + bit += 4; + x >>= 4; + } + if (!(x & 0x03)) { + bit += 2; + x >>= 2; + } + if (!(x & 0x01)) + bit++; + + return bit; +} + +/** + * \internal + * \brief Count trailing zeros in unsigned, 16-bit integer + * + * \param x Unsigned word to count the trailing zeros in. + * + * \return The number of trailing zeros in \a x. + */ +__always_inline static uint8_t ctz16(uint16_t x) +{ + uint8_t bit = 0; + + if (!(x & 0x00ff)) { + bit += 8; + x >>= 8; + } + + return bit + ctz8(x); +} + +/** + * \internal + * \brief Count trailing zeros in unsigned, 32-bit integer + * + * \param x Unsigned double word to count the trailing zeros in. + * + * \return The number of trailing zeros in \a x. + */ +__always_inline static uint8_t ctz32(uint32_t x) +{ + uint8_t bit = 0; + + if (!(x & 0x0000ffff)) { + bit += 16; + x >>= 16; + } + + return bit + ctz16(x); +} + +#endif /* CLZ_CTZ_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/bit_handling/clz_ctz.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/bit_handling/clz_ctz.h.REMOVED.git-id deleted file mode 100644 index 0db4f633..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/bit_handling/clz_ctz.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a58f1f4e289dc55b4a483bb50193d0f204d33bae \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/compiler.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/compiler.h new file mode 100644 index 00000000..5e4f2c43 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/compiler.h @@ -0,0 +1,1189 @@ +/** + * \file + * + * \brief Commonly used includes, types and macros. + * + * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef UTILS_COMPILER_H +#define UTILS_COMPILER_H + +/** + * \defgroup group_xmega_utils XMEGA compiler driver + * + * Compiler abstraction layer and code utilities for 8-bit AVR. + * This module provides various abstraction layers and utilities to make code compatible between different compilers. + * + * \{ + */ + +#if defined(__GNUC__) +# include +# include +#elif defined(__ICCAVR__) +# include +# include +#else +# error Unsupported compiler. +#endif + +#include +#include +#include +#include + +#include + +#ifdef __ICCAVR__ +/*! \name Compiler Keywords + * + * Port of some keywords from GCC to IAR Embedded Workbench. + */ +//! @{ +#define __asm__ asm +#define __inline__ inline +#define __volatile__ +//! @} +#endif + +/** + * \def UNUSED + * \brief Marking \a v as a unused parameter or value. + */ +#define UNUSED(v) (void)(v) + +/** + * \def unused + * \brief Marking \a v as a unused parameter or value. + */ +#define unused(v) do { (void)(v); } while(0) + +/** + * \def barrier + * \brief Memory barrier + */ +#ifdef __GNUC__ +# define barrier() asm volatile("" ::: "memory") +#else +# define barrier() asm ("") +#endif + +/** + * \brief Emit the compiler pragma \a arg. + * + * \param arg The pragma directive as it would appear after \e \#pragma + * (i.e. not stringified). + */ +#define COMPILER_PRAGMA(arg) _Pragma(#arg) + +/* + * AVR arch does not care about alignment anyway. + */ +#define COMPILER_PACK_RESET(alignment) +#define COMPILER_PACK_SET(alignment) + +/** + * \brief Set aligned boundary. + */ +#if (defined __GNUC__) +#define COMPILER_ALIGNED(a) __attribute__((__aligned__(a))) +#elif (defined __ICCAVR__) +#define COMPILER_ALIGNED(a) COMPILER_PRAGMA(data_alignment = a) +#endif + +/** + * \brief Set word-aligned boundary. + */ +#if (defined __GNUC__) +#define COMPILER_WORD_ALIGNED __attribute__((__aligned__(2))) +#elif (defined __ICCAVR__) +#define COMPILER_WORD_ALIGNED COMPILER_PRAGMA(data_alignment = 2) +#endif + +/** + * \name Tag functions as deprecated + * + * Tagging a function as deprecated will produce a warning when and only + * when the function is called. + * + * Usage is to add the __DEPRECATED__ symbol before the function definition. + * E.g.: + * __DEPRECATED__ uint8_t some_deprecated_function (void) + * { + * ... + * } + * + * \note Only supported by GCC 3.1 and above, no IAR support + * @{ + */ +#if ((defined __GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >=1))) +#define __DEPRECATED__ __attribute__((__deprecated__)) +#else +#define __DEPRECATED__ +#endif +//! @} + +/*! \name Usual Types + */ +//! @{ +typedef unsigned char Bool; //!< Boolean. +#ifndef __cplusplus +#if !defined(__bool_true_false_are_defined) +typedef unsigned char bool; //!< Boolean. +#endif +#endif +typedef int8_t S8 ; //!< 8-bit signed integer. +typedef uint8_t U8 ; //!< 8-bit unsigned integer. +typedef int16_t S16; //!< 16-bit signed integer. +typedef uint16_t U16; //!< 16-bit unsigned integer. +typedef uint16_t le16_t; +typedef uint16_t be16_t; +typedef int32_t S32; //!< 32-bit signed integer. +typedef uint32_t U32; //!< 32-bit unsigned integer. +typedef uint32_t le32_t; +typedef uint32_t be32_t; +typedef int64_t S64; //!< 64-bit signed integer. +typedef uint64_t U64; //!< 64-bit unsigned integer. +typedef float F32; //!< 32-bit floating-point number. +typedef double F64; //!< 64-bit floating-point number. +typedef uint16_t iram_size_t; +//! @} + + +/*! \name Status Types + */ +//! @{ +typedef Bool Status_bool_t; //!< Boolean status. +typedef U8 Status_t; //!< 8-bit-coded status. +//! @} + + +/*! \name Aliasing Aggregate Types + */ +//! @{ + +//! 16-bit union. +typedef union +{ + S16 s16 ; + U16 u16 ; + S8 s8 [2]; + U8 u8 [2]; +} Union16; + +//! 32-bit union. +typedef union +{ + S32 s32 ; + U32 u32 ; + S16 s16[2]; + U16 u16[2]; + S8 s8 [4]; + U8 u8 [4]; +} Union32; + +//! 64-bit union. +typedef union +{ + S64 s64 ; + U64 u64 ; + S32 s32[2]; + U32 u32[2]; + S16 s16[4]; + U16 u16[4]; + S8 s8 [8]; + U8 u8 [8]; +} Union64; + +//! Union of pointers to 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + S64 *s64ptr; + U64 *u64ptr; + S32 *s32ptr; + U32 *u32ptr; + S16 *s16ptr; + U16 *u16ptr; + S8 *s8ptr ; + U8 *u8ptr ; +} UnionPtr; + +//! Union of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + volatile S64 *s64ptr; + volatile U64 *u64ptr; + volatile S32 *s32ptr; + volatile U32 *u32ptr; + volatile S16 *s16ptr; + volatile U16 *u16ptr; + volatile S8 *s8ptr ; + volatile U8 *u8ptr ; +} UnionVPtr; + +//! Union of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + const S64 *s64ptr; + const U64 *u64ptr; + const S32 *s32ptr; + const U32 *u32ptr; + const S16 *s16ptr; + const U16 *u16ptr; + const S8 *s8ptr ; + const U8 *u8ptr ; +} UnionCPtr; + +//! Union of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + const volatile S64 *s64ptr; + const volatile U64 *u64ptr; + const volatile S32 *s32ptr; + const volatile U32 *u32ptr; + const volatile S16 *s16ptr; + const volatile U16 *u16ptr; + const volatile S8 *s8ptr ; + const volatile U8 *u8ptr ; +} UnionCVPtr; + +//! Structure of pointers to 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + S64 *s64ptr; + U64 *u64ptr; + S32 *s32ptr; + U32 *u32ptr; + S16 *s16ptr; + U16 *u16ptr; + S8 *s8ptr ; + U8 *u8ptr ; +} StructPtr; + +//! Structure of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + volatile S64 *s64ptr; + volatile U64 *u64ptr; + volatile S32 *s32ptr; + volatile U32 *u32ptr; + volatile S16 *s16ptr; + volatile U16 *u16ptr; + volatile S8 *s8ptr ; + volatile U8 *u8ptr ; +} StructVPtr; + +//! Structure of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + const S64 *s64ptr; + const U64 *u64ptr; + const S32 *s32ptr; + const U32 *u32ptr; + const S16 *s16ptr; + const U16 *u16ptr; + const S8 *s8ptr ; + const U8 *u8ptr ; +} StructCPtr; + +//! Structure of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + const volatile S64 *s64ptr; + const volatile U64 *u64ptr; + const volatile S32 *s32ptr; + const volatile U32 *u32ptr; + const volatile S16 *s16ptr; + const volatile U16 *u16ptr; + const volatile S8 *s8ptr ; + const volatile U8 *u8ptr ; +} StructCVPtr; + +//! @} + + +//_____ M A C R O S ________________________________________________________ + +/*! \name Usual Constants + */ +//! @{ +#define DISABLE 0 +#define ENABLE 1 +#ifndef __cplusplus +#if !defined(__bool_true_false_are_defined) +#define false 0 +#define true 1 +#endif +#endif +#define PASS 0 +#define FAIL 1 +#define LOW 0 +#define HIGH 1 +//! @} + + +//! \name Compile time error handling +//@{ + +/** + * \internal + * \def ERROR_FUNC(name, msg) + * \brief Fail compilation if function call isn't eliminated + * + * If the compiler fails to optimize away all calls to the function \a + * name, terminate compilation and display \a msg to the user. + * + * \note Not all compilers support this, so this is best-effort only. + * Sometimes, there may be a linker error instead, and when optimization + * is disabled, this mechanism will be completely disabled. + */ +#ifndef ERROR_FUNC +# define ERROR_FUNC(name, msg) \ + extern int name(void) +#endif + +//@} + +//! \name Function call demultiplexing +//@{ + +//! Error function for failed demultiplexing. +ERROR_FUNC(compiler_demux_bad_size, "Invalid parameter size"); + +/** + * \internal + * \brief Demultiplex function call based on size of datatype + * + * Evaluates to a function call to a function name with suffix 8, 16 or 32 + * depending on the size of the datatype. Any number of parameters can be + * passed to the function. + * + * Usage: + * \code + void foo8(uint8_t a, void *b); + void foo16(uint16_t a, void *b); + void foo32(uint32_t a, void *b); + + #define foo(x, y) compiler_demux_size(sizeof(x), foo, x, y) +\endcode + * + * \param size Size of the datatype. + * \param func Base function name. + * \param ... List of parameters to pass to the function. + */ +#define compiler_demux_size(size, func, ...) \ + (((size) == 1) ? func##8(__VA_ARGS__) : \ + ((size) == 2) ? func##16(__VA_ARGS__) : \ + ((size) == 4) ? func##32(__VA_ARGS__) : \ + compiler_demux_bad_size()) + +//@} + +/** + * \def __always_inline + * \brief The function should always be inlined. + * + * This annotation instructs the compiler to ignore its inlining + * heuristics and inline the function no matter how big it thinks it + * becomes. + */ +#if (defined __GNUC__) + #define __always_inline inline __attribute__((__always_inline__)) +#elif (defined __ICCAVR__) + #define __always_inline _Pragma("inline=forced") +#endif + +//! \name Optimization Control +//@{ + +/** + * \def __always_optimize + * \brief The function should always be optimized. + * + * This annotation instructs the compiler to ignore global optimization + * settings and always compile the function with a high level of + * optimization. + */ +#if (defined __GNUC__) + #define __always_optimize __attribute__((optimize(3))) +#elif (defined __ICCAVR__) + #define __always_optimize _Pragma("optimize=high") +#endif + +/** + * \def likely(exp) + * \brief The expression \a exp is likely to be true + */ +#ifndef likely +# define likely(exp) (exp) +#endif + +/** + * \def unlikely(exp) + * \brief The expression \a exp is unlikely to be true + */ +#ifndef unlikely +# define unlikely(exp) (exp) +#endif + +/** + * \def is_constant(exp) + * \brief Determine if an expression evaluates to a constant value. + * + * \param exp Any expression + * + * \return true if \a exp is constant, false otherwise. + */ +#ifdef __GNUC__ +# define is_constant(exp) __builtin_constant_p(exp) +#else +# define is_constant(exp) (0) +#endif + +//! @} + +/*! \name Bit-Field Handling + */ +#include "bit_handling/clz_ctz.h" +//! @{ + +/*! \brief Reads the bits of a value specified by a given bit-mask. + * + * \param value Value to read bits from. + * \param mask Bit-mask indicating bits to read. + * + * \return Read bits. + */ +#define Rd_bits( value, mask) ((value)&(mask)) + +/*! \brief Writes the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue to write bits to. + * \param mask Bit-mask indicating bits to write. + * \param bits Bits to write. + * + * \return Resulting value with written bits. + */ +#define Wr_bits(lvalue, mask, bits) ((lvalue) = ((lvalue) & ~(mask)) |\ + ((bits ) & (mask))) + +/*! \brief Tests the bits of a value specified by a given bit-mask. + * + * \param value Value of which to test bits. + * \param mask Bit-mask indicating bits to test. + * + * \return \c 1 if at least one of the tested bits is set, else \c 0. + */ +#define Tst_bits( value, mask) (Rd_bits(value, mask) != 0) + +/*! \brief Clears the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to clear bits. + * \param mask Bit-mask indicating bits to clear. + * + * \return Resulting value with cleared bits. + */ +#define Clr_bits(lvalue, mask) ((lvalue) &= ~(mask)) + +/*! \brief Sets the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to set bits. + * \param mask Bit-mask indicating bits to set. + * + * \return Resulting value with set bits. + */ +#define Set_bits(lvalue, mask) ((lvalue) |= (mask)) + +/*! \brief Toggles the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to toggle bits. + * \param mask Bit-mask indicating bits to toggle. + * + * \return Resulting value with toggled bits. + */ +#define Tgl_bits(lvalue, mask) ((lvalue) ^= (mask)) + +/*! \brief Reads the bit-field of a value specified by a given bit-mask. + * + * \param value Value to read a bit-field from. + * \param mask Bit-mask indicating the bit-field to read. + * + * \return Read bit-field. + */ +#define Rd_bitfield( value,mask) (Rd_bits( value, (uint32_t)mask) >> ctz(mask)) + +/*! \brief Writes the bit-field of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue to write a bit-field to. + * \param mask Bit-mask indicating the bit-field to write. + * \param bitfield Bit-field to write. + * + * \return Resulting value with written bit-field. + */ +#define Wr_bitfield(lvalue, mask, bitfield) (Wr_bits(lvalue, mask, (uint32_t)(bitfield) << ctz(mask))) + +//! @} + + +/*! \brief This macro is used to test fatal errors. + * + * The macro tests if the expression is false. If it is, a fatal error is + * detected and the application hangs up. If TEST_SUITE_DEFINE_ASSERT_MACRO + * is defined, a unit test version of the macro is used, to allow execution + * of further tests after a false expression. + * + * \param expr Expression to evaluate and supposed to be nonzero. + */ +#if defined(_ASSERT_ENABLE_) +# if defined(TEST_SUITE_DEFINE_ASSERT_MACRO) + // Assert() is defined in unit_test/suite.h +# include "unit_test/suite.h" +# else +# define Assert(expr) \ + {\ + if (!(expr)) while (true);\ + } +# endif +#else +# define Assert(expr) ((void) 0) +#endif + +/*! \name Bit Reversing + */ +//! @{ + +/*! \brief Reverses the bits of \a u8. + * + * \param u8 U8 of which to reverse the bits. + * + * \return Value resulting from \a u8 with reversed bits. + */ +#define bit_reverse8(u8) ((U8)(bit_reverse32((U8)(u8)) >> 24)) + +/*! \brief Reverses the bits of \a u16. + * + * \param u16 U16 of which to reverse the bits. + * + * \return Value resulting from \a u16 with reversed bits. + */ +#define bit_reverse16(u16) ((U16)(bit_reverse32((U16)(u16)) >> 16)) + +/*! \brief Reverses the bits of \a u32. + * + * \param u32 U32 of which to reverse the bits. + * + * \return Value resulting from \a u32 with reversed bits. + */ +#if (defined __GNUC__) + #define bit_reverse32(u32) \ + (\ + {\ + unsigned int __value = (U32)(u32);\ + __asm__ ("brev\t%0" : "+r" (__value) : : "cc");\ + (U32)__value;\ + }\ + ) +#elif (defined __ICCAVR__) + #define bit_reverse32(u32) ((U32)__bit_reverse((U32)(u32))) +#endif + +/*! \brief Reverses the bits of \a u64. + * + * \param u64 U64 of which to reverse the bits. + * + * \return Value resulting from \a u64 with reversed bits. + */ +#define bit_reverse64(u64) ((U64)(((U64)bit_reverse32((U64)(u64) >> 32)) |\ + ((U64)bit_reverse32((U64)(u64)) << 32))) + +//! @} + +//! \name Logarithmic functions +//! @{ + +/** + * \internal + * Undefined function. Will cause a link failure if ilog2() is called + * with an invalid constant value. + */ +int_fast8_t ilog2_undefined(void); + +/** + * \brief Calculate the base-2 logarithm of a number rounded down to + * the nearest integer. + * + * \param x A 32-bit value + * \return The base-2 logarithm of \a x, or -1 if \a x is 0. + */ +static inline int_fast8_t ilog2(uint32_t x) +{ + if (is_constant(x)) + return ((x) & (1ULL << 31) ? 31 : + (x) & (1ULL << 30) ? 30 : + (x) & (1ULL << 29) ? 29 : + (x) & (1ULL << 28) ? 28 : + (x) & (1ULL << 27) ? 27 : + (x) & (1ULL << 26) ? 26 : + (x) & (1ULL << 25) ? 25 : + (x) & (1ULL << 24) ? 24 : + (x) & (1ULL << 23) ? 23 : + (x) & (1ULL << 22) ? 22 : + (x) & (1ULL << 21) ? 21 : + (x) & (1ULL << 20) ? 20 : + (x) & (1ULL << 19) ? 19 : + (x) & (1ULL << 18) ? 18 : + (x) & (1ULL << 17) ? 17 : + (x) & (1ULL << 16) ? 16 : + (x) & (1ULL << 15) ? 15 : + (x) & (1ULL << 14) ? 14 : + (x) & (1ULL << 13) ? 13 : + (x) & (1ULL << 12) ? 12 : + (x) & (1ULL << 11) ? 11 : + (x) & (1ULL << 10) ? 10 : + (x) & (1ULL << 9) ? 9 : + (x) & (1ULL << 8) ? 8 : + (x) & (1ULL << 7) ? 7 : + (x) & (1ULL << 6) ? 6 : + (x) & (1ULL << 5) ? 5 : + (x) & (1ULL << 4) ? 4 : + (x) & (1ULL << 3) ? 3 : + (x) & (1ULL << 2) ? 2 : + (x) & (1ULL << 1) ? 1 : + (x) & (1ULL << 0) ? 0 : + ilog2_undefined()); + + return 31 - clz(x); +} + +//! @} + +/*! \name Alignment + */ +//! @{ + +/*! \brief Tests alignment of the number \a val with the \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return \c 1 if the number \a val is aligned with the \a n boundary, else \c 0. + */ +#define Test_align(val, n ) (!Tst_bits( val, (n) - 1 ) ) + +/*! \brief Gets alignment of the number \a val with respect to the \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Alignment of the number \a val with respect to the \a n boundary. + */ +#define Get_align( val, n ) ( Rd_bits( val, (n) - 1 ) ) + +/*! \brief Sets alignment of the lvalue number \a lval to \a alg with respect to the \a n boundary. + * + * \param lval Input/output lvalue. + * \param n Boundary. + * \param alg Alignment. + * + * \return New value of \a lval resulting from its alignment set to \a alg with respect to the \a n boundary. + */ +#define Set_align(lval, n, alg) ( Wr_bits(lval, (n) - 1, alg) ) + +/*! \brief Aligns the number \a val with the upper \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Value resulting from the number \a val aligned with the upper \a n boundary. + */ +#define Align_up( val, n ) (((val) + ((n) - 1)) & ~((n) - 1)) + +/*! \brief Aligns the number \a val with the lower \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Value resulting from the number \a val aligned with the lower \a n boundary. + */ +#define Align_down(val, n ) ( (val) & ~((n) - 1)) + +//! @} + + +/*! \name Mathematics + * + * Compiler optimization for non-constant expressions, only for abs under WinAVR + */ +//! @{ + +/*! \brief Takes the absolute value of \a a. + * + * \param a Input value. + * + * \return Absolute value of \a a. + * + * \note More optimized if only used with values known at compile time. + */ +#define Abs(a) (((a) < 0 ) ? -(a) : (a)) +#ifndef abs +#define abs(a) Abs(a) +#endif + +/*! \brief Takes the minimal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Minimal value of \a a and \a b. + * + * \note More optimized if only used with values known at compile time. + */ +#define Min(a, b) (((a) < (b)) ? (a) : (b)) +#define min(a, b) Min(a, b) + +/*! \brief Takes the maximal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Maximal value of \a a and \a b. + * + * \note More optimized if only used with values known at compile time. + */ +#define Max(a, b) (((a) > (b)) ? (a) : (b)) +#define max(a, b) Max(a, b) + +//! @} + + +/*! \brief Calls the routine at address \a addr. + * + * It generates a long call opcode. + * + * For example, `Long_call(0x80000000)' generates a software reset on a UC3 if + * it is invoked from the CPU supervisor mode. + * + * \param addr Address of the routine to call. + * + * \note It may be used as a long jump opcode in some special cases. + */ +#define Long_call(addr) ((*(void (*)(void))(addr))()) + +/*! \name System Register Access + */ +//! @{ + +/*! \brief Gets the value of the \a sysreg system register. + * + * \param sysreg Address of the system register of which to get the value. + * + * \return Value of the \a sysreg system register. + */ +#if (defined __GNUC__) + #define Get_system_register(sysreg) __builtin_mfsr(sysreg) +#elif (defined __ICCAVR__) + #define Get_system_register(sysreg) __get_system_register(sysreg) +#endif + +/*! \brief Sets the value of the \a sysreg system register to \a value. + * + * \param sysreg Address of the system register of which to set the value. + * \param value Value to set the \a sysreg system register to. + */ +#if (defined __GNUC__) + #define Set_system_register(sysreg, value) __builtin_mtsr(sysreg, value) +#elif (defined __ICCAVR__) + #define Set_system_register(sysreg, value) __set_system_register(sysreg, value) +#endif + +//! @} + +/*! \name Debug Register Access + */ +//! @{ + +/*! \brief Gets the value of the \a dbgreg debug register. + * + * \param dbgreg Address of the debug register of which to get the value. + * + * \return Value of the \a dbgreg debug register. + */ +#if (defined __GNUC__) + #define Get_debug_register(dbgreg) __builtin_mfdr(dbgreg) +#elif (defined __ICCAVR__) + #define Get_debug_register(dbgreg) __get_debug_register(dbgreg) +#endif + +/*! \brief Sets the value of the \a dbgreg debug register to \a value. + * + * \param dbgreg Address of the debug register of which to set the value. + * \param value Value to set the \a dbgreg debug register to. + */ +#if (defined __GNUC__) + #define Set_debug_register(dbgreg, value) __builtin_mtdr(dbgreg, value) +#elif (defined __ICCAVR__) + #define Set_debug_register(dbgreg, value) __set_debug_register(dbgreg, value) +#endif + +//! @} + + +/*! \name MCU Endianism Handling + * xmega is a MCU little endianism. + */ +//! @{ +#define MSB(u16) (((uint8_t* )&u16)[1]) +#define LSB(u16) (((uint8_t* )&u16)[0]) + +#define MSW(u32) (((uint16_t*)&u32)[1]) +#define LSW(u32) (((uint16_t*)&u32)[0]) +#define MSB0W(u32) (((uint8_t*)&(u32))[3]) //!< Most significant byte of 1st rank of \a u32. +#define MSB1W(u32) (((uint8_t*)&(u32))[2]) //!< Most significant byte of 2nd rank of \a u32. +#define MSB2W(u32) (((uint8_t*)&(u32))[1]) //!< Most significant byte of 3rd rank of \a u32. +#define MSB3W(u32) (((uint8_t*)&(u32))[0]) //!< Most significant byte of 4th rank of \a u32. +#define LSB3W(u32) MSB0W(u32) //!< Least significant byte of 4th rank of \a u32. +#define LSB2W(u32) MSB1W(u32) //!< Least significant byte of 3rd rank of \a u32. +#define LSB1W(u32) MSB2W(u32) //!< Least significant byte of 2nd rank of \a u32. +#define LSB0W(u32) MSB3W(u32) //!< Least significant byte of 1st rank of \a u32. + +#define MSB0(u32) (((uint8_t*)&u32)[3]) +#define MSB1(u32) (((uint8_t*)&u32)[2]) +#define MSB2(u32) (((uint8_t*)&u32)[1]) +#define MSB3(u32) (((uint8_t*)&u32)[0]) +#define LSB0(u32) MSB3(u32) +#define LSB1(u32) MSB2(u32) +#define LSB2(u32) MSB1(u32) +#define LSB3(u32) MSB0(u32) + +#define LE16(x) (x) +#define le16_to_cpu(x) (x) +#define cpu_to_le16(x) (x) +#define LE16_TO_CPU(x) (x) +#define CPU_TO_LE16(x) (x) + +#define BE16(x) Swap16(x) +#define be16_to_cpu(x) swap16(x) +#define cpu_to_be16(x) swap16(x) +#define BE16_TO_CPU(x) Swap16(x) +#define CPU_TO_BE16(x) Swap16(x) + +#define LE32(x) (x) +#define le32_to_cpu(x) (x) +#define cpu_to_le32(x) (x) +#define LE32_TO_CPU(x) (x) +#define CPU_TO_LE32(x) (x) + +#define BE32(x) Swap32(x) +#define be32_to_cpu(x) swap32(x) +#define cpu_to_be32(x) swap32(x) +#define BE32_TO_CPU(x) Swap32(x) +#define CPU_TO_BE32(x) Swap32(x) + + + +//! @} + + +/*! \name Endianism Conversion + * + * The same considerations as for clz and ctz apply here but AVR32-GCC's + * __builtin_bswap_16 and __builtin_bswap_32 do not behave like macros when + * applied to constant expressions, so two sets of macros are defined here: + * - Swap16, Swap32 and Swap64 to apply to constant expressions (values known + * at compile time); + * - swap16, swap32 and swap64 to apply to non-constant expressions (values + * unknown at compile time). + */ +//! @{ + +/*! \brief Toggles the endianism of \a u16 (by swapping its bytes). + * + * \param u16 U16 of which to toggle the endianism. + * + * \return Value resulting from \a u16 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap16(u16) ((U16)(((U16)(u16) >> 8) |\ + ((U16)(u16) << 8))) + +/*! \brief Toggles the endianism of \a u32 (by swapping its bytes). + * + * \param u32 U32 of which to toggle the endianism. + * + * \return Value resulting from \a u32 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap32(u32) ((U32)(((U32)Swap16((U32)(u32) >> 16)) |\ + ((U32)Swap16((U32)(u32)) << 16))) + +/*! \brief Toggles the endianism of \a u64 (by swapping its bytes). + * + * \param u64 U64 of which to toggle the endianism. + * + * \return Value resulting from \a u64 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap64(u64) ((U64)(((U64)Swap32((U64)(u64) >> 32)) |\ + ((U64)Swap32((U64)(u64)) << 32))) + +/*! \brief Toggles the endianism of \a u16 (by swapping its bytes). + * + * \param u16 U16 of which to toggle the endianism. + * + * \return Value resulting from \a u16 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#define swap16(u16) Swap16(u16) + +/*! \brief Toggles the endianism of \a u32 (by swapping its bytes). + * + * \param u32 U32 of which to toggle the endianism. + * + * \return Value resulting from \a u32 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#define swap32(u32) Swap32(u32) + +/*! \brief Toggles the endianism of \a u64 (by swapping its bytes). + * + * \param u64 U64 of which to toggle the endianism. + * + * \return Value resulting from \a u64 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#define swap64(u64) ((U64)(((U64)swap32((U64)(u64) >> 32)) |\ + ((U64)swap32((U64)(u64)) << 32))) + +//! @} + + +/*! \name Target Abstraction + */ +//! @{ + +#define _GLOBEXT_ extern //!< extern storage-class specifier. +#define _CONST_TYPE_ const //!< const type qualifier. +#define _MEM_TYPE_SLOW_ //!< Slow memory type. +#define _MEM_TYPE_MEDFAST_ //!< Fairly fast memory type. +#define _MEM_TYPE_FAST_ //!< Fast memory type. + +typedef U8 Byte; //!< 8-bit unsigned integer. + +#define memcmp_ram2ram memcmp //!< Target-specific memcmp of RAM to RAM. +#define memcmp_code2ram memcmp //!< Target-specific memcmp of RAM to NVRAM. +#define memcpy_ram2ram memcpy //!< Target-specific memcpy from RAM to RAM. +#define memcpy_code2ram memcpy //!< Target-specific memcpy from NVRAM to RAM. + +//! @} + +/** + * \brief Calculate \f$ \left\lceil \frac{a}{b} \right\rceil \f$ using + * integer arithmetic. + * + * \param a An integer + * \param b Another integer + * + * \return (\a a / \a b) rounded up to the nearest integer. + */ +#define div_ceil(a, b) (((a) + (b) - 1) / (b)) + +#include "preprocessor.h" +#include "progmem.h" +#include "interrupt.h" + + +#if (defined __GNUC__) + #define SHORTENUM __attribute__ ((packed)) +#elif (defined __ICCAVR__) + #define SHORTENUM /**/ +#endif + +#if (defined __GNUC__) + #define FUNC_PTR void * +#elif (defined __ICCAVR__) +#if (FLASHEND > 0x1FFFF) // Required for program code larger than 128K + #define FUNC_PTR void __farflash * +#else + #define FUNC_PTR void * +#endif /* ENABLE_FAR_FLASH */ +#endif + + +#if (defined __GNUC__) + #define FLASH_DECLARE(x) const x __attribute__((__progmem__)) +#elif (defined __ICCAVR__) + #define FLASH_DECLARE(x) const __flash x +#endif + +#if (defined __GNUC__) + #define FLASH_EXTERN(x) extern const x +#elif (defined __ICCAVR__) + #define FLASH_EXTERN(x) extern const __flash x +#endif + + +/*Defines the Flash Storage for the request and response of MAC*/ +#define CMD_ID_OCTET (0) + +/* Converting of values from CPU endian to little endian. */ +#define CPU_ENDIAN_TO_LE16(x) (x) +#define CPU_ENDIAN_TO_LE32(x) (x) +#define CPU_ENDIAN_TO_LE64(x) (x) + +/* Converting of values from little endian to CPU endian. */ +#define LE16_TO_CPU_ENDIAN(x) (x) +#define LE32_TO_CPU_ENDIAN(x) (x) +#define LE64_TO_CPU_ENDIAN(x) (x) + +/* Converting of constants from little endian to CPU endian. */ +#define CLE16_TO_CPU_ENDIAN(x) (x) +#define CLE32_TO_CPU_ENDIAN(x) (x) +#define CLE64_TO_CPU_ENDIAN(x) (x) + +/* Converting of constants from CPU endian to little endian. */ +#define CCPU_ENDIAN_TO_LE16(x) (x) +#define CCPU_ENDIAN_TO_LE32(x) (x) +#define CCPU_ENDIAN_TO_LE64(x) (x) + +#if (defined __GNUC__) + #define ADDR_COPY_DST_SRC_16(dst, src) memcpy((&(dst)), (&(src)), sizeof(uint16_t)) + #define ADDR_COPY_DST_SRC_64(dst, src) memcpy((&(dst)), (&(src)), sizeof(uint64_t)) + +/* Converts a 2 Byte array into a 16-Bit value */ +#define convert_byte_array_to_16_bit(data) \ + (*(uint16_t *)(data)) + +/* Converts a 4 Byte array into a 32-Bit value */ +#define convert_byte_array_to_32_bit(data) \ + (*(uint32_t *)(data)) + +/* Converts a 8 Byte array into a 64-Bit value */ +#define convert_byte_array_to_64_bit(data) \ + (*(uint64_t *)(data)) + +/* Converts a 16-Bit value into a 2 Byte array */ +#define convert_16_bit_to_byte_array(value, data) \ + ((*(uint16_t *)(data)) = (uint16_t)(value)) + +/* Converts spec 16-Bit value into a 2 Byte array */ +#define convert_spec_16_bit_to_byte_array(value, data) \ + ((*(uint16_t *)(data)) = (uint16_t)(value)) + +/* Converts spec 16-Bit value into a 2 Byte array */ +#define convert_16_bit_to_byte_address(value, data) \ + ((*(uint16_t *)(data)) = (uint16_t)(value)) + +/* Converts a 32-Bit value into a 4 Byte array */ +#define convert_32_bit_to_byte_array(value, data) \ + ((*(uint32_t *)(data)) = (uint32_t)(value)) + +/* Converts a 64-Bit value into a 8 Byte array */ +/* Here memcpy requires much less footprint */ +#define convert_64_bit_to_byte_array(value, data) \ + memcpy((data), (&(value)), sizeof(uint64_t)) + +#elif (defined __ICCAVR__) + #define ADDR_COPY_DST_SRC_16(dst, src) ((dst) = (src)) + #define ADDR_COPY_DST_SRC_64(dst, src) ((dst) = (src)) + +/* Converts a 2 Byte array into a 16-Bit value */ +#define convert_byte_array_to_16_bit(data) \ + (*(uint16_t *)(data)) + +/* Converts a 4 Byte array into a 32-Bit value */ +#define convert_byte_array_to_32_bit(data) \ + (*(uint32_t *)(data)) + +/* Converts a 8 Byte array into a 64-Bit value */ +#define convert_byte_array_to_64_bit(data) \ + (*(uint64_t *)(data)) + +/* Converts a 16-Bit value into a 2 Byte array */ +#define convert_16_bit_to_byte_array(value, data) \ + ((*(uint16_t *)(data)) = (uint16_t)(value)) + +/* Converts spec 16-Bit value into a 2 Byte array */ +#define convert_spec_16_bit_to_byte_array(value, data) \ + ((*(uint16_t *)(data)) = (uint16_t)(value)) + +/* Converts spec 16-Bit value into a 2 Byte array */ +#define convert_16_bit_to_byte_address(value, data) \ + ((*(uint16_t *)(data)) = (uint16_t)(value)) + +/* Converts a 32-Bit value into a 4 Byte array */ +#define convert_32_bit_to_byte_array(value, data) \ + ((*(uint32_t *)(data)) = (uint32_t)(value)) + +/* Converts a 64-Bit value into a 8 Byte array */ +#define convert_64_bit_to_byte_array(value, data) \ + ((*(uint64_t *)(data)) = (uint64_t)(value)) +#endif + +#define MEMCPY_ENDIAN memcpy +#define PGM_READ_BLOCK(dst, src, len) memcpy_P((dst), (src), (len)) + +#if (defined __GNUC__) + #define PGM_READ_BYTE(x) pgm_read_byte(x) + #define PGM_READ_WORD(x) pgm_read_word(x) +#elif (defined __ICCAVR__) + #define PGM_READ_BYTE(x) *(x) + #define PGM_READ_WORD(x) *(x) +#endif + + +#if (defined __GNUC__) + #define nop() do { __asm__ __volatile__ ("nop"); } while (0) +#elif (defined __ICCAVR__) + #define nop() __no_operation() +#endif + + +/** + * \} + */ + +#endif // UTILS_COMPILER_H diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/compiler.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/compiler.h.REMOVED.git-id deleted file mode 100644 index 72430898..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/compiler.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5e4f2c43a1c12e97919b724c2efe119508645411 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/mrepeat.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/mrepeat.h new file mode 100644 index 00000000..f4f9c94c --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/mrepeat.h @@ -0,0 +1,338 @@ +/** + * \file + * + * \brief Preprocessor macro repeating utils. + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef _MREPEAT_H_ +#define _MREPEAT_H_ + +/** + * \defgroup group_xmega_utils_mrepeat Macro Repeat + * + * \ingroup group_xmega_utils + * + * \{ + */ + +#include "preprocessor.h" + + +//! Maximal number of repetitions supported by MREPEAT. +#define MREPEAT_LIMIT 256 + +/*! \brief Macro repeat. + * + * This macro represents a horizontal repetition construct. + * + * \param count The number of repetitious calls to macro. Valid values range from 0 to MREPEAT_LIMIT. + * \param macro A binary operation of the form macro(n, data). This macro is expanded by MREPEAT with + * the current repetition number and the auxiliary data argument. + * \param data Auxiliary data passed to macro. + * + * \return macro(0, data) macro(1, data) ... macro(count - 1, data) + */ +#define MREPEAT(count, macro, data) TPASTE2(MREPEAT, count)(macro, data) + +#define MREPEAT0( macro, data) +#define MREPEAT1( macro, data) MREPEAT0( macro, data) macro( 0, data) +#define MREPEAT2( macro, data) MREPEAT1( macro, data) macro( 1, data) +#define MREPEAT3( macro, data) MREPEAT2( macro, data) macro( 2, data) +#define MREPEAT4( macro, data) MREPEAT3( macro, data) macro( 3, data) +#define MREPEAT5( macro, data) MREPEAT4( macro, data) macro( 4, data) +#define MREPEAT6( macro, data) MREPEAT5( macro, data) macro( 5, data) +#define MREPEAT7( macro, data) MREPEAT6( macro, data) macro( 6, data) +#define MREPEAT8( macro, data) MREPEAT7( macro, data) macro( 7, data) +#define MREPEAT9( macro, data) MREPEAT8( macro, data) macro( 8, data) +#define MREPEAT10( macro, data) MREPEAT9( macro, data) macro( 9, data) +#define MREPEAT11( macro, data) MREPEAT10( macro, data) macro( 10, data) +#define MREPEAT12( macro, data) MREPEAT11( macro, data) macro( 11, data) +#define MREPEAT13( macro, data) MREPEAT12( macro, data) macro( 12, data) +#define MREPEAT14( macro, data) MREPEAT13( macro, data) macro( 13, data) +#define MREPEAT15( macro, data) MREPEAT14( macro, data) macro( 14, data) +#define MREPEAT16( macro, data) MREPEAT15( macro, data) macro( 15, data) +#define MREPEAT17( macro, data) MREPEAT16( macro, data) macro( 16, data) +#define MREPEAT18( macro, data) MREPEAT17( macro, data) macro( 17, data) +#define MREPEAT19( macro, data) MREPEAT18( macro, data) macro( 18, data) +#define MREPEAT20( macro, data) MREPEAT19( macro, data) macro( 19, data) +#define MREPEAT21( macro, data) MREPEAT20( macro, data) macro( 20, data) +#define MREPEAT22( macro, data) MREPEAT21( macro, data) macro( 21, data) +#define MREPEAT23( macro, data) MREPEAT22( macro, data) macro( 22, data) +#define MREPEAT24( macro, data) MREPEAT23( macro, data) macro( 23, data) +#define MREPEAT25( macro, data) MREPEAT24( macro, data) macro( 24, data) +#define MREPEAT26( macro, data) MREPEAT25( macro, data) macro( 25, data) +#define MREPEAT27( macro, data) MREPEAT26( macro, data) macro( 26, data) +#define MREPEAT28( macro, data) MREPEAT27( macro, data) macro( 27, data) +#define MREPEAT29( macro, data) MREPEAT28( macro, data) macro( 28, data) +#define MREPEAT30( macro, data) MREPEAT29( macro, data) macro( 29, data) +#define MREPEAT31( macro, data) MREPEAT30( macro, data) macro( 30, data) +#define MREPEAT32( macro, data) MREPEAT31( macro, data) macro( 31, data) +#define MREPEAT33( macro, data) MREPEAT32( macro, data) macro( 32, data) +#define MREPEAT34( macro, data) MREPEAT33( macro, data) macro( 33, data) +#define MREPEAT35( macro, data) MREPEAT34( macro, data) macro( 34, data) +#define MREPEAT36( macro, data) MREPEAT35( macro, data) macro( 35, data) +#define MREPEAT37( macro, data) MREPEAT36( macro, data) macro( 36, data) +#define MREPEAT38( macro, data) MREPEAT37( macro, data) macro( 37, data) +#define MREPEAT39( macro, data) MREPEAT38( macro, data) macro( 38, data) +#define MREPEAT40( macro, data) MREPEAT39( macro, data) macro( 39, data) +#define MREPEAT41( macro, data) MREPEAT40( macro, data) macro( 40, data) +#define MREPEAT42( macro, data) MREPEAT41( macro, data) macro( 41, data) +#define MREPEAT43( macro, data) MREPEAT42( macro, data) macro( 42, data) +#define MREPEAT44( macro, data) MREPEAT43( macro, data) macro( 43, data) +#define MREPEAT45( macro, data) MREPEAT44( macro, data) macro( 44, data) +#define MREPEAT46( macro, data) MREPEAT45( macro, data) macro( 45, data) +#define MREPEAT47( macro, data) MREPEAT46( macro, data) macro( 46, data) +#define MREPEAT48( macro, data) MREPEAT47( macro, data) macro( 47, data) +#define MREPEAT49( macro, data) MREPEAT48( macro, data) macro( 48, data) +#define MREPEAT50( macro, data) MREPEAT49( macro, data) macro( 49, data) +#define MREPEAT51( macro, data) MREPEAT50( macro, data) macro( 50, data) +#define MREPEAT52( macro, data) MREPEAT51( macro, data) macro( 51, data) +#define MREPEAT53( macro, data) MREPEAT52( macro, data) macro( 52, data) +#define MREPEAT54( macro, data) MREPEAT53( macro, data) macro( 53, data) +#define MREPEAT55( macro, data) MREPEAT54( macro, data) macro( 54, data) +#define MREPEAT56( macro, data) MREPEAT55( macro, data) macro( 55, data) +#define MREPEAT57( macro, data) MREPEAT56( macro, data) macro( 56, data) +#define MREPEAT58( macro, data) MREPEAT57( macro, data) macro( 57, data) +#define MREPEAT59( macro, data) MREPEAT58( macro, data) macro( 58, data) +#define MREPEAT60( macro, data) MREPEAT59( macro, data) macro( 59, data) +#define MREPEAT61( macro, data) MREPEAT60( macro, data) macro( 60, data) +#define MREPEAT62( macro, data) MREPEAT61( macro, data) macro( 61, data) +#define MREPEAT63( macro, data) MREPEAT62( macro, data) macro( 62, data) +#define MREPEAT64( macro, data) MREPEAT63( macro, data) macro( 63, data) +#define MREPEAT65( macro, data) MREPEAT64( macro, data) macro( 64, data) +#define MREPEAT66( macro, data) MREPEAT65( macro, data) macro( 65, data) +#define MREPEAT67( macro, data) MREPEAT66( macro, data) macro( 66, data) +#define MREPEAT68( macro, data) MREPEAT67( macro, data) macro( 67, data) +#define MREPEAT69( macro, data) MREPEAT68( macro, data) macro( 68, data) +#define MREPEAT70( macro, data) MREPEAT69( macro, data) macro( 69, data) +#define MREPEAT71( macro, data) MREPEAT70( macro, data) macro( 70, data) +#define MREPEAT72( macro, data) MREPEAT71( macro, data) macro( 71, data) +#define MREPEAT73( macro, data) MREPEAT72( macro, data) macro( 72, data) +#define MREPEAT74( macro, data) MREPEAT73( macro, data) macro( 73, data) +#define MREPEAT75( macro, data) MREPEAT74( macro, data) macro( 74, data) +#define MREPEAT76( macro, data) MREPEAT75( macro, data) macro( 75, data) +#define MREPEAT77( macro, data) MREPEAT76( macro, data) macro( 76, data) +#define MREPEAT78( macro, data) MREPEAT77( macro, data) macro( 77, data) +#define MREPEAT79( macro, data) MREPEAT78( macro, data) macro( 78, data) +#define MREPEAT80( macro, data) MREPEAT79( macro, data) macro( 79, data) +#define MREPEAT81( macro, data) MREPEAT80( macro, data) macro( 80, data) +#define MREPEAT82( macro, data) MREPEAT81( macro, data) macro( 81, data) +#define MREPEAT83( macro, data) MREPEAT82( macro, data) macro( 82, data) +#define MREPEAT84( macro, data) MREPEAT83( macro, data) macro( 83, data) +#define MREPEAT85( macro, data) MREPEAT84( macro, data) macro( 84, data) +#define MREPEAT86( macro, data) MREPEAT85( macro, data) macro( 85, data) +#define MREPEAT87( macro, data) MREPEAT86( macro, data) macro( 86, data) +#define MREPEAT88( macro, data) MREPEAT87( macro, data) macro( 87, data) +#define MREPEAT89( macro, data) MREPEAT88( macro, data) macro( 88, data) +#define MREPEAT90( macro, data) MREPEAT89( macro, data) macro( 89, data) +#define MREPEAT91( macro, data) MREPEAT90( macro, data) macro( 90, data) +#define MREPEAT92( macro, data) MREPEAT91( macro, data) macro( 91, data) +#define MREPEAT93( macro, data) MREPEAT92( macro, data) macro( 92, data) +#define MREPEAT94( macro, data) MREPEAT93( macro, data) macro( 93, data) +#define MREPEAT95( macro, data) MREPEAT94( macro, data) macro( 94, data) +#define MREPEAT96( macro, data) MREPEAT95( macro, data) macro( 95, data) +#define MREPEAT97( macro, data) MREPEAT96( macro, data) macro( 96, data) +#define MREPEAT98( macro, data) MREPEAT97( macro, data) macro( 97, data) +#define MREPEAT99( macro, data) MREPEAT98( macro, data) macro( 98, data) +#define MREPEAT100(macro, data) MREPEAT99( macro, data) macro( 99, data) +#define MREPEAT101(macro, data) MREPEAT100(macro, data) macro(100, data) +#define MREPEAT102(macro, data) MREPEAT101(macro, data) macro(101, data) +#define MREPEAT103(macro, data) MREPEAT102(macro, data) macro(102, data) +#define MREPEAT104(macro, data) MREPEAT103(macro, data) macro(103, data) +#define MREPEAT105(macro, data) MREPEAT104(macro, data) macro(104, data) +#define MREPEAT106(macro, data) MREPEAT105(macro, data) macro(105, data) +#define MREPEAT107(macro, data) MREPEAT106(macro, data) macro(106, data) +#define MREPEAT108(macro, data) MREPEAT107(macro, data) macro(107, data) +#define MREPEAT109(macro, data) MREPEAT108(macro, data) macro(108, data) +#define MREPEAT110(macro, data) MREPEAT109(macro, data) macro(109, data) +#define MREPEAT111(macro, data) MREPEAT110(macro, data) macro(110, data) +#define MREPEAT112(macro, data) MREPEAT111(macro, data) macro(111, data) +#define MREPEAT113(macro, data) MREPEAT112(macro, data) macro(112, data) +#define MREPEAT114(macro, data) MREPEAT113(macro, data) macro(113, data) +#define MREPEAT115(macro, data) MREPEAT114(macro, data) macro(114, data) +#define MREPEAT116(macro, data) MREPEAT115(macro, data) macro(115, data) +#define MREPEAT117(macro, data) MREPEAT116(macro, data) macro(116, data) +#define MREPEAT118(macro, data) MREPEAT117(macro, data) macro(117, data) +#define MREPEAT119(macro, data) MREPEAT118(macro, data) macro(118, data) +#define MREPEAT120(macro, data) MREPEAT119(macro, data) macro(119, data) +#define MREPEAT121(macro, data) MREPEAT120(macro, data) macro(120, data) +#define MREPEAT122(macro, data) MREPEAT121(macro, data) macro(121, data) +#define MREPEAT123(macro, data) MREPEAT122(macro, data) macro(122, data) +#define MREPEAT124(macro, data) MREPEAT123(macro, data) macro(123, data) +#define MREPEAT125(macro, data) MREPEAT124(macro, data) macro(124, data) +#define MREPEAT126(macro, data) MREPEAT125(macro, data) macro(125, data) +#define MREPEAT127(macro, data) MREPEAT126(macro, data) macro(126, data) +#define MREPEAT128(macro, data) MREPEAT127(macro, data) macro(127, data) +#define MREPEAT129(macro, data) MREPEAT128(macro, data) macro(128, data) +#define MREPEAT130(macro, data) MREPEAT129(macro, data) macro(129, data) +#define MREPEAT131(macro, data) MREPEAT130(macro, data) macro(130, data) +#define MREPEAT132(macro, data) MREPEAT131(macro, data) macro(131, data) +#define MREPEAT133(macro, data) MREPEAT132(macro, data) macro(132, data) +#define MREPEAT134(macro, data) MREPEAT133(macro, data) macro(133, data) +#define MREPEAT135(macro, data) MREPEAT134(macro, data) macro(134, data) +#define MREPEAT136(macro, data) MREPEAT135(macro, data) macro(135, data) +#define MREPEAT137(macro, data) MREPEAT136(macro, data) macro(136, data) +#define MREPEAT138(macro, data) MREPEAT137(macro, data) macro(137, data) +#define MREPEAT139(macro, data) MREPEAT138(macro, data) macro(138, data) +#define MREPEAT140(macro, data) MREPEAT139(macro, data) macro(139, data) +#define MREPEAT141(macro, data) MREPEAT140(macro, data) macro(140, data) +#define MREPEAT142(macro, data) MREPEAT141(macro, data) macro(141, data) +#define MREPEAT143(macro, data) MREPEAT142(macro, data) macro(142, data) +#define MREPEAT144(macro, data) MREPEAT143(macro, data) macro(143, data) +#define MREPEAT145(macro, data) MREPEAT144(macro, data) macro(144, data) +#define MREPEAT146(macro, data) MREPEAT145(macro, data) macro(145, data) +#define MREPEAT147(macro, data) MREPEAT146(macro, data) macro(146, data) +#define MREPEAT148(macro, data) MREPEAT147(macro, data) macro(147, data) +#define MREPEAT149(macro, data) MREPEAT148(macro, data) macro(148, data) +#define MREPEAT150(macro, data) MREPEAT149(macro, data) macro(149, data) +#define MREPEAT151(macro, data) MREPEAT150(macro, data) macro(150, data) +#define MREPEAT152(macro, data) MREPEAT151(macro, data) macro(151, data) +#define MREPEAT153(macro, data) MREPEAT152(macro, data) macro(152, data) +#define MREPEAT154(macro, data) MREPEAT153(macro, data) macro(153, data) +#define MREPEAT155(macro, data) MREPEAT154(macro, data) macro(154, data) +#define MREPEAT156(macro, data) MREPEAT155(macro, data) macro(155, data) +#define MREPEAT157(macro, data) MREPEAT156(macro, data) macro(156, data) +#define MREPEAT158(macro, data) MREPEAT157(macro, data) macro(157, data) +#define MREPEAT159(macro, data) MREPEAT158(macro, data) macro(158, data) +#define MREPEAT160(macro, data) MREPEAT159(macro, data) macro(159, data) +#define MREPEAT161(macro, data) MREPEAT160(macro, data) macro(160, data) +#define MREPEAT162(macro, data) MREPEAT161(macro, data) macro(161, data) +#define MREPEAT163(macro, data) MREPEAT162(macro, data) macro(162, data) +#define MREPEAT164(macro, data) MREPEAT163(macro, data) macro(163, data) +#define MREPEAT165(macro, data) MREPEAT164(macro, data) macro(164, data) +#define MREPEAT166(macro, data) MREPEAT165(macro, data) macro(165, data) +#define MREPEAT167(macro, data) MREPEAT166(macro, data) macro(166, data) +#define MREPEAT168(macro, data) MREPEAT167(macro, data) macro(167, data) +#define MREPEAT169(macro, data) MREPEAT168(macro, data) macro(168, data) +#define MREPEAT170(macro, data) MREPEAT169(macro, data) macro(169, data) +#define MREPEAT171(macro, data) MREPEAT170(macro, data) macro(170, data) +#define MREPEAT172(macro, data) MREPEAT171(macro, data) macro(171, data) +#define MREPEAT173(macro, data) MREPEAT172(macro, data) macro(172, data) +#define MREPEAT174(macro, data) MREPEAT173(macro, data) macro(173, data) +#define MREPEAT175(macro, data) MREPEAT174(macro, data) macro(174, data) +#define MREPEAT176(macro, data) MREPEAT175(macro, data) macro(175, data) +#define MREPEAT177(macro, data) MREPEAT176(macro, data) macro(176, data) +#define MREPEAT178(macro, data) MREPEAT177(macro, data) macro(177, data) +#define MREPEAT179(macro, data) MREPEAT178(macro, data) macro(178, data) +#define MREPEAT180(macro, data) MREPEAT179(macro, data) macro(179, data) +#define MREPEAT181(macro, data) MREPEAT180(macro, data) macro(180, data) +#define MREPEAT182(macro, data) MREPEAT181(macro, data) macro(181, data) +#define MREPEAT183(macro, data) MREPEAT182(macro, data) macro(182, data) +#define MREPEAT184(macro, data) MREPEAT183(macro, data) macro(183, data) +#define MREPEAT185(macro, data) MREPEAT184(macro, data) macro(184, data) +#define MREPEAT186(macro, data) MREPEAT185(macro, data) macro(185, data) +#define MREPEAT187(macro, data) MREPEAT186(macro, data) macro(186, data) +#define MREPEAT188(macro, data) MREPEAT187(macro, data) macro(187, data) +#define MREPEAT189(macro, data) MREPEAT188(macro, data) macro(188, data) +#define MREPEAT190(macro, data) MREPEAT189(macro, data) macro(189, data) +#define MREPEAT191(macro, data) MREPEAT190(macro, data) macro(190, data) +#define MREPEAT192(macro, data) MREPEAT191(macro, data) macro(191, data) +#define MREPEAT193(macro, data) MREPEAT192(macro, data) macro(192, data) +#define MREPEAT194(macro, data) MREPEAT193(macro, data) macro(193, data) +#define MREPEAT195(macro, data) MREPEAT194(macro, data) macro(194, data) +#define MREPEAT196(macro, data) MREPEAT195(macro, data) macro(195, data) +#define MREPEAT197(macro, data) MREPEAT196(macro, data) macro(196, data) +#define MREPEAT198(macro, data) MREPEAT197(macro, data) macro(197, data) +#define MREPEAT199(macro, data) MREPEAT198(macro, data) macro(198, data) +#define MREPEAT200(macro, data) MREPEAT199(macro, data) macro(199, data) +#define MREPEAT201(macro, data) MREPEAT200(macro, data) macro(200, data) +#define MREPEAT202(macro, data) MREPEAT201(macro, data) macro(201, data) +#define MREPEAT203(macro, data) MREPEAT202(macro, data) macro(202, data) +#define MREPEAT204(macro, data) MREPEAT203(macro, data) macro(203, data) +#define MREPEAT205(macro, data) MREPEAT204(macro, data) macro(204, data) +#define MREPEAT206(macro, data) MREPEAT205(macro, data) macro(205, data) +#define MREPEAT207(macro, data) MREPEAT206(macro, data) macro(206, data) +#define MREPEAT208(macro, data) MREPEAT207(macro, data) macro(207, data) +#define MREPEAT209(macro, data) MREPEAT208(macro, data) macro(208, data) +#define MREPEAT210(macro, data) MREPEAT209(macro, data) macro(209, data) +#define MREPEAT211(macro, data) MREPEAT210(macro, data) macro(210, data) +#define MREPEAT212(macro, data) MREPEAT211(macro, data) macro(211, data) +#define MREPEAT213(macro, data) MREPEAT212(macro, data) macro(212, data) +#define MREPEAT214(macro, data) MREPEAT213(macro, data) macro(213, data) +#define MREPEAT215(macro, data) MREPEAT214(macro, data) macro(214, data) +#define MREPEAT216(macro, data) MREPEAT215(macro, data) macro(215, data) +#define MREPEAT217(macro, data) MREPEAT216(macro, data) macro(216, data) +#define MREPEAT218(macro, data) MREPEAT217(macro, data) macro(217, data) +#define MREPEAT219(macro, data) MREPEAT218(macro, data) macro(218, data) +#define MREPEAT220(macro, data) MREPEAT219(macro, data) macro(219, data) +#define MREPEAT221(macro, data) MREPEAT220(macro, data) macro(220, data) +#define MREPEAT222(macro, data) MREPEAT221(macro, data) macro(221, data) +#define MREPEAT223(macro, data) MREPEAT222(macro, data) macro(222, data) +#define MREPEAT224(macro, data) MREPEAT223(macro, data) macro(223, data) +#define MREPEAT225(macro, data) MREPEAT224(macro, data) macro(224, data) +#define MREPEAT226(macro, data) MREPEAT225(macro, data) macro(225, data) +#define MREPEAT227(macro, data) MREPEAT226(macro, data) macro(226, data) +#define MREPEAT228(macro, data) MREPEAT227(macro, data) macro(227, data) +#define MREPEAT229(macro, data) MREPEAT228(macro, data) macro(228, data) +#define MREPEAT230(macro, data) MREPEAT229(macro, data) macro(229, data) +#define MREPEAT231(macro, data) MREPEAT230(macro, data) macro(230, data) +#define MREPEAT232(macro, data) MREPEAT231(macro, data) macro(231, data) +#define MREPEAT233(macro, data) MREPEAT232(macro, data) macro(232, data) +#define MREPEAT234(macro, data) MREPEAT233(macro, data) macro(233, data) +#define MREPEAT235(macro, data) MREPEAT234(macro, data) macro(234, data) +#define MREPEAT236(macro, data) MREPEAT235(macro, data) macro(235, data) +#define MREPEAT237(macro, data) MREPEAT236(macro, data) macro(236, data) +#define MREPEAT238(macro, data) MREPEAT237(macro, data) macro(237, data) +#define MREPEAT239(macro, data) MREPEAT238(macro, data) macro(238, data) +#define MREPEAT240(macro, data) MREPEAT239(macro, data) macro(239, data) +#define MREPEAT241(macro, data) MREPEAT240(macro, data) macro(240, data) +#define MREPEAT242(macro, data) MREPEAT241(macro, data) macro(241, data) +#define MREPEAT243(macro, data) MREPEAT242(macro, data) macro(242, data) +#define MREPEAT244(macro, data) MREPEAT243(macro, data) macro(243, data) +#define MREPEAT245(macro, data) MREPEAT244(macro, data) macro(244, data) +#define MREPEAT246(macro, data) MREPEAT245(macro, data) macro(245, data) +#define MREPEAT247(macro, data) MREPEAT246(macro, data) macro(246, data) +#define MREPEAT248(macro, data) MREPEAT247(macro, data) macro(247, data) +#define MREPEAT249(macro, data) MREPEAT248(macro, data) macro(248, data) +#define MREPEAT250(macro, data) MREPEAT249(macro, data) macro(249, data) +#define MREPEAT251(macro, data) MREPEAT250(macro, data) macro(250, data) +#define MREPEAT252(macro, data) MREPEAT251(macro, data) macro(251, data) +#define MREPEAT253(macro, data) MREPEAT252(macro, data) macro(252, data) +#define MREPEAT254(macro, data) MREPEAT253(macro, data) macro(253, data) +#define MREPEAT255(macro, data) MREPEAT254(macro, data) macro(254, data) +#define MREPEAT256(macro, data) MREPEAT255(macro, data) macro(255, data) + +/** + * \} + */ + +#endif // _MREPEAT_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/mrepeat.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/mrepeat.h.REMOVED.git-id deleted file mode 100644 index f9331e0d..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/mrepeat.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f4f9c94c9c89585b7245ad9edb92738835dd1fc1 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/preprocessor.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/preprocessor.h new file mode 100644 index 00000000..b597f58d --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/preprocessor.h @@ -0,0 +1,54 @@ +/** + * \file + * + * \brief Preprocessor utils. + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef _PREPROCESSOR_H_ +#define _PREPROCESSOR_H_ + +#include "tpaste.h" +#include "stringz.h" +#include "mrepeat.h" + + +#endif // _PREPROCESSOR_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/preprocessor.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/preprocessor.h.REMOVED.git-id deleted file mode 100644 index 25e05f8c..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/preprocessor.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b597f58dd14c82b72e1d5f7eac3d8c835631bc70 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/stringz.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/stringz.h new file mode 100644 index 00000000..fcb3d93b --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/stringz.h @@ -0,0 +1,84 @@ +/** + * \file + * + * \brief Preprocessor stringizing utils. + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef _STRINGZ_H_ +#define _STRINGZ_H_ + +/** + * \defgroup group_xmega_utils_stringz Stringize + * + * \ingroup group_xmega_utils + * + * \{ + */ + +/*! \brief Stringize. + * + * Stringize a preprocessing token, this token being allowed to be \#defined. + * + * May be used only within macros with the token passed as an argument if the token is \#defined. + * + * For example, writing STRINGZ(PIN) within a macro \#defined by PIN_NAME(PIN) + * and invoked as PIN_NAME(PIN0) with PIN0 \#defined as A0 is equivalent to + * writing "A0". + */ +#define STRINGZ(x) #x + +/*! \brief Absolute stringize. + * + * Stringize a preprocessing token, this token being allowed to be \#defined. + * + * No restriction of use if the token is \#defined. + * + * For example, writing ASTRINGZ(PIN0) anywhere with PIN0 \#defined as A0 is + * equivalent to writing "A0". + */ +#define ASTRINGZ(x) STRINGZ(x) + +/** + * \} + */ + +#endif // _STRINGZ_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/stringz.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/stringz.h.REMOVED.git-id deleted file mode 100644 index a69b597a..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/stringz.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fcb3d93b13d1247657f3c2a9ffe0835b11b5669c \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/tpaste.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/tpaste.h new file mode 100644 index 00000000..168a0cf8 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/tpaste.h @@ -0,0 +1,104 @@ +/** + * \file + * + * \brief Preprocessor token pasting utils. + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef _TPASTE_H_ +#define _TPASTE_H_ + +/** + * \defgroup group_xmega_utils_tpaste Token Paste + * + * \ingroup group_xmega_utils + * + * \{ + */ + +/*! \name Token Paste + * + * Paste N preprocessing tokens together, these tokens being allowed to be \#defined. + * + * May be used only within macros with the tokens passed as arguments if the tokens are \#defined. + * + * For example, writing TPASTE2(U, WIDTH) within a macro \#defined by + * UTYPE(WIDTH) and invoked as UTYPE(UL_WIDTH) with UL_WIDTH \#defined as 32 is + * equivalent to writing U32. + */ +//! @{ +#define TPASTE2( a, b) a##b +#define TPASTE3( a, b, c) a##b##c +#define TPASTE4( a, b, c, d) a##b##c##d +#define TPASTE5( a, b, c, d, e) a##b##c##d##e +#define TPASTE6( a, b, c, d, e, f) a##b##c##d##e##f +#define TPASTE7( a, b, c, d, e, f, g) a##b##c##d##e##f##g +#define TPASTE8( a, b, c, d, e, f, g, h) a##b##c##d##e##f##g##h +#define TPASTE9( a, b, c, d, e, f, g, h, i) a##b##c##d##e##f##g##h##i +#define TPASTE10(a, b, c, d, e, f, g, h, i, j) a##b##c##d##e##f##g##h##i##j +//! @} + +/*! \name Absolute Token Paste + * + * Paste N preprocessing tokens together, these tokens being allowed to be \#defined. + * + * No restriction of use if the tokens are \#defined. + * + * For example, writing ATPASTE2(U, UL_WIDTH) anywhere with UL_WIDTH \#defined + * as 32 is equivalent to writing U32. + */ +//! @{ +#define ATPASTE2( a, b) TPASTE2( a, b) +#define ATPASTE3( a, b, c) TPASTE3( a, b, c) +#define ATPASTE4( a, b, c, d) TPASTE4( a, b, c, d) +#define ATPASTE5( a, b, c, d, e) TPASTE5( a, b, c, d, e) +#define ATPASTE6( a, b, c, d, e, f) TPASTE6( a, b, c, d, e, f) +#define ATPASTE7( a, b, c, d, e, f, g) TPASTE7( a, b, c, d, e, f, g) +#define ATPASTE8( a, b, c, d, e, f, g, h) TPASTE8( a, b, c, d, e, f, g, h) +#define ATPASTE9( a, b, c, d, e, f, g, h, i) TPASTE9( a, b, c, d, e, f, g, h, i) +#define ATPASTE10(a, b, c, d, e, f, g, h, i, j) TPASTE10(a, b, c, d, e, f, g, h, i, j) +//! @} + +/** + * \} + */ + +#endif // _TPASTE_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/tpaste.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/tpaste.h.REMOVED.git-id deleted file mode 100644 index eb6c4ba4..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/preprocessor/tpaste.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -168a0cf82309dd9b4f277f284dc6d32b62f2b6f3 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/progmem.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/progmem.h new file mode 100644 index 00000000..fcab5dbb --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/progmem.h @@ -0,0 +1,102 @@ +/** + * \file + * + * \brief Program memory access + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef UTILS_PROGMEM_H +#define UTILS_PROGMEM_H + +/** + * \defgroup group_xmega_utils_progmem Program memory + * + * \ingroup group_xmega_utils + * + * \{ + */ + +/*! \name Program memory + * + * Macros for locating and accessing data in program memory. + * + * @{ + */ +#if defined(__GNUC__) || defined(__DOXYGEN__) +# include +# define PROGMEM_LOCATION(type, name, loc) \ + type name __attribute__((section (#loc))) +# define PROGMEM_DECLARE(type, name) const type name __attribute__((__progmem__)) +# define PROGMEM_STRING(x) PSTR(x) +# define PROGMEM_STRING_T PGM_P +# define PROGMEM_T const +# define PROGMEM_PTR_T const * +# define PROGMEM_BYTE_ARRAY_T uint8_t* +# define PROGMEM_WORD_ARRAY_T uint16_t* +# define PROGMEM_READ_BYTE(x) pgm_read_byte(x) +# define PROGMEM_READ_WORD(x) pgm_read_word(x) + +#elif defined(__ICCAVR__) +# include +# ifndef __HAS_ELPM__ +# define _MEMATTR_ASF __flash +# else /* __HAS_ELPM__ */ +# define _MEMATTR_ASF __hugeflash +# endif /* __HAS_ELPM__ */ +# define PROGMEM_LOCATION(type, name, loc) const _MEMATTR_ASF type name @ loc +# define PROGMEM_DECLARE(type, name) _MEMATTR_ASF type name +# define PROGMEM_STRING(x) ((_MEMATTR_ASF const char *)(x)) +# define PROGMEM_STRING_T char const _MEMATTR_ASF * +# define PROGMEM_T const _MEMATTR_ASF +# define PROGMEM_PTR_T const _MEMATTR_ASF * +# define PROGMEM_BYTE_ARRAY_T uint8_t const _MEMATTR_ASF * +# define PROGMEM_WORD_ARRAY_T uint16_t const _MEMATTR_ASF * +# define PROGMEM_READ_BYTE(x) *(x) +# define PROGMEM_READ_WORD(x) *(x) +#endif +//! @} + +/** + * \} + */ + +#endif /* UTILS_PROGMEM_H */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/progmem.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/progmem.h.REMOVED.git-id deleted file mode 100644 index b0ce4725..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/progmem.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fcab5dbb70d87219e3b35449984a3aa7c4b77bdf \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/status_codes.h b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/status_codes.h new file mode 100644 index 00000000..035e6963 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/status_codes.h @@ -0,0 +1,121 @@ +/** + * \file + * + * \brief Status code definitions. + * + * This file defines various status codes returned by functions, + * indicating success or failure as well as what kind of failure. + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef STATUS_CODES_H_INCLUDED +#define STATUS_CODES_H_INCLUDED + +/** + * \defgroup group_xmega_utils_status_codes Status Codes + * + * \ingroup group_xmega_utils + * + * \{ + */ + +/* Note: this is a local workaround to avoid a pre-processor clash due to the + * lwIP macro ERR_TIMEOUT. */ +#if defined(__LWIP_ERR_H__) && defined(ERR_TIMEOUT) +#if (ERR_TIMEOUT != -3) + +/* Internal check to make sure that the later restore of lwIP's ERR_TIMEOUT + * macro is set to the correct value. Note that it is highly improbable that + * this value ever changes in lwIP. */ +#error ASF developers: check lwip err.h new value for ERR_TIMEOUT +#endif +#undef ERR_TIMEOUT +#endif + +/** + * Status code that may be returned by shell commands and protocol + * implementations. + * + * \note Any change to these status codes and the corresponding + * message strings is strictly forbidden. New codes can be added, + * however, but make sure that any message string tables are updated + * at the same time. + */ +enum status_code { + STATUS_OK = 0, //!< Success + ERR_IO_ERROR = -1, //!< I/O error + ERR_FLUSHED = -2, //!< Request flushed from queue + ERR_TIMEOUT = -3, //!< Operation timed out + ERR_BAD_DATA = -4, //!< Data integrity check failed + ERR_PROTOCOL = -5, //!< Protocol error + ERR_UNSUPPORTED_DEV = -6, //!< Unsupported device + ERR_NO_MEMORY = -7, //!< Insufficient memory + ERR_INVALID_ARG = -8, //!< Invalid argument + ERR_BAD_ADDRESS = -9, //!< Bad address + ERR_BUSY = -10, //!< Resource is busy + ERR_BAD_FORMAT = -11, //!< Data format not recognized + ERR_NO_TIMER = -12, //!< No timer available + ERR_TIMER_ALREADY_RUNNING = -13, //!< Timer already running + ERR_TIMER_NOT_RUNNING = -14, //!< Timer not running + + /** + * \brief Operation in progress + * + * This status code is for driver-internal use when an operation + * is currently being performed. + * + * \note Drivers should never return this status code to any + * callers. It is strictly for internal use. + */ + OPERATION_IN_PROGRESS = -128, +}; + +typedef enum status_code status_code_t; + +#if defined(__LWIP_ERR_H__) +#define ERR_TIMEOUT -3 +#endif + +/** + * \} + */ + +#endif /* STATUS_CODES_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/status_codes.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/status_codes.h.REMOVED.git-id deleted file mode 100644 index 6e8a091c..00000000 --- a/AVR Code/USB_BULK_TEST/src/ASF/xmega/utils/status_codes.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -035e69630b977987030a42f7c1eefc64d6621210 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/asf.h b/AVR Code/USB_BULK_TEST/src/asf.h new file mode 100644 index 00000000..cd3cf2f2 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/asf.h @@ -0,0 +1,101 @@ +/** + * \file + * + * \brief Autogenerated API include file for the Atmel Software Framework (ASF) + * + * Copyright (c) 2012 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef ASF_H +#define ASF_H + +/* + * This file includes all API header files for the selected drivers from ASF. + * Note: There might be duplicate includes required by more than one driver. + * + * The file is automatically generated and will be re-written when + * running the ASF driver selector tool. Any changes will be discarded. + */ + +// From module: CPU specific features +#include +#include + +// From module: Common build items for user board support templates +#include + +// From module: Generic board support +#include + +// From module: IOPORT - General purpose I/O service +#include + +// From module: Interrupt management - XMEGA implementation +#include + +// From module: NVM - Non Volatile Memory +#include + +// From module: Part identification macros +#include + +// From module: Sleep Controller driver +#include + +// From module: Sleep manager - XMEGA A/AU/B/D implementation +#include +#include + +// From module: System Clock Control - XMEGA A1U/A3U/A3BU/A4U/B/C implementation +#include + +// From module: USB Device Stack Core (Common API) +#include +#include + +// From module: USB Device Vendor Class (Single Interface Device) +#include + +// From module: USB Vendor Protocol +#include + +// From module: XMEGA compiler driver +#include +#include + +#endif // ASF_H diff --git a/AVR Code/USB_BULK_TEST/src/asf.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/asf.h.REMOVED.git-id deleted file mode 100644 index a8c20c99..00000000 --- a/AVR Code/USB_BULK_TEST/src/asf.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cd3cf2f277241c139057b35e270bf82ee2775182 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_board.h b/AVR Code/USB_BULK_TEST/src/config/conf_board.h new file mode 100644 index 00000000..7b88c97f --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/config/conf_board.h @@ -0,0 +1,14 @@ +/** + * \file + * + * \brief User board configuration template + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef CONF_BOARD_H +#define CONF_BOARD_H + +#endif // CONF_BOARD_H diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_board.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/config/conf_board.h.REMOVED.git-id deleted file mode 100644 index 00b9cc05..00000000 --- a/AVR Code/USB_BULK_TEST/src/config/conf_board.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7b88c97fc205be08107659cf807daf0d37d718c8 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_clock.h b/AVR Code/USB_BULK_TEST/src/config/conf_clock.h new file mode 100644 index 00000000..9f74e559 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/config/conf_clock.h @@ -0,0 +1,80 @@ +/** + * \file + * + * \brief Chip-specific system clock manager configuration + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef CONF_CLOCK_H_INCLUDED +#define CONF_CLOCK_H_INCLUDED + +//! Configuration using On-Chip RC oscillator at 48MHz +//! The RC oscillator is calibrated via USB Start Of Frame +//! Clk USB = 48MHz (used by USB) +//! Clk sys = 48MHz +//! Clk cpu/per = 24MHz +#define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC +#define CONFIG_OSC_RC32_CAL 48000000UL + +#define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF + +#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ +#define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 +#define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 + +/* +//! Use external board OSC (8MHz) +//! Clk pll = 48MHz (used by USB) +//! Clk sys = 48MHz +//! Clk cpu/per = 12MHz + +#define CONFIG_PLL0_SOURCE PLL_SRC_XOSC +#define CONFIG_PLL0_MUL 6 +#define CONFIG_PLL0_DIV 1 + +#define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL + +#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL +#define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2 +#define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 +*/ + +#endif /* CONF_CLOCK_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_clock.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/config/conf_clock.h.REMOVED.git-id deleted file mode 100644 index 706a9260..00000000 --- a/AVR Code/USB_BULK_TEST/src/config/conf_clock.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9f74e559e8d2e7c89ab41631170b7f1b369efac9 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_menu.h b/AVR Code/USB_BULK_TEST/src/config/conf_menu.h new file mode 100644 index 00000000..5a765a77 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/config/conf_menu.h @@ -0,0 +1,72 @@ +/** + * \file + * + * \brief Default configurations for menu system + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef DEFAULT_MENU_H_INCLUDED +#define DEFAULT_MENU_H_INCLUDED + +//! \name Indicator icon definitions +//@{ +//! Bitmap data, row by row, MSB is leftmost pixel, one byte per row. +#define GFX_MONO_MENU_INDICATOR_BITMAP 0xFF, 0x7E, 0x3C, 0x18 +//! Height in pixels of indicator icon +#define GFX_MONO_MENU_INDICATOR_HEIGHT 8 +//! Width in pixels of indicator icon +#define GFX_MONO_MENU_INDICATOR_WIDTH 4 +//@} + +//! \name Keyboard codes +//@{ +//! Down +#define GFX_MONO_MENU_KEYCODE_DOWN 40 +//! Up +#define GFX_MONO_MENU_KEYCODE_UP 38 +//! Back/exit +#define GFX_MONO_MENU_KEYCODE_BACK 8 +//! Enter/select +#define GFX_MONO_MENU_KEYCODE_ENTER 13 +//@} + +#endif /* DEFAULT_MENU_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_menu.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/config/conf_menu.h.REMOVED.git-id deleted file mode 100644 index 5b16beb5..00000000 --- a/AVR Code/USB_BULK_TEST/src/config/conf_menu.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5a765a77128b27ea957fca0deea1c5e96f5cc230 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_sleepmgr.h b/AVR Code/USB_BULK_TEST/src/config/conf_sleepmgr.h new file mode 100644 index 00000000..4c6708d9 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/config/conf_sleepmgr.h @@ -0,0 +1,51 @@ +/** + * \file + * + * \brief Sleep manager configuration + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef CONF_SLEEPMGR_H +#define CONF_SLEEPMGR_H + +#define CONFIG_SLEEPMGR_ENABLE + +#endif /* CONF_SLEEPMGR_H */ diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_sleepmgr.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/config/conf_sleepmgr.h.REMOVED.git-id deleted file mode 100644 index 6e44d28b..00000000 --- a/AVR Code/USB_BULK_TEST/src/config/conf_sleepmgr.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4c6708d91cf492b1e16b66206b02b75b505e62f0 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_spi_master.h b/AVR Code/USB_BULK_TEST/src/config/conf_spi_master.h new file mode 100644 index 00000000..afdc02ed --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/config/conf_spi_master.h @@ -0,0 +1,52 @@ +/** + * \file ********************************************************************* + * + * \brief Spi Master configuration for spi example + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef CONF_SPI_MASTER_H_INCLUDED +#define CONF_SPI_MASTER_H_INCLUDED + +//! Default Config Spi Master Dummy Field +// #define CONFIG_SPI_MASTER_DUMMY 0xFF + +#endif /* CONF_SPI_MASTER_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_spi_master.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/config/conf_spi_master.h.REMOVED.git-id deleted file mode 100644 index d2541039..00000000 --- a/AVR Code/USB_BULK_TEST/src/config/conf_spi_master.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -afdc02ed596a36b1b938564535481dfbb40dacff \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_spinctrl.h b/AVR Code/USB_BULK_TEST/src/config/conf_spinctrl.h new file mode 100644 index 00000000..2090b6a1 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/config/conf_spinctrl.h @@ -0,0 +1,75 @@ +/** + * \file + * + * \brief Default configurations for gfx_mono_spinctrl + * + * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef DEFAULT_GFX_MONO_SPINCTRL_H_INCLUDED +#define DEFAULT_GFX_MONO_SPINCTRL_H_INCLUDED + +//! Spinner value indicator +/* Bitmap data, row by row, MSB is leftmost pixel, one byte per row. */ +#define GFX_MONO_SPINCTRL_SPIN_INDICATOR_BITMAP 0x18, 0x3C, 0x7E, 0xFF +//! Height of spinner value indicator +#define GFX_MONO_SPINCTRL_SPIN_INDICATOR_HEIGHT 8 +//! Width of spinner value indicator +#define GFX_MONO_SPINCTRL_SPIN_INDICATOR_WIDTH 4 + +//! Spinner indicator +/* Bitmap data, row by row, MSB is leftmost pixel, one byte per row. */ +#define GFX_MONO_SPINCTRL_INDICATOR_BITMAP 0xFF, 0x7E, 0x3C, 0x18 +//! Height of spinner indicator +#define GFX_MONO_SPINCTRL_INDICATOR_HEIGHT 8 +//! Width of spinner indicator +#define GFX_MONO_SPINCTRL_INDICATOR_WIDTH 4 + +//! Keyboard code down +#define GFX_MONO_SPINCTRL_KEYCODE_DOWN 40 +//! Keyboard code up +#define GFX_MONO_SPINCTRL_KEYCODE_UP 38 +//! Keyboard code back +#define GFX_MONO_SPINCTRL_KEYCODE_BACK 8 +//! Keyboard code enter +#define GFX_MONO_SPINCTRL_KEYCODE_ENTER 13 + +#endif /* DEFAULT_GFX_MONO_SPINCTRL_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_spinctrl.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/config/conf_spinctrl.h.REMOVED.git-id deleted file mode 100644 index e8d8053d..00000000 --- a/AVR Code/USB_BULK_TEST/src/config/conf_spinctrl.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2090b6a1364618e0273dedc4eb85fca582e16518 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_st7565r.h b/AVR Code/USB_BULK_TEST/src/config/conf_st7565r.h new file mode 100644 index 00000000..0dd67fd8 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/config/conf_st7565r.h @@ -0,0 +1,101 @@ +/** + * \file + * + * \brief ST7565R display controller driver configuration file. + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef CONF_ST7565R_H_INCLUDED +#define CONF_ST7565R_H_INCLUDED + +#include + +#if BOARD == XMEGA_A3BU_XPLAINED +// Interface configuration for XMEGA-A3BU Xplained + +# define ST7565R_USART_SPI_INTERFACE +# define ST7565R_USART_SPI &USARTD0 + +# define ST7565R_A0_PIN NHD_C12832A1Z_REGISTER_SELECT +# define ST7565R_CS_PIN NHD_C12832A1Z_CSN +# define ST7565R_RESET_PIN NHD_C12832A1Z_RESETN + +#else +// Interface configuration for other boards +# warning ST7565R driver must be configured. Please see conf_st7565r.h. + +// Interface possibilities: +// 1) Regular SPI interface +// #define ST7565R_SPI_INTERFACE +// #define ST7565R_SPI &SPID + +// 2) USART SPI interface +// #define ST7565R_USART_SPI_INTERFACE +// #define ST7565R_USART_SPI &USARTD0 + +// Pin mapping: +// - Register select +// #define ST7565R_A0_PIN 0 +// - Chip select +// #define ST7565R_CS_PIN 1 +// - Reset +// #define ST7565R_RESET_PIN 2 + + +// Placeholder setup + +# define ST7565R_SPI_INTERFACE +# define ST7565R_SPI 0 + +# define ST7565R_A0_PIN 0 +# define ST7565R_CS_PIN 1 +# define ST7565R_RESET_PIN 2 + +#endif // BOARD + +// Board independent configuration + +// Minimum clock period is 50ns@3.3V -> max frequency is 20MHz +#define ST7565R_CLOCK_SPEED 1000000 +#define ST7565R_DISPLAY_CONTRAST_MAX 40 +#define ST7565R_DISPLAY_CONTRAST_MIN 30 + +#endif /* CONF_ST7565R_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_st7565r.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/config/conf_st7565r.h.REMOVED.git-id deleted file mode 100644 index 8f062bdb..00000000 --- a/AVR Code/USB_BULK_TEST/src/config/conf_st7565r.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0dd67fd83472ee12fedbd3634f85a8c19224e06e \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_sysfont.h b/AVR Code/USB_BULK_TEST/src/config/conf_sysfont.h new file mode 100644 index 00000000..05daa73b --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/config/conf_sysfont.h @@ -0,0 +1,1170 @@ +/** + * \file + * + * \brief Default configurations for sysfont + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef CONF_SYSFONT_H +#define CONF_SYSFONT_H + +/** + * \weakgroup gfx_mono_sysfont + * @{ + */ + +#include + +/* #define USE_FONT_BPMONO_10x16 */ +/* #define USE_FONT_BPMONO_10x14 */ +/* #define USE_FONT_MONO_MMM_10x12 */ +#define USE_FONT_BASIC_6x7 + +#if defined(USE_FONT_BPMONO_10x16) +/** Width of each glyph, including spacer column. */ +# define SYSFONT_WIDTH 10 +/** Height of each glyph, excluding spacer line. */ +# define SYSFONT_HEIGHT 16 +/** Line height. */ +# define SYSFONT_LINESPACING 8 +/** First character defined. */ +# define SYSFONT_FIRSTCHAR ((uint8_t)' ') +/** Last character defined. */ +# define SYSFONT_LASTCHAR ((uint8_t)'}') + +/** Define variable containing the font */ +# define SYSFONT_DEFINE_GLYPHS \ + /* Glyph data, row by row, MSB is leftmost pixel, one byte per row. */ \ + static PROGMEM_DECLARE(uint8_t, sysfont_glyphs[]) = { \ + /* "BPmono" font (http://www.backpacker.gr) at size 10x16 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, \ + 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, \ + 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* ! */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x6C, 0x00, \ + 0x6C, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* " */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, \ + 0x48, 0x00, 0xFC, 0x00, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, \ + 0xFC, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* # */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x3C, 0x00, 0x40, 0x00, 0x30, 0x00, 0x08, 0x00, 0x04, 0x00, \ + 0x78, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* $ */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, \ + 0xA4, 0x00, 0xA8, 0x00, 0x48, 0x00, 0x10, 0x00, 0x14, 0x00, \ + 0x2A, 0x00, 0x4A, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* % */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x88, 0x00, 0x70, 0x00, 0x88, 0x00, 0x8A, 0x00, \ + 0x8A, 0x00, 0x8C, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* & */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* ' */ \ + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* ( */ \ + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* ) */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x10, 0x00, \ + 0x7C, 0x00, 0x10, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* * */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0xFE, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* + */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x30, 0x00, 0x20, 0x00, \ + 0x00, 0x00, /* , */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* - */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* . */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* / */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x8C, 0x00, 0x94, 0x00, 0xA4, 0x00, 0xC4, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* 0 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, \ + 0x50, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* 1 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x40, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* 2 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x30, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x88, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* 3 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x18, 0x00, \ + 0x28, 0x00, 0x28, 0x00, 0x48, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0xFC, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* 4 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0xB8, 0x00, 0xC4, 0x00, 0x04, 0x00, 0x04, 0x00, \ + 0x04, 0x00, 0x84, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* 5 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x40, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0xB0, 0x00, 0xC8, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x48, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* 6 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x04, 0x00, \ + 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* 7 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x78, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* 8 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x8C, 0x00, 0x74, 0x00, 0x04, 0x00, \ + 0x08, 0x00, 0x10, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* 9 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* : */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x60, 0x00, 0x60, 0x00, 0xC0, 0x00, 0x80, 0x00, \ + 0x00, 0x00, /* ; */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x04, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x00, \ + 0x60, 0x00, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* < */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* = */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x40, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x02, 0x00, \ + 0x0C, 0x00, 0x30, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* > */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* ? */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x3C, 0x00, 0x42, 0x00, 0xBA, 0x00, 0xAA, 0x00, 0xAA, 0x00, \ + 0xAA, 0x00, 0xBC, 0x00, 0x40, 0x00, 0x3C, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* @ */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x44, 0x00, 0x7C, 0x00, \ + 0x44, 0x00, 0x82, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* A */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x88, 0x00, 0xF0, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x88, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* B */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x44, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0x44, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* C */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x88, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x88, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* D */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x40, 0x00, \ + 0x40, 0x00, 0x40, 0x00, 0x78, 0x00, 0x40, 0x00, 0x40, 0x00, \ + 0x40, 0x00, 0x40, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* E */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x40, 0x00, \ + 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x78, 0x00, 0x40, 0x00, \ + 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* F */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x44, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x9C, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x44, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* G */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0xFC, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* H */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* I */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x10, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* J */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x88, 0x00, 0x90, 0x00, 0xA0, 0x00, 0xD0, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x84, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* K */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* L */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0xCC, 0x00, 0xCC, 0x00, 0xB4, 0x00, 0xB4, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* M */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0xC4, 0x00, \ + 0xC4, 0x00, 0xA4, 0x00, 0xA4, 0x00, 0x94, 0x00, 0x94, 0x00, \ + 0x8C, 0x00, 0x8C, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* N */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x48, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x48, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* O */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x88, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x88, 0x00, 0xF0, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* P */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x48, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x48, 0x00, 0x30, 0x00, 0x20, 0x00, 0x1C, 0x00, \ + 0x00, 0x00, /* Q */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x88, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x88, 0x00, 0xF0, 0x00, 0x90, 0x00, \ + 0x88, 0x00, 0x84, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* R */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x84, 0x00, \ + 0x80, 0x00, 0x40, 0x00, 0x30, 0x00, 0x08, 0x00, 0x04, 0x00, \ + 0x04, 0x00, 0x84, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* S */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* T */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* U */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x82, 0x00, \ + 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x28, 0x00, \ + 0x28, 0x00, 0x28, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* V */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0xB4, 0x00, 0xB4, 0x00, 0xB4, 0x00, \ + 0x78, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* W */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x44, 0x00, \ + 0x44, 0x00, 0x28, 0x00, 0x10, 0x00, 0x10, 0x00, 0x28, 0x00, \ + 0x44, 0x00, 0x44, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* X */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x44, 0x00, \ + 0x44, 0x00, 0x28, 0x00, 0x28, 0x00, 0x28, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* Y */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x04, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, \ + 0x40, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* Z */ \ + 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xE0, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* [ */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* \ */ \ + 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* ] */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x28, 0x00, \ + 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* ^ */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* _ */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, \ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* ` */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x78, 0x00, 0x04, 0x00, 0x04, 0x00, 0x7C, 0x00, \ + 0x84, 0x00, 0x8C, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* a */ \ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0xB8, 0x00, 0xC4, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x88, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* b */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x7C, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* c */ \ + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, \ + 0x02, 0x00, 0x3E, 0x00, 0x42, 0x00, 0x82, 0x00, 0x82, 0x00, \ + 0x82, 0x00, 0x42, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* d */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x7C, 0x00, 0x82, 0x00, 0x82, 0x00, 0xFE, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* e */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0xFC, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* f */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x7C, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x8C, 0x00, 0x74, 0x00, 0x04, 0x00, 0x44, 0x00, \ + 0x38, 0x00, /* g */ \ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0xB8, 0x00, 0xC4, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* h */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x70, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* i */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, \ + 0xE0, 0x00, /* j */ \ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0x88, 0x00, 0x90, 0x00, 0xA0, 0x00, 0xE0, 0x00, \ + 0x90, 0x00, 0x88, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* k */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* l */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0xAC, 0x00, 0xD4, 0x00, 0x94, 0x00, 0x94, 0x00, \ + 0x94, 0x00, 0x94, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* m */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0xB8, 0x00, 0xC4, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* n */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x78, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* o */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0xB8, 0x00, 0xC4, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0xF8, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x80, 0x00, /* p */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x7C, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x7C, 0x00, 0x04, 0x00, 0x04, 0x00, \ + 0x04, 0x00, /* q */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0xCC, 0x00, 0x30, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* r */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x7C, 0x00, 0x80, 0x00, 0x80, 0x00, 0x78, 0x00, \ + 0x04, 0x00, 0x04, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* s */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x20, 0x00, 0xFC, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* t */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x88, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* u */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x82, 0x00, 0x44, 0x00, 0x44, 0x00, 0x28, 0x00, \ + 0x28, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* v */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x84, 0x00, 0x84, 0x00, 0xB4, 0x00, 0xB4, 0x00, \ + 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* w */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x44, 0x00, 0x28, 0x00, 0x28, 0x00, 0x10, 0x00, \ + 0x28, 0x00, 0x44, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* x */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x82, 0x00, 0x44, 0x00, 0x44, 0x00, 0x28, 0x00, \ + 0x28, 0x00, 0x28, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, \ + 0x20, 0x00, /* y */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0xFC, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, \ + 0x20, 0x00, 0x40, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* z */ \ + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* { */ \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* | */ \ + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, \ + 0x00, 0x00, /* } */ \ + }; +#elif defined(USE_FONT_BPMONO_10x14) +/** Width of each glyph, including spacer column. */ +# define SYSFONT_WIDTH 10 +/** Height of each glyph, excluding spacer line. */ +# define SYSFONT_HEIGHT 14 +/** Line height. */ +# define SYSFONT_LINESPACING 8 +/** First character defined. */ +# define SYSFONT_FIRSTCHAR ((uint8_t)' ') +/** Last character defined. */ +# define SYSFONT_LASTCHAR ((uint8_t)'}') + +/** Define variable containing the font */ +# define SYSFONT_DEFINE_GLYPHS \ + /* Glyph data, row by row, MSB is leftmost pixel, one byte per row. */ \ + static PROGMEM_DECLARE(uint8_t, sysfont_glyphs[]) = { \ + /* "BPmono" font (http://www.backpacker.gr) at size 10x14 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */ \ + 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, \ + 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, \ + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ! */ \ + 0x00, 0x00, 0x00, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x6C, 0x00, \ + 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* " */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, \ + 0x7C, 0x00, 0x28, 0x00, 0x28, 0x00, 0x7C, 0x00, 0x28, 0x00, \ + 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* # */ \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x3C, 0x00, 0x40, 0x00, \ + 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x78, 0x00, \ + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* $ */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0xA4, 0x00, \ + 0xA8, 0x00, 0x50, 0x00, 0x28, 0x00, 0x54, 0x00, 0x94, 0x00, \ + 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* % */ \ + 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x90, 0x00, 0x90, 0x00, \ + 0x90, 0x00, 0x60, 0x00, 0x94, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* & */ \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' */ \ + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* ( */ \ + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, /* ) */ \ + 0x00, 0x00, 0x28, 0x00, 0x10, 0x00, 0x7C, 0x00, 0x10, 0x00, \ + 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* * */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* + */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x10, 0x00, 0x30, 0x00, 0x20, 0x00, 0x00, 0x00, /* , */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* - */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, \ + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* . */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, 0x40, 0x00, \ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* / */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x84, 0x00, \ + 0x8C, 0x00, 0x94, 0x00, 0xA4, 0x00, 0xC4, 0x00, 0x84, 0x00, \ + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, \ + 0x50, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x00, \ + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 2 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x08, 0x00, 0x30, 0x00, 0x08, 0x00, 0x08, 0x00, 0x88, 0x00, \ + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 3 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x18, 0x00, \ + 0x28, 0x00, 0x48, 0x00, 0x88, 0x00, 0xFC, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 4 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0xF0, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x40, 0x00, \ + 0x80, 0x00, 0xF0, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x08, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, 0x40, 0x00, \ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 7 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x70, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x88, 0x00, 0x78, 0x00, 0x08, 0x00, 0x10, 0x00, \ + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, \ + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* : */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, \ + 0x30, 0x00, 0x60, 0x00, 0x40, 0x00, 0x00, 0x00, /* ; */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, \ + 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, \ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* < */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* = */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, \ + 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, \ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* > */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x48, 0x00, \ + 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ? */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, \ + 0x42, 0x00, 0x9A, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xBE, 0x00, \ + 0x80, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, /* @ */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x28, 0x00, \ + 0x28, 0x00, 0x44, 0x00, 0x7C, 0x00, 0x44, 0x00, 0x44, 0x00, \ + 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* A */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0xF8, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* B */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x40, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x40, 0x00, \ + 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x88, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x88, 0x00, \ + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* D */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0xF0, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* E */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0xF8, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* F */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x40, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0x9C, 0x00, 0x84, 0x00, 0x44, 0x00, \ + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* G */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0xF8, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* H */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* I */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* J */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x88, 0x00, \ + 0x90, 0x00, 0xA0, 0x00, 0xD0, 0x00, 0x88, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* K */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* L */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0xCC, 0x00, \ + 0xCC, 0x00, 0xB4, 0x00, 0xB4, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* M */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0xC4, 0x00, \ + 0xC4, 0x00, 0xA4, 0x00, 0xA4, 0x00, 0x94, 0x00, 0x94, 0x00, \ + 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* N */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* O */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0xF8, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* P */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x78, 0x00, 0x20, 0x00, 0x18, 0x00, 0x00, 0x00, /* Q */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0xF8, 0x00, 0x88, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0x60, 0x00, 0x18, 0x00, 0x04, 0x00, 0x04, 0x00, \ + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* S */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* T */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* U */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, 0x00, \ + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* V */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0xA8, 0x00, \ + 0xA8, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0x50, 0x00, \ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* W */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x50, 0x00, 0x20, 0x00, 0x20, 0x00, 0x50, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* X */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x50, 0x00, 0x50, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Y */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x04, 0x00, \ + 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x00, \ + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Z */ \ + 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x40, 0x00, 0x40, 0x00, \ + 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, \ + 0x40, 0x00, 0x40, 0x00, 0x70, 0x00, 0x00, 0x00, /* [ */ \ + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* \ */ \ + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x38, 0x00, 0x00, 0x00, /* ] */ \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x28, 0x00, 0x44, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^ */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* _ */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ` */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x70, 0x00, 0x08, 0x00, 0x08, 0x00, 0x78, 0x00, 0x88, 0x00, \ + 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */ \ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0xF8, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x78, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c */ \ + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, \ + 0x7C, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x8C, 0x00, \ + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x78, 0x00, 0x84, 0x00, 0xFC, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e */ \ + 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0xFC, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x7C, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x7C, 0x00, 0x04, 0x00, 0x78, 0x00, 0x00, 0x00, /* g */ \ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0xB8, 0x00, 0xC4, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* h */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, \ + 0x70, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* i */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, \ + 0x78, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x70, 0x00, /* j */ \ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x88, 0x00, 0x90, 0x00, 0xA0, 0x00, 0xD0, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* k */ \ + 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* l */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xA4, 0x00, 0xFC, 0x00, 0xA4, 0x00, 0xA4, 0x00, 0xA4, 0x00, \ + 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* m */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xB8, 0x00, 0xC4, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* n */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x78, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* o */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xB8, 0x00, 0xC4, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0xF8, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* p */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x7C, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, \ + 0x7C, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, /* q */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xD8, 0x00, 0x60, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, \ + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x78, 0x00, 0x80, 0x00, 0x40, 0x00, 0x30, 0x00, 0x08, 0x00, \ + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* s */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, \ + 0xFC, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* t */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* u */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, 0x48, 0x00, 0x48, 0x00, \ + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* v */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x88, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0xA8, 0x00, \ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* w */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x88, 0x00, 0x50, 0x00, 0x20, 0x00, 0x20, 0x00, 0x50, 0x00, \ + 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* x */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x84, 0x00, 0x84, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, 0x00, \ + 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x00, 0x00, /* y */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xF8, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, \ + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* z */ \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, /* { */ \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, /* | */ \ + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x10, 0x00, \ + 0x10, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, /* } */ \ + }; +#elif defined(USE_FONT_MONO_MMM_10x12) +/** Width of each glyph, including spacer column. */ +# define SYSFONT_WIDTH 10 +/** Height of each glyph, excluding spacer line. */ +# define SYSFONT_HEIGHT 12 +/** Line height. */ +# define SYSFONT_LINESPACING 8 +/** First character defined. */ +# define SYSFONT_FIRSTCHAR ((uint8_t)' ') +/** Last character defined. */ +# define SYSFONT_LASTCHAR ((uint8_t)'}') + +/** Define variable containing the font */ +# define SYSFONT_DEFINE_GLYPHS \ + /* Glyph data, row by row, MSB is leftmost pixel, one byte per row. */ \ + static PROGMEM_DECLARE(uint8_t, sysfont_glyphs[]) = { \ + /* "MonoMMM" font (http://www.dafont.com/monommm-5.font) size 10x12 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* ! */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x50, 0x00, \ + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* " */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0xF8, 0x00, \ + 0x50, 0x00, 0xF8, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* # */ \ + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x70, 0x00, 0xA8, 0x00, \ + 0xA0, 0x00, 0x70, 0x00, 0x28, 0x00, 0xA8, 0x00, 0x70, 0x00, \ + 0x20, 0x00, 0x00, 0x00, /* $ */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8, 0x00, 0xB0, 0x00, \ + 0x50, 0x00, 0x20, 0x00, 0x50, 0x00, 0x68, 0x00, 0x98, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* % */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x90, 0x00, \ + 0xA0, 0x00, 0x40, 0x00, 0xA8, 0x00, 0x90, 0x00, 0x68, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* & */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* ' */ \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x10, 0x00, 0x00, 0x00, /* ( */ \ + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x40, 0x00, 0x00, 0x00, /* ) */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x00, \ + 0x70, 0x00, 0xF8, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* * */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0xF8, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* + */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x40, 0x00, /* , */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* - */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* . */ \ + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0x10, 0x00, 0x10, 0x00, 0x20, 0x00, 0x60, 0x00, 0x40, 0x00, \ + 0xC0, 0x00, 0x00, 0x00, /* / */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x98, 0x00, 0xA8, 0x00, 0xC8, 0x00, 0x88, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* 0 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xE0, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* 1 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0xF8, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* 2 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x08, 0x00, 0x30, 0x00, 0x08, 0x00, 0x88, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* 3 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, \ + 0x50, 0x00, 0x90, 0x00, 0xF8, 0x00, 0x10, 0x00, 0x10, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* 4 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x80, 0x00, \ + 0xF0, 0x00, 0x08, 0x00, 0x08, 0x00, 0x88, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* 5 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0xF0, 0x00, 0x88, 0x00, 0x88, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* 6 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* 7 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x70, 0x00, 0x88, 0x00, 0x88, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* 8 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x78, 0x00, 0x08, 0x00, 0x08, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* 9 */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* : */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x40, 0x00, /* ; */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, \ + 0x20, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10, 0x00, 0x08, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* < */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xF8, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* = */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, \ + 0x10, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* > */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* ? */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0xB8, 0x00, 0xA8, 0x00, 0xB8, 0x00, 0x80, 0x00, 0x78, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* @ */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x88, 0x00, 0xF8, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* A */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0xF0, 0x00, 0x88, 0x00, 0x88, 0x00, 0xF0, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* B */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x88, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* C */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xF0, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* D */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0xF0, 0x00, 0x80, 0x00, 0x80, 0x00, 0xF8, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* E */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0xF0, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* F */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x80, 0x00, 0x98, 0x00, 0x88, 0x00, 0x88, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* G */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0xF8, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* H */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xF8, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* I */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0x08, 0x00, 0x08, 0x00, 0x88, 0x00, 0x88, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* J */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0xB0, 0x00, \ + 0xE0, 0x00, 0xC0, 0x00, 0xE0, 0x00, 0xB0, 0x00, 0x98, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* K */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xF8, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* L */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0xD8, 0x00, \ + 0xF8, 0x00, 0xA8, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* M */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0xC8, 0x00, \ + 0xC8, 0x00, 0xA8, 0x00, 0x98, 0x00, 0x98, 0x00, 0x88, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* N */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* O */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0xF0, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* P */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xA8, 0x00, 0x70, 0x00, \ + 0x08, 0x00, 0x00, 0x00, /* Q */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0xF0, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* R */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x88, 0x00, \ + 0x80, 0x00, 0x70, 0x00, 0x08, 0x00, 0x88, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* S */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* T */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* U */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* V */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x88, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0x50, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* W */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x50, 0x00, \ + 0x70, 0x00, 0x20, 0x00, 0x70, 0x00, 0x50, 0x00, 0x88, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* X */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x50, 0x00, \ + 0x70, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* Y */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x08, 0x00, \ + 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x00, 0xF8, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* Z */ \ + 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x30, 0x00, 0x00, 0x00, /* [ */ \ + 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x40, 0x00, 0x60, 0x00, \ + 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0x04, 0x00, 0x00, 0x00, /* \ */ \ + 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x60, 0x00, 0x00, 0x00, /* ] */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x50, 0x00, \ + 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* ^ */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0xFC, 0x00, /* _ */ \ + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* ` */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xF0, 0x00, 0x08, 0x00, 0xF8, 0x00, 0x88, 0x00, 0xF8, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* a */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0xF0, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xF0, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* b */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x70, 0x00, 0x88, 0x00, 0x80, 0x00, 0x88, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* c */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, \ + 0x78, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x78, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* d */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x70, 0x00, 0x88, 0x00, 0xF8, 0x00, 0x80, 0x00, 0x78, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* e */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x20, 0x00, \ + 0x70, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* f */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x78, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x78, 0x00, \ + 0x08, 0x00, 0x70, 0x00, /* g */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0xF0, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* h */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, \ + 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* i */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, \ + 0xE0, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0xC0, 0x00, /* j */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x98, 0x00, 0xA0, 0x00, 0xE0, 0x00, 0x90, 0x00, 0x88, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* k */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xF8, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* l */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xF8, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0xA8, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* m */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xF0, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* n */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x70, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x70, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* o */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xF0, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0xF0, 0x00, \ + 0x80, 0x00, 0x80, 0x00, /* p */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x78, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x78, 0x00, \ + 0x08, 0x00, 0x08, 0x00, /* q */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xF8, 0x00, 0x88, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* r */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xF8, 0x00, 0x80, 0x00, 0xF8, 0x00, 0x08, 0x00, 0xF8, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* s */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x78, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x18, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* t */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x78, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* u */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x88, 0x00, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 0x20, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* v */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xA8, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0xA8, 0x00, 0x50, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* w */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xD8, 0x00, 0x50, 0x00, 0x20, 0x00, 0x50, 0x00, 0xD8, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* x */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x78, 0x00, \ + 0x08, 0x00, 0x70, 0x00, /* y */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0xF8, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0xF8, 0x00, \ + 0x00, 0x00, 0x00, 0x00, /* z */ \ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x10, 0x00, 0x00, 0x00, /* { */ \ + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x00, 0x00, /* | */ \ + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x20, 0x00, 0x10, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, \ + 0x40, 0x00, 0x00, 0x00, /* } */ \ + }; +#elif defined(USE_FONT_BASIC_6x7) +/** Width of each glyph, including spacer column. */ +# define SYSFONT_WIDTH 6 +/** Height of each glyph, excluding spacer line. */ +# define SYSFONT_HEIGHT 7 +/** Line height. */ +# define SYSFONT_LINESPACING 8 +/** First character defined. */ +# define SYSFONT_FIRSTCHAR ((uint8_t)' ') +/** Last character defined. */ +# define SYSFONT_LASTCHAR ((uint8_t)'}') + +/** Define variable containing the font */ +# define SYSFONT_DEFINE_GLYPHS \ + /* Glyph data, row by row, MSB is leftmost pixel, one byte per row. */ \ + static PROGMEM_DECLARE(uint8_t, sysfont_glyphs[]) = { \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* " " */ \ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x20, /* "!" */ \ + 0x50, 0x50, 0x50, 0x00, 0x00, 0x00, 0x00, /* """ */ \ + 0x50, 0x50, 0xf8, 0x50, 0xf8, 0x50, 0x50, /* "#" */ \ + 0x20, 0x78, 0xa0, 0x70, 0x28, 0xf0, 0x20, /* "$" */ \ + 0xc0, 0xc8, 0x10, 0x20, 0x40, 0x98, 0x18, /* "%" */ \ + 0x60, 0x90, 0xa0, 0x40, 0xa8, 0x90, 0x68, /* "&" */ \ + 0x60, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, /* "'" */ \ + 0x10, 0x20, 0x40, 0x40, 0x40, 0x20, 0x10, /* "(" */ \ + 0x40, 0x20, 0x10, 0x10, 0x10, 0x20, 0x40, /* ")" */ \ + 0x00, 0x50, 0x20, 0xf8, 0x20, 0x50, 0x00, /* "*" */ \ + 0x00, 0x20, 0x20, 0xf8, 0x20, 0x20, 0x00, /* "+" */ \ + 0x00, 0x00, 0x00, 0x00, 0x60, 0x20, 0x40, /* "," */ \ + 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, /* "-" */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, /* "." */ \ + 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, /* "/" */ \ + 0x70, 0x88, 0x98, 0xa8, 0xc8, 0x88, 0x70, /* "0" */ \ + 0x20, 0x60, 0x20, 0x20, 0x20, 0x20, 0x70, /* "1" */ \ + 0x70, 0x88, 0x08, 0x10, 0x20, 0x40, 0xf8, /* "2" */ \ + 0xf8, 0x10, 0x20, 0x10, 0x08, 0x88, 0x70, /* "3" */ \ + 0x10, 0x30, 0x50, 0x90, 0xf8, 0x10, 0x10, /* "4" */ \ + 0xf8, 0x80, 0xf0, 0x08, 0x08, 0x88, 0x70, /* "5" */ \ + 0x30, 0x40, 0x80, 0xf0, 0x88, 0x88, 0x70, /* "6" */ \ + 0xf8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x40, /* "7" */ \ + 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x70, /* "8" */ \ + 0x70, 0x88, 0x88, 0x78, 0x08, 0x10, 0x60, /* "9" */ \ + 0x00, 0x60, 0x60, 0x00, 0x60, 0x60, 0x00, /* ":" */ \ + 0x00, 0x60, 0x60, 0x00, 0x60, 0x20, 0x40, /* ";" */ \ + 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, /* "<" */ \ + 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, /* "=" */ \ + 0x80, 0x40, 0x20, 0x10, 0x20, 0x40, 0x80, /* ">" */ \ + 0x70, 0x88, 0x08, 0x10, 0x20, 0x00, 0x20, /* "?" */ \ + 0x70, 0x88, 0x08, 0x68, 0xa8, 0xa8, 0x70, /* "@" */ \ + 0x70, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88, /* "A" */ \ + 0xf0, 0x88, 0x88, 0xf0, 0x88, 0x88, 0xf0, /* "B" */ \ + 0x70, 0x88, 0x80, 0x80, 0x80, 0x88, 0x70, /* "C" */ \ + 0xe0, 0x90, 0x88, 0x88, 0x88, 0x90, 0xe0, /* "D" */ \ + 0xf8, 0x80, 0x80, 0xf0, 0x80, 0x80, 0xf8, /* "E" */ \ + 0xf8, 0x80, 0x80, 0xe0, 0x80, 0x80, 0x80, /* "F" */ \ + 0x70, 0x88, 0x80, 0x80, 0x98, 0x88, 0x70, /* "G" */ \ + 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88, 0x88, /* "H" */ \ + 0x70, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, /* "I" */ \ + 0x38, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60, /* "J" */ \ + 0x88, 0x90, 0xa0, 0xc0, 0xa0, 0x90, 0x88, /* "K" */ \ + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xf8, /* "L" */ \ + 0x88, 0xd8, 0xa8, 0x88, 0x88, 0x88, 0x88, /* "M" */ \ + 0x88, 0x88, 0xc8, 0xa8, 0x98, 0x88, 0x88, /* "N" */ \ + 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, /* "O" */ \ + 0xf0, 0x88, 0x88, 0xf0, 0x80, 0x80, 0x80, /* "P" */ \ + 0x70, 0x88, 0x88, 0x88, 0xa8, 0x90, 0x68, /* "Q" */ \ + 0xf0, 0x88, 0x88, 0xf0, 0xa0, 0x90, 0x88, /* "R" */ \ + 0x78, 0x80, 0x80, 0x70, 0x08, 0x08, 0xf0, /* "S" */ \ + 0xf8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* "T" */ \ + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, /* "U" */ \ + 0x88, 0x88, 0x88, 0x88, 0x88, 0x50, 0x20, /* "V" */ \ + 0x88, 0x88, 0x88, 0xa8, 0xa8, 0xd8, 0x88, /* "W" */ \ + 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88, /* "X" */ \ + 0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x20, /* "Y" */ \ + 0xf8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xf8, /* "Z" */ \ + 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38, /* "[" */ \ + 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, /* "\" */ \ + 0xe0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xe0, /* "]" */ \ + 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, /* "^" */ \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, /* "_" */ \ + 0x40, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, /* "`" */ \ + 0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78, /* "a" */ \ + 0x80, 0x80, 0xb0, 0xc8, 0x88, 0x88, 0xf0, /* "b" */ \ + 0x00, 0x00, 0x70, 0x80, 0x80, 0x88, 0x70, /* "c" */ \ + 0x08, 0x08, 0x68, 0x98, 0x88, 0x88, 0x78, /* "d" */ \ + 0x00, 0x00, 0x70, 0x88, 0xf8, 0x80, 0x70, /* "e" */ \ + 0x30, 0x48, 0x40, 0xe0, 0x40, 0x40, 0x40, /* "f" */ \ + 0x00, 0x00, 0x78, 0x88, 0x78, 0x08, 0x30, /* "g" */ \ + 0x80, 0x80, 0xb0, 0xc8, 0x88, 0x88, 0x88, /* "h" */ \ + 0x20, 0x00, 0x60, 0x20, 0x20, 0x20, 0x70, /* "i" */ \ + 0x10, 0x00, 0x30, 0x10, 0x10, 0x90, 0x60, /* "j" */ \ + 0x40, 0x40, 0x48, 0x50, 0x60, 0x50, 0x48, /* "k" */ \ + 0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, /* "l" */ \ + 0x00, 0x00, 0xd0, 0xa8, 0xa8, 0x88, 0x88, /* "m" */ \ + 0x00, 0x00, 0xb0, 0xc8, 0x88, 0x88, 0x88, /* "n" */ \ + 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70, /* "o" */ \ + 0x00, 0x00, 0xf0, 0x88, 0xf0, 0x80, 0x80, /* "p" */ \ + 0x00, 0x00, 0x68, 0x98, 0x78, 0x08, 0x08, /* "q" */ \ + 0x00, 0x00, 0xb0, 0xc8, 0x80, 0x80, 0x80, /* "r" */ \ + 0x00, 0x00, 0x70, 0x80, 0x70, 0x08, 0xf0, /* "s" */ \ + 0x40, 0x40, 0xe0, 0x40, 0x40, 0x48, 0x30, /* "t" */ \ + 0x00, 0x00, 0x88, 0x88, 0x88, 0x98, 0x68, /* "u" */ \ + 0x00, 0x00, 0x88, 0x88, 0x88, 0x50, 0x20, /* "v" */ \ + 0x00, 0x00, 0x88, 0x88, 0xa8, 0xa8, 0x50, /* "w" */ \ + 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, /* "x" */ \ + 0x00, 0x00, 0x88, 0x88, 0x78, 0x08, 0x70, /* "y" */ \ + 0x00, 0x00, 0xf8, 0x10, 0x20, 0x40, 0xf8, /* "z" */ \ + 0x10, 0x20, 0x20, 0x40, 0x20, 0x20, 0x10, /* "{" */ \ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* "|" */ \ + 0x40, 0x20, 0x20, 0x10, 0x20, 0x20, 0x40, /* "}" */ \ + }; +#endif + +/** @} */ + +#endif /* CONF_SYSFONT_H */ diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_sysfont.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/config/conf_sysfont.h.REMOVED.git-id deleted file mode 100644 index cbe09eeb..00000000 --- a/AVR Code/USB_BULK_TEST/src/config/conf_sysfont.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -05daa73beef5eba6260cf530a89e846f6b95ddaf \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_usart_spi.h b/AVR Code/USB_BULK_TEST/src/config/conf_usart_spi.h new file mode 100644 index 00000000..aa9a9718 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/config/conf_usart_spi.h @@ -0,0 +1,50 @@ +/** + * \file ********************************************************************* + * + * \brief Spi Master configuration for spi example + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ +#ifndef CONF_USART_SPI_H_INCLUDED +#define CONF_USART_SPI_H_INCLUDED + + +#endif /* CONF_USART_SPI_H_INCLUDED */ diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_usart_spi.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/config/conf_usart_spi.h.REMOVED.git-id deleted file mode 100644 index 08b8157d..00000000 --- a/AVR Code/USB_BULK_TEST/src/config/conf_usart_spi.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aa9a97184fe21ba5691e6a343e2032259d89fecb \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_usb.h b/AVR Code/USB_BULK_TEST/src/config/conf_usb.h new file mode 100644 index 00000000..4e336bd2 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/config/conf_usb.h @@ -0,0 +1,165 @@ +/** + * \file + * + * \brief USB configuration file + * + * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _CONF_USB_H_ +#define _CONF_USB_H_ + +#include "compiler.h" +#include "globals.h" + + +/** + * USB Device Configuration + * @{ + */ + +//! Device definition (mandatory) +#define USB_DEVICE_VENDOR_ID 0x03eb +#define USB_DEVICE_PRODUCT_ID 0xba94 +#define USB_DEVICE_MAJOR_VERSION 2 +#define USB_DEVICE_MINOR_VERSION 0 +#define USB_DEVICE_POWER 500 // Consumption on Vbus line (mA) +#define USB_DEVICE_ATTR \ + (USB_CONFIG_ATTR_BUS_POWERED) +// (USB_CONFIG_ATTR_SELF_POWERED) +// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED) +// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED) + +//! USB Device string definitions (Optional) +#define USB_DEVICE_MANUFACTURE_NAME "EspoTek" +#define USB_DEVICE_PRODUCT_NAME "Labrador" +// #define USB_DEVICE_SERIAL_NAME "123123123123" + +/** + * Device speeds support + * Low speed not supported by this vendor class + * @{ + */ +//! To authorize the High speed +#if (UC3A3||UC3A4) +# define USB_DEVICE_HS_SUPPORT +#elif (SAM3XA||SAM3U) +# define USB_DEVICE_HS_SUPPORT +#endif +//@} + + +/** + * USB Device Callbacks definitions (Optional) + * @{ + */ +#define UDC_VBUS_EVENT(b_vbus_high) +#define UDC_SOF_EVENT() main_sof_action() +#define UDC_SUSPEND_EVENT() main_suspend_action() +#define UDC_RESUME_EVENT() main_resume_action() +//! Mandatory when USB_DEVICE_ATTR authorizes remote wakeup feature +// #define UDC_REMOTEWAKEUP_ENABLE() user_callback_remotewakeup_enable() +// extern void user_callback_remotewakeup_enable(void); +// #define UDC_REMOTEWAKEUP_DISABLE() user_callback_remotewakeup_disable() +// extern void user_callback_remotewakeup_disable(void); +//! When a extra string descriptor must be supported +//! other than manufacturer, product and serial string +// #define UDC_GET_EXTRA_STRING() +//@} + +//@} + + +/** + * USB Interface Configuration + * @{ + */ + +/** + * Configuration of vendor interface + * @{ + */ +//! Interface callback definition +#define UDI_VENDOR_ENABLE_EXT() main_vendor_enable() +#define UDI_VENDOR_DISABLE_EXT() main_vendor_disable() +#define UDI_VENDOR_SETUP_OUT_RECEIVED() main_setup_out_received() +#define UDI_VENDOR_SETUP_IN_RECEIVED() main_setup_in_received() + +//! endpoints size for full speed +//! Note: Disable the endpoints of a type, if size equal 0 +#define UDI_VENDOR_EPS_SIZE_INT_FS 0 +#define UDI_VENDOR_EPS_SIZE_BULK_FS 0 +#if SAMG55 +#define UDI_VENDOR_EPS_SIZE_ISO_FS 0 +#else + #ifdef SINGLE_ENDPOINT_INTERFACE + #define UDI_VENDOR_EPS_SIZE_ISO_FS 1023 + #else + #define UDI_VENDOR_EPS_SIZE_ISO_FS 128 + #endif +#endif + +//! endpoints size for high speed +#define UDI_VENDOR_EPS_SIZE_INT_HS 64 +#define UDI_VENDOR_EPS_SIZE_BULK_HS 512 +#define UDI_VENDOR_EPS_SIZE_ISO_HS 64 + +//@} + +//@} + + +/** + * USB Device Driver Configuration + * @{ + */ +//! Limit the isochronous endpoint in singe bank mode for USBB driver +//! to avoid exceeding USB DPRAM. +#define UDD_ISOCHRONOUS_NB_BANK(ep) 1 +//@} + +//! The includes of classes and other headers must be done +//! at the end of this file to avoid compile error +#include "udi_vendor_conf.h" +#include "ui.h" +#include "main.h" + +#endif // _CONF_USB_H_ diff --git a/AVR Code/USB_BULK_TEST/src/config/conf_usb.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/config/conf_usb.h.REMOVED.git-id deleted file mode 100644 index 290c77cd..00000000 --- a/AVR Code/USB_BULK_TEST/src/config/conf_usb.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4e336bd2e2cf9cc16fda2b3dd946da4d54b6a580 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/globals.h b/AVR Code/USB_BULK_TEST/src/globals.h new file mode 100644 index 00000000..bbbb9509 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/globals.h @@ -0,0 +1,73 @@ +/* + * globals.h + * + * Created: 18/04/2015 12:44:42 PM + * Author: Esposch + */ + + +#ifndef GLOBALS_H_ +#define GLOBALS_H_ + +#define SINGLE_ENDPOINT_INTERFACE + +//#define VERO +#define OVERCLOCK 48 +#define FIRMWARE_VERSION_ID 0x0003 +#define ATMEL_DFU_OFFSET 0x01fc + +#define TC_SPISLAVE TCD0 +#define TC_PSU TCD1 +#define TC_PSU_OVF TCD1_OVF_vect +#define TC_DAC TCC0 +#define TCDAC_OVF EVSYS_CHMUX_TCC0_OVF_gc +#define TC_AUXDAC TCC1 +#define TC_CALI TCE0 +#define TCDAC_AUX_OVF EVSYS_CHMUX_TCC1_OVF_gc +#define HALFPACKET_SIZE 375 +#define PACKET_SIZE 750 +#define B2_START 1125 +#define BUFFER_SIZE (PACKET_SIZE*2) +#define DACBUF_SIZE 512 + +COMPILER_WORD_ALIGNED +extern volatile unsigned char isoBuf[BUFFER_SIZE]; +COMPILER_WORD_ALIGNED +extern volatile unsigned char dacBuf_CH1[DACBUF_SIZE]; +extern volatile unsigned char dacBuf_CH2[DACBUF_SIZE]; + +extern volatile unsigned char b1_state; +extern volatile unsigned char b2_state; +extern volatile unsigned char usb_state; + +extern volatile bool main_b_vendor_enable; + +extern volatile uint16_t dacBuf_len; +extern volatile uint16_t auxDacBufLen; + +extern volatile unsigned char dummy; + +extern volatile unsigned char global_mode; + +extern volatile char PSU_target; + +extern volatile unsigned char test_byte; + +extern volatile unsigned char debugOnNextEnd; + +extern volatile unsigned int median_TRFCNT; + +extern volatile unsigned short dma_ch0_ran; +extern volatile unsigned short dma_ch1_ran; + +extern volatile unsigned char futureMode; +extern volatile unsigned char modeChanged; + +COMPILER_WORD_ALIGNED +extern const unsigned short firmver; +extern const unsigned char variant; + +#include "unified_debug_structure.h" +extern unified_debug uds; + +#endif /* GLOBALS_H_ */ \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/globals.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/globals.h.REMOVED.git-id deleted file mode 100644 index 2d59b167..00000000 --- a/AVR Code/USB_BULK_TEST/src/globals.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bbbb9509622e1e73eb9f61bc994c9eb96602327b \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/main.c b/AVR Code/USB_BULK_TEST/src/main.c new file mode 100644 index 00000000..2a31dc93 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/main.c @@ -0,0 +1,306 @@ +//Include the ASF Licence! + +#include +#include +#include + +#include "ui.h" +#include "globals.h" +#include "tiny_adc.h" +#include "tiny_dma.h" +#include "tiny_timer.h" +#include "tiny_dac.h" +#include "tiny_uart.h" +#include "tiny_dig.h" +#include "tiny_calibration.h" +#include "tiny_eeprom.h" + +volatile bool main_b_vendor_enable = false; + +COMPILER_WORD_ALIGNED +volatile unsigned char isoBuf[BUFFER_SIZE]; +COMPILER_WORD_ALIGNED +volatile unsigned char dacBuf_CH1[DACBUF_SIZE]; +volatile unsigned char dacBuf_CH2[DACBUF_SIZE]; + +volatile unsigned char b1_state = 0; +volatile unsigned char b2_state = 0; +volatile unsigned char usb_state = 0; + +volatile uint16_t dacBuf_len = 128; +volatile uint16_t auxDacBufLen = 128; +volatile unsigned char dummy = 0x55; +volatile unsigned char global_mode = 255; + +volatile char PSU_target = 0; + +volatile unsigned char test_byte = 123; + +uint32_t debug_counter; + +unsigned char tripleUsbSuccess = 0; + +volatile unsigned char firstFrame = 0; +volatile unsigned char tcinit = 0; + +volatile unsigned int currentTrfcnt; +volatile unsigned char debugOnNextEnd = 0; + +/* +#define CNT_CNT_MAX 256 +volatile unsigned short cntCnt[CNT_CNT_MAX]; +volatile unsigned short cntCntCnt = 0; +#define DEBUG_DIVISION 0 +volatile unsigned char debug_divider = 0; +*/ +volatile unsigned int median_TRFCNT = 65535; + +volatile char debug_data[8] = "DEBUG123"; + +volatile unsigned short dma_ch0_ran; +volatile unsigned short dma_ch1_ran; + +volatile unsigned char futureMode; +volatile unsigned char modeChanged = 0; + +unified_debug uds; + +const unsigned short firmver = FIRMWARE_VERSION_ID; + +#ifdef SINGLE_ENDPOINT_INTERFACE + const unsigned char variant = 0x02; +#else + const unsigned char variant = 0x01; +#endif + +volatile unsigned char eeprom_buffer_write[EEPROM_PAGE_SIZE]; +volatile unsigned char eeprom_buffer_read[EEPROM_PAGE_SIZE]; + +void jump_to_bootloader(){ + void(* start_bootloader)(void) = (void (*)(void))((BOOT_SECTION_START + ATMEL_DFU_OFFSET)>>1); + EIND = BOOT_SECTION_START>>17; + start_bootloader(); +} + +int main(void){ + eeprom_safe_read(); + if(eeprom_buffer_read[0]){ + memcpy(eeprom_buffer_write, eeprom_buffer_read, EEPROM_PAGE_SIZE); + eeprom_buffer_write[0] = 0; + eeprom_safe_write(); + //eeprom_safe_read(); + jump_to_bootloader(); + } + + irq_initialize_vectors(); + cpu_irq_enable(); +// sysclk_init(); + tiny_calibration_init(); + + board_init(); + udc_start(); + tiny_dac_setup(); + tiny_dma_setup(); + tiny_adc_setup(0, 0); + tiny_adc_pid_setup(); + tiny_adc_ch1setup(12); + tiny_timer_setup(); + tiny_uart_setup(); + tiny_spi_setup(); + tiny_dig_setup(); + + //USARTC0.DATA = 0x55; + //asm("nop"); + + + + strcpy(uds.header, "debug123"); + + while (true) { + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + if(modeChanged){ + switch(futureMode){ + case 0: + tiny_dma_set_mode_0(); + break; + case 1: + tiny_dma_set_mode_1(); + break; + case 2: + tiny_dma_set_mode_2(); + break; + case 3: + tiny_dma_set_mode_3(); + break; + case 4: + tiny_dma_set_mode_4(); + break; + case 5: + tiny_dma_set_mode_5(); + break; + case 6: + tiny_dma_set_mode_6(); + break; + case 7: + tiny_dma_set_mode_7(); + break; + } + modeChanged = 0; + } + } +} + +//! Global variable to give and record information about setup request management +udd_ctrl_request_t udd_g_ctrlreq; + +//CALLBACKS: +void main_suspend_action(void) +{ + return; +} + +void main_resume_action(void) +{ + return; +} + +void main_sof_action(void) +{ + #ifdef SINGLE_ENDPOINT_INTERFACE + switch(global_mode){ + case 0: + tiny_dma_loop_mode_0(); + break; + case 1: + tiny_dma_loop_mode_1(); + break; + case 2: + tiny_dma_loop_mode_2(); + break; + case 3: + tiny_dma_loop_mode_3(); + break; + case 4: + tiny_dma_loop_mode_4(); + break; + case 6: + tiny_dma_loop_mode_6(); + break; + case 7: + tiny_dma_loop_mode_7(); + break; + default: + break; + } + #endif + + uds.trfcntL0 = DMA.CH0.TRFCNTL; + uds.trfcntH0 = DMA.CH0.TRFCNTH; + uds.trfcntL1 = DMA.CH1.TRFCNTL; + uds.trfcntH1 = DMA.CH1.TRFCNTH; + uds.counterL = TC_CALI.CNTL; + uds.counterH = TC_CALI.CNTH; + if((DMA.CH0.TRFCNT > 325) && (DMA.CH0.TRFCNT < 425)){ + currentTrfcnt = DMA.CH0.TRFCNT; + asm("nop"); + } + if(firstFrame){ + tiny_calibration_first_sof(); + firstFrame = 0; + tcinit = 1; + return; + } + else{ + if(tcinit){ + if(calibration_values_found == 0x03){ + tiny_calibration_maintain(); + tiny_calibration_layer2(); + } else tiny_calibration_find_values(); + /*if(debug_divider == DEBUG_DIVISION){ + debug_divider = 0; + cntCnt[cntCntCnt] = DMA.CH0.TRFCNT; + if(cntCntCnt == (CNT_CNT_MAX - 1)){ + cntCntCnt = 0; + } + else cntCntCnt++; + } + else debug_divider++;*/ + } + } + + if(debugOnNextEnd){ + currentTrfcnt = DMA.CH0.TRFCNT; + debugOnNextEnd = 0; + } + #ifndef SINGLE_ENDPOINT_INTERFACE + if(global_mode < 5){ + usb_state = (DMA.CH0.TRFCNT < 375) ? 1 : 0; + } + else{ + usb_state = (DMA.CH0.TRFCNT < 750) ? 1 : 0; + } + #else + usb_state = !usb_state; + #endif + + return; +} + +bool main_vendor_enable(void) +{ + main_b_vendor_enable = true; + firstFrame = 1; + udd_ep_run(0x81, false, (uint8_t *)&isoBuf[0], 125, iso_callback); + #ifndef SINGLE_ENDPOINT_INTERFACE + udd_ep_run(0x82, false, (uint8_t *)&isoBuf[125], 125, iso_callback); + udd_ep_run(0x83, false, (uint8_t *)&isoBuf[250], 125, iso_callback); + udd_ep_run(0x84, false, (uint8_t *)&isoBuf[375], 125, iso_callback); + udd_ep_run(0x85, false, (uint8_t *)&isoBuf[500], 125, iso_callback); + udd_ep_run(0x86, false, (uint8_t *)&isoBuf[625], 125, iso_callback); + #endif + return true; +} + +void main_vendor_disable(void) +{ + main_b_vendor_enable = false; +} + +bool main_setup_out_received(void) +{ + return 1; +} + +bool main_setup_in_received(void) +{ + return true; +} + +void iso_callback(udd_ep_status_t status, iram_size_t nb_transfered, udd_ep_id_t ep){ + #ifndef SINGLE_ENDPOINT_INTERFACE + unsigned short offset = (ep - 0x81) * 125; + if (global_mode < 5){ + if(ep > 0x83) offset += 375; //Shift from range [375, 750] to [750, 1125] Don't do this in modes 6 and 7 because they use 750 byte long sub-buffers. + udd_ep_run(ep, false, (uint8_t *)&isoBuf[usb_state * HALFPACKET_SIZE + offset], 125, iso_callback); + } + else{ + udd_ep_run(ep, false, (uint8_t *)&isoBuf[usb_state * PACKET_SIZE + offset], 125, iso_callback); + } + return; + #else + udd_ep_run(0x81, false, (uint8_t *)&isoBuf[usb_state * PACKET_SIZE], PACKET_SIZE, iso_callback); + #endif +} diff --git a/AVR Code/USB_BULK_TEST/src/main.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/main.c.REMOVED.git-id deleted file mode 100644 index 8e8a14a8..00000000 --- a/AVR Code/USB_BULK_TEST/src/main.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2a31dc9369acc7c6f86a75250d5c254e9911b845 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/main.h b/AVR Code/USB_BULK_TEST/src/main.h new file mode 100644 index 00000000..7b7817ed --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/main.h @@ -0,0 +1,91 @@ +/** + * \file + * + * \brief Declaration of main function used by example + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _MAIN_H_ +#define _MAIN_H_ + +/*! \brief Notify via user interface that enumeration is ok + * This is called by vendor interface when USB Host enable it. + * + * \retval true if vendor startup is successfully done + */ +bool main_vendor_enable(void); + +/*! \brief Notify via user interface that enumeration is disabled + * This is called by vendor interface when USB Host disable it. + */ +void main_vendor_disable(void); + +/*! \brief Manages the leds behaviors + * Called when a start of frame is received on USB line each 1ms. + */ +void main_sof_action(void); + +/*! \brief Enters the application in low power mode + * Callback called when USB host sets USB line in suspend state + */ +void main_suspend_action(void); + +/*! \brief Turn on a led to notify active mode + * Called when the USB line is resumed from the suspend state + */ +void main_resume_action(void); + +/*! \brief Manage the reception of setup request OUT + * + * \retval true if request accepted + */ +bool main_setup_out_received(void); + +/*! \brief Manage the reception of setup request IN + * + * \retval true if request accepted + */ +bool main_setup_in_received(void); + +void iso_callback(udd_ep_status_t status, iram_size_t nb_transfered, udd_ep_id_t ep); + +#endif // _MAIN_H_ diff --git a/AVR Code/USB_BULK_TEST/src/main.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/main.h.REMOVED.git-id deleted file mode 100644 index a0eed466..00000000 --- a/AVR Code/USB_BULK_TEST/src/main.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7b7817ed83496915a3709403c6a8e46c194596fe \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_adc.c b/AVR Code/USB_BULK_TEST/src/tiny_adc.c new file mode 100644 index 00000000..171dc4b0 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_adc.c @@ -0,0 +1,93 @@ +/* + * tiny_adc.c + * + * Created: 19/06/2015 7:17:23 PM + * Author: Esposch + */ + +#include "tiny_adc.h" +#include "globals.h" +#include "string.h" +#include +#include +#include + +// These 2 files need to be included in order to read +// the production calibration values from EEPROM +#include +#include + +void tiny_adc_setup(unsigned char ch2_enable, unsigned char seven_fiddy_ksps){ + PR.PRPA &=0b11111101; + + ADCA.CTRLA = 0x00; //Turn off + ADCA.CTRLB = ADC_FREERUN_bm | (seven_fiddy_ksps == 2 ? ADC_RESOLUTION_LEFT12BIT_gc : ADC_RESOLUTION_8BIT_gc) | ADC_CONMODE_bm ; + ADCA.REFCTRL = ADC_REFSEL_INTVCC2_gc; + ADCA.EVCTRL = ch2_enable ? ADC_SWEEP_0123_gc : ADC_SWEEP_01_gc; //Non-zero causes issues with interrupts! ;.; + + #if OVERCLOCK == 48 + ADCA.PRESCALER = seven_fiddy_ksps == 1 ? ADC_PRESCALER_DIV32_gc : ADC_PRESCALER_DIV64_gc; //ADC Clock = Sysclock/128 + #else + ADCA.PRESCALER = seven_fiddy_ksps == 1 ? ADC_PRESCALER_DIV16_gc : ADC_PRESCALER_DIV32_gc; //ADC Clock = Sysclock/128 + #endif + ADCA.CALL = ReadCalibrationByte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0)); //Load calibration bytes from production row. + ADCA.CALH = ReadCalibrationByte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1)); //Load calibration bytes from production row. + ADCA.CMP = 0x0000; //No compare used + + ADCA.CTRLA = ADC_ENABLE_bm; + + tiny_adc_pid_setup(); + + return; +} + +void tiny_adc_ch0setup(unsigned char gain_mask){ + ADCA.CH0.CTRL = 0x00; //Reset + ADCA.CH0.CTRL = ADC_CH_START_bm | (gain_mask&0x1c) | ADC_CH_INPUTMODE_DIFFWGAIN_gc; + #ifdef VERO + ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc | ((gain_mask&0x80) ? ADC_CH_MUXNEG_PIN6_gc : ADC_CH_MUXNEG_PIN4_gc); + #else + ADCA.CH0.MUXCTRL = ((gain_mask&0x80) ? ADC_CH_MUXPOS_PIN2_gc : ADC_CH_MUXPOS_PIN0_gc) | ((gain_mask&0x80) ? ADC_CH_MUXNEG_PIN6_gc : ADC_CH_MUXNEG_PIN4_gc); + #endif + ADCA.CH0.INTCTRL = ADC_CH_INTLVL_OFF_gc; + ADCA.CH0.SCAN = 0x00; //Disable scanning +} + +void tiny_adc_ch1setup(unsigned char gain_mask){ + ADCA.CH2.CTRL = 0x00; //Reset + ADCA.CH2.CTRL = ADC_CH_START_bm | gain_mask | ADC_CH_INPUTMODE_DIFFWGAIN_gc; + ADCA.CH2.MUXCTRL = ADC_CH_MUXPOS_PIN2_gc | ADC_CH_MUXNEG_PIN4_gc; + ADCA.CH2.INTCTRL = ADC_CH_INTLVL_OFF_gc; + ADCA.CH2.SCAN = 0x00; //Disable scanning +} + +void tiny_adc_pid_setup(void){ + ADCA.CH1.CTRL = 0x00; //Reset + ADCA.CH1.CTRL = ADC_CH_START_bm | ADC_CH_GAIN_1X_gc | ADC_CH_INPUTMODE_DIFFWGAIN_gc; + ADCA.CH1.MUXCTRL = ADC_CH_MUXPOS_PIN5_gc | 0b00000111; + ADCA.CH1.INTCTRL = ADC_CH_INTLVL_OFF_gc; + ADCA.CH1.SCAN = 0x00; //Disable scanning +} + + +//FROM: http://www.avrfreaks.net/forum/xmega-production-signature-row +uint8_t ReadCalibrationByte(uint8_t index){ + uint8_t result; + + /* Load the NVM Command register to read the calibration row. */ + NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc; + result = pgm_read_byte(index); + + /* Clean up NVM Command register. */ + NVM_CMD = NVM_CMD_NO_OPERATION_gc; + + return( result ); +} + +ISR(ADCA_CH0_vect){ + asm("nop"); + asm("nop"); + asm("nop"); + asm("nop"); + ADCA.CH0.INTFLAGS = 0x01; +} \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_adc.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_adc.c.REMOVED.git-id deleted file mode 100644 index 21af6a73..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_adc.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -171dc4b0f37dfd979963ec77a6558585adb11de7 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_adc.h b/AVR Code/USB_BULK_TEST/src/tiny_adc.h new file mode 100644 index 00000000..d2b00170 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_adc.h @@ -0,0 +1,23 @@ +/* + * tiny_adc.h + * + * Created: 19/06/2015 7:15:32 PM + * Author: Esposch + */ + + +#ifndef TINY_ADC_H_ +#define TINY_ADC_H_ + +#include +#include + +void tiny_adc_setup(unsigned char ch2_enable, unsigned char seven_fiddy_ksps); +void tiny_adc_ch0setup(unsigned char gain_mask); +void tiny_adc_ch1setup(unsigned char gain_mask); +uint8_t ReadCalibrationByte(uint8_t index); //FROM: http://www.avrfreaks.net/forum/xmega-production-signature-row +void tiny_adc_pid_setup(void); + + + +#endif /* TINY_ADC_H_ */ \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_adc.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_adc.h.REMOVED.git-id deleted file mode 100644 index 62c20ad5..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_adc.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d2b001702e4bd32b1331e4ff7dfa73635a833247 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_calibration.c b/AVR Code/USB_BULK_TEST/src/tiny_calibration.c new file mode 100644 index 00000000..a1ac1c4c --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_calibration.c @@ -0,0 +1,222 @@ +/* + * tiny_calibration.c + * + * Created: 9/01/2017 4:20:59 PM + * Author: Esposch + */ + +#include "tiny_calibration.h" +#include "globals.h" +#include "tiny_adc.h" + +volatile unsigned char median_TRFCNT_delay = 255; + +void tiny_calibration_init(){ + //Set up 48MHz DFLL for USB. + OSC.DFLLCTRL = OSC_RC32MCREF_USBSOF_gc; + DFLLRC32M.CALB = ReadCalibrationByte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSC)); //THIS is the val for 48MHz. RCOSC32M is for a 32MHz calibration. That makes a lot of sense now... + DFLLRC32M.COMP2 = 0xBB; + DFLLRC32M.COMP1= 0x80; //0xBB80 = 48,000. + DFLLRC32M.CTRL = 0x01; //Enable + + //Turn on the 48MHz clock and scale it down to 24MHz + CCP = CCP_IOREG_gc; + #if OVERCLOCK == 48 + CLK.PSCTRL = CLK_PSADIV_1_gc | CLK_PSBCDIV_1_1_gc; //All peripheral clocks = CLKsys / 2. + #else + CLK.PSCTRL = CLK_PSADIV_2_gc | CLK_PSBCDIV_1_1_gc; //All peripheral clocks = CLKsys / 2. + #endif + //CLK.USBCTRL handled by udc + OSC.CTRL = OSC_RC32MEN_bm | OSC_RC2MEN_bm; //Enable 32MHz reference. Keep 2MHz on. + while(OSC.STATUS != (OSC_RC32MRDY_bm | OSC_RC2MRDY_bm)); //Wait for it to be ready before continuing + + //4 step process from ASF manual. Puts a 48MHz clock on the PLL output + OSC.CTRL |= OSC_RC2MEN_bm; //1. Enable reference clock source. + OSC.PLLCTRL = OSC_PLLSRC_RC2M_gc | 24; //2. Set the multiplication factor and select the clock reference for the PLL. + while(!(OSC.STATUS & OSC_RC2MRDY_bm)); //3. Wait until the clock reference source is stable. + OSC.CTRL |= OSC_PLLEN_bm; //4. Enable the PLL + + //Move CPU + Peripherals to 48MHz PLLL clock. + while(!(OSC.STATUS & OSC_PLLRDY_bm)); + CCP = CCP_IOREG_gc; + CLK.CTRL = CLK_SCLKSEL_PLL_gc; + + //DFLLRC2M.CALB -= 1; + //DFLLRC2M.CALA -= 21; + return; +} + +tiny_calibration_first_sof(){ + PR.PRPE &= 0b11111110; + TC_CALI.PER = 23999; + TC_CALI.CNT = 12000; + #if OVERCLOCK == 48 + TC_CALI.CTRLA = TC_CLKSEL_DIV2_gc; + #else + TC_CALI.CTRLA = TC_CLKSEL_DIV1_gc; + #endif + return; +} + +unsigned char deadTime = 0; +volatile unsigned long outOfRange = 0; + +volatile unsigned char warmup = 10; +void tiny_calibration_maintain(){ + unsigned int cnt = TC_CALI.CNT; + + if(cnt > 12000){ + DFLLRC2M.CALA = cali_value_negative_gradient; + } + if(cnt < 12000){ + DFLLRC2M.CALA = cali_value_positive_gradient; + } + if(warmup){ + warmup--; //There's a warmup period in case tiny_calibration_find_values returns outside range; it won't record out of range until this period is over. + } + else if((cnt<11000) || (cnt>13000)){ + //This is an untested, last-ditch effort to hopefully prevent runaway if there's significant drift over time. + calibration_values_found = 0x00; + outOfRange++; + uds.outOfRangeH = (outOfRange >> 8) & 0xff; + uds.outOfRangeL = outOfRange & 0xff; + warmup = 6; + } + + if((median_TRFCNT == 65535) && (global_mode != 255)){ + if(!median_TRFCNT_delay){ + median_TRFCNT_delay--; + } else median_TRFCNT = DMA.CH0.TRFCNT; + } + return; +} + +volatile unsigned int calTemp; +void tiny_calibration_safe_add(int rawValue){ + unsigned int addValue; + unsigned char subtract; + if(rawValue == 0){ + return; + } + if(rawValue > 0){ + addValue = (unsigned int) rawValue; + subtract = 0; + } + if(rawValue < 0){ + rawValue = -rawValue; + addValue = rawValue; + subtract = 1; + } + calTemp = DFLLRC2M.CALB; + calTemp = calTemp << 7; + calTemp += DFLLRC2M.CALA; + asm("nop"); + if(calTemp < addValue){ + calTemp=0; + return; + } + if((calTemp + addValue) > 0x1fff){ + calTemp = 0x1fff; + return; + } + if(subtract){ + calTemp -= addValue; + } + else{ + calTemp += addValue; + } + DFLLRC2M.CALA = calTemp & 0x7f; + //DFLLRC2M.CALB = calTemp >> 7; + } + +int tiny_distance_from_centre(unsigned int point){ + int midVal = point-12000; + return midVal < 0 ? -midVal : midVal; +} + +volatile unsigned char calibration_values_found = 0x00; +volatile unsigned int last_val = 12000; +volatile int gradient; +volatile unsigned int calChange; +#define NUM_INAROW 12 +volatile unsigned char inarow = NUM_INAROW; + +void tiny_calibration_find_values(){ + unsigned int cnt = TC_CALI.CNT; + gradient = cnt - last_val; + + //Find the negative value first. + if(calibration_values_found == 0x00){ + if((gradient < -50) && (gradient > -150)){ + if(inarow){ + inarow--; + }else{ + cali_value_negative_gradient = DFLLRC2M.CALA; + calibration_values_found = 0x01; + inarow = NUM_INAROW; + } + } + else{ + inarow = NUM_INAROW; + calChange = gradient < -150 ? 1 : -1; + calChange -= gradient / 48; + tiny_calibration_safe_add(calChange); + } + } + + //Search for the positive gradient + if(calibration_values_found == 0x01){ + if(gradient > 50){ + if(inarow){ + inarow--; + } else{ + cali_value_positive_gradient = DFLLRC2M.CALA; + calibration_values_found = 0x03; + } + } + else tiny_calibration_safe_add((gradient > 150 ? -1 : 1)); + } + last_val = cnt; +} + +#define LAYER2_INTERVAL 64 +#define MAXIMUM_DEVIATION 1 +volatile unsigned int layer2_counter = LAYER2_INTERVAL; +void tiny_calibration_layer2(){ + //Run only once every LAYER2_INTERVAL milliseconds. + if(layer2_counter){ + layer2_counter--; + return; + } + layer2_counter = LAYER2_INTERVAL; + + //Return if a median TRFCNT hasn't been set yet. + if(median_TRFCNT == 65535){ + return; + } + unsigned int TRFCNT_temp = DMA.CH0.TRFCNT; + TRFCNT_temp = TRFCNT_temp % (global_mode > 5 ? PACKET_SIZE : HALFPACKET_SIZE); + + if((TRFCNT_temp > median_TRFCNT) && (magnitude_difference(TRFCNT_temp, median_TRFCNT) > MAXIMUM_DEVIATION)){ + TC_CALI.PERBUF = 24000; + return; + } + if((TRFCNT_temp < median_TRFCNT) && (magnitude_difference(TRFCNT_temp, median_TRFCNT) > MAXIMUM_DEVIATION)){ + TC_CALI.PERBUF = 23999; + return; + } +} + +unsigned int magnitude_difference(unsigned int a, unsigned int b){ + if(a==b) return 0; + if(a>b) return a - b; + if(b>a) return b - a; +} + +void tiny_calibration_synchronise_phase(unsigned int phase, unsigned int precision){ + //Wait for the calibration timer to roughly equal a phase value, then return. + unsigned int maxVal = phase + precision; + unsigned int minVal = phase - precision; + while (!((TC_CALI.CNT < maxVal) && (TC_CALI.CNT > minVal))); + return; +} diff --git a/AVR Code/USB_BULK_TEST/src/tiny_calibration.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_calibration.c.REMOVED.git-id deleted file mode 100644 index 36a3188d..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_calibration.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a1ac1c4c9f3a360b441e163d1b4064484b587ee0 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_calibration.h b/AVR Code/USB_BULK_TEST/src/tiny_calibration.h new file mode 100644 index 00000000..edd9e0f3 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_calibration.h @@ -0,0 +1,32 @@ +/* + * tiny_calibration.h + * + * Created: 9/01/2017 4:21:09 PM + * Author: Esposch + */ + + +#ifndef TINY_CALIBRATION_H_ +#define TINY_CALIBRATION_H_ + +#include +#include + +void tiny_calibration_init(); +void tiny_calibration_first_sof(); +void tiny_calibration_maintain(); +void tiny_calibration_safe_add(int rawValue); +int tiny_distance_from_centre(unsigned int point); +void tiny_calibration_find_values(); +void tiny_calibration_layer2(); +unsigned int magnitude_difference(unsigned int a, unsigned int b); +void tiny_calibration_synchronise_phase(unsigned int phase, unsigned int precision); + +extern volatile unsigned char calibration_values_found; +extern volatile unsigned char median_TRFCNT_delay; + +volatile unsigned char cali_value_negative_gradient; +volatile unsigned char cali_value_positive_gradient; + + +#endif /* TINY_CALIBRATION_H_ */ \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_calibration.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_calibration.h.REMOVED.git-id deleted file mode 100644 index ac5a7c18..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_calibration.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -edd9e0f3523c962a265a54b7abb1d5893c7cf047 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_dac.c b/AVR Code/USB_BULK_TEST/src/tiny_dac.c new file mode 100644 index 00000000..122a33c2 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_dac.c @@ -0,0 +1,35 @@ +/* + * tiny_dac.c + * + * Created: 3/07/2015 1:06:44 PM + * Author: Esposch + */ + +#include "tiny_dac.h" +#include "tiny_adc.h" + +#include +#include + +void tiny_dac_setup(void){ + + //Turn on in PR + PR.PRPB &=0b11111011; + + DACB.CTRLA = DAC_CH1EN_bm | DAC_CH0EN_bm | DAC_ENABLE_bm; + DACB.CTRLB = DAC_CHSEL_DUAL_gc; + DACB.CTRLC = DAC_REFSEL_AVCC_gc | DAC_LEFTADJ_bm; + //EVCTRL unset + //DACB.CH0DATAH = 127;//contains (8-bit) sample, assuming left adjust! + + //TODO: Calibrate + DACB.CH0GAINCAL = ReadCalibrationByte(offsetof(NVM_PROD_SIGNATURES_t, DACB0GAINCAL)); //Load calibration bytes from production row. + DACB.CH0OFFSETCAL = ReadCalibrationByte(offsetof(NVM_PROD_SIGNATURES_t, DACB0OFFCAL)); //Load calibration bytes from production row. + + DACB.CH1GAINCAL = ReadCalibrationByte(offsetof(NVM_PROD_SIGNATURES_t, DACB1GAINCAL)); //Load calibration bytes from production row. + DACB.CH1OFFSETCAL = ReadCalibrationByte(offsetof(NVM_PROD_SIGNATURES_t, DACB1OFFCAL)); //Load calibration bytes from production row. + + //Set up for triple mode! + PORTB.DIR |= 0x03; + PORTB.OUT = 0x00; +} \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_dac.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_dac.c.REMOVED.git-id deleted file mode 100644 index dc5f4ee9..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_dac.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -122a33c20c7086677c72cafb4451a012afa752b6 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_dac.h b/AVR Code/USB_BULK_TEST/src/tiny_dac.h new file mode 100644 index 00000000..59894c9f --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_dac.h @@ -0,0 +1,18 @@ +/* + * tiny_dac.h + * + * Created: 3/07/2015 1:06:53 PM + * Author: Esposch + */ + +#include +#include + +#ifndef TINY_DAC_H_ +#define TINY_DAC_H_ + +void tiny_dac_setup(void); + + + +#endif /* TINY_DAC_H_ */ \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_dac.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_dac.h.REMOVED.git-id deleted file mode 100644 index c3b4ac45..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_dac.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -59894c9f7a76761b2d52d7d20c4d8bda6356d2f3 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_dig.c b/AVR Code/USB_BULK_TEST/src/tiny_dig.c new file mode 100644 index 00000000..8063205e --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_dig.c @@ -0,0 +1,16 @@ +/* + * tiny_dig_out.c + * + * Created: 14/10/2015 4:51:19 PM + * Author: Esposch + */ + +#include "tiny_dig.h" +#include "globals.h" + + +void tiny_dig_setup(void){ + PORTE.DIR = 0x0f; + PORTE.OUT = 0x05; + return; +} diff --git a/AVR Code/USB_BULK_TEST/src/tiny_dig.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_dig.c.REMOVED.git-id deleted file mode 100644 index 3f59bf87..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_dig.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8063205ed352dc6a6c9f1a29655c05325b1aef2b \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_dig.h b/AVR Code/USB_BULK_TEST/src/tiny_dig.h new file mode 100644 index 00000000..57af7a9f --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_dig.h @@ -0,0 +1,18 @@ +/* + * tiny_dig_out.h + * + * Created: 14/10/2015 4:51:29 PM + * Author: Esposch + */ + + +#ifndef TINY_DIG_OUT_H_ +#define TINY_DIG_OUT_H_ + +#include + +void tiny_dig_setup(void); + + + +#endif /* TINY_DIG_OUT_H_ */ \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_dig.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_dig.h.REMOVED.git-id deleted file mode 100644 index 22be5126..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_dig.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -57af7a9f665ceda2796be1e346373374b2d9ba68 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_dma.c b/AVR Code/USB_BULK_TEST/src/tiny_dma.c new file mode 100644 index 00000000..50e1baf0 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_dma.c @@ -0,0 +1,674 @@ +/* + * tiny_dma.c + * + * Created: 25/06/2015 9:00:42 AM + * Author: Esposch + */ + +#include "tiny_dma.h" +#include "tiny_adc.h" +#include "tiny_uart.h" +#include "tiny_calibration.h" +#include "globals.h" +#include "util/delay.h" + +#ifndef SINGLE_ENDPOINT_INTERFACE + #define DMA_STANDARD_INTERRUPT (0x00) + #define DMA_STANDARD_CTRLA (DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm) + #define DMA_STANDARD_TRANSFER_LENGTH (PACKET_SIZE) +#else + #define DMA_STANDARD_INTERRUPT (0x03) + #define DMA_STANDARD_CTRLA (DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm) + #define DMA_STANDARD_TRANSFER_LENGTH (HALFPACKET_SIZE) +#endif + +void tiny_dma_setup(void){ + //Turn on DMA + PR.PRGEN &=0b111111110; //Turn on DMA clk + #ifndef SINGLE_ENDPOINT_INTERFACE + DMA.CTRL = DMA_ENABLE_bm | DMA_PRIMODE_CH0123_gc; + #else + DMA.CTRL = DMA_ENABLE_bm | DMA_PRIMODE_RR0123_gc; + #warning "Round Robin on DMA" + #endif + +} +void tiny_dma_flush(void){ + DMA.CH0.CTRLA = 0x00; + DMA.CH0.CTRLA = DMA_CH_RESET_bm; + + DMA.CH1.CTRLA = 0x00; + DMA.CH1.CTRLA = DMA_CH_RESET_bm; + + DMA.CH2.CTRLA = 0x00; + DMA.CH2.CTRLA = DMA_CH_RESET_bm; + + DMA.CH3.CTRLA = 0x00; + DMA.CH3.CTRLA = DMA_CH_RESET_bm; + + b1_state = 0; + b2_state = 0; + usb_state = 0; + + dma_ch0_ran = 0; + dma_ch1_ran = 0; +} +void tiny_dma_delayed_set(unsigned char mode){ + futureMode = mode; + modeChanged = 1; +} +void tiny_dma_set_mode_0(void){ + + global_mode = 0; + + tiny_dma_flush(); + + DMA.CH2.REPCNT = 0; //Repeat forever! + DMA.CH2.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; + DMA.CH2.CTRLB = 0x00; //No interrupt for DacBuf!! + DMA.CH2.ADDRCTRL = DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_SRCRELOAD_BLOCK_gc | DMA_CH_SRCDIR_INC_gc; //Dest reloads after each burst, with byte incrementing. Src reloads at end of block, also incrementing address. + DMA.CH2.TRIGSRC = DMA_CH_TRIGSRC_EVSYS_CH1_gc; //Triggered from TCC0 when it hits PER + DMA.CH2.TRFCNT = auxDacBufLen; + + DMA.CH2.SRCADDR0 = (( (uint16_t) &dacBuf_CH2[0]) >> 0) & 0xFF; //Source address is dacbuf + DMA.CH2.SRCADDR1 = (( (uint16_t) &dacBuf_CH2[0]) >> 8) & 0xFF; + DMA.CH2.SRCADDR2 = 0x00; + + DMA.CH2.DESTADDR0 = (( (uint16_t) &DACB.CH1DATAH) >> 0) & 0xFF; //Dest address is high byte of DAC register + DMA.CH2.DESTADDR1 = (( (uint16_t) &DACB.CH1DATAH) >> 8) & 0xFF; + DMA.CH2.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH2.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + + DMA.CH3.REPCNT = 0; //Repeat forever! + DMA.CH3.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; + DMA.CH3.CTRLB = 0x00; //Hi interrupt on block complete + DMA.CH3.ADDRCTRL = DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_SRCRELOAD_BLOCK_gc | DMA_CH_SRCDIR_INC_gc; //Dest reloads after each burst, with byte incrementing. Src reloads at end of block, also incrementing address. + DMA.CH3.TRIGSRC = DMA_CH_TRIGSRC_EVSYS_CH2_gc; //Triggered from TCC0 when it hits PER + DMA.CH3.TRFCNT = dacBuf_len; + + DMA.CH3.SRCADDR0 = (( (uint16_t) &dacBuf_CH1[0]) >> 0) & 0xFF; //Source address is dacbuf + DMA.CH3.SRCADDR1 = (( (uint16_t) &dacBuf_CH1[0]) >> 8) & 0xFF; + DMA.CH3.SRCADDR2 = 0x00; + + DMA.CH3.DESTADDR0 = (( (uint16_t) &DACB.CH0DATAH) >> 0) & 0xFF; //Dest address is high byte of DAC register + DMA.CH3.DESTADDR1 = (( (uint16_t) &DACB.CH0DATAH) >> 8) & 0xFF; + DMA.CH3.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH3.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + + DMA.CH0.CTRLA = 0x00; + DMA.CH0.CTRLA = DMA_CH_RESET_bm; + + DMA.CH0.CTRLA = DMA_STANDARD_CTRLA; + DMA.CH0.CTRLB = DMA_STANDARD_INTERRUPT; + DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_DESTRELOAD_BLOCK_gc; //Source reloads after each burst, with byte incrementing. Dest does not reload, but does increment address. + DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_ADCA_CH0_gc; //Triggered from ADCA channel 0 + DMA.CH0.TRFCNT = DMA_STANDARD_TRANSFER_LENGTH; + + DMA.CH0.SRCADDR0 = (( (uint16_t) &ADCA.CH0.RESL) >> 0) & 0xFF; //Source address is ADC + DMA.CH0.SRCADDR1 = (( (uint16_t) &ADCA.CH0.RESL) >> 8) & 0xFF; + DMA.CH0.SRCADDR2 = 0x00; + + DMA.CH0.DESTADDR0 = (( (uint16_t) &isoBuf[0]) >> 0) & 0xFF; //Dest address is isoBuf + DMA.CH0.DESTADDR1 = (( (uint16_t) &isoBuf[0]) >> 8) & 0xFF; + DMA.CH0.DESTADDR2 = 0x00; + + tiny_calibration_synchronise_phase(500, 200); + median_TRFCNT = 200; + median_TRFCNT_delay = 1; //Wait a few frames before actually setting median_TRFCNT, in case a SOF interrupt was queued during tiny_dma_set_mode_xxx. + DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + +} + +void tiny_dma_loop_mode_0(void){ + return; +} + +void tiny_dma_set_mode_1(void){ + global_mode = 1; + + tiny_dma_flush(); + + //AUX channel (to keep it tx, therefore always rx) + DMA.CH2.CTRLA = 0x00; + DMA.CH2.CTRLA = DMA_CH_RESET_bm; + + DMA.CH2.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm; //Do not repeat! + DMA.CH2.CTRLB = 0x00; //No int + DMA.CH2.ADDRCTRL = DMA_CH_SRCDIR_FIXED_gc | DMA_CH_DESTDIR_FIXED_gc; //Source and address fixed. + DMA.CH2.TRIGSRC = DMA_CH_TRIGSRC_USARTC0_RXC_gc; + DMA.CH2.TRFCNT = 0; + DMA.CH2.REPCNT = 0; + + DMA.CH2.SRCADDR0 = (( (uint16_t) &dummy) >> 0) & 0xFF; + DMA.CH2.SRCADDR1 = (( (uint16_t) &dummy) >> 8) & 0xFF; + DMA.CH2.SRCADDR2 = 0x00; + + DMA.CH2.DESTADDR0 = (( (uint16_t) &USARTC0.DATA) >> 0) & 0xFF; + DMA.CH2.DESTADDR1 = (( (uint16_t) &USARTC0.DATA) >> 8) & 0xFF; + DMA.CH2.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH2.CTRLA |= DMA_CH_REPEAT_bm | DMA_CH_ENABLE_bm; //Enable! + + USARTC0.DATA = 0x55; + USARTC0.DATA = 0x55; + + DMA.CH3.REPCNT = 0; //Repeat forever! + DMA.CH3.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; + DMA.CH3.CTRLB = 0x00; //No interrupt for DacBuf!! + DMA.CH3.ADDRCTRL = DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_SRCRELOAD_BLOCK_gc | DMA_CH_SRCDIR_INC_gc; //Dest reloads after each burst, with byte incrementing. Src reloads at end of block, also incrementing address. + DMA.CH3.TRIGSRC = DMA_CH_TRIGSRC_EVSYS_CH1_gc; //Triggered from TCC0 when it hits PER + DMA.CH3.TRFCNT = auxDacBufLen; + + DMA.CH3.SRCADDR0 = (( (uint16_t) &dacBuf_CH2[0]) >> 0) & 0xFF; //Source address is dacbuf + DMA.CH3.SRCADDR1 = (( (uint16_t) &dacBuf_CH2[0]) >> 8) & 0xFF; + DMA.CH3.SRCADDR2 = 0x00; + + DMA.CH3.DESTADDR0 = (( (uint16_t) &DACB.CH1DATAH) >> 0) & 0xFF; //Dest address is high byte of DAC register + DMA.CH3.DESTADDR1 = (( (uint16_t) &DACB.CH1DATAH) >> 8) & 0xFF; + DMA.CH3.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH3.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + + DMA.CH1.CTRLA = DMA_STANDARD_CTRLA; + DMA.CH1.CTRLB = DMA_STANDARD_INTERRUPT; + DMA.CH1.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_DESTRELOAD_BLOCK_gc; //Source reloads after each burst, with byte incrementing. Dest does not reload, but does increment address. + DMA.CH1.TRIGSRC = DMA_CH_TRIGSRC_USARTC0_RXC_gc; + DMA.CH1.TRFCNT = DMA_STANDARD_TRANSFER_LENGTH; + + DMA.CH1.SRCADDR0 = (( (uint16_t) &USARTC0.DATA) >> 0) & 0xFF; + DMA.CH1.SRCADDR1 = (( (uint16_t) &USARTC0.DATA) >> 8) & 0xFF; + DMA.CH1.SRCADDR2 = 0x00; + + DMA.CH1.DESTADDR0 = (( (uint16_t) &isoBuf[PACKET_SIZE]) >> 0) & 0xFF; //Dest address is isoBuf + DMA.CH1.DESTADDR1 = (( (uint16_t) &isoBuf[PACKET_SIZE]) >> 8) & 0xFF; + DMA.CH1.DESTADDR2 = 0x00; + + DMA.CH0.CTRLA = DMA_STANDARD_CTRLA; + DMA.CH0.CTRLB = DMA_STANDARD_INTERRUPT; + DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_DESTRELOAD_BLOCK_gc; //Source reloads after each burst, with byte incrementing. Dest does not reload, but does increment address. + DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_ADCA_CH0_gc; //Triggered from ADCA channel 0 + DMA.CH0.TRFCNT = DMA_STANDARD_TRANSFER_LENGTH; + + DMA.CH0.SRCADDR0 = (( (uint16_t) &ADCA.CH0.RESL) >> 0) & 0xFF; //Source address is ADC + DMA.CH0.SRCADDR1 = (( (uint16_t) &ADCA.CH0.RESL) >> 8) & 0xFF; + DMA.CH0.SRCADDR2 = 0x00; + + DMA.CH0.DESTADDR0 = (( (uint16_t) &isoBuf[0]) >> 0) & 0xFF; //Dest address is isoBuf + DMA.CH0.DESTADDR1 = (( (uint16_t) &isoBuf[0]) >> 8) & 0xFF; + DMA.CH0.DESTADDR2 = 0x00; + + tiny_calibration_synchronise_phase(500, 200); + median_TRFCNT = 200; + median_TRFCNT_delay = 1; //Wait a few frames before actually setting median_TRFCNT, in case a SOF interrupt was queued during tiny_dma_set_mode_xxx. + DMA.CH1.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm; //Enable! +} + +void tiny_dma_loop_mode_1(void){ + return; +} + +void tiny_dma_set_mode_2(void){ + + global_mode = 2; + + tiny_dma_flush(); + + DMA.CH2.REPCNT = 0; //Repeat forever! + DMA.CH2.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; + DMA.CH2.CTRLB = 0x00; //No interrupt for DacBuf!! + DMA.CH2.ADDRCTRL = DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_SRCRELOAD_BLOCK_gc | DMA_CH_SRCDIR_INC_gc; //Dest reloads after each burst, with byte incrementing. Src reloads at end of block, also incrementing address. + DMA.CH2.TRIGSRC = DMA_CH_TRIGSRC_EVSYS_CH1_gc; //Triggered from TCC0 when it hits PER + DMA.CH2.TRFCNT = auxDacBufLen; + + DMA.CH2.SRCADDR0 = (( (uint16_t) &dacBuf_CH2[0]) >> 0) & 0xFF; //Source address is dacbuf + DMA.CH2.SRCADDR1 = (( (uint16_t) &dacBuf_CH2[0]) >> 8) & 0xFF; + DMA.CH2.SRCADDR2 = 0x00; + + DMA.CH2.DESTADDR0 = (( (uint16_t) &DACB.CH1DATAH) >> 0) & 0xFF; //Dest address is high byte of DAC register + DMA.CH2.DESTADDR1 = (( (uint16_t) &DACB.CH1DATAH) >> 8) & 0xFF; + DMA.CH2.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH2.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + + DMA.CH3.REPCNT = 0; //Repeat forever! + DMA.CH3.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; + DMA.CH3.CTRLB = 0x00; //Hi interrupt on block complete + DMA.CH3.ADDRCTRL = DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_SRCRELOAD_BLOCK_gc | DMA_CH_SRCDIR_INC_gc; //Dest reloads after each burst, with byte incrementing. Src reloads at end of block, also incrementing address. + DMA.CH3.TRIGSRC = DMA_CH_TRIGSRC_EVSYS_CH2_gc; //Triggered from TCC0 when it hits PER + DMA.CH3.TRFCNT = dacBuf_len; + + DMA.CH3.SRCADDR0 = (( (uint16_t) &dacBuf_CH1[0]) >> 0) & 0xFF; //Source address is dacbuf + DMA.CH3.SRCADDR1 = (( (uint16_t) &dacBuf_CH1[0]) >> 8) & 0xFF; + DMA.CH3.SRCADDR2 = 0x00; + + DMA.CH3.DESTADDR0 = (( (uint16_t) &DACB.CH0DATAH) >> 0) & 0xFF; //Dest address is high byte of DAC register + DMA.CH3.DESTADDR1 = (( (uint16_t) &DACB.CH0DATAH) >> 8) & 0xFF; + DMA.CH3.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH3.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + + DMA.CH0.CTRLA = 0x00; + DMA.CH0.CTRLA = DMA_CH_RESET_bm; + + DMA.CH0.CTRLA = DMA_STANDARD_CTRLA; + DMA.CH0.CTRLB = DMA_STANDARD_INTERRUPT; + DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_DESTRELOAD_BLOCK_gc; //Source reloads after each burst, with byte incrementing. Dest does not reload, but does increment address. + DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_ADCA_CH0_gc; //Triggered from ADCA channel 0 + DMA.CH0.TRFCNT = DMA_STANDARD_TRANSFER_LENGTH; + + DMA.CH0.SRCADDR0 = (( (uint16_t) &ADCA.CH0.RESL) >> 0) & 0xFF; //Source address is ADC + DMA.CH0.SRCADDR1 = (( (uint16_t) &ADCA.CH0.RESL) >> 8) & 0xFF; + DMA.CH0.SRCADDR2 = 0x00; + + DMA.CH0.DESTADDR0 = (( (uint16_t) &isoBuf[0]) >> 0) & 0xFF; //Dest address is isoBuf + DMA.CH0.DESTADDR1 = (( (uint16_t) &isoBuf[0]) >> 8) & 0xFF; + DMA.CH0.DESTADDR2 = 0x00; + + + DMA.CH1.CTRLA = DMA_STANDARD_CTRLA; + DMA.CH1.CTRLB = DMA_STANDARD_INTERRUPT; + DMA.CH1.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_DESTRELOAD_BLOCK_gc; //Source reloads after each burst, with byte incrementing. Dest does not reload, but does increment address. + DMA.CH1.TRIGSRC = DMA_CH_TRIGSRC_ADCA_CH0_gc; //Triggered from ADCA channel 0 + DMA.CH1.TRFCNT = DMA_STANDARD_TRANSFER_LENGTH; + + DMA.CH1.SRCADDR0 = (( (uint16_t) &ADCA.CH2.RESL) >> 0) & 0xFF; //Source address is ADC + DMA.CH1.SRCADDR1 = (( (uint16_t) &ADCA.CH2.RESL) >> 8) & 0xFF; + DMA.CH1.SRCADDR2 = 0x00; + + DMA.CH1.DESTADDR0 = (( (uint16_t) &isoBuf[PACKET_SIZE]) >> 0) & 0xFF; //Dest address is isoBuf + DMA.CH1.DESTADDR1 = (( (uint16_t) &isoBuf[PACKET_SIZE]) >> 8) & 0xFF; + DMA.CH1.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + + tiny_calibration_synchronise_phase(500, 200); + median_TRFCNT = 200; + median_TRFCNT_delay = 1; //Wait a few frames before actually setting median_TRFCNT, in case a SOF interrupt was queued during tiny_dma_set_mode_xxx. + DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + DMA.CH1.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + +} + +void tiny_dma_loop_mode_2(void){ + return; +} + + + +void tiny_dma_set_mode_3(void){ + global_mode = 3; + tiny_dma_flush(); + + DMA.CH3.REPCNT = 0; //Repeat forever! + DMA.CH3.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; + DMA.CH3.CTRLB = 0x00; //No interrupt for DacBuf!! + DMA.CH3.ADDRCTRL = DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_SRCRELOAD_BLOCK_gc | DMA_CH_SRCDIR_INC_gc; //Dest reloads after each burst, with byte incrementing. Src reloads at end of block, also incrementing address. + DMA.CH3.TRIGSRC = DMA_CH_TRIGSRC_EVSYS_CH1_gc; //Triggered from TCC0 when it hits PER + DMA.CH3.TRFCNT = auxDacBufLen; + + DMA.CH3.SRCADDR0 = (( (uint16_t) &dacBuf_CH2[0]) >> 0) & 0xFF; //Source address is dacbuf + DMA.CH3.SRCADDR1 = (( (uint16_t) &dacBuf_CH2[0]) >> 8) & 0xFF; + DMA.CH3.SRCADDR2 = 0x00; + + DMA.CH3.DESTADDR0 = (( (uint16_t) &DACB.CH1DATAH) >> 0) & 0xFF; //Dest address is high byte of DAC register + DMA.CH3.DESTADDR1 = (( (uint16_t) &DACB.CH1DATAH) >> 8) & 0xFF; + DMA.CH3.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH3.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + + DMA.CH2.REPCNT = 0; //Repeat forever! + DMA.CH2.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; + DMA.CH2.CTRLB = 0x00; //Hi interrupt on block complete + DMA.CH2.ADDRCTRL = DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_SRCRELOAD_BLOCK_gc | DMA_CH_SRCDIR_INC_gc; //Dest reloads after each burst, with byte incrementing. Src reloads at end of block, also incrementing address. + DMA.CH2.TRIGSRC = DMA_CH_TRIGSRC_EVSYS_CH2_gc; //Triggered from TCC0 when it hits PER + DMA.CH2.TRFCNT = dacBuf_len; + + DMA.CH2.SRCADDR0 = (( (uint16_t) &dacBuf_CH1[0]) >> 0) & 0xFF; //Source address is dacbuf + DMA.CH2.SRCADDR1 = (( (uint16_t) &dacBuf_CH1[0]) >> 8) & 0xFF; + DMA.CH2.SRCADDR2 = 0x00; + + DMA.CH2.DESTADDR0 = (( (uint16_t) &DACB.CH0DATAH) >> 0) & 0xFF; //Dest address is high byte of DAC register + DMA.CH2.DESTADDR1 = (( (uint16_t) &DACB.CH0DATAH) >> 8) & 0xFF; + DMA.CH2.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH2.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + + + //AUX channel (to keep it tx, therefore always rx) + DMA.CH1.CTRLA = 0x00; + DMA.CH1.CTRLA = DMA_CH_RESET_bm; + + DMA.CH1.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm; //Do not repeat! + DMA.CH1.CTRLB = 0x00; //No int + DMA.CH1.ADDRCTRL = DMA_CH_SRCDIR_FIXED_gc | DMA_CH_DESTDIR_FIXED_gc; //Source and address fixed. + DMA.CH1.TRIGSRC = DMA_CH_TRIGSRC_USARTC0_RXC_gc; + DMA.CH1.TRFCNT = 0; + DMA.CH1.REPCNT = 0; + + DMA.CH1.SRCADDR0 = (( (uint16_t) &dummy) >> 0) & 0xFF; + DMA.CH1.SRCADDR1 = (( (uint16_t) &dummy) >> 8) & 0xFF; + DMA.CH1.SRCADDR2 = 0x00; + + DMA.CH1.DESTADDR0 = (( (uint16_t) &USARTC0.DATA) >> 0) & 0xFF; + DMA.CH1.DESTADDR1 = (( (uint16_t) &USARTC0.DATA) >> 8) & 0xFF; + DMA.CH1.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH1.CTRLA |= DMA_CH_REPEAT_bm | DMA_CH_ENABLE_bm; //Enable! + + USARTC0.DATA = 0x55; + + //Actual data being transferred + DMA.CH0.CTRLA = 0x00; + DMA.CH0.CTRLA = DMA_CH_RESET_bm; + + DMA.CH0.CTRLA = DMA_STANDARD_CTRLA; + DMA.CH0.CTRLB = DMA_STANDARD_INTERRUPT; + DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_DESTRELOAD_BLOCK_gc; //Source reloads after each burst, with byte incrementing. Dest does not reload, but does increment address. + DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_USARTC0_RXC_gc; + DMA.CH0.TRFCNT = DMA_STANDARD_TRANSFER_LENGTH; + + DMA.CH0.SRCADDR0 = (( (uint16_t) &USARTC0.DATA) >> 0) & 0xFF; //Source address is ADC + DMA.CH0.SRCADDR1 = (( (uint16_t) &USARTC0.DATA) >> 8) & 0xFF; + DMA.CH0.SRCADDR2 = 0x00; + + DMA.CH0.DESTADDR0 = (( (uint16_t) &isoBuf[0]) >> 0) & 0xFF; //Dest address is isoBuf + DMA.CH0.DESTADDR1 = (( (uint16_t) &isoBuf[0]) >> 8) & 0xFF; + DMA.CH0.DESTADDR2 = 0x00; + + tiny_calibration_synchronise_phase(500, 200); + median_TRFCNT = 200; + median_TRFCNT_delay = 1; //Wait a few frames before actually setting median_TRFCNT, in case a SOF interrupt was queued during tiny_dma_set_mode_xxx. + + //Must enable last for REPCNT won't work! + DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm; //Enable! +} + +void tiny_dma_loop_mode_3(void){ + return; +} + +void tiny_dma_set_mode_4(void){ + + global_mode = 4; + + tiny_dma_flush(); + + //AUX channel (to keep it tx, therefore always rx) + DMA.CH2.CTRLA = 0x00; + DMA.CH2.CTRLA = DMA_CH_RESET_bm; + + DMA.CH2.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm; //Do not repeat! + DMA.CH2.CTRLB = 0x00; //No int + DMA.CH2.ADDRCTRL = DMA_CH_SRCDIR_FIXED_gc | DMA_CH_DESTDIR_FIXED_gc; //Source and address fixed. + DMA.CH2.TRIGSRC = DMA_CH_TRIGSRC_USARTC0_RXC_gc; + DMA.CH2.TRFCNT = 0; + DMA.CH2.REPCNT = 0; + + DMA.CH2.SRCADDR0 = (( (uint16_t) &dummy) >> 0) & 0xFF; + DMA.CH2.SRCADDR1 = (( (uint16_t) &dummy) >> 8) & 0xFF; + DMA.CH2.SRCADDR2 = 0x00; + + DMA.CH2.DESTADDR0 = (( (uint16_t) &USARTC0.DATA) >> 0) & 0xFF; + DMA.CH2.DESTADDR1 = (( (uint16_t) &USARTC0.DATA) >> 8) & 0xFF; + DMA.CH2.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH2.CTRLA |= DMA_CH_REPEAT_bm | DMA_CH_ENABLE_bm; //Enable! + + USARTC0.DATA = 0x55; + + DMA.CH3.REPCNT = 0; //Repeat forever! + DMA.CH3.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; + DMA.CH3.CTRLB = 0x00; //No interrupt for DacBuf!! + DMA.CH3.ADDRCTRL = DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_SRCRELOAD_BLOCK_gc | DMA_CH_SRCDIR_INC_gc; //Dest reloads after each burst, with byte incrementing. Src reloads at end of block, also incrementing address. + DMA.CH3.TRIGSRC = DMA_CH_TRIGSRC_EVSYS_CH1_gc; //Triggered from TCC0 when it hits PER + DMA.CH3.TRFCNT = auxDacBufLen; + + DMA.CH3.SRCADDR0 = (( (uint16_t) &dacBuf_CH2[0]) >> 0) & 0xFF; //Source address is dacbuf + DMA.CH3.SRCADDR1 = (( (uint16_t) &dacBuf_CH2[0]) >> 8) & 0xFF; + DMA.CH3.SRCADDR2 = 0x00; + + DMA.CH3.DESTADDR0 = (( (uint16_t) &DACB.CH1DATAH) >> 0) & 0xFF; //Dest address is high byte of DAC register + DMA.CH3.DESTADDR1 = (( (uint16_t) &DACB.CH1DATAH) >> 8) & 0xFF; + DMA.CH3.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH3.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + + //Actual data being transferred + DMA.CH0.CTRLA = DMA_STANDARD_CTRLA; + DMA.CH0.CTRLB = DMA_STANDARD_INTERRUPT; + DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_DESTRELOAD_BLOCK_gc; //Source reloads after each burst, with byte incrementing. Dest does not reload, but does increment address. + DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_USARTC0_RXC_gc; + DMA.CH0.TRFCNT = DMA_STANDARD_TRANSFER_LENGTH; + + DMA.CH0.SRCADDR0 = (( (uint16_t) &USARTC0.DATA) >> 0) & 0xFF; //Source address is ADC + DMA.CH0.SRCADDR1 = (( (uint16_t) &USARTC0.DATA) >> 8) & 0xFF; + DMA.CH0.SRCADDR2 = 0x00; + + DMA.CH0.DESTADDR0 = (( (uint16_t) &isoBuf[0]) >> 0) & 0xFF; //Dest address is isoBuf + DMA.CH0.DESTADDR1 = (( (uint16_t) &isoBuf[0]) >> 8) & 0xFF; + DMA.CH0.DESTADDR2 = 0x00; + + + DMA.CH1.CTRLA = DMA_STANDARD_CTRLA; + DMA.CH1.CTRLB = DMA_STANDARD_INTERRUPT; + DMA.CH1.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_DESTRELOAD_BLOCK_gc; //Source reloads after each burst, with byte incrementing. Dest does not reload, but does increment address. + DMA.CH1.TRIGSRC = DMA_CH_TRIGSRC_SPIC_gc; + DMA.CH1.TRFCNT = DMA_STANDARD_TRANSFER_LENGTH; + + DMA.CH1.SRCADDR0 = (( (uint16_t) &SPIC.DATA) >> 0) & 0xFF; //Source address is ADC + DMA.CH1.SRCADDR1 = (( (uint16_t) &SPIC.DATA) >> 8) & 0xFF; + DMA.CH1.SRCADDR2 = 0x00; + + DMA.CH1.DESTADDR0 = (( (uint16_t) &isoBuf[PACKET_SIZE]) >> 0) & 0xFF; //Dest address is isoBuf + DMA.CH1.DESTADDR1 = (( (uint16_t) &isoBuf[PACKET_SIZE]) >> 8) & 0xFF; + DMA.CH1.DESTADDR2 = 0x00; + + tiny_calibration_synchronise_phase(500, 200); + median_TRFCNT = 200; + median_TRFCNT_delay = 1; //Wait a few frames before actually setting median_TRFCNT, in case a SOF interrupt was queued during tiny_dma_set_mode_xxx. + DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + DMA.CH1.CTRLA |= DMA_CH_ENABLE_bm; //Enable! +} + +void tiny_dma_loop_mode_4(void){ +return; +} + + +void tiny_dma_set_mode_5(void){ + while(1); //Deliberate Crash! Mode 5 should be invalid. +} + +void tiny_dma_set_mode_6(void){ + + global_mode = 6; + + tiny_dma_flush(); + + DMA.CH2.REPCNT = 0; //Repeat forever! + DMA.CH2.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; + DMA.CH2.CTRLB = 0x00; //Hi interrupt on block complete + DMA.CH2.ADDRCTRL = DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_SRCRELOAD_BLOCK_gc | DMA_CH_SRCDIR_INC_gc; //Dest reloads after each burst, with byte incrementing. Src reloads at end of block, also incrementing address. + DMA.CH2.TRIGSRC = DMA_CH_TRIGSRC_EVSYS_CH2_gc; //Triggered from TCC0 when it hits PER + DMA.CH2.TRFCNT = dacBuf_len; + + DMA.CH2.SRCADDR0 = (( (uint16_t) &dacBuf_CH1[0]) >> 0) & 0xFF; //Source address is dacbuf + DMA.CH2.SRCADDR1 = (( (uint16_t) &dacBuf_CH1[0]) >> 8) & 0xFF; + DMA.CH2.SRCADDR2 = 0x00; + + DMA.CH2.DESTADDR0 = (( (uint16_t) &DACB.CH0DATAH) >> 0) & 0xFF; //Dest address is high byte of DAC register + DMA.CH2.DESTADDR1 = (( (uint16_t) &DACB.CH0DATAH) >> 8) & 0xFF; + DMA.CH2.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH2.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + + DMA.CH3.REPCNT = 0; //Repeat forever! + DMA.CH3.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; + DMA.CH3.CTRLB = 0x00; //No interrupt for DacBuf!! + DMA.CH3.ADDRCTRL = DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_SRCRELOAD_BLOCK_gc | DMA_CH_SRCDIR_INC_gc; //Dest reloads after each burst, with byte incrementing. Src reloads at end of block, also incrementing address. + DMA.CH3.TRIGSRC = DMA_CH_TRIGSRC_EVSYS_CH1_gc; //Triggered from TCC0 when it hits PER + DMA.CH3.TRFCNT = auxDacBufLen; + + DMA.CH3.SRCADDR0 = (( (uint16_t) &dacBuf_CH2[0]) >> 0) & 0xFF; //Source address is dacbuf + DMA.CH3.SRCADDR1 = (( (uint16_t) &dacBuf_CH2[0]) >> 8) & 0xFF; + DMA.CH3.SRCADDR2 = 0x00; + + DMA.CH3.DESTADDR0 = (( (uint16_t) &DACB.CH1DATAH) >> 0) & 0xFF; //Dest address is high byte of DAC register + DMA.CH3.DESTADDR1 = (( (uint16_t) &DACB.CH1DATAH) >> 8) & 0xFF; + DMA.CH3.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH3.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + + DMA.CH0.CTRLA = 0x00; + DMA.CH0.CTRLA = DMA_CH_RESET_bm; + + DMA.CH0.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; + DMA.CH0.CTRLB = 0x00; //No interrupt! + DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_DESTRELOAD_BLOCK_gc; //Source reloads after each burst, with byte incrementing. Dest does not reload, but does increment address. + DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_ADCA_CH0_gc; //Triggered from ADCA channel 0 + DMA.CH0.TRFCNT = BUFFER_SIZE; + + DMA.CH0.SRCADDR0 = (( (uint16_t) &ADCA.CH0.RESL) >> 0) & 0xFF; //Source address is ADC + DMA.CH0.SRCADDR1 = (( (uint16_t) &ADCA.CH0.RESL) >> 8) & 0xFF; + DMA.CH0.SRCADDR2 = 0x00; + + DMA.CH0.DESTADDR0 = (( (uint16_t) &isoBuf[0]) >> 0) & 0xFF; //Dest address is isoBuf + DMA.CH0.DESTADDR1 = (( (uint16_t) &isoBuf[0]) >> 8) & 0xFF; + DMA.CH0.DESTADDR2 = 0x00; + + tiny_calibration_synchronise_phase(500, 200); + median_TRFCNT = 400; + median_TRFCNT_delay = 1; //Wait a few frames before actually setting median_TRFCNT, in case a SOF interrupt was queued during tiny_dma_set_mode_xxx. + DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + + +} + +void tiny_dma_loop_mode_6(void){ + return; +} + +void tiny_dma_set_mode_7(void){ + + global_mode = 7; + + tiny_dma_flush(); + + DMA.CH2.REPCNT = 0; //Repeat forever! + DMA.CH2.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; + DMA.CH2.CTRLB = 0x00; //Hi interrupt on block complete + DMA.CH2.ADDRCTRL = DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_SRCRELOAD_BLOCK_gc | DMA_CH_SRCDIR_INC_gc; //Dest reloads after each burst, with byte incrementing. Src reloads at end of block, also incrementing address. + DMA.CH2.TRIGSRC = DMA_CH_TRIGSRC_EVSYS_CH2_gc; //Triggered from TCC0 when it hits PER + DMA.CH2.TRFCNT = dacBuf_len; + + DMA.CH2.SRCADDR0 = (( (uint16_t) &dacBuf_CH1[0]) >> 0) & 0xFF; //Source address is dacbuf + DMA.CH2.SRCADDR1 = (( (uint16_t) &dacBuf_CH1[0]) >> 8) & 0xFF; + DMA.CH2.SRCADDR2 = 0x00; + + DMA.CH2.DESTADDR0 = (( (uint16_t) &DACB.CH0DATAH) >> 0) & 0xFF; //Dest address is high byte of DAC register + DMA.CH2.DESTADDR1 = (( (uint16_t) &DACB.CH0DATAH) >> 8) & 0xFF; + DMA.CH2.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH2.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + + DMA.CH3.REPCNT = 0; //Repeat forever! + DMA.CH3.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; + DMA.CH3.CTRLB = 0x00; //No interrupt for DacBuf!! + DMA.CH3.ADDRCTRL = DMA_CH_DESTRELOAD_BURST_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_SRCRELOAD_BLOCK_gc | DMA_CH_SRCDIR_INC_gc; //Dest reloads after each burst, with byte incrementing. Src reloads at end of block, also incrementing address. + DMA.CH3.TRIGSRC = DMA_CH_TRIGSRC_EVSYS_CH1_gc; //Triggered from TCC0 when it hits PER + DMA.CH3.TRFCNT = auxDacBufLen; + + DMA.CH3.SRCADDR0 = (( (uint16_t) &dacBuf_CH2[0]) >> 0) & 0xFF; //Source address is dacbuf + DMA.CH3.SRCADDR1 = (( (uint16_t) &dacBuf_CH2[0]) >> 8) & 0xFF; + DMA.CH3.SRCADDR2 = 0x00; + + DMA.CH3.DESTADDR0 = (( (uint16_t) &DACB.CH1DATAH) >> 0) & 0xFF; //Dest address is high byte of DAC register + DMA.CH3.DESTADDR1 = (( (uint16_t) &DACB.CH1DATAH) >> 8) & 0xFF; + DMA.CH3.DESTADDR2 = 0x00; + + //Must enable last for REPCNT won't work! + DMA.CH3.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + + DMA.CH0.CTRLA = 0x00; + DMA.CH0.CTRLA = DMA_CH_RESET_bm; + + DMA.CH0.CTRLA = DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_SINGLE_bm | DMA_CH_REPEAT_bm; //Do not repeat! + DMA.CH0.CTRLB = 0x00; //No interrupt! + DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_BURST_gc | DMA_CH_SRCDIR_INC_gc | DMA_CH_DESTDIR_INC_gc | DMA_CH_DESTRELOAD_BLOCK_gc; //Source reloads after each burst, with byte incrementing. Dest does not reload, but does increment address. + DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_ADCA_CH0_gc; //Triggered from ADCA channel 0 + DMA.CH0.TRFCNT = BUFFER_SIZE; + + DMA.CH0.SRCADDR0 = (( (uint16_t) &ADCA.CH0.RESL) >> 0) & 0xFF; //Source address is ADC + DMA.CH0.SRCADDR1 = (( (uint16_t) &ADCA.CH0.RESL) >> 8) & 0xFF; + DMA.CH0.SRCADDR2 = 0x00; + + DMA.CH0.DESTADDR0 = (( (uint16_t) &isoBuf[0]) >> 0) & 0xFF; //Dest address is isoBuf + DMA.CH0.DESTADDR1 = (( (uint16_t) &isoBuf[0]) >> 8) & 0xFF; + DMA.CH0.DESTADDR2 = 0x00; + + tiny_calibration_synchronise_phase(500, 200); + median_TRFCNT = 400; + median_TRFCNT_delay = 1; //Wait a few frames before actually setting median_TRFCNT, in case a SOF interrupt was queued during tiny_dma_set_mode_xxx. + DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm; //Enable! + +} + +void tiny_dma_loop_mode_7(void){ +} + +ISR(DMA_CH0_vect){ + DMA.INTFLAGS = 0x01; + //dma_ch0_ran++; + //uds.dma_ch0_cntL = dma_ch0_ran & 0xff; + //uds.dma_ch0_cntH = (dma_ch0_ran >> 8) & 0xff; + + #ifdef SINGLE_ENDPOINT_INTERFACE + DMA.CH0.CTRLA = 0x00; + DMA.CH0.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm; //Do not repeat! + DMA.CH0.TRFCNT = HALFPACKET_SIZE; + + short ptr = usb_state ? 0 : PACKET_SIZE; + + DMA.CH0.DESTADDR0 = (( (uint16_t) &isoBuf[ptr]) >> 0) & 0xFF; //Dest address is isoBuf + DMA.CH0.DESTADDR1 = (( (uint16_t) &isoBuf[ptr]) >> 8) & 0xFF; + + DMA.CH0.CTRLA |= DMA_CH_ENABLE_bm; + #endif +} + +ISR(DMA_CH1_vect){ + DMA.INTFLAGS = 0x02; + //dma_ch1_ran++; + //uds.dma_ch1_cntL = dma_ch1_ran & 0xff; + //uds.dma_ch1_cntH = (dma_ch1_ran >> 8) & 0xff; + +#ifdef SINGLE_ENDPOINT_INTERFACE + DMA.CH1.CTRLA = 0x00; + DMA.CH1.CTRLA = DMA_CH_BURSTLEN_1BYTE_gc | DMA_CH_SINGLE_bm; //Do not repeat! + DMA.CH1.TRFCNT = HALFPACKET_SIZE; + + short ptr = usb_state ? HALFPACKET_SIZE : PACKET_SIZE + HALFPACKET_SIZE; + + DMA.CH1.DESTADDR0 = (( (uint16_t) &isoBuf[ptr]) >> 0) & 0xFF; //Dest address is isoBuf + DMA.CH1.DESTADDR1 = (( (uint16_t) &isoBuf[ptr]) >> 8) & 0xFF; + + DMA.CH1.CTRLA |= DMA_CH_ENABLE_bm; + #endif +} diff --git a/AVR Code/USB_BULK_TEST/src/tiny_dma.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_dma.c.REMOVED.git-id deleted file mode 100644 index 95849edc..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_dma.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -50e1baf0e521d270b1e897f86c32924d1deb9f60 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_dma.h b/AVR Code/USB_BULK_TEST/src/tiny_dma.h new file mode 100644 index 00000000..a0f8885b --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_dma.h @@ -0,0 +1,45 @@ +/* + * tiny_dma.h + * + * Created: 25/06/2015 9:01:15 AM + * Author: Esposch + */ + + +#ifndef TINY_DMA_H_ +#define TINY_DMA_H_ + +#include +#include +#include "globals.h" + +void tiny_dma_setup(void); +void tiny_dma_flush(void); + +void tiny_dma_set_mode_0(void); +void tiny_dma_loop_mode_0(void); + +void tiny_dma_set_mode_1(void); +void tiny_dma_loop_mode_1(void); + +void tiny_dma_set_mode_2(void); +void tiny_dma_loop_mode_2(void); + +void tiny_dma_set_mode_3(void); +void tiny_dma_loop_mode_3(void); + +void tiny_dma_set_mode_4(void); +void tiny_dma_loop_mode_4(void); + +void tiny_dma_set_mode_5(void); + +void tiny_dma_set_mode_6(void); +void tiny_dma_loop_mode_6(void); + +void tiny_dma_set_mode_7(void); +void tiny_dma_loop_mode_7(void); + +void tiny_dma_delayed_set(unsigned char mode); + + +#endif /* TINY_DMA_H_ */ \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_dma.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_dma.h.REMOVED.git-id deleted file mode 100644 index 73ec9a55..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_dma.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a0f8885b223d04a6b4d9cef5a8fe0b1226e34e8d \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_eeprom.c b/AVR Code/USB_BULK_TEST/src/tiny_eeprom.c new file mode 100644 index 00000000..0d909f8f --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_eeprom.c @@ -0,0 +1,25 @@ +/* + * tiny_eeprom.c + * + * Created: 22/04/2017 12:37:21 PM + * Author: Esposch + */ +#include +#include "tiny_eeprom.h" + +void eeprom_safe_read(){ + unsigned char previous_clk_settings = CLK.PSCTRL; + CLK.PSCTRL = CLK_PSADIV4_bm; //Slow down the clock to prevent EEPROM misses + nvm_eeprom_read_buffer(EEPROM_CURRENT_PAGE*EEPROM_PAGE_SIZE, eeprom_buffer_read, EEPROM_PAGE_SIZE); + CLK.PSCTRL = previous_clk_settings; + return; +} + +void eeprom_safe_write(){ + unsigned char previous_clk_settings = CLK.PSCTRL; + CLK.PSCTRL = CLK_PSADIV4_bm; //Slow down the clock to prevent EEPROM misses + nvm_eeprom_load_page_to_buffer(eeprom_buffer_write); + nvm_eeprom_atomic_write_page(EEPROM_CURRENT_PAGE); + CLK.PSCTRL = previous_clk_settings; + return; +} diff --git a/AVR Code/USB_BULK_TEST/src/tiny_eeprom.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_eeprom.c.REMOVED.git-id deleted file mode 100644 index 79f29699..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_eeprom.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0d909f8fdcd02d8cd8c9a24ddab57ac01ff9af46 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_eeprom.h b/AVR Code/USB_BULK_TEST/src/tiny_eeprom.h new file mode 100644 index 00000000..013c633c --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_eeprom.h @@ -0,0 +1,20 @@ +/* + * tiny_eeprom.h + * + * Created: 22/04/2017 12:37:34 PM + * Author: Esposch + */ + + +#ifndef TINY_EEPROM_H_ +#define TINY_EEPROM_H_ + +#define EEPROM_CURRENT_PAGE 1 + +void eeprom_safe_read(); +void eeprom_safe_write(); +extern volatile unsigned char eeprom_buffer_write[EEPROM_PAGE_SIZE]; +extern volatile unsigned char eeprom_buffer_read[EEPROM_PAGE_SIZE]; + + +#endif /* TINY_EEPROM_H_ */ \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_eeprom.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_eeprom.h.REMOVED.git-id deleted file mode 100644 index 3e527679..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_eeprom.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -013c633cbe8894ab8d5cab1e70d618f077048e21 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_timer.c b/AVR Code/USB_BULK_TEST/src/tiny_timer.c new file mode 100644 index 00000000..95c8a9df --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_timer.c @@ -0,0 +1,80 @@ +/* + * tiny_timercounter.c + * + * Created: 2/07/2015 10:50:11 AM + * Author: Esposch + */ + +#include "tiny_timer.h" +#include "globals.h" + +#define PSU_PER 2048 +#define jump 6 + +void tiny_timer_setup(void){ + //Turn everything on! + PR.PRPC &= 0b11111100; //Enable TCC0, TCC1 + PR.PRPD &= 0b11111100; //Enable TCD0, TCD1 + PR.PRGEN &= 0b11111101; //Enable EVSYS + + //Set up EVSYS + EVSYS.CH2MUX = TCDAC_OVF; + EVSYS.CH2CTRL = 0x00; //No filtering or Quadrature stuff + + EVSYS.CH1MUX = TCDAC_AUX_OVF; + EVSYS.CH1CTRL = 0x00; //No filtering or Quadrature stuff + + //Waveform (50Hz sin wave) + TC_DAC.CTRLA = 0x04; //Some clk setting - not 100% sure since it was SW generated + TC_DAC.CTRLB = TC_WGMODE_SINGLESLOPE_gc; //No enable is set + TC_DAC.CTRLE = TC_BYTEM_NORMAL_gc; + TC_DAC.PER = 469; + TC_DAC.INTCTRLA = 0x00; + //Aux channel (blank 50Hz) + TC_AUXDAC.CTRLA = 0x04; //Some clk setting - not 100% sure since it was SW generated + TC_AUXDAC.CTRLB = TC_WGMODE_SINGLESLOPE_gc; //No enable is set + TC_AUXDAC.CTRLE = TC_BYTEM_NORMAL_gc; + TC_AUXDAC.PER = 469; + TC_AUXDAC.INTCTRLA = 0x00; + + //PSU + PORTD.DIR |= 0b00010000; + TC_PSU.CTRLB = 0x10 | TC_WGMODE_SINGLESLOPE_gc; //CCAEN is set + TC_PSU.CTRLE = TC_BYTEM_NORMAL_gc; + TC_PSU.INTCTRLA = TC_OVFINTLVL_MED_gc; + TC_PSU.PER = PSU_PER; // Max value of CNT + TC_PSU.CCA = 0; //Initial Duty cycle of 0% + TC_PSU.CTRLA = TC_CLKSEL_DIV1_gc; + /* + //PSU "PID"loop + TCC1.CTRLB = 0x00 | TC_WGMODE_SINGLESLOPE_gc; + TCC1.INTCTRLA = TC_OVFINTLVL_LO_gc; + TCC1.CTRLE = TC_BYTEM_NORMAL_gc; + TCC1.PER = 1800; // Max value of CNT + TCC1.CTRLA = TC_CLKSEL_DIV1_gc; + */ +} + +ISR(TC_PSU_OVF){ + char tempvar; + char err; + volatile char nothing; + TC_PSU.INTFLAGS = 0xff; + if (global_mode == 7){ + nothing = ADCA.CH1.RESL; + tempvar = ADCA.CH1.RESH; + } + else{ + tempvar = ADCA.CH1.RESL; + } + //tempvar = (global_mode == 7 ? (char) ADCA.CH1.RESH : (char) ADCA.CH1.RESL); + //test_byte = tempvar; + + err = (char) (PSU_target - tempvar); + if ((err > 1) & ((unsigned short) TC_PSU.CCA < PSU_PER - jump) ){ + TC_PSU.CCABUF = TC_PSU.CCA + ((err > 8) ? jump : 1); + } + else if ((err < -1) & ((unsigned short) TC_PSU.CCA > jump)){ + TC_PSU.CCABUF = TC_PSU.CCA - ((err < -8) ? jump : 1); + } +} \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_timer.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_timer.c.REMOVED.git-id deleted file mode 100644 index 6589a994..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_timer.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -95c8a9df507735073bcbdc1688858b9a52c38def \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_timer.h b/AVR Code/USB_BULK_TEST/src/tiny_timer.h new file mode 100644 index 00000000..ed5a0ab5 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_timer.h @@ -0,0 +1,19 @@ +/* + * tiny_timercounter.h + * + * Created: 2/07/2015 10:49:59 AM + * Author: Esposch + */ + +#include +#include + +#ifndef TINY_TIMER_H_ +#define TINY_TIMER_H_ + +void tiny_timer_setup(void); +void tiny_spi_setup(void); + + + +#endif /* TINY_TIMERCOUNTER_H_ */ \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_timer.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_timer.h.REMOVED.git-id deleted file mode 100644 index bcbc4ad9..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_timer.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ed5a0ab56eb78ad59979793688a6bdc872248b18 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_uart.c b/AVR Code/USB_BULK_TEST/src/tiny_uart.c new file mode 100644 index 00000000..a30ce551 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_uart.c @@ -0,0 +1,59 @@ +/* + * tiny_uart.c + * + * Created: 16/07/2015 6:32:52 PM + * Author: Esposch + */ + +#include "tiny_uart.h" +#include "globals.h" + + +void tiny_uart_setup(void){ + PR.PRPC &= 0b11101111; + //PR.PRPE &= 0b11111110; ??? + + PORTC.DIR |= 0b10101010; + PORTC.OUT = 0xff; + PORTC.PIN2CTRL = PORT_INVEN_bm | PORT_OPC_PULLUP_gc; + //PORTC.REMAP = 0x10; //Remap USART to [7:4] + //#ifndef VERO +// PORTC.REMAP = 0x20; //Swap MOSI and SCK - for small boards only!!! + //#endif + + USARTC0.CTRLA = USART_RXCINTLVL_HI_gc; + USARTC0.CTRLC = USART_CMODE_MSPI_gc | 0b00000100; //LSB received first, UPCHA disabled + #if OVERCLOCK == 48 + USARTC0.BAUDCTRLA = 7; //BSEL = fper/(2fbaud) -1; 48/(2*3) - 1 = 7 + #else + USARTC0.BAUDCTRLA = 3; //BSEL = fper/(2fbaud) -1; 24/(2*3) - 1 = 3 + #endif + USARTC0.BAUDCTRLB = 0x00;// USART_BSCALE0_bm goes to 1.5MHz for some reason; + USARTC0.CTRLB = USART_RXEN_bm | USART_TXEN_bm; +} + + +void tiny_spi_setup(void){ + //Power Reduction disable + PR.PRPC &= 0b11110111; + + //SPI enable + SPIC.CTRL = SPI_ENABLE_bm; //Slave mode + SPIC.INTCTRL = SPI_INTLVL_OFF_gc; + //#ifdef VERO + PORTC.PIN5CTRL = PORT_INVEN_bm | PORT_OPC_PULLUP_gc; + //#else + // PORTC.PIN7CTRL = PORT_INVEN_bm | PORT_OPC_PULLUP_gc; //Pin5 if not swapped + //#endif + + return; +} + +ISR(SPIC_INT_vect){ + asm("nop"); +} + +ISR(USARTC0_RXC_vect){ + unsigned char temp = USARTC0.DATA; + USARTC0.DATA = temp; +} \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_uart.c.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_uart.c.REMOVED.git-id deleted file mode 100644 index ec2fe3f4..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_uart.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a30ce5517475366f225d4c5e018dfa23dda19da2 \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_uart.h b/AVR Code/USB_BULK_TEST/src/tiny_uart.h new file mode 100644 index 00000000..ec38ec38 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/tiny_uart.h @@ -0,0 +1,19 @@ +/* + * tiny_uart.h + * + * Created: 16/07/2015 6:33:02 PM + * Author: Esposch + */ + + +#ifndef TINY_UART_H_ +#define TINY_UART_H_ + +#include +#include + +void tiny_uart_setup(void); +void tiny_spi_setup(void); + + +#endif /* TINY_UART_H_ */ \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/tiny_uart.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/tiny_uart.h.REMOVED.git-id deleted file mode 100644 index 7f717ff3..00000000 --- a/AVR Code/USB_BULK_TEST/src/tiny_uart.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ec38ec3811d5f02be20c85db9df6bcceb96da92f \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/ui.h b/AVR Code/USB_BULK_TEST/src/ui.h new file mode 100644 index 00000000..2ac4dfa3 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/ui.h @@ -0,0 +1,73 @@ +/** + * \file + * + * \brief Common User Interface for USB vendor class application + * + * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +/* + * Support and FAQ: visit Atmel Support + */ + +#ifndef _UI_H_ +#define _UI_H_ + +//! \brief Initializes the user interface +void ui_init(void); + +//! \brief Enters the user interface in power down mode +void ui_powerdown(void); + +//! \brief Exits the user interface of power down mode +void ui_wakeup(void); + +/*! \brief Notify the state of loopback + * It is called when a the loopback is started and stopped. + * + * \param b_started loopback started if true, else stopped + */ +void ui_loop_back_state(bool b_started); + +/*! \brief This process is called each 1ms + * It is called only if the USB interface is enabled. + * + * \param framenumber Current frame number + */ +void ui_process(uint16_t framenumber); + +#endif // _UI_H_ diff --git a/AVR Code/USB_BULK_TEST/src/ui.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/ui.h.REMOVED.git-id deleted file mode 100644 index c0347c79..00000000 --- a/AVR Code/USB_BULK_TEST/src/ui.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2ac4dfa3221a08ea881ed695eb9b61bde1c5ca5b \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST/src/unified_debug_structure.h b/AVR Code/USB_BULK_TEST/src/unified_debug_structure.h new file mode 100644 index 00000000..199e4a91 --- /dev/null +++ b/AVR Code/USB_BULK_TEST/src/unified_debug_structure.h @@ -0,0 +1,38 @@ +/* + * unified_debug_structure.h + * + * Created: 1/02/2017 9:38:31 AM + * Author: Esposch + */ + + +#ifndef UNIFIED_DEBUG_STRUCTURE_H_ +#define UNIFIED_DEBUG_STRUCTURE_H_ + +#include + +//EVERYTHING MUST BE SENT ONE BYTE AT A TIME, HIGH AND LOW BYTES SEPARATE, IN ORDER TO AVOID ISSUES WITH ENDIANNESS. +typedef struct uds{ + volatile char header[9]; + volatile uint8_t trfcntL0; + volatile uint8_t trfcntH0; + volatile uint8_t trfcntL1; + volatile uint8_t trfcntH1; + volatile uint8_t medianTrfcntL; + volatile uint8_t medianTrfcntH; + volatile uint8_t calValNeg; + volatile uint8_t calValPos; + volatile uint8_t CALA; + volatile uint8_t CALB; + volatile uint8_t outOfRangeL; + volatile uint8_t outOfRangeH; + volatile uint8_t counterL; + volatile uint8_t counterH; + volatile uint8_t dma_ch0_cntL; + volatile uint8_t dma_ch0_cntH; + volatile uint8_t dma_ch1_cntL; + volatile uint8_t dma_ch1_cntH; + +} unified_debug; + +#endif /* UNIFIED_DEBUG_STRUCTURE_H_ */ diff --git a/AVR Code/USB_BULK_TEST/src/unified_debug_structure.h.REMOVED.git-id b/AVR Code/USB_BULK_TEST/src/unified_debug_structure.h.REMOVED.git-id deleted file mode 100644 index 3bd55b8a..00000000 --- a/AVR Code/USB_BULK_TEST/src/unified_debug_structure.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -199e4a916b325ca33358adcf8f2fc63f67fe04ae \ No newline at end of file diff --git a/AVR Code/USB_BULK_TEST_6_2.atsln.REMOVED.git-id b/AVR Code/USB_BULK_TEST_6_2.atsln.REMOVED.git-id deleted file mode 100644 index 36bcbc42..00000000 --- a/AVR Code/USB_BULK_TEST_6_2.atsln.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2f780e8c37a5793d6957573a02eb53faa5e20ad7 \ No newline at end of file diff --git a/Desktop_Interface/.DS_Store.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/.DS_Store.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 1ce1bea2..00000000 --- a/Desktop_Interface/.DS_Store.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0043d09029c61620757ad386a48686e338c9dbaf \ No newline at end of file diff --git a/Desktop_Interface/._.DS_Store.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/._.DS_Store.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 95175ab4..00000000 --- a/Desktop_Interface/._.DS_Store.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -301d01b13096dca1cd26a9b8830a99612aa2553b \ No newline at end of file diff --git a/Desktop_Interface/.qmake.stash.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/.qmake.stash.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 4b390d9e..00000000 --- a/Desktop_Interface/.qmake.stash.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4a612239348db9cc466ad5e3f8783ebe3b7bc25b \ No newline at end of file diff --git a/Desktop_Interface/Labrador.pro b/Desktop_Interface/Labrador.pro new file mode 100644 index 00000000..e99908ce --- /dev/null +++ b/Desktop_Interface/Labrador.pro @@ -0,0 +1,276 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2016-03-30T13:27:52 +# +#------------------------------------------------- + + +############################################################################ +######CLEAN->RUN QMAKE->BUILD after changing anything on this page!!!###### +########################################################################## + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport + +TARGET = Labrador +TEMPLATE = app + +QCP_VER = 1 +DEFINES += "QCP_VER=$${QCP_VER}" +equals(QCP_VER,"2"){ + DEFINES += QCUSTOMPLOT_USE_OPENGL + message("Using QCP2 with OpenGL support") +} + +include(ui_elements.pri) + +MOC_DIR = $$PWD/moc + +SOURCES += main.cpp\ + mainwindow.cpp \ + functiongencontrol.cpp \ + isodriver.cpp \ + isobuffer.cpp \ + desktop_settings.cpp \ + scoperangeenterdialog.cpp \ + genericusbdriver.cpp \ + isobufferbuffer.cpp + +HEADERS += mainwindow.h \ + functiongencontrol.h \ + xmega.h \ + isodriver.h \ + isobuffer.h \ + desktop_settings.h \ + scoperangeenterdialog.h \ + genericusbdriver.h \ + isobufferbuffer.h \ + q_debugstream.h \ + unified_debug_structure.h + +android:{ +FORMS += ui_files_mobile/mainwindow.ui \ + ui_files_mobile/scoperangeenterdialog.ui +} + +!android:{ +FORMS += ui_files_desktop/mainwindow.ui \ + ui_files_desktop/scoperangeenterdialog.ui +} + + +RESOURCES += \ + resources.qrc + +DESTDIR = bin + +RC_ICONS = appicon.ico + +INCLUDEPATH += $$PWD/ui_elements +DEPENDPATH += $$PWD/ui_elements + + +########################################################### +################ WINDOWS BUILD ONLY ################ +######################################################### + +win32{ + INCLUDEPATH += $$PWD/build_win + SOURCES += winusbdriver.cpp + HEADERS += winusbdriver.h + + #libusbk include + contains(QT_ARCH, i386) { + message("Building for Windows (x86)") + CONFIG(release, debug|release): LIBS += -L$$PWD/build_win/libusbk/bin/lib/x86/ -llibusbK + else:CONFIG(debug, debug|release): LIBS += -L$$PWD/build_win/libusbk/bin/lib/x86/ -llibusbK + } else { + message("Building for Windows (x64)") + CONFIG(release, debug|release): LIBS += -L$$PWD/build_win/libusbk/bin/lib/amd64/ -llibusbK + else:CONFIG(debug, debug|release): LIBS += -L$$PWD/build_win/libusbk/bin/lib/amd64/ -llibusbK + } + INCLUDEPATH += $$PWD/build_win/libusbk/includes + DEPENDPATH += $$PWD/build/win/libusbk/includes + DEFINES += PLATFORM_WINDOWS +} + +############################################################# +################ GNU/LINUX BUILD ONLY ################ +########################################################### + +unix:!android:!macx{ + INCLUDEPATH += $$PWD/build_linux + contains(QT_ARCH, arm) { + message("Building for Raspberry Pi") + #libusb include + unix:!android:!macx:LIBS += -lusb-1.0 ##make sure you have the libusb-1.0-0-dev package! + unix:!android:!macx:INCLUDEPATH += build_linux/libusb + unix:!android:!macx:DEPENDPATH += build_linux/libusb + + #libdfuprog include + unix:!android:!macx:LIBS += -L$$PWD/build_linux/libdfuprog/lib/arm -ldfuprog-0.9 + unix:!android:!macx:INCLUDEPATH += $$PWD/build_linux/libdfuprog/include + unix:!android:!macx:DEPENDPATH += $$PWD/build_linux/libdfuprog/include + QMAKE_CFLAGS += -fsigned-char + QMAKE_CXXFLAGS += -fsigned-char + DEFINES += "PLATFORM_RASPBERRY_PI" + #All ARM-Linux GCC treats char as unsigned by default??? + } else { + contains(QT_ARCH, i386) { + message("Building for Linux (x86)") + unix:!android:!macx:LIBS += -lusb-1.0 ##make sure you have the libusb-1.0-0-dev package! + unix:!android:!macx:INCLUDEPATH += build_linux/libusb + unix:!android:!macx:DEPENDPATH += build_linux/libusb + + #libdfuprog include + unix:!android:!macx:LIBS += -L$$PWD/build_linux/libdfuprog/lib/x86 -ldfuprog-0.9 + unix:!android:!macx:INCLUDEPATH += $$PWD/build_linux/libdfuprog/include + unix:!android:!macx:DEPENDPATH += $$PWD/build_linux/libdfuprog/include + } else { + message("Building for Linux (x64)") + #libusb include + unix:!android:!macx:LIBS += -Lbuild_linux/libusb -lusb-1.0 ##I suspect the -L here does nothing! + unix:!android:!macx:INCLUDEPATH += build_linux/libusb + unix:!android:!macx:DEPENDPATH += build_linux/libusb + + #libdfuprog include + unix:!android:!macx:LIBS += -L$$PWD/build_linux/libdfuprog/lib/x64 -ldfuprog-0.9 + unix:!android:!macx:INCLUDEPATH += $$PWD/build_linux/libdfuprog/include + unix:!android:!macx:DEPENDPATH += $$PWD/build_linux/libdfuprog/include + } + } +} + + + +############################################################# +################ MAC OSX BUILD ONLY ################## +########################################################### + +macx:INCLUDEPATH += $$PWD/build_mac + +#libusb dylib include +macx:LIBS += -L$$PWD/build_mac/libusb/lib -lusb-1.0 +macx:INCLUDEPATH += $$PWD/build_mac/libusb/include/libusb-1.0 +macx:DEPENDPATH += $$PWD/build_mac/libusb/include/libusb-1.0 + +#libdfuprog dylib include +macx:LIBS += -L$$PWD/build_mac/libdfuprog/lib -ldfuprog-0.9 +macx:INCLUDEPATH += $$PWD/build_mac/libdfuprog/include +macx:DEPENDPATH += $$PWD/build_mac/libdfuprog/include + +macx:QMAKE_LFLAGS += "-undefined dynamic_lookup" + +QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.10 + + + + +############################################################# +######## SHARED UNIX-LIKE BUILDS (MAC + LINUX) ######### +########################################################### + +unix:SOURCES += unixusbdriver.cpp +unix:HEADERS += unixusbdriver.h + +############################################################# +######## SHARED ANDROID/LINUX GCC FLAGS ######### +########################################################### + +unix:!macx: QMAKE_CXXFLAGS_RELEASE -= -O0 +unix:!macx: QMAKE_CXXFLAGS_RELEASE -= -O1 +unix:!macx: QMAKE_CXXFLAGS_RELEASE -= -O2 +unix:!macx: QMAKE_CXXFLAGS_RELEASE -= -O3 + +android: QMAKE_CXXFLAGS_RELEASE -= -O0 +android: QMAKE_CXXFLAGS_RELEASE -= -O1 +android: QMAKE_CXXFLAGS_RELEASE -= -O2 +android: QMAKE_CXXFLAGS_RELEASE -= -O3 +android: QMAKE_CXXFLAGS_RELEASE -= -Os + + +android: QMAKE_CFLAGS_RELEASE -= -O0 +android: QMAKE_CFLAGS_RELEASE -= -O1 +android: QMAKE_CFLAGS_RELEASE -= -O2 +android: QMAKE_CFLAGS_RELEASE -= -O3 +android: QMAKE_CFLAGS_RELEASE -= -Os + + +############################################################# +################# ANDROID BUILD ONLY ################# +########################################################### + +android:{ + QMAKE_CFLAGS += -fsigned-char + QMAKE_CXXFLAGS += -fsigned-char + #Android treats char as unsigned by default (why???) + + QT += androidextras + CONFIG += mobility + MOBILITY = + + INCLUDEPATH += $$PWD/build_android + SOURCES += androidusbdriver.cpp + HEADERS += androidusbdriver.h + INCLUDEPATH += $$PWD/build_android/libusb-martin-kuldeep + DEPENDPATH += $$PWD/build_android/libusb-martin-kuldeep + + ANDROID_PACKAGE_SOURCE_DIR = $$PWD/build_android/package_source + assets_deploy.files=$$files($$PWD/build_android/package_source/assets/*) + assets_deploy.path=/assets + INSTALLS += asssets_deploy + + #libdfuprog include + LIBS += -L$$PWD/build_android/libdfuprog/lib -ldfuprog-0.9 + INCLUDEPATH += $$PWD/build_android/libdfuprog/include + DEPENDPATH += $$PWD/build_android/libdfuprog/include + ANDROID_EXTRA_LIBS += $${PWD}/build_android/libdfuprog/lib/libdfuprog-0.9.so + + #liblog include + LIBS += -L$$PWD/build_android/liblog/lib -llog + ANDROID_EXTRA_LIBS += $${PWD}/build_android/liblog/lib/liblog.so + + + + DISTFILES += \ + build_android/package_source/AndroidManifest.xml \ + build_android/package_source/gradle/wrapper/gradle-wrapper.jar \ + build_android/package_source/gradlew \ + build_android/package_source/res/values/libs.xml \ + build_android/package_source/build.gradle \ + build_android/package_source/gradle/wrapper/gradle-wrapper.properties \ + build_android/package_source/gradlew.bat \ + build_android/package_source/AndroidManifest.xml \ + build_android/package_source/res/values/libs.xml \ + build_android/package_source/build.gradle \ + build_android/package_source/src/androidInterface.java + + equals(ANDROID_TARGET_ARCH, armeabi-v7a){ + message("qmake building for Android (ARM) platform") + LIBS += -L$${PWD}\build_android\libusb-martin-kuldeep\android\armeabi-v7a -lusb1.0 + ANDROID_EXTRA_LIBS += $${PWD}\build_android\libusb-martin-kuldeep\android\armeabi-v7a/libusb1.0.so + } + equals(ANDROID_TARGET_ARCH, x86){ + message("qmake building for Android (x86) platform") + LIBS += -L$$PWD/build_android/libusb-martin-kuldeep/android/x86 -lusb1.0 + ANDROID_EXTRA_LIBS += $$PWD/build_android/libusb-martin-kuldeep/android/x86/libusb1.0.so + } +} + +DISTFILES += \ + build_android/package_source/AndroidManifest.xml \ + build_android/package_source/gradle/wrapper/gradle-wrapper.jar \ + build_android/package_source/gradlew \ + build_android/package_source/res/values/libs.xml \ + build_android/package_source/build.gradle \ + build_android/package_source/gradle/wrapper/gradle-wrapper.properties \ + build_android/package_source/gradlew.bat \ + build_android/package_source/AndroidManifest.xml \ + build_android/package_source/gradle/wrapper/gradle-wrapper.jar \ + build_android/package_source/gradlew \ + build_android/package_source/res/values/libs.xml \ + build_android/package_source/build.gradle \ + build_android/package_source/gradle/wrapper/gradle-wrapper.properties \ + build_android/package_source/gradlew.bat \ + build_android/package_source/res/xml/device_filter.xml diff --git a/Desktop_Interface/Labrador.pro.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/Labrador.pro.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index aa9d46cb..00000000 --- a/Desktop_Interface/Labrador.pro.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b0fee96cf5a3b98a61d3849fa6acffc95a176d4e \ No newline at end of file diff --git a/Desktop_Interface/Labrador.pro.user.1aedbdd.18.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/Labrador.pro.user.1aedbdd.18.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index ed2ee8fc..00000000 --- a/Desktop_Interface/Labrador.pro.user.1aedbdd.18.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -07ecd6b63a55eb91ce8776f509cced90074280ed \ No newline at end of file diff --git a/Desktop_Interface/Labrador.pro.user.269d77a.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/Labrador.pro.user.269d77a.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 701d84f3..00000000 --- a/Desktop_Interface/Labrador.pro.user.269d77a.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b7ef363dd913a43e6a4d2f3206bd61cab0bf38eb \ No newline at end of file diff --git a/Desktop_Interface/Labrador.pro.user.418854c.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/Labrador.pro.user.418854c.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index e519b90d..00000000 --- a/Desktop_Interface/Labrador.pro.user.418854c.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -87d1314a1a7c0db5e976aa5d42ec8868380c32f9 \ No newline at end of file diff --git a/Desktop_Interface/Labrador.pro.user.4395d92.3.3-pre1.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/Labrador.pro.user.4395d92.3.3-pre1.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 95ad4626..00000000 --- a/Desktop_Interface/Labrador.pro.user.4395d92.3.3-pre1.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5d394806324a52cc05a5e80ab9929284abafcba0 \ No newline at end of file diff --git a/Desktop_Interface/Labrador.pro.user.5435f0c.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/Labrador.pro.user.5435f0c.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 5b692515..00000000 --- a/Desktop_Interface/Labrador.pro.user.5435f0c.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -22d2b5e3656787cb3f7132eb6ace5d838a3dc73c \ No newline at end of file diff --git a/Desktop_Interface/Labrador.pro.user.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/Labrador.pro.user.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 12a46d39..00000000 --- a/Desktop_Interface/Labrador.pro.user.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -97e2213c5b31ce16553ad120b2ea00c1680ea04f \ No newline at end of file diff --git a/Desktop_Interface/Labrador.pro.user.ab2277d.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/Labrador.pro.user.ab2277d.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 89f034a0..00000000 --- a/Desktop_Interface/Labrador.pro.user.ab2277d.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -20ae345c1e6dcac2457a19eee35d23a053399588 \ No newline at end of file diff --git a/Desktop_Interface/Labrador_libusbk_resource.rc.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/Labrador_libusbk_resource.rc.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 41c2fcc6..00000000 --- a/Desktop_Interface/Labrador_libusbk_resource.rc.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6a92256e38b1cb81f1ff87ea7ed966f2a89856d5 \ No newline at end of file diff --git a/Desktop_Interface/Labrador_resource.rc.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/Labrador_resource.rc.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index f68edbac..00000000 --- a/Desktop_Interface/Labrador_resource.rc.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -71c620008a1a6cddb196a905bfb807f7bebef968 \ No newline at end of file diff --git a/Desktop_Interface/Makefile.Debug.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/Makefile.Debug.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 0e3c32b0..00000000 --- a/Desktop_Interface/Makefile.Debug.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c75ee697a063e11b91c63f140e0b9dc404a7b66e \ No newline at end of file diff --git a/Desktop_Interface/Makefile.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/Makefile.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 4568c91b..00000000 --- a/Desktop_Interface/Makefile.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -209df9bf45c202a9c19d146b81f75787cfcf3baa \ No newline at end of file diff --git a/Desktop_Interface/Makefile.Release.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/Makefile.Release.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index b71618a9..00000000 --- a/Desktop_Interface/Makefile.Release.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6c9e5bb2fa306d9e51a9d6c8ea2304c19dc96186 \ No newline at end of file diff --git a/Desktop_Interface/Thumbs.db.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/Thumbs.db.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 69431f67..00000000 --- a/Desktop_Interface/Thumbs.db.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3fd92c0ddb2cf412720f6d7c5904f499dbe4459d \ No newline at end of file diff --git a/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/cache.properties.REMOVED.git-id b/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/cache.properties.REMOVED.git-id deleted file mode 100644 index 184e36c6..00000000 --- a/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/cache.properties.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -19631cf2dc406a2d9bb9a71bac354fa2eaf75c8c \ No newline at end of file diff --git a/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/cache.properties.lock.REMOVED.git-id b/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/cache.properties.lock.REMOVED.git-id deleted file mode 100644 index ef4d288a..00000000 --- a/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/cache.properties.lock.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -65acfb186c410095c763735cfb3200a0d1119a4e \ No newline at end of file diff --git a/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/fileHashes.bin.REMOVED.git-id b/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/fileHashes.bin.REMOVED.git-id deleted file mode 100644 index de7db0a2..00000000 --- a/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/fileHashes.bin.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4c67a17651306a71849c9db6c4519ebd32f57cce \ No newline at end of file diff --git a/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin.REMOVED.git-id b/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin.REMOVED.git-id deleted file mode 100644 index 67b90f21..00000000 --- a/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2cc6b5c5eea20cde3dbb0a305b2cdd2e01b1944b \ No newline at end of file diff --git a/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/outputFileStates.bin.REMOVED.git-id b/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/outputFileStates.bin.REMOVED.git-id deleted file mode 100644 index 75bca3d0..00000000 --- a/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/outputFileStates.bin.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f056a292c5f3a349b3265e1cbb313604e5082473 \ No newline at end of file diff --git a/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin.REMOVED.git-id b/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin.REMOVED.git-id deleted file mode 100644 index 3e57985d..00000000 --- a/Desktop_Interface/android-build/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -44c1e42e6f1e3979f94516adf1b0ec593e3a6418 \ No newline at end of file diff --git a/Desktop_Interface/android-build/AndroidManifest.xml.REMOVED.git-id b/Desktop_Interface/android-build/AndroidManifest.xml.REMOVED.git-id deleted file mode 100644 index 9d610b79..00000000 --- a/Desktop_Interface/android-build/AndroidManifest.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -778be5ebea55e51b0cdd65420f001794548fa0a5 \ No newline at end of file diff --git a/Desktop_Interface/android-build/AndroidManifest.xml.autosave.REMOVED.git-id b/Desktop_Interface/android-build/AndroidManifest.xml.autosave.REMOVED.git-id deleted file mode 100644 index 81d1a2ec..00000000 --- a/Desktop_Interface/android-build/AndroidManifest.xml.autosave.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -45804aa388539188d4d2df6fde2d841edd5f2bf6 \ No newline at end of file diff --git a/Desktop_Interface/android-build/assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list.REMOVED.git-id b/Desktop_Interface/android-build/assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list.REMOVED.git-id deleted file mode 100644 index c936d71a..00000000 --- a/Desktop_Interface/android-build/assets/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3668bf657139054c49a4692fa32094510495a915 \ No newline at end of file diff --git a/Desktop_Interface/android-build/assets/firmware/labrafirm_0003_01.hex.REMOVED.git-id b/Desktop_Interface/android-build/assets/firmware/labrafirm_0003_01.hex.REMOVED.git-id deleted file mode 100644 index b3667a22..00000000 --- a/Desktop_Interface/android-build/assets/firmware/labrafirm_0003_01.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f7946fd762c2bf7eaa4b76d5eb68948870244c19 \ No newline at end of file diff --git a/Desktop_Interface/android-build/assets/firmware/labrafirm_0003_02.hex.REMOVED.git-id b/Desktop_Interface/android-build/assets/firmware/labrafirm_0003_02.hex.REMOVED.git-id deleted file mode 100644 index 42c42b45..00000000 --- a/Desktop_Interface/android-build/assets/firmware/labrafirm_0003_02.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -879125a9685d89a7f05bd38994079919338f49b6 \ No newline at end of file diff --git a/Desktop_Interface/android-build/assets/waveforms/DC.tlw.REMOVED.git-id b/Desktop_Interface/android-build/assets/waveforms/DC.tlw.REMOVED.git-id deleted file mode 100644 index e3326948..00000000 --- a/Desktop_Interface/android-build/assets/waveforms/DC.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -69f322d2c3c6452561c8232b20784828fc438399 \ No newline at end of file diff --git a/Desktop_Interface/android-build/assets/waveforms/Sawtooth.tlw.REMOVED.git-id b/Desktop_Interface/android-build/assets/waveforms/Sawtooth.tlw.REMOVED.git-id deleted file mode 100644 index 87e86502..00000000 --- a/Desktop_Interface/android-build/assets/waveforms/Sawtooth.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e989a81be4fb7a2d79495ce7e96db776b0366a94 \ No newline at end of file diff --git a/Desktop_Interface/android-build/assets/waveforms/Sin.tlw.REMOVED.git-id b/Desktop_Interface/android-build/assets/waveforms/Sin.tlw.REMOVED.git-id deleted file mode 100644 index ceeb1ad1..00000000 --- a/Desktop_Interface/android-build/assets/waveforms/Sin.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e376c35388394ccfa4a86cb5bc6f9961e00fef20 \ No newline at end of file diff --git a/Desktop_Interface/android-build/assets/waveforms/Square.tlw.REMOVED.git-id b/Desktop_Interface/android-build/assets/waveforms/Square.tlw.REMOVED.git-id deleted file mode 100644 index 25d85bc6..00000000 --- a/Desktop_Interface/android-build/assets/waveforms/Square.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7bdd30bee84b15cc3fe88dd02751316a2016060c \ No newline at end of file diff --git a/Desktop_Interface/android-build/assets/waveforms/Triangle.tlw.REMOVED.git-id b/Desktop_Interface/android-build/assets/waveforms/Triangle.tlw.REMOVED.git-id deleted file mode 100644 index 768d2ac7..00000000 --- a/Desktop_Interface/android-build/assets/waveforms/Triangle.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -420ac92c2c292688434b3987874cc98a9180e336 \ No newline at end of file diff --git a/Desktop_Interface/android-build/assets/waveforms/_list.wfl.REMOVED.git-id b/Desktop_Interface/android-build/assets/waveforms/_list.wfl.REMOVED.git-id deleted file mode 100644 index 2b3bbd46..00000000 --- a/Desktop_Interface/android-build/assets/waveforms/_list.wfl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d9c5ca2b7e1352538debad0a17885fc4355864fc \ No newline at end of file diff --git a/Desktop_Interface/android-build/build.gradle.REMOVED.git-id b/Desktop_Interface/android-build/build.gradle.REMOVED.git-id deleted file mode 100644 index 6af3117a..00000000 --- a/Desktop_Interface/android-build/build.gradle.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ef416b0b88c1420d7bed0975240c678198aa73c2 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/generated/source/aidl/debug/org/kde/necessitas/ministro/IMinistro.java.REMOVED.git-id b/Desktop_Interface/android-build/build/generated/source/aidl/debug/org/kde/necessitas/ministro/IMinistro.java.REMOVED.git-id deleted file mode 100644 index c6e5527d..00000000 --- a/Desktop_Interface/android-build/build/generated/source/aidl/debug/org/kde/necessitas/ministro/IMinistro.java.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d785f4828fe4913e69b02e4a0d42ec2a6563739b \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/generated/source/aidl/debug/org/kde/necessitas/ministro/IMinistroCallback.java.REMOVED.git-id b/Desktop_Interface/android-build/build/generated/source/aidl/debug/org/kde/necessitas/ministro/IMinistroCallback.java.REMOVED.git-id deleted file mode 100644 index 3f9f2761..00000000 --- a/Desktop_Interface/android-build/build/generated/source/aidl/debug/org/kde/necessitas/ministro/IMinistroCallback.java.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6e6c51a0fb96b523dc2571e16e0aa19ae7088db8 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/generated/source/aidl/release/org/kde/necessitas/ministro/IMinistro.java.REMOVED.git-id b/Desktop_Interface/android-build/build/generated/source/aidl/release/org/kde/necessitas/ministro/IMinistro.java.REMOVED.git-id deleted file mode 100644 index c6e5527d..00000000 --- a/Desktop_Interface/android-build/build/generated/source/aidl/release/org/kde/necessitas/ministro/IMinistro.java.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d785f4828fe4913e69b02e4a0d42ec2a6563739b \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/generated/source/aidl/release/org/kde/necessitas/ministro/IMinistroCallback.java.REMOVED.git-id b/Desktop_Interface/android-build/build/generated/source/aidl/release/org/kde/necessitas/ministro/IMinistroCallback.java.REMOVED.git-id deleted file mode 100644 index 3f9f2761..00000000 --- a/Desktop_Interface/android-build/build/generated/source/aidl/release/org/kde/necessitas/ministro/IMinistroCallback.java.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6e6c51a0fb96b523dc2571e16e0aa19ae7088db8 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/generated/source/buildConfig/debug/org/qtproject/example/Labrador/BuildConfig.java.REMOVED.git-id b/Desktop_Interface/android-build/build/generated/source/buildConfig/debug/org/qtproject/example/Labrador/BuildConfig.java.REMOVED.git-id deleted file mode 100644 index 7f600589..00000000 --- a/Desktop_Interface/android-build/build/generated/source/buildConfig/debug/org/qtproject/example/Labrador/BuildConfig.java.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2b12c8cfdd4caa39909c3b2ff8fd07a42fffb96c \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/generated/source/buildConfig/release/org/qtproject/example/Labrador/BuildConfig.java.REMOVED.git-id b/Desktop_Interface/android-build/build/generated/source/buildConfig/release/org/qtproject/example/Labrador/BuildConfig.java.REMOVED.git-id deleted file mode 100644 index cf0e18fa..00000000 --- a/Desktop_Interface/android-build/build/generated/source/buildConfig/release/org/qtproject/example/Labrador/BuildConfig.java.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1f0d52f57d5e59f5dfac1b86502f41696bfc5e8c \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/generated/source/r/debug/org/qtproject/example/Labrador/R.java.REMOVED.git-id b/Desktop_Interface/android-build/build/generated/source/r/debug/org/qtproject/example/Labrador/R.java.REMOVED.git-id deleted file mode 100644 index 2f0f66ed..00000000 --- a/Desktop_Interface/android-build/build/generated/source/r/debug/org/qtproject/example/Labrador/R.java.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3091d16f76ce6ad7c805578686958d95896e840e \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/generated/source/r/release/org/qtproject/example/Labrador/R.java.REMOVED.git-id b/Desktop_Interface/android-build/build/generated/source/r/release/org/qtproject/example/Labrador/R.java.REMOVED.git-id deleted file mode 100644 index 2f0f66ed..00000000 --- a/Desktop_Interface/android-build/build/generated/source/r/release/org/qtproject/example/Labrador/R.java.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3091d16f76ce6ad7c805578686958d95896e840e \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/debug/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/debug/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list.REMOVED.git-id deleted file mode 100644 index c936d71a..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/debug/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3668bf657139054c49a4692fa32094510495a915 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/debug/firmware/labrafirm_0003_01.hex.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/debug/firmware/labrafirm_0003_01.hex.REMOVED.git-id deleted file mode 100644 index b3667a22..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/debug/firmware/labrafirm_0003_01.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f7946fd762c2bf7eaa4b76d5eb68948870244c19 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/debug/firmware/labrafirm_0003_02.hex.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/debug/firmware/labrafirm_0003_02.hex.REMOVED.git-id deleted file mode 100644 index 42c42b45..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/debug/firmware/labrafirm_0003_02.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -879125a9685d89a7f05bd38994079919338f49b6 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/DC.tlw.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/DC.tlw.REMOVED.git-id deleted file mode 100644 index e3326948..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/DC.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -69f322d2c3c6452561c8232b20784828fc438399 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/Sawtooth.tlw.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/Sawtooth.tlw.REMOVED.git-id deleted file mode 100644 index 87e86502..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/Sawtooth.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e989a81be4fb7a2d79495ce7e96db776b0366a94 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/Sin.tlw.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/Sin.tlw.REMOVED.git-id deleted file mode 100644 index ceeb1ad1..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/Sin.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e376c35388394ccfa4a86cb5bc6f9961e00fef20 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/Square.tlw.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/Square.tlw.REMOVED.git-id deleted file mode 100644 index 25d85bc6..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/Square.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7bdd30bee84b15cc3fe88dd02751316a2016060c \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/Triangle.tlw.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/Triangle.tlw.REMOVED.git-id deleted file mode 100644 index 768d2ac7..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/Triangle.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -420ac92c2c292688434b3987874cc98a9180e336 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/_list.wfl.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/_list.wfl.REMOVED.git-id deleted file mode 100644 index 2b3bbd46..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/debug/waveforms/_list.wfl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d9c5ca2b7e1352538debad0a17885fc4355864fc \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/release/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/release/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list.REMOVED.git-id deleted file mode 100644 index c936d71a..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/release/--Added-by-androiddeployqt--/qt_cache_pregenerated_file_list.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3668bf657139054c49a4692fa32094510495a915 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/release/firmware/labrafirm_0003_01.hex.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/release/firmware/labrafirm_0003_01.hex.REMOVED.git-id deleted file mode 100644 index b3667a22..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/release/firmware/labrafirm_0003_01.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f7946fd762c2bf7eaa4b76d5eb68948870244c19 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/release/firmware/labrafirm_0003_02.hex.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/release/firmware/labrafirm_0003_02.hex.REMOVED.git-id deleted file mode 100644 index 42c42b45..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/release/firmware/labrafirm_0003_02.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -879125a9685d89a7f05bd38994079919338f49b6 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/DC.tlw.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/DC.tlw.REMOVED.git-id deleted file mode 100644 index e3326948..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/DC.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -69f322d2c3c6452561c8232b20784828fc438399 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/Sawtooth.tlw.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/Sawtooth.tlw.REMOVED.git-id deleted file mode 100644 index 87e86502..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/Sawtooth.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e989a81be4fb7a2d79495ce7e96db776b0366a94 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/Sin.tlw.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/Sin.tlw.REMOVED.git-id deleted file mode 100644 index ceeb1ad1..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/Sin.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e376c35388394ccfa4a86cb5bc6f9961e00fef20 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/Square.tlw.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/Square.tlw.REMOVED.git-id deleted file mode 100644 index 25d85bc6..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/Square.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7bdd30bee84b15cc3fe88dd02751316a2016060c \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/Triangle.tlw.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/Triangle.tlw.REMOVED.git-id deleted file mode 100644 index 768d2ac7..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/Triangle.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -420ac92c2c292688434b3987874cc98a9180e336 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/_list.wfl.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/_list.wfl.REMOVED.git-id deleted file mode 100644 index 2b3bbd46..00000000 --- a/Desktop_Interface/android-build/build/intermediates/assets/release/waveforms/_list.wfl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d9c5ca2b7e1352538debad0a17885fc4355864fc \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/com/EspoTek/Labrador/Java/androidInterface.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/com/EspoTek/Labrador/Java/androidInterface.class.REMOVED.git-id deleted file mode 100644 index 0ef4b563..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/com/EspoTek/Labrador/Java/androidInterface.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -40cb400b3181a4e1d498c578fcf7896d83cb9474 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistro$Stub$Proxy.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistro$Stub$Proxy.class.REMOVED.git-id deleted file mode 100644 index bd53c92b..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistro$Stub$Proxy.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d967fe87f176c6c13995a3d0d586790192d1a6bd \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistro$Stub.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistro$Stub.class.REMOVED.git-id deleted file mode 100644 index b146a8df..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistro$Stub.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2de2f483640913f8c6a265f32207f34228898fd5 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistro.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistro.class.REMOVED.git-id deleted file mode 100644 index 59dbc7a6..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistro.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9b984325131098a100ec1237936d4d5fc219f4a7 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistroCallback$Stub$Proxy.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistroCallback$Stub$Proxy.class.REMOVED.git-id deleted file mode 100644 index ef3d6048..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistroCallback$Stub$Proxy.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2ab52eddb035f944b0cb2a279a9bd1cc0dd1ffd2 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistroCallback$Stub.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistroCallback$Stub.class.REMOVED.git-id deleted file mode 100644 index 1ffeba6c..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistroCallback$Stub.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -139d566283e991dd3e8d8456c614763300ca1737 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistroCallback.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistroCallback.class.REMOVED.git-id deleted file mode 100644 index c056c893..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/kde/necessitas/ministro/IMinistroCallback.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -61c0129078b6e1714f4dc75ee7838d9789051146 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/BuildConfig.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/BuildConfig.class.REMOVED.git-id deleted file mode 100644 index 5f91f8c4..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/BuildConfig.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a702990e597b33d8880be60d40dd0712115d03ca \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$array.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$array.class.REMOVED.git-id deleted file mode 100644 index ae7ac54c..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$array.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ee588922229197e056655f15253143cd727985e0 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$attr.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$attr.class.REMOVED.git-id deleted file mode 100644 index 7c87f38e..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$attr.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b8079837ab299e64673bab5b0983db23a79a17ce \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$layout.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$layout.class.REMOVED.git-id deleted file mode 100644 index 70885ed9..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$layout.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fdd228d281a582362f520b9948e530c1a673046b \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$mipmap.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$mipmap.class.REMOVED.git-id deleted file mode 100644 index 3d16956a..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$mipmap.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -69e4741e408a36d0ba20802932365f709a5a6794 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$string.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$string.class.REMOVED.git-id deleted file mode 100644 index 0061ced7..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$string.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6f131c3f47e5060faedfc805fa986f1affff079f \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$xml.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$xml.class.REMOVED.git-id deleted file mode 100644 index 4d1a8b46..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R$xml.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cb33f62bc902185d43659da6d2985401319c08fa \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R.class.REMOVED.git-id deleted file mode 100644 index d2fa7515..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/example/Labrador/R.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -79b9abc21964201e35c8814c22150042650528fb \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivity.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivity.class.REMOVED.git-id deleted file mode 100644 index eec5e578..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivity.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -912eec8a6c967bfa68e0753277daa422f72a64fb \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivityLoader$1.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivityLoader$1.class.REMOVED.git-id deleted file mode 100644 index d95fa5e0..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivityLoader$1.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -41c0bd4cc2f13e55388bf3b6acb775be142a535e \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivityLoader$2.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivityLoader$2.class.REMOVED.git-id deleted file mode 100644 index 7b8b3a6c..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivityLoader$2.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -22007d6acebdc831bbfcca73024276d91b1317a0 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivityLoader$3.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivityLoader$3.class.REMOVED.git-id deleted file mode 100644 index e0d284fc..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivityLoader$3.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -99174636267ae4ab39f9a5089517e031a5f933f6 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivityLoader.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivityLoader.class.REMOVED.git-id deleted file mode 100644 index 70e1ab38..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtActivityLoader.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5bb20c93533cd6c05ae79b58ef4720fc5b8deec8 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtApplication$InvokeResult.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtApplication$InvokeResult.class.REMOVED.git-id deleted file mode 100644 index 3358f8c8..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtApplication$InvokeResult.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b674dee3041cca0891a0683f1e9be3e46aa238c2 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtApplication.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtApplication.class.REMOVED.git-id deleted file mode 100644 index de4f8c71..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtApplication.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4f90a6b9ee29832c3ef0756fa6ba82bf332da2ca \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$1.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$1.class.REMOVED.git-id deleted file mode 100644 index 3f08db71..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$1.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2b2abc0e9fec80ab2f2f6c5f1bbf0fc757a920cb \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$2.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$2.class.REMOVED.git-id deleted file mode 100644 index 84195c6e..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$2.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ca085bea1eac1a6572ec4acfdf49938f9ba9a9fb \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$3$1$1.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$3$1$1.class.REMOVED.git-id deleted file mode 100644 index 290d19fd..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$3$1$1.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -feb1da444f93e4ff96e598cdabfb13645a8bb29b \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$3$1.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$3$1.class.REMOVED.git-id deleted file mode 100644 index c2d25d77..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$3$1.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1e9ef9840393874d20a43e89426f167581589297 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$3.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$3.class.REMOVED.git-id deleted file mode 100644 index b82bec7c..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$3.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f74c0e4e3b6231cb52a04d2c2c03063c5b947267 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$4.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$4.class.REMOVED.git-id deleted file mode 100644 index 790d0a02..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader$4.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -73525e6cc5251cef7c51dee5300db5536df7edd7 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader.class.REMOVED.git-id deleted file mode 100644 index cc1d8e75..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtLoader.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -407bed74afd06263dea279117ae0396e0cef2f3a \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtService.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtService.class.REMOVED.git-id deleted file mode 100644 index e8c13d28..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtService.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f3c0b5ccbff0ec989f58f042a5b513426cbb2ab7 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtServiceLoader.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtServiceLoader.class.REMOVED.git-id deleted file mode 100644 index 56ce0451..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/debug/org/qtproject/qt5/android/bindings/QtServiceLoader.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -baaa8fa744cb749bdb53b2cf16205f3e7899da8c \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/com/EspoTek/Labrador/Java/androidInterface.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/com/EspoTek/Labrador/Java/androidInterface.class.REMOVED.git-id deleted file mode 100644 index 0ef4b563..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/com/EspoTek/Labrador/Java/androidInterface.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -40cb400b3181a4e1d498c578fcf7896d83cb9474 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistro$Stub$Proxy.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistro$Stub$Proxy.class.REMOVED.git-id deleted file mode 100644 index bd53c92b..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistro$Stub$Proxy.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d967fe87f176c6c13995a3d0d586790192d1a6bd \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistro$Stub.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistro$Stub.class.REMOVED.git-id deleted file mode 100644 index b146a8df..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistro$Stub.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2de2f483640913f8c6a265f32207f34228898fd5 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistro.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistro.class.REMOVED.git-id deleted file mode 100644 index 59dbc7a6..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistro.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9b984325131098a100ec1237936d4d5fc219f4a7 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistroCallback$Stub$Proxy.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistroCallback$Stub$Proxy.class.REMOVED.git-id deleted file mode 100644 index ef3d6048..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistroCallback$Stub$Proxy.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2ab52eddb035f944b0cb2a279a9bd1cc0dd1ffd2 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistroCallback$Stub.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistroCallback$Stub.class.REMOVED.git-id deleted file mode 100644 index 1ffeba6c..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistroCallback$Stub.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -139d566283e991dd3e8d8456c614763300ca1737 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistroCallback.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistroCallback.class.REMOVED.git-id deleted file mode 100644 index c056c893..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/kde/necessitas/ministro/IMinistroCallback.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -61c0129078b6e1714f4dc75ee7838d9789051146 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/BuildConfig.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/BuildConfig.class.REMOVED.git-id deleted file mode 100644 index 46daf341..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/BuildConfig.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4bed2ddbb0c9e00f7d48e0baee1529ed6ead0563 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$array.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$array.class.REMOVED.git-id deleted file mode 100644 index ae7ac54c..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$array.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ee588922229197e056655f15253143cd727985e0 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$attr.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$attr.class.REMOVED.git-id deleted file mode 100644 index 7c87f38e..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$attr.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b8079837ab299e64673bab5b0983db23a79a17ce \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$layout.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$layout.class.REMOVED.git-id deleted file mode 100644 index 70885ed9..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$layout.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fdd228d281a582362f520b9948e530c1a673046b \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$mipmap.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$mipmap.class.REMOVED.git-id deleted file mode 100644 index 3d16956a..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$mipmap.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -69e4741e408a36d0ba20802932365f709a5a6794 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$string.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$string.class.REMOVED.git-id deleted file mode 100644 index 0061ced7..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$string.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6f131c3f47e5060faedfc805fa986f1affff079f \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$xml.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$xml.class.REMOVED.git-id deleted file mode 100644 index 4d1a8b46..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R$xml.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cb33f62bc902185d43659da6d2985401319c08fa \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R.class.REMOVED.git-id deleted file mode 100644 index d2fa7515..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/example/Labrador/R.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -79b9abc21964201e35c8814c22150042650528fb \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivity.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivity.class.REMOVED.git-id deleted file mode 100644 index eec5e578..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivity.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -912eec8a6c967bfa68e0753277daa422f72a64fb \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivityLoader$1.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivityLoader$1.class.REMOVED.git-id deleted file mode 100644 index d95fa5e0..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivityLoader$1.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -41c0bd4cc2f13e55388bf3b6acb775be142a535e \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivityLoader$2.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivityLoader$2.class.REMOVED.git-id deleted file mode 100644 index 7b8b3a6c..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivityLoader$2.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -22007d6acebdc831bbfcca73024276d91b1317a0 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivityLoader$3.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivityLoader$3.class.REMOVED.git-id deleted file mode 100644 index e0d284fc..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivityLoader$3.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -99174636267ae4ab39f9a5089517e031a5f933f6 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivityLoader.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivityLoader.class.REMOVED.git-id deleted file mode 100644 index 70e1ab38..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtActivityLoader.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5bb20c93533cd6c05ae79b58ef4720fc5b8deec8 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtApplication$InvokeResult.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtApplication$InvokeResult.class.REMOVED.git-id deleted file mode 100644 index 3358f8c8..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtApplication$InvokeResult.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b674dee3041cca0891a0683f1e9be3e46aa238c2 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtApplication.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtApplication.class.REMOVED.git-id deleted file mode 100644 index de4f8c71..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtApplication.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4f90a6b9ee29832c3ef0756fa6ba82bf332da2ca \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$1.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$1.class.REMOVED.git-id deleted file mode 100644 index 3f08db71..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$1.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2b2abc0e9fec80ab2f2f6c5f1bbf0fc757a920cb \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$2.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$2.class.REMOVED.git-id deleted file mode 100644 index 84195c6e..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$2.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ca085bea1eac1a6572ec4acfdf49938f9ba9a9fb \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$3$1$1.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$3$1$1.class.REMOVED.git-id deleted file mode 100644 index 290d19fd..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$3$1$1.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -feb1da444f93e4ff96e598cdabfb13645a8bb29b \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$3$1.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$3$1.class.REMOVED.git-id deleted file mode 100644 index c2d25d77..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$3$1.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1e9ef9840393874d20a43e89426f167581589297 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$3.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$3.class.REMOVED.git-id deleted file mode 100644 index b82bec7c..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$3.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f74c0e4e3b6231cb52a04d2c2c03063c5b947267 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$4.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$4.class.REMOVED.git-id deleted file mode 100644 index 790d0a02..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader$4.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -73525e6cc5251cef7c51dee5300db5536df7edd7 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader.class.REMOVED.git-id deleted file mode 100644 index cc1d8e75..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtLoader.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -407bed74afd06263dea279117ae0396e0cef2f3a \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtService.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtService.class.REMOVED.git-id deleted file mode 100644 index e8c13d28..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtService.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f3c0b5ccbff0ec989f58f042a5b513426cbb2ab7 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtServiceLoader.class.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtServiceLoader.class.REMOVED.git-id deleted file mode 100644 index 56ce0451..00000000 --- a/Desktop_Interface/android-build/build/intermediates/classes/release/org/qtproject/qt5/android/bindings/QtServiceLoader.class.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -baaa8fa744cb749bdb53b2cf16205f3e7899da8c \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/dex-cache/cache.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/dex-cache/cache.xml.REMOVED.git-id deleted file mode 100644 index bfb3ec55..00000000 --- a/Desktop_Interface/android-build/build/intermediates/dex-cache/cache.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9902f3c9aa0db74396ef8f20d161f3b67b044065 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/dex/debug/classes.dex.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/dex/debug/classes.dex.REMOVED.git-id deleted file mode 100644 index d7898283..00000000 --- a/Desktop_Interface/android-build/build/intermediates/dex/debug/classes.dex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c46860bfbc6ebf6922abc1ea9e4862b5d24d2c81 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/dex/release/classes.dex.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/dex/release/classes.dex.REMOVED.git-id deleted file mode 100644 index 72aef77e..00000000 --- a/Desktop_Interface/android-build/build/intermediates/dex/release/classes.dex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e88580a8e13bdde2aa5dc5fa28dc28a4079bb94f \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/incremental/aidl/debug/dependency.store.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/incremental/aidl/debug/dependency.store.REMOVED.git-id deleted file mode 100644 index 0c7a7bf4..00000000 --- a/Desktop_Interface/android-build/build/intermediates/incremental/aidl/debug/dependency.store.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9b36a1d84ab9847f5eb192858b8ae91118cd4786 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/incremental/aidl/release/dependency.store.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/incremental/aidl/release/dependency.store.REMOVED.git-id deleted file mode 100644 index 19140ac6..00000000 --- a/Desktop_Interface/android-build/build/intermediates/incremental/aidl/release/dependency.store.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -27bf3a92b9bdede03ca3b7cda1eab194aee55049 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/incremental/mergeAssets/debug/merger.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/incremental/mergeAssets/debug/merger.xml.REMOVED.git-id deleted file mode 100644 index b20ebae1..00000000 --- a/Desktop_Interface/android-build/build/intermediates/incremental/mergeAssets/debug/merger.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1f23bacbf0053cae88d8fccec13833426b40d820 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/incremental/mergeAssets/release/merger.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/incremental/mergeAssets/release/merger.xml.REMOVED.git-id deleted file mode 100644 index 7867290c..00000000 --- a/Desktop_Interface/android-build/build/intermediates/incremental/mergeAssets/release/merger.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9e342ac1cc19a2e35d715ff7e6e9af09ed871669 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/incremental/mergeResources/debug/merger.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/incremental/mergeResources/debug/merger.xml.REMOVED.git-id deleted file mode 100644 index 51b18c7d..00000000 --- a/Desktop_Interface/android-build/build/intermediates/incremental/mergeResources/debug/merger.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -891d7434b3364e9c02ecc72fae0aeecce6d00a52 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/incremental/mergeResources/release/merger.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/incremental/mergeResources/release/merger.xml.REMOVED.git-id deleted file mode 100644 index 9cd1f528..00000000 --- a/Desktop_Interface/android-build/build/intermediates/incremental/mergeResources/release/merger.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -631cf9235bc0c89991a133bce19bb3a19a59f85b \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/javaResources/debug/androidInterface.java.bak.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/javaResources/debug/androidInterface.java.bak.REMOVED.git-id deleted file mode 100644 index eef66601..00000000 --- a/Desktop_Interface/android-build/build/intermediates/javaResources/debug/androidInterface.java.bak.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d480bb2df3c38016e18106ba7afcf4d4bfb6c05c \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/javaResources/release/androidInterface.java.bak.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/javaResources/release/androidInterface.java.bak.REMOVED.git-id deleted file mode 100644 index eef66601..00000000 --- a/Desktop_Interface/android-build/build/intermediates/javaResources/release/androidInterface.java.bak.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d480bb2df3c38016e18106ba7afcf4d4bfb6c05c \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/manifests/full/debug/AndroidManifest.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/manifests/full/debug/AndroidManifest.xml.REMOVED.git-id deleted file mode 100644 index 32f9d769..00000000 --- a/Desktop_Interface/android-build/build/intermediates/manifests/full/debug/AndroidManifest.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2102faad13c502de1a54217210497edc0e0ea5ce \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/manifests/full/release/AndroidManifest.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/manifests/full/release/AndroidManifest.xml.REMOVED.git-id deleted file mode 100644 index 8e59b3e2..00000000 --- a/Desktop_Interface/android-build/build/intermediates/manifests/full/release/AndroidManifest.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0838648bc861807d54426955e39a5449c956cfc0 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/pre-dexed/debug/QtAndroid-bundled-b9c529ec9bda4b335b762db89d9dac573a70dd33.jar.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/pre-dexed/debug/QtAndroid-bundled-b9c529ec9bda4b335b762db89d9dac573a70dd33.jar.REMOVED.git-id deleted file mode 100644 index 8c5fdbdf..00000000 --- a/Desktop_Interface/android-build/build/intermediates/pre-dexed/debug/QtAndroid-bundled-b9c529ec9bda4b335b762db89d9dac573a70dd33.jar.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cc29800de5ea48f5fa34e36e9969a9ebca59d651 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/pre-dexed/release/QtAndroid-bundled-b9c529ec9bda4b335b762db89d9dac573a70dd33.jar.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/pre-dexed/release/QtAndroid-bundled-b9c529ec9bda4b335b762db89d9dac573a70dd33.jar.REMOVED.git-id deleted file mode 100644 index 8c5fdbdf..00000000 --- a/Desktop_Interface/android-build/build/intermediates/pre-dexed/release/QtAndroid-bundled-b9c529ec9bda4b335b762db89d9dac573a70dd33.jar.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cc29800de5ea48f5fa34e36e9969a9ebca59d651 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/layout/splash.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/layout/splash.xml.REMOVED.git-id deleted file mode 100644 index d47d8329..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/layout/splash.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bbcdbcf9358d098f5b0654e5f03311c51106b206 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-hdpi-v4/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-hdpi-v4/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index c7daa9fd..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-hdpi-v4/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a5ce000735148378b67ee4c30bf1cea0cccc4349 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-mdpi-v4/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-mdpi-v4/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 3f83a048..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-mdpi-v4/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3855f30983948e1bfaa6b34521df2f1e22d2f59a \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-xhdpi-v4/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-xhdpi-v4/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 7a745930..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-xhdpi-v4/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2ad602aba497cefd0198b575eec95333ce69d260 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-xxhdpi-v4/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-xxhdpi-v4/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 52799fdc..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-xxhdpi-v4/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fc64d1478f59df3ba65a30ef59a75d68135d1f87 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-xxxhdpi-v4/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-xxxhdpi-v4/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 684875ff..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/mipmap-xxxhdpi-v4/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3865922c76aecd53a7915d3b10c1d5bc10d6ce79 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-de/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-de/values.xml.REMOVED.git-id deleted file mode 100644 index 46777659..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-de/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -23012317b98823932eddddff8a304d892c6f045d \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-el/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-el/values.xml.REMOVED.git-id deleted file mode 100644 index 744f44d5..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-el/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6acb6e1fbce3c6173ae4f6c067f2f9faf4bad9ea \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-es/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-es/values.xml.REMOVED.git-id deleted file mode 100644 index 1470a9ac..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-es/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -02950f8544454faa3262264fdd63deec71d655b4 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-et/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-et/values.xml.REMOVED.git-id deleted file mode 100644 index 42c117ac..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-et/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0e2a304fd69848f0ae0fb146757c7fcc46c71d89 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-fa/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-fa/values.xml.REMOVED.git-id deleted file mode 100644 index 89f1abe0..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-fa/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0392c5e0e9384af0750c1afc4b2cddf0cda9c235 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-fr/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-fr/values.xml.REMOVED.git-id deleted file mode 100644 index 4c183faf..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-fr/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e9de8fde48d871953060d775cd682be29ec4e678 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-id/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-id/values.xml.REMOVED.git-id deleted file mode 100644 index fa6bd918..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-id/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9db35bd36e22de1ddc48264fcd1f5680f4c14d9d \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-it/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-it/values.xml.REMOVED.git-id deleted file mode 100644 index b543c196..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-it/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -baa4c911a5312301560b002ceac7c08fdeb40f34 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-ja/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-ja/values.xml.REMOVED.git-id deleted file mode 100644 index b38675e7..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-ja/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -126bb19db5fa10567349895c78ce89e2d8961a9e \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-ms/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-ms/values.xml.REMOVED.git-id deleted file mode 100644 index 26b9b2be..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-ms/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f9998e728aa896c9e30e04fb152fd7f04eef4661 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-nb/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-nb/values.xml.REMOVED.git-id deleted file mode 100644 index 6224fc7a..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-nb/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9ac6fd4f55f9895291cc98a2c5ccbdfe03801cd6 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-nl/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-nl/values.xml.REMOVED.git-id deleted file mode 100644 index 16601f39..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-nl/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0309e2f2cfc7788ec0fd4ed460188906f19a598c \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-pl/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-pl/values.xml.REMOVED.git-id deleted file mode 100644 index c71cead8..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-pl/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -71c05dcb9f5788ca9e802ecb7159398a2876da28 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-pt-rBR/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-pt-rBR/values.xml.REMOVED.git-id deleted file mode 100644 index f94b530e..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-pt-rBR/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b4e81cb1110bf993c9385c24d0eb8f758eb3e4ef \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-ro/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-ro/values.xml.REMOVED.git-id deleted file mode 100644 index fe9479bf..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-ro/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d362fe441f759508f0bff2f7836e438385922ce3 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-rs/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-rs/values.xml.REMOVED.git-id deleted file mode 100644 index 011ee155..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-rs/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -76081f051c22c5ef954bc3a9f25300a26ca9c0c6 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-ru/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-ru/values.xml.REMOVED.git-id deleted file mode 100644 index 90e72ed7..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-ru/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -278b97a1dc4010aab6d1ac8ae222ea5cd7d8e9d1 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-zh-rCN/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-zh-rCN/values.xml.REMOVED.git-id deleted file mode 100644 index e63e4f38..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-zh-rCN/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -70e8c5714c6300eea0aab665436f9a5cd54a5863 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values-zh-rTW/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values-zh-rTW/values.xml.REMOVED.git-id deleted file mode 100644 index 63e6fa59..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values-zh-rTW/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ae0cfff5840ecb70fe8b34f7986def541b7d31b2 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/values/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/values/values.xml.REMOVED.git-id deleted file mode 100644 index ae1d6054..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/values/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d2b9d11feacc6e7a2a5d4c1015a29f19d56df850 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/debug/xml/device_filter.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/debug/xml/device_filter.xml.REMOVED.git-id deleted file mode 100644 index 4c8913bb..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/debug/xml/device_filter.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a8c50fdce6cf3cfcfadf2c44cbef9579ee10b9c4 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/layout/splash.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/layout/splash.xml.REMOVED.git-id deleted file mode 100644 index d47d8329..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/layout/splash.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bbcdbcf9358d098f5b0654e5f03311c51106b206 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-hdpi-v4/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-hdpi-v4/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index c7daa9fd..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-hdpi-v4/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a5ce000735148378b67ee4c30bf1cea0cccc4349 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-mdpi-v4/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-mdpi-v4/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 3f83a048..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-mdpi-v4/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3855f30983948e1bfaa6b34521df2f1e22d2f59a \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-xhdpi-v4/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-xhdpi-v4/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 7a745930..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-xhdpi-v4/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2ad602aba497cefd0198b575eec95333ce69d260 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-xxhdpi-v4/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-xxhdpi-v4/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 52799fdc..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-xxhdpi-v4/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fc64d1478f59df3ba65a30ef59a75d68135d1f87 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-xxxhdpi-v4/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-xxxhdpi-v4/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 684875ff..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/mipmap-xxxhdpi-v4/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3865922c76aecd53a7915d3b10c1d5bc10d6ce79 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-de/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-de/values.xml.REMOVED.git-id deleted file mode 100644 index 46777659..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-de/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -23012317b98823932eddddff8a304d892c6f045d \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-el/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-el/values.xml.REMOVED.git-id deleted file mode 100644 index 744f44d5..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-el/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6acb6e1fbce3c6173ae4f6c067f2f9faf4bad9ea \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-es/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-es/values.xml.REMOVED.git-id deleted file mode 100644 index 1470a9ac..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-es/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -02950f8544454faa3262264fdd63deec71d655b4 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-et/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-et/values.xml.REMOVED.git-id deleted file mode 100644 index 42c117ac..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-et/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0e2a304fd69848f0ae0fb146757c7fcc46c71d89 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-fa/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-fa/values.xml.REMOVED.git-id deleted file mode 100644 index 89f1abe0..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-fa/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0392c5e0e9384af0750c1afc4b2cddf0cda9c235 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-fr/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-fr/values.xml.REMOVED.git-id deleted file mode 100644 index 4c183faf..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-fr/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e9de8fde48d871953060d775cd682be29ec4e678 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-id/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-id/values.xml.REMOVED.git-id deleted file mode 100644 index fa6bd918..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-id/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9db35bd36e22de1ddc48264fcd1f5680f4c14d9d \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-it/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-it/values.xml.REMOVED.git-id deleted file mode 100644 index b543c196..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-it/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -baa4c911a5312301560b002ceac7c08fdeb40f34 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-ja/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-ja/values.xml.REMOVED.git-id deleted file mode 100644 index b38675e7..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-ja/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -126bb19db5fa10567349895c78ce89e2d8961a9e \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-ms/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-ms/values.xml.REMOVED.git-id deleted file mode 100644 index 26b9b2be..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-ms/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f9998e728aa896c9e30e04fb152fd7f04eef4661 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-nb/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-nb/values.xml.REMOVED.git-id deleted file mode 100644 index 6224fc7a..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-nb/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9ac6fd4f55f9895291cc98a2c5ccbdfe03801cd6 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-nl/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-nl/values.xml.REMOVED.git-id deleted file mode 100644 index 16601f39..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-nl/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0309e2f2cfc7788ec0fd4ed460188906f19a598c \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-pl/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-pl/values.xml.REMOVED.git-id deleted file mode 100644 index c71cead8..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-pl/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -71c05dcb9f5788ca9e802ecb7159398a2876da28 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-pt-rBR/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-pt-rBR/values.xml.REMOVED.git-id deleted file mode 100644 index f94b530e..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-pt-rBR/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b4e81cb1110bf993c9385c24d0eb8f758eb3e4ef \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-ro/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-ro/values.xml.REMOVED.git-id deleted file mode 100644 index fe9479bf..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-ro/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d362fe441f759508f0bff2f7836e438385922ce3 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-rs/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-rs/values.xml.REMOVED.git-id deleted file mode 100644 index 011ee155..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-rs/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -76081f051c22c5ef954bc3a9f25300a26ca9c0c6 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-ru/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-ru/values.xml.REMOVED.git-id deleted file mode 100644 index 90e72ed7..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-ru/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -278b97a1dc4010aab6d1ac8ae222ea5cd7d8e9d1 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-zh-rCN/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-zh-rCN/values.xml.REMOVED.git-id deleted file mode 100644 index e63e4f38..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-zh-rCN/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -70e8c5714c6300eea0aab665436f9a5cd54a5863 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values-zh-rTW/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values-zh-rTW/values.xml.REMOVED.git-id deleted file mode 100644 index 63e6fa59..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values-zh-rTW/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ae0cfff5840ecb70fe8b34f7986def541b7d31b2 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/values/values.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/values/values.xml.REMOVED.git-id deleted file mode 100644 index ae1d6054..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/values/values.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d2b9d11feacc6e7a2a5d4c1015a29f19d56df850 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/res/release/xml/device_filter.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/res/release/xml/device_filter.xml.REMOVED.git-id deleted file mode 100644 index 4c8913bb..00000000 --- a/Desktop_Interface/android-build/build/intermediates/res/release/xml/device_filter.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a8c50fdce6cf3cfcfadf2c44cbef9579ee10b9c4 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/resources/resources-debug.ap_.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/resources/resources-debug.ap_.REMOVED.git-id deleted file mode 100644 index 2e1fd371..00000000 --- a/Desktop_Interface/android-build/build/intermediates/resources/resources-debug.ap_.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -45f660b83b38ec4bcc075f84a6d17299182ce316 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/intermediates/resources/resources-release.ap_.REMOVED.git-id b/Desktop_Interface/android-build/build/intermediates/resources/resources-release.ap_.REMOVED.git-id deleted file mode 100644 index 764372d4..00000000 --- a/Desktop_Interface/android-build/build/intermediates/resources/resources-release.ap_.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f27a42edad0dd0ced364750ff9ea93ef1263eaf3 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/outputs/apk/android-build-debug-unaligned.apk.REMOVED.git-id b/Desktop_Interface/android-build/build/outputs/apk/android-build-debug-unaligned.apk.REMOVED.git-id deleted file mode 100644 index 0281b941..00000000 --- a/Desktop_Interface/android-build/build/outputs/apk/android-build-debug-unaligned.apk.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2064c69c7e6cf71ccd20533871ae9bba46f75aa7 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/outputs/apk/android-build-debug.apk.REMOVED.git-id b/Desktop_Interface/android-build/build/outputs/apk/android-build-debug.apk.REMOVED.git-id deleted file mode 100644 index ad52c304..00000000 --- a/Desktop_Interface/android-build/build/outputs/apk/android-build-debug.apk.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8cd0ffc74763728b9e4d6e3b37105af093c85828 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/outputs/apk/android-build-release-signed - Copy.zip.REMOVED.git-id b/Desktop_Interface/android-build/build/outputs/apk/android-build-release-signed - Copy.zip.REMOVED.git-id deleted file mode 100644 index ae828676..00000000 --- a/Desktop_Interface/android-build/build/outputs/apk/android-build-release-signed - Copy.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2d3de438c39797d9b7f8e60b17d789965c280de1 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/outputs/apk/android-build-release-signed.apk.REMOVED.git-id b/Desktop_Interface/android-build/build/outputs/apk/android-build-release-signed.apk.REMOVED.git-id deleted file mode 100644 index 68a04e99..00000000 --- a/Desktop_Interface/android-build/build/outputs/apk/android-build-release-signed.apk.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -86f5990ef19030f71c42e2d7ac55f080967ec1d9 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal.html.REMOVED.git-id b/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal.html.REMOVED.git-id deleted file mode 100644 index 3630ae82..00000000 --- a/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal.html.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ac09e7b2e66b85cac37a4e2ae02b3eadfd0fe32d \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal.xml.REMOVED.git-id b/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal.xml.REMOVED.git-id deleted file mode 100644 index 5b2a5ea2..00000000 --- a/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1eb416706f2416b63c412ed2ae392ab7b9c118ea \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/Thumbs.db.REMOVED.git-id b/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/Thumbs.db.REMOVED.git-id deleted file mode 100644 index 496c6cda..00000000 --- a/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/Thumbs.db.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aae6e4d0c2d79d8add15d0557a4a3f80e516822b \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/hololike.css.REMOVED.git-id b/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/hololike.css.REMOVED.git-id deleted file mode 100644 index e14ea2cf..00000000 --- a/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/hololike.css.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -09645da18f6aec634b5a71a22e7bc48ae9eea89d \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/lint-error.png.REMOVED.git-id b/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/lint-error.png.REMOVED.git-id deleted file mode 100644 index 27f53071..00000000 --- a/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/lint-error.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fb4c982a3856185b9ec75ac1427237bb195c983f \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/lint-run.png.REMOVED.git-id b/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/lint-run.png.REMOVED.git-id deleted file mode 100644 index 5131f946..00000000 --- a/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/lint-run.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d1a074b005303ef1202e023c9fda99b8bca2b591 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/lint-warning.png.REMOVED.git-id b/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/lint-warning.png.REMOVED.git-id deleted file mode 100644 index b4c17955..00000000 --- a/Desktop_Interface/android-build/build/outputs/lint-results-release-fatal_files/lint-warning.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3960cddb508b0947d0bb2c46cfd42f23b4f7e432 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/outputs/logs/manifest-merger-debug-report.txt.REMOVED.git-id b/Desktop_Interface/android-build/build/outputs/logs/manifest-merger-debug-report.txt.REMOVED.git-id deleted file mode 100644 index bd05791e..00000000 --- a/Desktop_Interface/android-build/build/outputs/logs/manifest-merger-debug-report.txt.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cd8ce92fc8d247842915acfbb589338627f11e52 \ No newline at end of file diff --git a/Desktop_Interface/android-build/build/outputs/logs/manifest-merger-release-report.txt.REMOVED.git-id b/Desktop_Interface/android-build/build/outputs/logs/manifest-merger-release-report.txt.REMOVED.git-id deleted file mode 100644 index bd05791e..00000000 --- a/Desktop_Interface/android-build/build/outputs/logs/manifest-merger-release-report.txt.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cd8ce92fc8d247842915acfbb589338627f11e52 \ No newline at end of file diff --git a/Desktop_Interface/android-build/gradle.properties.REMOVED.git-id b/Desktop_Interface/android-build/gradle.properties.REMOVED.git-id deleted file mode 100644 index 66711434..00000000 --- a/Desktop_Interface/android-build/gradle.properties.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -63ee31e483c9f8872d9b74af50307d1c6e294f74 \ No newline at end of file diff --git a/Desktop_Interface/android-build/gradle.properties~.REMOVED.git-id b/Desktop_Interface/android-build/gradle.properties~.REMOVED.git-id deleted file mode 100644 index 9341d3fd..00000000 --- a/Desktop_Interface/android-build/gradle.properties~.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9079463055754018dedc3bb1863c806547f78eac \ No newline at end of file diff --git a/Desktop_Interface/android-build/gradle/wrapper/gradle-wrapper.jar.REMOVED.git-id b/Desktop_Interface/android-build/gradle/wrapper/gradle-wrapper.jar.REMOVED.git-id deleted file mode 100644 index 382c51d0..00000000 --- a/Desktop_Interface/android-build/gradle/wrapper/gradle-wrapper.jar.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8c0fb64a8698b08ecc4158d828ca593c4928e9dd \ No newline at end of file diff --git a/Desktop_Interface/android-build/gradle/wrapper/gradle-wrapper.properties.REMOVED.git-id b/Desktop_Interface/android-build/gradle/wrapper/gradle-wrapper.properties.REMOVED.git-id deleted file mode 100644 index 6ea1c853..00000000 --- a/Desktop_Interface/android-build/gradle/wrapper/gradle-wrapper.properties.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0c71e760dc93830dd3411fe50d6f5c86bf0a8f4d \ No newline at end of file diff --git a/Desktop_Interface/android-build/gradle/wrapper/gradle-wrapper.properties~.REMOVED.git-id b/Desktop_Interface/android-build/gradle/wrapper/gradle-wrapper.properties~.REMOVED.git-id deleted file mode 100644 index ba902396..00000000 --- a/Desktop_Interface/android-build/gradle/wrapper/gradle-wrapper.properties~.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1e61d1fd3a9bc5be8381127e4d6457cf08e7c473 \ No newline at end of file diff --git a/Desktop_Interface/android-build/gradlew.REMOVED.git-id b/Desktop_Interface/android-build/gradlew.REMOVED.git-id deleted file mode 100644 index 48aa526b..00000000 --- a/Desktop_Interface/android-build/gradlew.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -91a7e269e19dfc62e27137a0b57ef3e430cee4fd \ No newline at end of file diff --git a/Desktop_Interface/android-build/gradlew.bat.REMOVED.git-id b/Desktop_Interface/android-build/gradlew.bat.REMOVED.git-id deleted file mode 100644 index c1b45adf..00000000 --- a/Desktop_Interface/android-build/gradlew.bat.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8a0b282aa6885fb573c106b3551f7275c5f17e8e \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/QtAndroid-bundled.jar.REMOVED.git-id b/Desktop_Interface/android-build/libs/QtAndroid-bundled.jar.REMOVED.git-id deleted file mode 100644 index 79b00782..00000000 --- a/Desktop_Interface/android-build/libs/QtAndroid-bundled.jar.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -be92d82794019f435865611424791d4dca681797 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libLabrador.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libLabrador.so.REMOVED.git-id deleted file mode 100644 index 2e1d1875..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libLabrador.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ad4f4cc72bdeaa9d80fb039f73c04e82c79d6603 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5AndroidExtras.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5AndroidExtras.so.REMOVED.git-id deleted file mode 100644 index bc3c58f3..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5AndroidExtras.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4bb9403e79d99fd2f28a974e5627ca37efc25d59 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5Core.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5Core.so.REMOVED.git-id deleted file mode 100644 index 6d44bd4b..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5Core.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6efb1e6ff77edf436adaa6a74b0ccf76a1c8f4b8 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5Gui.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5Gui.so.REMOVED.git-id deleted file mode 100644 index 8671ea52..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5Gui.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4389f212f89439e7bdf7f7a9960350e5cc698560 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5PrintSupport.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5PrintSupport.so.REMOVED.git-id deleted file mode 100644 index d5469bcc..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5PrintSupport.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -dc1e1fc88e8330ccfc916be0f6037caee74fc94b \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5Widgets.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5Widgets.so.REMOVED.git-id deleted file mode 100644 index c9c17e17..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libQt5Widgets.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a02508dfea1044de0c75d3b512be7e6f1e4b6489 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libdfuprog-0.9.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libdfuprog-0.9.so.REMOVED.git-id deleted file mode 100644 index 3c7825a1..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libdfuprog-0.9.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e94f13a61a2e935d741e43fd3a461fb5d3f3fb02 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libgnustl_shared.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libgnustl_shared.so.REMOVED.git-id deleted file mode 100644 index 9f4e0a74..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libgnustl_shared.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c57710f8e86044362042bd1106a4f57c0eb18106 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/liblog.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/liblog.so.REMOVED.git-id deleted file mode 100644 index 27f455e0..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/liblog.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e21eb593c8f46df7d5a411f18f292dbb096a9253 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqdds.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqdds.so.REMOVED.git-id deleted file mode 100644 index 3fec4522..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqdds.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7f98aef83e6d5130830e863fb77ec1e14f4c7d28 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqgif.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqgif.so.REMOVED.git-id deleted file mode 100644 index 669b75dd..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqgif.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -77831a8d03848d2daa6beda012b761115dc6e9bc \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqicns.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqicns.so.REMOVED.git-id deleted file mode 100644 index f4e02606..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqicns.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2de8c1a72233512477ba8a20688736da6a3449c3 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqico.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqico.so.REMOVED.git-id deleted file mode 100644 index 7857e3f6..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqico.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6d6a9c78842828078439fdedbb8ca58149e579b2 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqjpeg.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqjpeg.so.REMOVED.git-id deleted file mode 100644 index a67dce5c..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqjpeg.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -03fb41aeef0113868a97d6acedaaddb1eaf85916 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqtga.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqtga.so.REMOVED.git-id deleted file mode 100644 index 4bb1790d..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqtga.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -067f95f26b8f4cced9c25c459e283ecf9a47a935 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqtiff.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqtiff.so.REMOVED.git-id deleted file mode 100644 index ce970fec..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqtiff.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -de3e06b102027089ed7ab5626ead99023b9715fa \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqwbmp.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqwbmp.so.REMOVED.git-id deleted file mode 100644 index 2dfa6e4a..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqwbmp.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8a245fbb98c669162514cd668d4a65968b288e52 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqwebp.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqwebp.so.REMOVED.git-id deleted file mode 100644 index 59ea6210..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_imageformats_libqwebp.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3afd7ce0688807897026e3ffa9844ba3cdc47c4b \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_platforms_android_libqtforandroid.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_platforms_android_libqtforandroid.so.REMOVED.git-id deleted file mode 100644 index 51f9cd97..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libplugins_platforms_android_libqtforandroid.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -58a5e10bd6820c57c22a4ffaec83e43c86862f75 \ No newline at end of file diff --git a/Desktop_Interface/android-build/libs/armeabi-v7a/libusb1.0.so.REMOVED.git-id b/Desktop_Interface/android-build/libs/armeabi-v7a/libusb1.0.so.REMOVED.git-id deleted file mode 100644 index 2e8bcfd7..00000000 --- a/Desktop_Interface/android-build/libs/armeabi-v7a/libusb1.0.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ffddb4b3cece1f758e4971f6932f19562175acd1 \ No newline at end of file diff --git a/Desktop_Interface/android-build/local.properties.REMOVED.git-id b/Desktop_Interface/android-build/local.properties.REMOVED.git-id deleted file mode 100644 index 295a42d1..00000000 --- a/Desktop_Interface/android-build/local.properties.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bb31d8d515c7d6398acf79ecbf1057851497d820 \ No newline at end of file diff --git a/Desktop_Interface/android-build/local.properties~.REMOVED.git-id b/Desktop_Interface/android-build/local.properties~.REMOVED.git-id deleted file mode 100644 index 22db0449..00000000 --- a/Desktop_Interface/android-build/local.properties~.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -342f07a9359a44af35a48bdb989ab7d640378c5e \ No newline at end of file diff --git a/Desktop_Interface/android-build/res/Thumbs.db.REMOVED.git-id b/Desktop_Interface/android-build/res/Thumbs.db.REMOVED.git-id deleted file mode 100644 index cc424b7a..00000000 --- a/Desktop_Interface/android-build/res/Thumbs.db.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -728c7c09f66a1c1c54ac921895b5bda14a21d55b \ No newline at end of file diff --git a/Desktop_Interface/android-build/res/mipmap-hdpi/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/res/mipmap-hdpi/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 7b387687..00000000 --- a/Desktop_Interface/android-build/res/mipmap-hdpi/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b77d2db15ac66d272f411892fef5dc78f1a334ec \ No newline at end of file diff --git a/Desktop_Interface/android-build/res/mipmap-mdpi/Thumbs.db.REMOVED.git-id b/Desktop_Interface/android-build/res/mipmap-mdpi/Thumbs.db.REMOVED.git-id deleted file mode 100644 index 770c6a93..00000000 --- a/Desktop_Interface/android-build/res/mipmap-mdpi/Thumbs.db.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9ce77f46f29740353189bbb1961626c4a537455a \ No newline at end of file diff --git a/Desktop_Interface/android-build/res/mipmap-mdpi/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/res/mipmap-mdpi/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 45e1c039..00000000 --- a/Desktop_Interface/android-build/res/mipmap-mdpi/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -85c704a8fa459a34d512155668563e8eb7986ea8 \ No newline at end of file diff --git a/Desktop_Interface/android-build/res/mipmap-xhdpi/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/res/mipmap-xhdpi/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 8673d8db..00000000 --- a/Desktop_Interface/android-build/res/mipmap-xhdpi/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -872eabdbf53fbc6155a1f08711874f0a4e343b16 \ No newline at end of file diff --git a/Desktop_Interface/android-build/res/mipmap-xxhdpi/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/res/mipmap-xxhdpi/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index c5041fc2..00000000 --- a/Desktop_Interface/android-build/res/mipmap-xxhdpi/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e6058385db5d994fcc73681590faa55bcce4119e \ No newline at end of file diff --git a/Desktop_Interface/android-build/res/mipmap-xxxhdpi/Thumbs.db.REMOVED.git-id b/Desktop_Interface/android-build/res/mipmap-xxxhdpi/Thumbs.db.REMOVED.git-id deleted file mode 100644 index 5e30c8cf..00000000 --- a/Desktop_Interface/android-build/res/mipmap-xxxhdpi/Thumbs.db.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6678b8f4b15e3a0c94fa71d1445d9a6641827f95 \ No newline at end of file diff --git a/Desktop_Interface/android-build/res/mipmap-xxxhdpi/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/android-build/res/mipmap-xxxhdpi/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 50284b7d..00000000 --- a/Desktop_Interface/android-build/res/mipmap-xxxhdpi/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2b287a9164a0e2f7e7914bf9abbdbcd17f217513 \ No newline at end of file diff --git a/Desktop_Interface/android-build/res/values/libs.xml.REMOVED.git-id b/Desktop_Interface/android-build/res/values/libs.xml.REMOVED.git-id deleted file mode 100644 index 3cb9f097..00000000 --- a/Desktop_Interface/android-build/res/values/libs.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -65185e735aa589e7ff5f51c8b231a72b7151d14c \ No newline at end of file diff --git a/Desktop_Interface/android-build/res/web_hi_res_512.png.REMOVED.git-id b/Desktop_Interface/android-build/res/web_hi_res_512.png.REMOVED.git-id deleted file mode 100644 index 0abefa4f..00000000 --- a/Desktop_Interface/android-build/res/web_hi_res_512.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -893eebc776c2d6f520d41af0b4d8075a9c99716d \ No newline at end of file diff --git a/Desktop_Interface/android-build/res/xml/device_filter.xml.REMOVED.git-id b/Desktop_Interface/android-build/res/xml/device_filter.xml.REMOVED.git-id deleted file mode 100644 index 436375a5..00000000 --- a/Desktop_Interface/android-build/res/xml/device_filter.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5d9a80593045cdda9d8316eba096bb3c5823100a \ No newline at end of file diff --git a/Desktop_Interface/android-build/src/androidInterface.java.REMOVED.git-id b/Desktop_Interface/android-build/src/androidInterface.java.REMOVED.git-id deleted file mode 100644 index 86600d3e..00000000 --- a/Desktop_Interface/android-build/src/androidInterface.java.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7caea66ab4cc45a43869b1c24c948cc768c57811 \ No newline at end of file diff --git a/Desktop_Interface/android-build/src/androidInterface.java.bak.REMOVED.git-id b/Desktop_Interface/android-build/src/androidInterface.java.bak.REMOVED.git-id deleted file mode 100644 index eef66601..00000000 --- a/Desktop_Interface/android-build/src/androidInterface.java.bak.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d480bb2df3c38016e18106ba7afcf4d4bfb6c05c \ No newline at end of file diff --git a/Desktop_Interface/android-libLabrador.so-deployment-settings.json.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/android-libLabrador.so-deployment-settings.json.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index bbc01add..00000000 --- a/Desktop_Interface/android-libLabrador.so-deployment-settings.json.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9bd7b7cc07c06a8eb01b5c18940597965f1d10ef \ No newline at end of file diff --git a/Desktop_Interface/androidusbdriver.cpp b/Desktop_Interface/androidusbdriver.cpp new file mode 100644 index 00000000..ef7ea3b8 --- /dev/null +++ b/Desktop_Interface/androidusbdriver.cpp @@ -0,0 +1,274 @@ +#include "androidusbdriver.h" +#include "QStandardPaths" + +androidUsbDriver::androidUsbDriver(QWidget *parent) : unixUsbDriver(parent) +{ + qDebug() << "androidUsbDriver object created!"; + mainActivity = QtAndroid::androidActivity(); +} + +androidUsbDriver::~androidUsbDriver(void){ + qDebug() << "\n\nandroidUsbDriver destructor ran!"; + mainActivity.callMethod("closeDevice"); +} + +unsigned char androidUsbDriver::usbInit(unsigned long VIDin, unsigned long PIDin){ + qDebug() << "Entering androidUsbDriver::usbInit"; + + mainActivity.callMethod("nonStaticTest"); + + qDebug() << "If you cannot see 'nonStaticTest' above, then the _______JAVA CLASS DOES NOT EXIST____"; + + + mainActivity.callMethod("findDevice"); + + //QAndroidJniObject usbfs_path_java = mainActivity.getObjectField("usbfs_path"); + //QString usbfs_path_qstring = usbfs_path_java.toString(); + //char *usbfs_path = usbfs_path_qstring.toUtf8().data(); + + QAndroidJniObject usbfs_path_java = mainActivity.getObjectField("usbfs_path"); + QString usbfs_path_qstring = usbfs_path_java.toString(); + std::string usbfs_path_stdstr = usbfs_path_qstring.toStdString(); + char usbfs_path[128]; + strcpy(usbfs_path, usbfs_path_stdstr.c_str()); + + jint file_descriptor_java = mainActivity.getField("file_descriptor"); + int file_descriptor = (int)file_descriptor_java; + + qDebug() << "usbfs path = " << usbfs_path; + qDebug() << "file descriptor = " << file_descriptor; + + if(file_descriptor == -69){ + qDebug() << "DEVICE NOT DETECTED"; + return -69; + } + + int error = libusb_init(&ctx); + if(error){ + qDebug() << "libusb_init FAILED"; + return error; + } else qDebug() << "Libusb context initialised"; + + libusb_set_debug(ctx, 3); + + qDebug() << "Opening Device!"; + libusb_device * device_ptr = libusb_get_device2(ctx, usbfs_path); + error = libusb_open2(device_ptr, &handle, file_descriptor); + if(error){ + qDebug() << "ERROR OPENING DEVICE"; + return error; + } + qDebug() << "Device Found!!"; + /*qDebug("Looking for device %x:%x", VIDin, PIDin); + handle = libusb_open_device_with_vid_pid(ctx, VIDin, PIDin); + if(handle==NULL){ + qDebug() << "DEVICE NOT FOUND"; + return -1; + } + qDebug() << "Device found!!"; +*/ + qDebug() << (libusb_kernel_driver_active(handle, 0) ? "KERNEL DRIVER ACTIVE" : "KERNEL DRIVER INACTIVE"); + if(libusb_kernel_driver_active(handle, 0)){ + libusb_detach_kernel_driver(handle, 0); + } + error = libusb_claim_interface(handle, 0); + if(error){ + qDebug() << "libusb_claim_interface FAILED"; + qDebug() << "ERROR" << error << libusb_error_name(error); + return error; + } else qDebug() << "Interface claimed!"; + + return 0; +} + +int androidUsbDriver::get_new_bootloader_ctx(libusb_device **device_ptr, libusb_device_handle **handle, libusb_context **ctx){ + + *(ctx) = NULL; + *(handle) = NULL; + *(device_ptr) = NULL; + + mainActivity.callMethod("closeDevice"); + //Find device in Java + mainActivity.callMethod("findDevice_bootloader"); + QAndroidJniObject usbfs_path_java = mainActivity.getObjectField("usbfs_path"); + QString usbfs_path_qstring = usbfs_path_java.toString(); + std::string usbfs_path_stdstr = usbfs_path_qstring.toStdString(); + char usbfs_path[128]; + strcpy(usbfs_path, usbfs_path_stdstr.c_str()); + jint file_descriptor_java = mainActivity.getField("file_descriptor"); + int file_descriptor = (int)file_descriptor_java; + + qDebug() << "usbfs path = " << usbfs_path; + qDebug() << "file descriptor = " << file_descriptor; + + //Initialise libusb-martin-kuldeep + int error = libusb_init(ctx); + if(error){ + qDebug() << "libusb_init FAILED"; + return error; + } else qDebug() << "Libusb context initialised"; + + libusb_set_debug(*(ctx), 3); + + qDebug() << "Opening Device!"; + *(device_ptr) = libusb_get_device2(*(ctx), usbfs_path); + + error = libusb_open2(*(device_ptr), handle, file_descriptor); + if(error){ + qDebug() << "ERROR OPENING DEVICE"; + return error; + } + qDebug() << "Device Found!!"; + /*qDebug("Looking for device %x:%x", VIDin, PIDin); + handle = libusb_open_device_with_vid_pid(ctx, VIDin, PIDin); + if(handle==NULL){ + qDebug() << "DEVICE NOT FOUND"; + return -1; + } + qDebug() << "Device found!!"; +*/ + qDebug() << (libusb_kernel_driver_active(*(handle), 0) ? "KERNEL DRIVER ACTIVE" : "KERNEL DRIVER INACTIVE"); + if(libusb_kernel_driver_active(*(handle), 0)){ + libusb_detach_kernel_driver(*(handle), 0); + } + error = libusb_claim_interface(*(handle), 0); + if(error){ + qDebug() << "libusb_claim_interface FAILED"; + qDebug() << "ERROR" << error << libusb_error_name(error); + return error; + } else qDebug() << "Interface claimed!"; + + return 0; +} + +int androidUsbDriver::flashFirmware(void){ + + //File name + char fname[128]; + qDebug() << "\n\n\n\n\n\n\n\nFIRMWARE MISMATCH!!!! FLASHING....\n\n\n\n\n\n\n"; + sprintf(fname, "assets:/firmware/labrafirm_%04x_%02x.hex", EXPECTED_FIRMWARE_VERSION, DEFINED_EXPECTED_VARIANT); + qDebug() << "FLASHING " << fname; + + //Copy to somewhere that fopen can access + QFile asset_file(fname); + qDebug() << "asset_file.exists()" << asset_file.exists(); + QString filePath = QStandardPaths::writableLocation( QStandardPaths::StandardLocation::AppLocalDataLocation ); + filePath.append( "/firmware.hex"); + if (asset_file.exists()) { + if( QFile::exists( filePath ) ) + QFile::remove( filePath ); + + if( asset_file.copy( filePath ) ){ + QFile::setPermissions( filePath, QFile::WriteOwner | QFile::ReadOwner ); + qDebug() << "firmware temp file copied to" << filePath; + } + } else qDebug() << "File not found in assets"; + + std::string filePath_stdstr = filePath.toStdString(); + char filePath_cstring[256]; + strcpy(filePath_cstring, filePath_stdstr.c_str()); + + qDebug() << "File path is" << "filePath_cstring"; + + //Switch modes + bootloaderJump(); + mainActivity.callMethod("closeDevice"); + libusb_release_interface(handle, 0); + libusb_close(handle); + libusb_exit(ctx); + + qDebug() << "BA94 closed"; + + QThread::msleep(2000); + + //Initialise libusb-martin-kuldeep + libusb_context *ctx; + libusb_device * device_ptr; + libusb_device_handle *handle; + int error = get_new_bootloader_ctx(&device_ptr, &handle, &ctx); + if(error){ + qDebug() << "get_new_bootloader_ctx FAILED"; + return 69; + } + + /* + //Extract bus/device number + usbfs_path[16] = NULL; + char *busNumber = &usbfs_path[13]; + char *devNumber = &usbfs_path[17]; + + qDebug() << "Thingo thinks it's octal!!"; + qDebug() << busNumber; + qDebug() << devNumber; + + qDebug() << "Remove those leading zeros"; + + for (int i=0; i<3; i++){ + if(busNumber[0] == '0') busNumber++; + if(devNumber[0] == '0') devNumber++; + } + + qDebug() << "Here we go!"; + + qDebug() << busNumber; + qDebug() << devNumber; +*/ + + //Set up interface to dfuprog + int exit_code; + char command1[256]; + sprintf(command1, "dfu-programmer atxmega32a4u erase --force --debug 300"); + char command2[256]; + sprintf(command2, "dfu-programmer atxmega32a4u flash %s --debug 300", filePath_cstring); + char command3[256]; + sprintf(command3, "dfu-programmer atxmega32a4u launch"); + char command4[256]; + sprintf(command4, "dfu-programmer atxmega32a4u launch"); + + //Run stage 1 + exit_code = dfuprog_virtual_cmd(command1, device_ptr, handle, ctx, 0); + if(exit_code){ + //return exit_code+100; + } + + error = get_new_bootloader_ctx(&device_ptr, &handle, &ctx); + if(error){ + qDebug() << "get_new_bootloader_ctx FAILED"; + return 169; + } + + + //Run stage 2 + exit_code = dfuprog_virtual_cmd(command2, device_ptr, handle, ctx, 0); + if(exit_code){ + //return exit_code+200; + } + + error = get_new_bootloader_ctx(&device_ptr, &handle, &ctx); + if(error){ + qDebug() << "get_new_bootloader_ctx FAILED"; + return 269; + } + + + //Run stage 3 + exit_code = dfuprog_virtual_cmd(command3, device_ptr, handle, ctx, 0); + if(exit_code){ + //return exit_code+300; + } + + QThread::msleep(2000); + + error = get_new_bootloader_ctx(&device_ptr, &handle, &ctx); + if(error){ + qDebug() << "get_new_bootloader_ctx FAILED"; + return 369; + } + + //Run stage 4 - double launch to clear the eeprom flag from bootloaderJump. + exit_code = dfuprog_virtual_cmd(command4, device_ptr, handle, ctx, 0); + + mainActivity.callMethod("closeDevice"); + return 0; +} + diff --git a/Desktop_Interface/androidusbdriver.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/androidusbdriver.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index de663998..00000000 --- a/Desktop_Interface/androidusbdriver.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1f4be55624983686164e79e2b9a2524d6656eedf \ No newline at end of file diff --git a/Desktop_Interface/androidusbdriver.h b/Desktop_Interface/androidusbdriver.h new file mode 100644 index 00000000..a69f99a1 --- /dev/null +++ b/Desktop_Interface/androidusbdriver.h @@ -0,0 +1,29 @@ +#ifndef androidUsbDriver_H +#define androidUsbDriver_H + +#include +#include +#include +#include + +#include "unixusbdriver.h" +#include "libusb.h" +#include +#include + + +class androidUsbDriver : public unixUsbDriver +{ + Q_OBJECT +public: + explicit androidUsbDriver(QWidget *parent = 0); + ~androidUsbDriver(); +private: + //Generic Functions + QAndroidJniObject mainActivity; + unsigned char usbInit(unsigned long VIDin, unsigned long PIDin); + int flashFirmware(void); + int get_new_bootloader_ctx(libusb_device **device_ptr, libusb_device_handle **handle, libusb_context **ctx); +}; + +#endif // unixUsbDriver_H diff --git a/Desktop_Interface/androidusbdriver.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/androidusbdriver.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index ba4f439e..00000000 --- a/Desktop_Interface/androidusbdriver.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9a76518896b9b64e6af26f6e41aca8fb5effa38b \ No newline at end of file diff --git a/Desktop_Interface/androidusbdriver.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/androidusbdriver.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 1e3a7894..00000000 --- a/Desktop_Interface/androidusbdriver.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -09cdf7f60c1e5e6b6afad6b7dc2c33b9cfc0b0c8 \ No newline at end of file diff --git a/Desktop_Interface/app_process.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/app_process.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 51bac273..00000000 --- a/Desktop_Interface/app_process.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -24a7bc12faa22343244c90568e4747040d9d0a13 \ No newline at end of file diff --git a/Desktop_Interface/appicon.ico b/Desktop_Interface/appicon.ico new file mode 100644 index 00000000..3ed6f07a Binary files /dev/null and b/Desktop_Interface/appicon.ico differ diff --git a/Desktop_Interface/appicon.ico.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/appicon.ico.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index a02b83c5..00000000 --- a/Desktop_Interface/appicon.ico.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7ea9674d8203107793447a028a37ede045e69a88 \ No newline at end of file diff --git a/Desktop_Interface/bin/.DS_Store.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/bin/.DS_Store.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 112bc444..00000000 --- a/Desktop_Interface/bin/.DS_Store.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f943b7ad9e3830a17d37ea9ac811ed6806ba3a4f \ No newline at end of file diff --git a/Desktop_Interface/bin/._.DS_Store.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/bin/._.DS_Store.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 95175ab4..00000000 --- a/Desktop_Interface/bin/._.DS_Store.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -301d01b13096dca1cd26a9b8830a99612aa2553b \ No newline at end of file diff --git a/Desktop_Interface/bin/._labrador.dmg.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/bin/._labrador.dmg.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index cb425707..00000000 --- a/Desktop_Interface/bin/._labrador.dmg.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4f7ad2642812f34dbd1eee02076639d9e1ea816d \ No newline at end of file diff --git a/Desktop_Interface/bin/Labrador.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/bin/Labrador.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 3854b919..00000000 --- a/Desktop_Interface/bin/Labrador.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -40a0a3d9532598c8bd011e89f03c85c922e9bedf \ No newline at end of file diff --git a/Desktop_Interface/bin/Labrador.exe.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/bin/Labrador.exe.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index ad185ea3..00000000 --- a/Desktop_Interface/bin/Labrador.exe.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -19302fea035bc752b0f9f020d0a0edca0c7f6d87 \ No newline at end of file diff --git a/Desktop_Interface/bin/Labrador.pdb.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/bin/Labrador.pdb.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 06b5d03c..00000000 --- a/Desktop_Interface/bin/Labrador.pdb.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2792c117745b6ae65ed60b0ad7b0509483e44755 \ No newline at end of file diff --git a/Desktop_Interface/bin/Labrador_goed.exe.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/bin/Labrador_goed.exe.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index ee01e436..00000000 --- a/Desktop_Interface/bin/Labrador_goed.exe.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -135640b475285d976c0a56bfccf1790d7b478dd2 \ No newline at end of file diff --git a/Desktop_Interface/bin/Labrador_libusbk.exe.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/bin/Labrador_libusbk.exe.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 5adb94d9..00000000 --- a/Desktop_Interface/bin/Labrador_libusbk.exe.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3ed8274777c08ce8fd30e74c20e542cbfb81ca80 \ No newline at end of file diff --git a/Desktop_Interface/bin/firmware/dfu-programmer.exe.REMOVED.git-id b/Desktop_Interface/bin/firmware/dfu-programmer.exe.REMOVED.git-id deleted file mode 100644 index b819c11c..00000000 --- a/Desktop_Interface/bin/firmware/dfu-programmer.exe.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b27d99e3b1bb4ec243a6f22881053dd6e6e94334 \ No newline at end of file diff --git a/Desktop_Interface/bin/firmware/flash.bat.REMOVED.git-id b/Desktop_Interface/bin/firmware/flash.bat.REMOVED.git-id deleted file mode 100644 index c0361a58..00000000 --- a/Desktop_Interface/bin/firmware/flash.bat.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -33b4424dfe12584fb5dffb5e26758a13d7b57b57 \ No newline at end of file diff --git a/Desktop_Interface/bin/firmware/labrafirm_0001_01.hex b/Desktop_Interface/bin/firmware/labrafirm_0001_01.hex new file mode 100644 index 00000000..044f2051 --- /dev/null +++ b/Desktop_Interface/bin/firmware/labrafirm_0001_01.hex @@ -0,0 +1,715 @@ +:1000000017C1000031C100002FC100002DC1000048 +:100010002BC1000029C100000C9414090C94230981 +:1000200023C1000021C100001FC100001DC100004C +:100030001BC1000019C1000017C1000015C100005C +:1000400013C1000011C100000FC100000DC100006C +:100050000BC1000009C1000007C1000005C100007C +:100060000C94FF090C940A0AFFC00000FDC00000B8 +:10007000FBC00000F9C00000F7C00000F5C00000A0 +:10008000F3C00000F1C00000EFC00000EDC00000B0 +:10009000EBC00000E9C00000E7C00000E5C00000C0 +:1000A000E3C00000E1C00000DFC00000DDC00000D0 +:1000B000DBC00000D9C00000D7C00000D5C00000E0 +:1000C000D3C00000D1C00000CFC00000CDC00000F0 +:1000D000CBC00000C9C00000C7C00000C5C0000000 +:1000E000C3C00000C1C00000BFC00000BDC0000010 +:1000F000BBC00000B9C00000B7C00000B5C0000020 +:10010000B3C00000B1C00000AFC00000ADC000002F +:10011000ABC00000A9C00000A7C00000A3C400003D +:10012000A3C00000A1C000009FC000009DC000004F +:100130009BC0000099C0000097C0000095C000005F +:1001400093C0000091C000008FC000000C9474099F +:100150008BC0000089C0000087C0000085C000007F +:1001600083C0000081C000007FC000007DC000008F +:100170007BC0000079C0000077C0000075C000009F +:1001800073C0000071C000006FC000006DC00000AF +:100190006BC0000069C0000067C0000065C00000BF +:1001A00063C0000061C000005FC000005DC00000CF +:1001B0005BC0000059C0000057C0000055C00000DF +:1001C00053C0000051C000004FC000004DC00000EF +:1001D0004BC0000049C0000047C0000045C00000FF +:1001E00043C0000041C000003FC000003DC000000F +:1001F0003BC000000C9420140C94D8140F0411047C +:1002000013041504170419041B041D04DB0B010C53 +:10021000280C510C5A0C5F0CA40CA90CC80CCF0C68 +:100220006B0C730C7B0C860C880C8A0C920C9A0C51 +:1002300011241FBECFEFCDBFDFE2DEBF10E2A0E092 +:10024000B0E2E2EDFBE202C005900D92AA3BB107DD +:10025000D9F72DE2AAEBB0E201C01D92AC3FB20784 +:10026000E1F794D20C94E715CBCE84E0809356004E +:100270008CE1C0D3809363008BEB8093660080E8B1 +:100280008093650081E08093600088ED84BF1092C8 +:10029000410083E080935000809151008330E1F76A +:1002A0008091500081608093500088E180935500D8 +:1002B0008091510080FFFCCF80915000806180933D +:1002C00050008091510084FFFCCF88ED84BF84E012 +:1002D000809340000895E0E7F0E085818E7F85837C +:1002E000E0E0FAE08FEB9DE586A397A380EE9EE227 +:1002F00080A391A382E0808308958091200A909149 +:10030000210A813E2EE2920718F020919E2306C01A +:10031000803E2EE2920721F020919B2320936A00D9 +:1003200020910520222321F080910520815033C0A7 +:10033000885F9A42813D974080F11092BA20809167 +:10034000BB209091BC20A091BD20B091BE20019611 +:10035000A11DB11D8093BB209093BC20A093BD2014 +:10036000B093BE208091BB209091BC20A091BD2075 +:10037000B091BE20892F9A2FAB2FBB278093BE232D +:100380008091BB209091BC20A091BD20B091BE2057 +:100390008093BD2386E08093052080910720909173 +:1003A00008200196B1F4809109208F3F91F080914F +:1003B0000620811106C0809106208150809306207E +:1003C00008958091140190911501809307209093D6 +:1003D00008200895009709F45EC00CF457C040E06F +:1003E00020916B0030E020939C2330939D2320913B +:1003F0009C2330919D233695322F222737952795C0 +:1004000020939C2330939D2350916A0020919C233C +:1004100030919D23250F311D20939C2330939D23E4 +:10042000000020919C2330919D232817390728F440 +:1004300010929C2310929D23089520919C2330912B +:100440009D23280F391F2115304238F08FEF9FE18F +:1004500080939C2390939D23089520919C23309119 +:100460009D23442329F0A901481B590BCA0102C04E +:10047000820F931F80939C2390939D2380919C23B4 +:1004800090919D238F7780936A000895919581952F +:10049000910941E0A5CF0895CF93DF93C091200A41 +:1004A000D091210A80910320909104209E01281B65 +:1004B000390B20939F233093A0238091BA20811180 +:1004C0004BC080919F239091A0238E3C9F4FD4F4EA +:1004D00080919F239091A0238B369F4F9CF0809119 +:1004E0000220882321F080910220815008C0809151 +:1004F0006A0080939E2381E08093BA208CE08093F1 +:1005000002202AC08CE08093022080919F2390914A +:10051000A0238A369F4F1CF08FEF9FEF02C081E02F +:1005200090E08093992390939A2380919F239091B8 +:10053000A0232091992330919A2360E370E00E94D8 +:10054000BE15261B370B2093992330939A23809155 +:10055000992390919A233EDF8091BA20813029F52A +:1005600080919F239091A023C39794F080910220C3 +:10057000882331F08091022081508093022015C0A1 +:1005800080916A0080939B2383E08093BA200DC002 +:1005900080919F239091A023873991051CF481E0DD +:1005A00090E002C08FEF9FEF15DFC0930320D09340 +:1005B0000420DF91CF9108958617970779F0681787 +:1005C000790728F49C01261B370BB90109C086174F +:1005D000970718F4681B790B03C0089560E070E07A +:1005E000CB010895CF93DF9380910020909101205B +:1005F000892B51F0809100209091012001978093E8 +:1006000000209093012043C080E490E0809300207C +:100610009093012080910720909108200196B9F1D4 +:10062000809114019091150120910920263018F431 +:1006300067E771E002C06EEE72E00E94AA15EC015D +:1006400080910720909108208C179D0758F46091A5 +:10065000072070910820CE01AFDF029718F080ECE0 +:100660009DE511C08091072090910820C817D907F7 +:1006700070F46091072070910820CE019DDF0297F1 +:1006800030F08FEB9DE58093360A9093370ADF9127 +:10069000CF910895AC01460F571F861B970B2091F1 +:1006A000200A3091210A24173507C8F72091200A23 +:1006B0003091210A8217930790F70895E0E8F6E059 +:1006C0008FE0808385E0848308951F93CF93DF9329 +:1006D000C0E4D0E0198180E4898340E250E064ED19 +:1006E0007DE280E290E00E94390F1983DF91CF9183 +:1006F0001F9108951F93CF93DF93C0E4D0E0198139 +:1007000080E4898387ED97E20E94810F81E00E9457 +:10071000930F1983DF91CF911F91089508950F933F +:100720001F93842F242F30E0215831099DE7929F99 +:10073000A001939F500D112490910920953048F409 +:10074000843810F049585E4F9091C42027E731E07B +:1007500004C09091C4202EEE32E0929FB001939F8E +:10076000700D11249A01260F371FA9014850584DCA +:100770000FE813E02DE730E060E00E944B131F917B +:100780000F9108951CBEEEEFF0E409949EDF809176 +:10079000D42D882369F080E2E4EDFDE2A7EDB7E215 +:1007A00001900D928A95E1F71092D727A3DFEADF37 +:1007B00087E08093A200789458DDB0DF86D765D1BA +:1007C00088D160E080E01FD10BD18CE0FFD04AD50A +:1007D000EED507D673DF60EA70E28AEA93E20E9400 +:1007E000E015000000000000000000000000000014 +:1007F00000000000000000000000000000008091E8 +:10080000BF20882371F3E091D6258E2F90E08830A9 +:100810009105A0F4FC01E250FF4F0C94D11585D155 +:100820000DC0F5D10BC07CD209C000D307C08CD35A +:1008300005C012D403C011D401C082D41092BF20CD +:10084000D0CF08950895809114018093B3238091AF +:1008500015018093B423809124018093B523809166 +:1008600025018093B6238091200A8093BF23809135 +:10087000210A8093C0238091140190911501863440 +:10088000914080F08091140190911501893A914036 +:1008900048F480911401909115018093F42D909368 +:1008A000F52D00008091C220882339F014DD1092CC +:1008B000C22081E08093C12008958091C1208823C7 +:1008C00041F08091BA20833019F417DD8BDE01C02E +:1008D000E3DD8091C020882351F080911401909134 +:1008E00015018093F42D9093F52D1092C0208091E6 +:1008F00009202091140130911501853028F481E000 +:100900002737314030F004C081E02E3E324008F0FD +:1009100080E08093C42008950F931F9381E080931B +:10092000C7208093C2200FE813E02DE730E048EFA6 +:1009300057E260E081E80E944B132DE730E045E785 +:1009400058E260E082E80E944B132DE730E042EF6E +:1009500058E260E083E80E944B132DE730E04FE659 +:1009600059E260E084E80E944B132DE730E04CEE42 +:1009700059E260E085E80E944B132DE730E049E63C +:100980005AE260E086E80E944B1381E01F910F91CC +:1009900008951092C720089581E0089581E0089598 +:1009A00010922002982F9C7193689093200287FFE9 +:1009B00003C090E182E002C090E080E0892B809348 +:1009C000210210922202109226020895E0E0F2E045 +:1009D00010AA836880AB80E181AB12AA16AA0895A1 +:1009E000E0E0F2E010A683E880A78FE281A712A6DC +:1009F00016A60895AAECB1E092E09C93E82FF0E0EF +:100A000084911C920895909171009D7F9093710044 +:100A100010920002623011F09CE101C09EE19093BF +:100A2000010290E490930202811102C080E401C0AF +:100A300080EC80930302613011F084E001C083E018 +:100A40008093040280E2D6DF80930C0281E2D2DF41 +:100A500080930D02109218021092190281E0809387 +:100A60000002BECF1F920F920FB60F9211248F93E8 +:100A7000000000000000000081E0809323028F91BD +:100A80000F900FBE0F901F901895CF93DF93E0E764 +:100A9000F0E082818B7F8283C0E2D3E08DE08883A7 +:100AA00080E4898389E08A8383E3A4DF888782E303 +:100AB000A1DF898787E39EDF8A8786E39BDF8B87B9 +:100AC000E0E2F6E08081836080831482DF91CF9141 +:100AD0000895E0E7F0E080818E7F808383E8809353 +:100AE00000010895E0E0F1E0108A80E4808B10A21C +:100AF00080A310AA80ABE0E4F1E010828083109222 +:100B0000C6201092C52081E08093C4201092A823B3 +:100B10001092A9231092A6231092A72308958093E0 +:100B2000D62581E08093BF200895CF93DF93109264 +:100B30000920D8DFC0E0D1E01EAA84E288AB19AA60 +:100B400049E54AAB32E03BAB60910B2070910C2041 +:100B50006CAB7DAB67ED75E268AF79AF1AAE9BE326 +:100B60009CAF93E090933D0110923E0128A920682C +:100B700028AB10924601E0E4F1E08083109241013D +:100B8000409342019093430140910D2050910E20DB +:100B9000409344015093450146EC53E24093480191 +:100BA0005093490110924A0129E320934C019093FC +:100BB0004D0110924E01908190689083188A90E4C4 +:100BC000988B888B198A95E99A8B90E19B8B4EEED6 +:100BD00052E04C8B5D8B888F398F1A8E88EF97E2AD +:100BE0008C8F9D8F1E8E68EC70E084EF91E052DD5B +:100BF00088EC90E0809307209093082081E0809318 +:100C0000062088898068888BDF91CF9108951F9393 +:100C1000CF93DF9311E01093092064DFC0E0D1E0AF +:100C200018AA80E488AB84E088AB19AA1AAA4BE41E +:100C30004BAB1CAA1DAA1EAA8AE090E288AF99AF0E +:100C40001AAE60EA6CAF38E030933D0110923E017D +:100C500088A9806A88ABE0EAF8E085E58083808334 +:100C600010924601E0E4F1E084E2808310924101B9 +:100C700099E59093420122E020934301A0910B203B +:100C8000B0910C20A0934401B0934501A7EDB5E2CB +:100C9000A0934801B093490110924A019BE39093BD +:100CA0004C0193E090934D0110924E019081906819 +:100CB000908388A319A295E99AA34BA34EEE52E024 +:100CC0004CA35DA368A739A71AA666EE7AE26CA7C3 +:100CD0007DA71EA6888B198A9A8B90E19B8B4C8BE3 +:100CE0005D8B888F298F1A8E88EF97E28C8F9D8F6E +:100CF0001E8E68EC70E084EF91E0CCDC88EC90E034 +:100D000080930720909308201093062088A1806884 +:100D100088A388898068888BDF91CF911F9108957F +:100D20001F93CF93DF9312E010930920DBDEC0E026 +:100D3000D1E01EAA84E288AB19AA39E53AAB1BAB15 +:100D400040910B2050910C204CAB5DAB47ED55E230 +:100D500048AF59AF1AAE9BE39CAF93E090933D012F +:100D600010923E0128A9206828AB10924601E0E4C9 +:100D7000F1E080831092410130934201909343014E +:100D800020910D2030910E20209344013093450195 +:100D900026EC33E2209348013093490110924A0136 +:100DA00029E320934C0190934D0110924E019081C4 +:100DB00090689083188A90E4988B888B198A45E90B +:100DC0004A8B90E19B8B2EEE32E02C8B3D8B888FF3 +:100DD000198F1A8E68EF77E26C8F7D8F1E8E88A335 +:100DE00019A24AA39BA32CA33DA384E388A719A718 +:100DF0001AA686EE9AE28CA79DA71EA668EC70E064 +:100E000084EF91E047DC88EC90E08093072090939A +:100E1000082081E08093062088898068888B88A1DB +:100E2000806888A3DF91CF911F9108951F93CF937E +:100E3000DF9313E01093092055DEC0E0D1E010925B +:100E40004601E0E4F1E084E280831092410129E56B +:100E50002093420192E09093430140910B205091E6 +:100E60000C20409344015093450147ED55E24093D7 +:100E700048015093490110924A019BE390934C0121 +:100E800010934D0110924E019081906890831EAA9C +:100E900088AB19AA2AAB1BAB20910D2030910E20F4 +:100EA0002CAB3DAB26EC33E228AF39AF1AAE99E359 +:100EB0009CAF10933D0110923E0198A9906898ABA9 +:100EC00018A250E458A394E098A319A21AA24BE4E4 +:100ED0004BA31CA21DA21EA22AE030E228A739A71C +:100EE0001AA630EA3CA728E02DA71EA698A1906A72 +:100EF00098A395E59093A008188A588B888B198A37 +:100F000085E98A8B4B8B8EEE92E08C8B9D8B388F94 +:100F1000298F1A8E88EF97E28C8F9D8F1E8E68EC3A +:100F200070E084EF91E0B6DB88EC90E080930720DE +:100F30009093082081E08093062088898068888BC0 +:100F4000DF91CF911F9108951F93CF93DF9314E00A +:100F500010930920C7DDC0E0D1E018AA80E488AB77 +:100F600018AB19AA1AAA3BE43BAB1CAA1DAA1EAADD +:100F70008AE090E288AF99AF1AAE50EA5CAF88E0A1 +:100F800080933D0110923E0198A9906A98AB95E537 +:100F90009093A00810924601E0E4F1E094E290837F +:100FA0001092410129E52093420122E02093430160 +:100FB00060910B2070910C20609344017093450167 +:100FC00067ED75E2609348017093490110924A0100 +:100FD0002BE320934C0123E020934D0110924E010E +:100FE000208120682083988B198A45E94A8B3B8BA6 +:100FF0002EEE32E02C8B3D8B588F898F1A8E68EF46 +:1010000077E26C8F7D8F1E8E98A319A24AA39AE473 +:101010009BA32CA33DA393EC98A789A71AA686EEC1 +:101020009AE28CA79DA71EA668EC70E084EF91E081 +:1010300031DB88EC90E0809307209093082081E0DA +:101040008093062088898068888B88A1806888A31F +:10105000DF91CF911F910895FFCFCF93DF9386E06B +:10106000809309203FDDC0E0D1E01EAA84E288AB76 +:1010700019AA39E53AAB93E09BAB40910D20509112 +:101080000E204CAB5DAB46EC53E248AF59AF1AAE05 +:1010900029E32CAF90933D0110923E0128A92068CE +:1010A00028AB10924601E0E4F1E080831092410108 +:1010B0003093420122E02093430140910B20509154 +:1010C0000C20409344015093450147ED55E2409375 +:1010D00048015093490110924A013BE330934C017F +:1010E00090934D0110924E01908190689083188AE0 +:1010F00090E4988B888B198A95E99A8B90E19B8B69 +:101100004CED55E04C8B5D8B888F298F1A8E88EFC4 +:1011100097E28C8F9D8F1E8E68EC70E084EF91E0DB +:10112000B9DA80E991E0809307209093082081E06C +:101130008093062088898068888BDF91CF910895FD +:10114000CF93DF9387E080930920CCDCC0E0D1E02F +:101150001EAA84E288AB19AA39E53AAB93E09BABAF +:1011600040910D2050910E204CAB5DAB46EC53E20C +:1011700048AF59AF1AAE29E32CAF90933D011092BE +:101180003E0128A9206828AB10924601E0E4F1E076 +:101190008083109241013093420122E02093430169 +:1011A00040910B2050910C204093440150934501F5 +:1011B00047ED55E2409348015093490110924A018E +:1011C0003BE330934C0190934D0110924E0190817E +:1011D00090689083188A90E4988B95E2988B198A8E +:1011E00095E99A8B90E19B8B4CED55E04C8B5D8B98 +:1011F000888F298F1A8E88EF97E28C8F9D8F1E8E95 +:1012000068EC70E084EF91E045DA80E991E080934A +:1012100007209093082081E08093062088898068C9 +:10122000888BDF91CF9108951F920F920FB60F9286 +:1012300011248F9381E0809303018F910F900FBE53 +:101240000F901F9018951F920F920FB60F921124B6 +:101250008F9382E0809303018F910F900FBE0F90C8 +:101260001F901895E0E7F0E083818C7F8383848171 +:101270008C7F848380818D7F8083E0E8F1E080EC47 +:101280008283128688EC81831186A0E0B8E034E086 +:101290003C9323E011962C93119714961C9214976B +:1012A00085ED91E096968D939C93979716961C9258 +:1012B0001697E0E4F8E030832183148286A397A395 +:1012C0001682E0E6F6E0808180618083E0E4F9E068 +:1012D00083E18183148282E08683A6A3B7A310A64C +:1012E00011A681E0808308951F920F920FB60F928E +:1012F00011242F933F934F935F938F939F93CF939B +:10130000DF931F92CDB7DEB78FEF80934C098091AA +:101310000920873031F480912C02898390912D022D +:1013200002C090912C028091C320891B20916809F2 +:101330003091690982308CF02A3F374070F4209157 +:1013400068093091690989301CF481E090E002C09D +:1013500086E090E0820F931F18C0209168093091B9 +:1013600069098F3FB4F42730310598F0209168095E +:1013700030916909883F1CF081E090E002C086E06E +:1013800090E0A901481B590BCA01809378099093FA +:1013900079090F90DF91CF919F918F915F914F913C +:1013A0003F912F910F900FBE0F901F901895E0E77F +:1013B000F0E083818F7E8383E0E4F6E080818A6AB7 +:1013C00080838FEF848388E5828BE0EAF8E080E316 +:1013D000838384EC858387E08683178288E1848316 +:1013E0000895E0E7F0E08381877F8383E0ECF8E015 +:1013F00080E48083118288E58093550608951F92CA +:101400000F920FB60F92112400000F900FBE0F9095 +:101410001F9018951F920F920FB60F9211248F9361 +:10142000EF93FF93E0EAF8E080818083FF91EF91F2 +:101430008F910F900FBE0F901F9018959FB7F89443 +:10144000A0E5B0E016968C911697897F16968C933E +:101450001697E0E6F0E080E885838BEB86831696AE +:101460008C911697846016968C938081816080831E +:101470009FBF08959FB7F894E82FF0E0E059FF4F21 +:1014800060958081682360839FBF0895CF938630E5 +:1014900011F0C0E001C0C8E18091510081FD0DC094 +:1014A0009FB7F894809150008260809350009FBF56 +:1014B0008091510081FFFCCFC1DF6C2F636084E419 +:1014C00090E0BCD460E480E0CF91D4CF8091C8207C +:1014D00008958091C820813009F45BCA0895F0D046 +:1014E000FC0183818093C820811101C015CA81E06D +:1014F00008959091C625892F807697FF07C0803484 +:1015000091F48091C72581110EC048CA803459F4E6 +:101510008091C725811107C08091CC259091CD2560 +:10152000892B09F039CA80E008958091C8258F770A +:101530000C94CD129091D020911102C080E00895BA +:10154000E091CD20F091CE200190F081E02D9481AA +:101550008917A0F7E093CB20F093CC202281338130 +:101560002E0F3F1FE217F30798F49181943061F436 +:101570009281891309C09381691306C0E093CB203F +:10158000F093CC2081E008959081E90FF11DEACF1E +:10159000E093CB20F093CC20D1CFE091CD20F091FF +:1015A000CE200190F081E02D228133812E0F3F1F4C +:1015B000FC014081E40FF11DE217F30748F481813B +:1015C000843031F0853039F08081E80FF11DF4CF9F +:1015D00080E090E00895CF0108951F93CF93DF93AB +:1015E000182FA8DF882339F1C091CB20D091CC20CF +:1015F000CE01D3DFEC01892B41F04C815D816B8101 +:101600008A81D8D78111F4CF16C0E091CD20F09116 +:10161000CE2092818381E92FF82FE10FF11DE10F98 +:10162000F11D0190F081E02D0190F081E02DDF911E +:10163000CF911F91099480E0DF91CF911F91089580 +:10164000EF92FF921F93CF93DF93C82F60E072DF7A +:10165000811102C010E02DC0E091CD20F091CE208C +:1016600092818381E92FF82FEC0FF11DEC0FF11D12 +:10167000E080F180D7011696ED91FC9117970995BE +:10168000682F8C2F57DF182F882321F3C091CB2090 +:10169000D091CC20CE0181DFEC01892B21F08A8111 +:1016A0000E940714F7CFD7011296ED91FC91139782 +:1016B0000995812FDF91CF911F91FF90EF900895B1 +:1016C0008091CB209091CC200895FBC6CF93809140 +:1016D000D020811108C01092D0201092D4201092F6 +:1016E000D520CF910895C0E0E091CD20F091CE209B +:1016F0000190F081E02D8481C81768F78C2FA0DF5E +:10170000CF5FF2CFCF938091D0208823F1F0C0E05B +:10171000E091CD20F091CE20A081B18114968C91E2 +:10172000C81798F492818381E92FF82FEC0FF11DEF +:10173000EC0FF11D0190F081E02D0084F185E02D8A +:10174000309709F00995CF5FE3CFCF910895EF92DD +:10175000FF920F931F93CF93DF931F92CDB7DEB706 +:101760001092D0251092D1251092D2251092D32517 +:101770001092D4251092D5258091C62587FF07C0E9 +:101780002091CC253091CD25232B09F44EC3982FE1 +:101790009076903409F00BC1E091C7258E2F90E030 +:1017A000FC01E05AF109EA30F10508F0CDC2EA5F28 +:1017B000FE4F0C94D11581E08093C02080910720CA +:1017C000909108208093B723809107209091082062 +:1017D0009093B82380919E238093B92380919B237B +:1017E0008093BA2380916A008093BB2380916B0021 +:1017F0008093BC236091CC257091CD258AEA93E239 +:10180000D4C0109200088091C8259091C92580937A +:101810003608909337088091CA258F70809300080E +:101820006091CC257091CD2586EC93E2BCD62091B9 +:101830000D2030910E208091CC259091CD25281738 +:10184000390709F4F0C280930D2090930E2026C032 +:10185000109240088091C8259091C9258093760800 +:10186000909377088091CA258F708093400860918B +:10187000CC257091CD2587ED95E295D620910B2052 +:1018800030910C208091CC259091CD2528173907D7 +:1018900009F4C9C280930B2090930C2080910920F9 +:1018A00051C010926809109269098091C8258093EF +:1018B000C320B9C28091C82580932406B4C2E091A8 +:1018C000C825F091C925E830F10508F03DC2E05F78 +:1018D000FE4F0C94D11560E080E095D88091CA2528 +:1018E0005FD880E02FC060E080E08DD88091CA256D +:1018F00057D881E027C061E081E085D88091CA2572 +:101900004FD88091CB2562D882E01CC083E01AC0FA +:1019100084E018C060E080E076D88091CA2540D885 +:1019200085E010C061E080E06ED88091CA2538D88B +:1019300086E008C062E080E066D88091CA258068B1 +:101940002FD887E0ECD86FC28091C8258093840699 +:101950006AC28091C8259091C925892B91F00E9477 +:10196000650380E2E4EDFDE2A7EDB7E201900D92A0 +:101970008A95E1F781E08093D7270E947A030E943D +:101980006503E9E7F0E091E088EDF89484BF908387 +:101990006091CC257091CD258AEA90E206C06091D5 +:1019A000CC257091CD2589EA90E2FDD53CC29111FC +:1019B000CBC187FFFCC02091CC253091CD252115CE +:1019C000310509F4C1C18F7109F09EC08091C7250E +:1019D000863071F0883009F48EC08111B5C1223093 +:1019E000310509F0B1C162E070E084ED90E2DDCF35 +:1019F0008091C8259091C925292F332722303105A0 +:101A0000A1F064F42130310509F09EC180911920C4 +:101A100090911A20DC016C9170E05BC0233031059D +:101A200089F12F30310509F18FC1E0911920F09132 +:101A30001A202189821708F087C19927880F991FDA +:101A4000880F991FE0911B20F0911C20E80FF91FCF +:101A500080819181FC0162817381A5D5E091CE25C1 +:101A6000F091CF2582E0818335C080911D20909137 +:101A70001E20009709F468C1DC0112966D917C91DB +:101A8000139727C099278130910569F038F00297A4 +:101A900009F05AC168E08AE890E208C064E070E0AA +:101AA0008CE990E216C067E083E990E2282FAAE76C +:101AB000B0E2FC01819190E08D939D938E2F821B6B +:101AC0008617C0F3660F6E5F6093782070E088E73A +:101AD00090E269D58091CC259091CD252091D0259B +:101AE0003091D1258217930708F09DC18093D025AE +:101AF0009093D12598C12130310509F025C161E0CD +:101B000070E080ED90E251CF8130C9F58091C7251A +:101B10008A3009F019C12130310509F015C18091D1 +:101B2000D020882309F410C1E090CA25F090CB257D +:101B30000091CD201091CE20D801ED91FC918481AF +:101B4000E81608F001C160E08E2DF4DC882309F46A +:101B5000FBC0FF24EE0CFF1CF801828193818E0DE7 +:101B60009F1DDC01ED91FC910680F781E02D099528 +:101B70008093D22061E070E082ED90E216CF823057 +:101B800009F0E2C08091C7258111DEC02230310505 +:101B900009F0DAC08091CA255ED590E08093C92013 +:101BA0009093CA2062E070E089EC90E2FECE8F71E3 +:101BB00009F07DC08091C725833009F4C5C018F4B1 +:101BC0008130A1F0C1C0853019F0893039F1BCC035 +:101BD0008091CC259091CD25892B09F0B5C085E960 +:101BE0009AE08093D2259093D3251DC18091CC2576 +:101BF0009091CD25892B09F0A7C08091C82590919F +:101C0000C925019709F0A0C08091D4209091D520DA +:101C10008D7F8093D4209093D52005C18091CC25D1 +:101C20009091CD25892B09F08FC0BAD4882309F46F +:101C30008BC02091C8253091C9253327E091192008 +:101C4000F0911A20818990E08217930708F47CC0F4 +:101C50003DDD8091C8259091C9258093D0208823AF +:101C600009F4E1C099278150904C880F991F880F83 +:101C7000991F20911B2030911C20820F931F80936D +:101C8000CD209093CE2010E0E091CD20F091CE2099 +:101C90000190F081E02D8481181708F0C4C060E045 +:101CA000812F9BDC882309F44FC01F5FEDCF81306B +:101CB000F1F48091C7258B3009F046C08091CC2586 +:101CC0009091CD25892B09F03FC08091D0208823A9 +:101CD00009F43AC01091CA256091C825812F698303 +:101CE000AFDC6981882381F1812F77DC2BC08230C2 +:101CF00059F58091C725813019F0833089F024C0CF +:101D00008091CC259091CD25892BF1F48091C82527 +:101D10009091C925892BC1F48091CA25A3D412C002 +:101D20008091CC259091CD25892B71F48091C82587 +:101D30009091C925892B41F48091CA2538D580918D +:101D4000CA256ED581116FC08091C6258F718130F3 +:101D5000B9F58091D020882399F1E090CA25F090C0 +:101D6000CB250091CD201091CE20D801ED91FC9192 +:101D70008481E81628F560E08E2DDCDB882301F1F4 +:101D8000F701FF27EE0FFF1FD80112968D919C914E +:101D90001397E80FF91F00811181D8011696ED9174 +:101DA000FC9117970995682F8E2DC4DB882341F08D +:101DB000D8011496ED91FC9115970995811133C0C6 +:101DC0008091C6258F71823081F58091D020882343 +:101DD00061F1F12CE091CD20F091CE20A081B18174 +:101DE00014968C91F81608F592818381E92FF82FCB +:101DF000EF0DF11DEF0DF11D00811181D801169637 +:101E0000ED91FC9117970995682F8F2D93DB88230F +:101E100061F0D8011496ED91FC9115970995811107 +:101E200002C0F394D7CF81E001C080E00F90DF9132 +:101E3000CF911F910F91FF90EF9008951BBEFC0171 +:101E400028ED24BF608308958091CF0187FDFCCFEA +:101E500008951F93CF93DF93C0ECD1E01A858A8752 +:101E600061E08BEC91E0EADF1A87DF91CF911F915F +:101E70000895CF92DF92EF92FF920F931F93CF932B +:101E8000DF9300D0CDB7DEB78C017B0149835A8345 +:101E9000DBDF8CECC82EDD24D394F60190819860B2 +:101EA0009083B801705F49815A81C70180D6F601DD +:101EB0008081877F80830F900F90DF91CF911F915A +:101EC0000F91FF90EF90DF90CF900895CF93DF9325 +:101ED00000D0CDB7DEB76A838983B6DFACECB1E062 +:101EE0009C9198609C938981E82FF0E0F05F6A8173 +:101EF00060838C91877F8C930F900F90DF91CF91AF +:101F000008950F931F93CF938C019EDFC0E0F801DB +:101F100061918F018C2FDADFCF5FC032C1F7CF9193 +:101F20001F910F910895CF93DF931F92CDB7DEB726 +:101F300089838ADF898120E2829FC0011124E0EC3D +:101F4000F1E012829183808385E30F90DF91CF913E +:101F500080CF4091CA01E62FF72F8093CA01849168 +:101F60004093CA010895E82FF0E0EA50F24D8081D5 +:101F70008F3F09F4FFCF9FB7F89480818F5F8083F4 +:101F80009FBF0895E82FF0E0EA50F24D8081811163 +:101F900001C0FFCF9FB7F8948081815080839FBF9D +:101FA0000895CF93C82F80919823C11105C088232D +:101FB00039F081E0E7DF04C0811102C081E0D3DFA6 +:101FC000C0939823CF910895282F2F70082E000CCE +:101FD000990B392F331F3327331F832F90E0820F44 +:101FE000911D820F911D23E0880F991F2A95E1F71B +:101FF0008C5D9C4D08950F93E8ECF4E080818F7D1B +:10200000808380818F7D8083ECE2F3E202E00593A0 +:1020100010922E2310922F2300E2069300E40693E1 +:10202000E4E2F3E200E2069300E40693E6ECF5E274 +:102030001486158616861786128613861092072335 +:102040000F9108950F9385E080930723EDE2F3E26B +:1020500004E00593E5E2F3E204E005930F910895AF +:102060000F9383E08093072310922E2310922F2347 +:10207000ECE2F3E202E006930F910895E091D2259D +:10208000F091D325309709F009940895282F2F70E7 +:10209000082E000C990B392F331F3327331F832F42 +:1020A00090E0820F911D820F911D029749E0489F99 +:1020B0009001499F300D1124C901895A9D4D089501 +:1020C0008F929F92AF92BF92DF92EF92FF920F9307 +:1020D0001F93CF93DF93D82ED9DFEC018D2D74DFC2 +:1020E0007C01DC011196EC91E770E150E73040F49F +:1020F000F0E0EE0FFF1FE455FF4D0081118102C09B +:1021000008E010E0ED81FE812B813C814881D70100 +:10211000D7FE48C016968D919C9117978E0F9F1FE2 +:102120008D839E838217930761F1281B390B21153C +:10213000B4E03B0738F02FEF33E0C901B8010AD50E +:10214000281B390B41FF0AC0C901B80103D5AC01F6 +:1021500091E0452B09F090E0892F01C080E0988143 +:1021600080FB91F99883F7011682178222833383CB +:1021700029813A818D819E81820F931F848395836B +:102180000EC041FF71C04D7F4883D70116961D9246 +:102190001C92179712961D921C921397F70102E05A +:1021A00006937BC01296AD90BC90139742FF10C06F +:1021B00089809A80C901B801CDD4B0E4DB9EB0011A +:1021C000112469567F4DAC01C4018E0F9F1FEFD4BF +:1021D0008D819E818A0D9B1D8D839E832B813C81E9 +:1021E0002817390710F42D833E83F70186819781E4 +:1021F000A816B906C9F58D819E8182179307A1F1B2 +:10220000281B390B2115F4E03F0710F02FEF33E0C6 +:10221000C901B8019FD4281B390BD70112961D9212 +:102220001C9213972017310778F488818460888383 +:10223000B0E4DB9EC001112489569F4DF7018483D1 +:10224000958306831783AACF49815A818D819E8108 +:10225000840F951FD70114968D939C93159716960E +:102260002D933C9317979ACF888180FF16C08E7F5D +:102270008883EF81F885309781F06D817E814D2DC7 +:1022800080E0DF91CF911F910F91FF90EF90DF9051 +:10229000BF90AF909F908F900994DF91CF911F9145 +:1022A0000F91FF90EF90DF90BF90AF909F908F9035 +:1022B00008950F93CF93DF9380910723833029F400 +:1022C000DDDEDF91CF910F9196CE209103233091E7 +:1022D0000423C091D025D091D125C21BD30B61F529 +:1022E0008091052390910623820F931F80930523ED +:1022F000909306232091CC253091CD2528173907BE +:1023000021F08091D620882331F084E08093072348 +:10231000E4E2F3E236C0E091D425F091D525309780 +:1023200099F00995882381F01092032310920423D9 +:10233000C091D025D091D125C034D10528F010927C +:10234000D620C0E4D0E003C081E08093D620C093C3 +:102350002E23D0932F238091032390910423209147 +:10236000CE253091CF25280F391F2093302330936D +:102370003123C80FD91FC0930323D0930423ECE269 +:10238000F3E202E00693DF91CF910F9108950F934E +:10239000CF93DF931F92CDB7DEB78091CC0480FF3F +:1023A00065C021E02093CC0484E293E2FC0100E8C4 +:1023B0000693ECE2F3E200E806932093CA04FC01E2 +:1023C00000E1069380910723882329F0835082300F +:1023D00008F454DE10DE809126239091272308977D +:1023E00009F046C088E0E3ECF2E2A6ECB5E2019029 +:1023F0000D928A95E1F78091C80480628093C804A9 +:102400008091C80480628093C804A1D9811102C060 +:1024100019DE2EC09091C62597FF0EC0109205239D +:1024200010920623109203231092042392E09093BB +:10243000072389833EDF08C02091CC253091CD252C +:10244000232B21F489830CDE898113C0109205238C +:1024500010920623109203231092042391E090938C +:102460000723E4E2F3E202E0069303C080E001C048 +:1024700081E00F90DF91CF910F910895CF93CFB767 +:10248000F89481E08EDDEAECF4E080E4808380E281 +:102490008083E1ECF4E0808181608083A9ECB4E08A +:1024A0008C9182608C93E8ECF4E08081806480837E +:1024B0008C9181608C93808180688083CFBFCF9125 +:1024C0000895CF931092600080E30E94460A8091A5 +:1024D000C00480648093C00481E080936000CFB723 +:1024E000F89480E090E0FC0123E0EE0FFF1F2A95B6 +:1024F000E1F7E85FFC4D158E01968E30910599F756 +:1025000080E090E039E0389FF001399FF00D112410 +:10251000E95AFD4D20812E7F208301968C30910554 +:1025200091F76AE170E082E014DD8F3F09F48FE1FA +:102530008093FA046BE170E082E00BDD8F3F09F4D9 +:102540008FE18093FB048091C00486608093C00477 +:102550008091C00480688093C0048091C004806131 +:102560008093C00484E293E28093C6049093C704EE +:102570008091C00480628093C0048FEF8093C50473 +:102580008091C80482608093C8041092982385E0EB +:10259000EADC74DFCFBFCF9108958093C304089520 +:1025A0008091C3040895E6ECF5E280879187628705 +:1025B000738708950F931F93CF93DF931F92CDB727 +:1025C000DEB78A01698300DDFC018181807C69813D +:1025D00081113AC06370613019F020F080E803C0C7 +:1025E00080EC01C080E400381105E9F058F40032B5 +:1025F0001105A9F000341105A1F000311105C9F44D +:1026000091E018C0011592E0190779F00F3F93E0AF +:10261000190769F00115114061F495E00BC092E0D3 +:1026200009C093E007C094E005C096E003C097E0BE +:1026300001C090E0118226E02083982B9183818154 +:102640008062818381E001C080E00F90DF91CF91B3 +:102650001F910F910895B8DCFC01818182FB8827CE +:1026600080F90895CF93C82FAFDCFC01818182FFF0 +:102670000FC091819B7F91838C2F08DDFC0190819D +:1026800090FF06C09E7F90830780F085E02D09951E +:1026900081E0CF9108958F929F92AF92BF92DF9287 +:1026A000EF92FF920F931F93CF93DF931F92CDB7BB +:1026B000DEB7D82E5A0179016983E8DC4C018D2DF3 +:1026C00083DC9C01DC0111968C911197807C6981DF +:1026D000882309F45EC011968C911197807C803C10 +:1026E00021F011968C9182FD54C09FB7F894F401AB +:1026F000808180FF02C09FBF4CC0816080839FBFEC +:10270000F401A182B282E382F482158216820783E9 +:10271000108791E0611104C0E114F10409F090E028 +:10272000D4018C9190FB81F98B7F8C93D7FE04C0F0 +:10273000F9011682178229C0D90111968C9111973F +:10274000807C803CC9F41196EC91E770E150E73051 +:1027500040F4F0E0EE0FFF1FE455FF4D6081718102 +:1027600002C068E070E0C701F5D1892B29F0F401BF +:1027700080818E7F80830DC0D90112961D921C929C +:10278000139716961D921C9217978D2D99DC81E058 +:1027900001C080E00F90DF91CF911F910F91FF90CA +:1027A000EF90DF90BF90AF909F908F900895EF9241 +:1027B000FF920F93CF93C82F07DC7C018C2F66DC30 +:1027C000DC01F70102E005939C9190FF1BC09E7F06 +:1027D0009C931796ED91FC911897309799F0D7013B +:1027E000C7FF05C016966D917C91179704C012968D +:1027F0006D917C9113974C2F81E0CF910F91FF90B9 +:10280000EF900994CF910F91FF90EF900895CF939F +:10281000C82FCDDF8C2FD8DBFC011182CF9108951A +:102820000F93CF93C82FD0DBFC01918194609183EB +:1028300001E006938C2FBBDF81E0CF910F910895CB +:102840001F920F920FB60F9211240F932F933F9365 +:102850004F935F936F937F938F939F93AF93BF93A8 +:10286000CF93EF93FF938091CB0487FF08C080E85C +:102870008093CA040E94820B0E94230486C0809128 +:10288000CB0482FF18C084E08093CA0480912C237B +:1028900086FF7BC08091CC0481FD77C078DD8111FB +:1028A00074C080910723813011F4DADB6EC084306C +:1028B00009F06BC021C08091CB0481FF26C082E06B +:1028C0008093CA048091242386FF5FC08091CC044A +:1028D00081FD5BC05CDD811158C08091072382308F +:1028E00041F484E080930723E4E2F3E202E00693FC +:1028F0004CC0833009F049C0EDE2F3E204E00593F7 +:10290000E5E2F3E204E0059340C08091CB0484FF4C +:1029100025C080E18093CA04C1E08C2F48DF8C2F52 +:10292000806845DFCF5FC630C1F70E94660B10920A +:10293000C30410922523C093242383E4809325238A +:1029400010922D23C0932C2380932D2383EC92E2AD +:1029500080932823909329234EDB17C08091CB04CA +:1029600086FF08C080E48093CA0480E01ADB0E94DE +:1029700021040BC08091CB0485FF07C080E28093C7 +:10298000CA0481E00EDB0E942204FF91EF91CF91F7 +:10299000BF91AF919F918F917F916F915F914F9177 +:1029A0003F912F910F910F900FBE0F901F90189590 +:1029B0001F920F920FB60F9211240F931F932F9314 +:1029C0003F934F935F936F937F938F939F93AF93B7 +:1029D000BF93CF93DF93EF93FF938091CC0481FF5C +:1029E0001AC082E08093CC048091C5048195880F41 +:1029F000E4E2F3E2E81BF109208131812452334201 +:102A000083E0369527958A95E1F7822F869520FDFC +:102A100006C0C0E005C0BBDC882319F386C0C0E84F +:102A2000C80F8C2FD1DAFC01208125FF7EC000E287 +:102A30000693C11174C080910723843019F41EDB02 +:102A4000DADA73C000912623109127238091D025D4 +:102A50009091D125C0910323D09104239E01200F92 +:102A6000311F8217930718F48C010C1B1D0B8091EA +:102A7000CE259091CF25A80163EC72E28C0F9D1FAB +:102A800096D0C00FD11FC0930323D09304230034EA +:102A9000110569F480910523909106238C0F9D1FE9 +:102AA0002091CC253091CD258217930788F0C093D3 +:102AB000D025D093D125E091D425F091D52530971C +:102AC00029F00995811102C0BDDA2FC0C9DA2DC0E5 +:102AD0008091D0259091D1258C179D07D9F4E09154 +:102AE000D425F091D525309779F30995882361F3A2 +:102AF0002091052330910623809103239091042394 +:102B0000820F931F80930523909306231092032333 +:102B100010920423E4E2F3E202E0069306C0C03818 +:102B200011F4C7DB02C08C2FCBDAFF91EF91DF915C +:102B3000CF91BF91AF919F918F917F916F915F9155 +:102B40004F913F912F911F910F910F900FBE0F90BA +:102B50001F901895AA1BBB1B51E107C0AA1FBB1FE2 +:102B6000A617B70710F0A61BB70B881F991F5A9519 +:102B7000A9F780959095BC01CD01089597FB072E8C +:102B800016F4009406D077FD08D0E4DF07FC05D0EA +:102B90003EF4909581959F4F0895709561957F4F74 +:102BA0000895EE0FFF1F0590F491E02D0994FB01AD +:102BB000DC0102C001900D9241505040D8F70895B9 +:102BC000FB01DC0101900D920020E1F70895F894DB +:022BD000FFCF35 +:102BD20040000CE02E0AFFFFFFFF55800080006FCF +:102BE2000A690A790A660A000064201F2000002888 +:102BF2002023200F2000000009023C000101008078 +:102C0200FA0904000006FFFFFF00070581018000AA +:102C12000107058201800001070583018000010789 +:102C220005840180000107058501800001070586F2 +:102C3200018000011201000200000040EB0394BA7F +:102C42000002010200010000000300000000000079 +:102C5200000000000000000000004C61627261642C +:102C62006F72004573706F54656B000004030904B2 +:102C72006465627567313233000101001000200083 +:0A2C82004000800000010002FF0383 +:00000001FF diff --git a/Desktop_Interface/bin/firmware/labrafirm_0001_01.hex.REMOVED.git-id b/Desktop_Interface/bin/firmware/labrafirm_0001_01.hex.REMOVED.git-id deleted file mode 100644 index 07d97bdc..00000000 --- a/Desktop_Interface/bin/firmware/labrafirm_0001_01.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -044f2051fdfc79136bee11c6968cf73fa30eb572 \ No newline at end of file diff --git a/Desktop_Interface/bin/firmware/labrafirm_0003_01.hex b/Desktop_Interface/bin/firmware/labrafirm_0003_01.hex new file mode 100644 index 00000000..f7946fd7 --- /dev/null +++ b/Desktop_Interface/bin/firmware/labrafirm_0003_01.hex @@ -0,0 +1,715 @@ +:1000000017C1000031C100002FC100002DC1000048 +:100010002BC1000029C100000C9414090C94230981 +:1000200023C1000021C100001FC100001DC100004C +:100030001BC1000019C1000017C1000015C100005C +:1000400013C1000011C100000FC100000DC100006C +:100050000BC1000009C1000007C1000005C100007C +:100060000C94FF090C940A0AFFC00000FDC00000B8 +:10007000FBC00000F9C00000F7C00000F5C00000A0 +:10008000F3C00000F1C00000EFC00000EDC00000B0 +:10009000EBC00000E9C00000E7C00000E5C00000C0 +:1000A000E3C00000E1C00000DFC00000DDC00000D0 +:1000B000DBC00000D9C00000D7C00000D5C00000E0 +:1000C000D3C00000D1C00000CFC00000CDC00000F0 +:1000D000CBC00000C9C00000C7C00000C5C0000000 +:1000E000C3C00000C1C00000BFC00000BDC0000010 +:1000F000BBC00000B9C00000B7C00000B5C0000020 +:10010000B3C00000B1C00000AFC00000ADC000002F +:10011000ABC00000A9C00000A7C00000A3C400003D +:10012000A3C00000A1C000009FC000009DC000004F +:100130009BC0000099C0000097C0000095C000005F +:1001400093C0000091C000008FC000000C9474099F +:100150008BC0000089C0000087C0000085C000007F +:1001600083C0000081C000007FC000007DC000008F +:100170007BC0000079C0000077C0000075C000009F +:1001800073C0000071C000006FC000006DC00000AF +:100190006BC0000069C0000067C0000065C00000BF +:1001A00063C0000061C000005FC000005DC00000CF +:1001B0005BC0000059C0000057C0000055C00000DF +:1001C00053C0000051C000004FC000004DC00000EF +:1001D0004BC0000049C0000047C0000045C00000FF +:1001E00043C0000041C000003FC000003DC000000F +:1001F0003BC000000C9420140C94D8140F0411047C +:1002000013041504170419041B041D04DB0B010C53 +:10021000280C510C5A0C5F0CA40CA90CC80CCF0C68 +:100220006B0C730C7B0C860C880C8A0C920C9A0C51 +:1002300011241FBECFEFCDBFDFE2DEBF10E2A0E092 +:10024000B0E2E2EDFBE202C005900D92AA3BB107DD +:10025000D9F72DE2AAEBB0E201C01D92AC3FB20784 +:10026000E1F794D20C94E715CBCE84E0809356004E +:100270008CE1C0D3809363008BEB8093660080E8B1 +:100280008093650081E08093600088ED84BF1092C8 +:10029000410083E080935000809151008330E1F76A +:1002A0008091500081608093500088E180935500D8 +:1002B0008091510080FFFCCF80915000806180933D +:1002C00050008091510084FFFCCF88ED84BF84E012 +:1002D000809340000895E0E7F0E085818E7F85837C +:1002E000E0E0FAE08FEB9DE586A397A380EE9EE227 +:1002F00080A391A382E0808308958091200A909149 +:10030000210A813E2EE2920718F020919E2306C01A +:10031000803E2EE2920721F020919B2320936A00D9 +:1003200020910520222321F080910520815033C0A7 +:10033000885F9A42813D974080F11092BA20809167 +:10034000BB209091BC20A091BD20B091BE20019611 +:10035000A11DB11D8093BB209093BC20A093BD2014 +:10036000B093BE208091BB209091BC20A091BD2075 +:10037000B091BE20892F9A2FAB2FBB278093BE232D +:100380008091BB209091BC20A091BD20B091BE2057 +:100390008093BD2386E08093052080910720909173 +:1003A00008200196B1F4809109208F3F91F080914F +:1003B0000620811106C0809106208150809306207E +:1003C00008958091140190911501809307209093D6 +:1003D00008200895009709F45EC00CF457C040E06F +:1003E00020916B0030E020939C2330939D2320913B +:1003F0009C2330919D233695322F222737952795C0 +:1004000020939C2330939D2350916A0020919C233C +:1004100030919D23250F311D20939C2330939D23E4 +:10042000000020919C2330919D232817390728F440 +:1004300010929C2310929D23089520919C2330912B +:100440009D23280F391F2115304238F08FEF9FE18F +:1004500080939C2390939D23089520919C23309119 +:100460009D23442329F0A901481B590BCA0102C04E +:10047000820F931F80939C2390939D2380919C23B4 +:1004800090919D238F7780936A000895919581952F +:10049000910941E0A5CF0895CF93DF93C091200A41 +:1004A000D091210A80910320909104209E01281B65 +:1004B000390B20939F233093A0238091BA20811180 +:1004C0004BC080919F239091A0238E3C9F4FD4F4EA +:1004D00080919F239091A0238B369F4F9CF0809119 +:1004E0000220882321F080910220815008C0809151 +:1004F0006A0080939E2381E08093BA208CE08093F1 +:1005000002202AC08CE08093022080919F2390914A +:10051000A0238A369F4F1CF08FEF9FEF02C081E02F +:1005200090E08093992390939A2380919F239091B8 +:10053000A0232091992330919A2360E370E00E94D8 +:10054000BE15261B370B2093992330939A23809155 +:10055000992390919A233EDF8091BA20813029F52A +:1005600080919F239091A023C39794F080910220C3 +:10057000882331F08091022081508093022015C0A1 +:1005800080916A0080939B2383E08093BA200DC002 +:1005900080919F239091A023873991051CF481E0DD +:1005A00090E002C08FEF9FEF15DFC0930320D09340 +:1005B0000420DF91CF9108958617970779F0681787 +:1005C000790728F49C01261B370BB90109C086174F +:1005D000970718F4681B790B03C0089560E070E07A +:1005E000CB010895CF93DF9380910020909101205B +:1005F000892B51F0809100209091012001978093E8 +:1006000000209093012043C080E490E0809300207C +:100610009093012080910720909108200196B9F1D4 +:10062000809114019091150120910920263018F431 +:1006300067E771E002C06EEE72E00E94AA15EC015D +:1006400080910720909108208C179D0758F46091A5 +:10065000072070910820CE01AFDF029718F080ECE0 +:100660009DE511C08091072090910820C817D907F7 +:1006700070F46091072070910820CE019DDF0297F1 +:1006800030F08FEB9DE58093360A9093370ADF9127 +:10069000CF910895AC01460F571F861B970B2091F1 +:1006A000200A3091210A24173507C8F72091200A23 +:1006B0003091210A8217930790F70895E0E8F6E059 +:1006C0008FE0808385E0848308951F93CF93DF9329 +:1006D000C0E4D0E0198180E4898340E250E064ED19 +:1006E0007DE280E290E00E94390F1983DF91CF9183 +:1006F0001F9108951F93CF93DF93C0E4D0E0198139 +:1007000080E4898387ED97E20E94810F81E00E9457 +:10071000930F1983DF91CF911F91089508950F933F +:100720001F93842F242F30E0215831099DE7929F99 +:10073000A001939F500D112490910920953048F409 +:10074000843810F049585E4F9091C42027E731E07B +:1007500004C09091C4202EEE32E0929FB001939F8E +:10076000700D11249A01260F371FA9014850584DCA +:100770000FE813E02DE730E060E00E944B131F917B +:100780000F9108951CBEEEEFF0E409949EDF809176 +:10079000D42D882369F080E2E4EDFDE2A7EDB7E215 +:1007A00001900D928A95E1F71092D727A3DFEADF37 +:1007B00087E08093A200789458DDB0DF86D765D1BA +:1007C00088D160E080E01FD10BD18CE0FFD04AD50A +:1007D000EED507D673DF60EA70E28AEA93E20E9400 +:1007E000E015000000000000000000000000000014 +:1007F00000000000000000000000000000008091E8 +:10080000BF20882371F3E091D6258E2F90E08830A9 +:100810009105A0F4FC01E250FF4F0C94D11585D155 +:100820000DC0F5D10BC07CD209C000D307C08CD35A +:1008300005C012D403C011D401C082D41092BF20CD +:10084000D0CF08950895809114018093B3238091AF +:1008500015018093B423809124018093B523809166 +:1008600025018093B6238091200A8093BF23809135 +:10087000210A8093C0238091140190911501863440 +:10088000914080F08091140190911501893A914036 +:1008900048F480911401909115018093F42D909368 +:1008A000F52D00008091C220882339F014DD1092CC +:1008B000C22081E08093C12008958091C1208823C7 +:1008C00041F08091BA20833019F417DD8BDE01C02E +:1008D000E3DD8091C020882351F080911401909134 +:1008E00015018093F42D9093F52D1092C0208091E6 +:1008F00009202091140130911501853028F481E000 +:100900002737314030F004C081E02E3E324008F0FD +:1009100080E08093C42008950F931F9381E080931B +:10092000C7208093C2200FE813E02DE730E048EFA6 +:1009300057E260E081E80E944B132DE730E045E785 +:1009400058E260E082E80E944B132DE730E042EF6E +:1009500058E260E083E80E944B132DE730E04FE659 +:1009600059E260E084E80E944B132DE730E04CEE42 +:1009700059E260E085E80E944B132DE730E049E63C +:100980005AE260E086E80E944B1381E01F910F91CC +:1009900008951092C720089581E0089581E0089598 +:1009A00010922002982F9C7193689093200287FFE9 +:1009B00003C090E182E002C090E080E0892B809348 +:1009C000210210922202109226020895E0E0F2E045 +:1009D00010AA836880AB80E181AB12AA16AA0895A1 +:1009E000E0E0F2E010A683E880A78FE281A712A6DC +:1009F00016A60895AAECB1E092E09C93E82FF0E0EF +:100A000084911C920895909171009D7F9093710044 +:100A100010920002623011F09CE101C09EE19093BF +:100A2000010290E490930202811102C080E401C0AF +:100A300080EC80930302613011F084E001C083E018 +:100A40008093040280E2D6DF80930C0281E2D2DF41 +:100A500080930D02109218021092190281E0809387 +:100A60000002BECF1F920F920FB60F9211248F93E8 +:100A7000000000000000000081E0809323028F91BD +:100A80000F900FBE0F901F901895CF93DF93E0E764 +:100A9000F0E082818B7F8283C0E2D3E08DE08883A7 +:100AA00080E4898389E08A8383E3A4DF888782E303 +:100AB000A1DF898787E39EDF8A8786E39BDF8B87B9 +:100AC000E0E2F6E08081836080831482DF91CF9141 +:100AD0000895E0E7F0E080818E7F808383E8809353 +:100AE00000010895E0E0F1E0108A80E4808B10A21C +:100AF00080A310AA80ABE0E4F1E010828083109222 +:100B0000C6201092C52081E08093C4201092A823B3 +:100B10001092A9231092A6231092A72308958093E0 +:100B2000D62581E08093BF200895CF93DF93109264 +:100B30000920D8DFC0E0D1E01EAA84E288AB19AA60 +:100B400049E54AAB32E03BAB60910B2070910C2041 +:100B50006CAB7DAB67ED75E268AF79AF1AAE9BE326 +:100B60009CAF93E090933D0110923E0128A920682C +:100B700028AB10924601E0E4F1E08083109241013D +:100B8000409342019093430140910D2050910E20DB +:100B9000409344015093450146EC53E24093480191 +:100BA0005093490110924A0129E320934C019093FC +:100BB0004D0110924E01908190689083188A90E4C4 +:100BC000988B888B198A95E99A8B90E19B8B4EEED6 +:100BD00052E04C8B5D8B888F398F1A8E88EF97E2AD +:100BE0008C8F9D8F1E8E68EC70E084EF91E052DD5B +:100BF00088EC90E0809307209093082081E0809318 +:100C0000062088898068888BDF91CF9108951F9393 +:100C1000CF93DF9311E01093092064DFC0E0D1E0AF +:100C200018AA80E488AB84E088AB19AA1AAA4BE41E +:100C30004BAB1CAA1DAA1EAA8AE090E288AF99AF0E +:100C40001AAE60EA6CAF38E030933D0110923E017D +:100C500088A9806A88ABE0EAF8E085E58083808334 +:100C600010924601E0E4F1E084E2808310924101B9 +:100C700099E59093420122E020934301A0910B203B +:100C8000B0910C20A0934401B0934501A7EDB5E2CB +:100C9000A0934801B093490110924A019BE39093BD +:100CA0004C0193E090934D0110924E019081906819 +:100CB000908388A319A295E99AA34BA34EEE52E024 +:100CC0004CA35DA368A739A71AA666EE7AE26CA7C3 +:100CD0007DA71EA6888B198A9A8B90E19B8B4C8BE3 +:100CE0005D8B888F298F1A8E88EF97E28C8F9D8F6E +:100CF0001E8E68EC70E084EF91E0CCDC88EC90E034 +:100D000080930720909308201093062088A1806884 +:100D100088A388898068888BDF91CF911F9108957F +:100D20001F93CF93DF9312E010930920DBDEC0E026 +:100D3000D1E01EAA84E288AB19AA39E53AAB1BAB15 +:100D400040910B2050910C204CAB5DAB47ED55E230 +:100D500048AF59AF1AAE9BE39CAF93E090933D012F +:100D600010923E0128A9206828AB10924601E0E4C9 +:100D7000F1E080831092410130934201909343014E +:100D800020910D2030910E20209344013093450195 +:100D900026EC33E2209348013093490110924A0136 +:100DA00029E320934C0190934D0110924E019081C4 +:100DB00090689083188A90E4988B888B198A45E90B +:100DC0004A8B90E19B8B2EEE32E02C8B3D8B888FF3 +:100DD000198F1A8E68EF77E26C8F7D8F1E8E88A335 +:100DE00019A24AA39BA32CA33DA384E388A719A718 +:100DF0001AA686EE9AE28CA79DA71EA668EC70E064 +:100E000084EF91E047DC88EC90E08093072090939A +:100E1000082081E08093062088898068888B88A1DB +:100E2000806888A3DF91CF911F9108951F93CF937E +:100E3000DF9313E01093092055DEC0E0D1E010925B +:100E40004601E0E4F1E084E280831092410129E56B +:100E50002093420192E09093430140910B205091E6 +:100E60000C20409344015093450147ED55E24093D7 +:100E700048015093490110924A019BE390934C0121 +:100E800010934D0110924E019081906890831EAA9C +:100E900088AB19AA2AAB1BAB20910D2030910E20F4 +:100EA0002CAB3DAB26EC33E228AF39AF1AAE99E359 +:100EB0009CAF10933D0110923E0198A9906898ABA9 +:100EC00018A250E458A394E098A319A21AA24BE4E4 +:100ED0004BA31CA21DA21EA22AE030E228A739A71C +:100EE0001AA630EA3CA728E02DA71EA698A1906A72 +:100EF00098A395E59093A008188A588B888B198A37 +:100F000085E98A8B4B8B8EEE92E08C8B9D8B388F94 +:100F1000298F1A8E88EF97E28C8F9D8F1E8E68EC3A +:100F200070E084EF91E0B6DB88EC90E080930720DE +:100F30009093082081E08093062088898068888BC0 +:100F4000DF91CF911F9108951F93CF93DF9314E00A +:100F500010930920C7DDC0E0D1E018AA80E488AB77 +:100F600018AB19AA1AAA3BE43BAB1CAA1DAA1EAADD +:100F70008AE090E288AF99AF1AAE50EA5CAF88E0A1 +:100F800080933D0110923E0198A9906A98AB95E537 +:100F90009093A00810924601E0E4F1E094E290837F +:100FA0001092410129E52093420122E02093430160 +:100FB00060910B2070910C20609344017093450167 +:100FC00067ED75E2609348017093490110924A0100 +:100FD0002BE320934C0123E020934D0110924E010E +:100FE000208120682083988B198A45E94A8B3B8BA6 +:100FF0002EEE32E02C8B3D8B588F898F1A8E68EF46 +:1010000077E26C8F7D8F1E8E98A319A24AA39AE473 +:101010009BA32CA33DA393EC98A789A71AA686EEC1 +:101020009AE28CA79DA71EA668EC70E084EF91E081 +:1010300031DB88EC90E0809307209093082081E0DA +:101040008093062088898068888B88A1806888A31F +:10105000DF91CF911F910895FFCFCF93DF9386E06B +:10106000809309203FDDC0E0D1E01EAA84E288AB76 +:1010700019AA39E53AAB93E09BAB40910D20509112 +:101080000E204CAB5DAB46EC53E248AF59AF1AAE05 +:1010900029E32CAF90933D0110923E0128A92068CE +:1010A00028AB10924601E0E4F1E080831092410108 +:1010B0003093420122E02093430140910B20509154 +:1010C0000C20409344015093450147ED55E2409375 +:1010D00048015093490110924A013BE330934C017F +:1010E00090934D0110924E01908190689083188AE0 +:1010F00090E4988B888B198A95E99A8B90E19B8B69 +:101100004CED55E04C8B5D8B888F298F1A8E88EFC4 +:1011100097E28C8F9D8F1E8E68EC70E084EF91E0DB +:10112000B9DA80E991E0809307209093082081E06C +:101130008093062088898068888BDF91CF910895FD +:10114000CF93DF9387E080930920CCDCC0E0D1E02F +:101150001EAA84E288AB19AA39E53AAB93E09BABAF +:1011600040910D2050910E204CAB5DAB46EC53E20C +:1011700048AF59AF1AAE29E32CAF90933D011092BE +:101180003E0128A9206828AB10924601E0E4F1E076 +:101190008083109241013093420122E02093430169 +:1011A00040910B2050910C204093440150934501F5 +:1011B00047ED55E2409348015093490110924A018E +:1011C0003BE330934C0190934D0110924E0190817E +:1011D00090689083188A90E4988B95E2988B198A8E +:1011E00095E99A8B90E19B8B4CED55E04C8B5D8B98 +:1011F000888F298F1A8E88EF97E28C8F9D8F1E8E95 +:1012000068EC70E084EF91E045DA80E991E080934A +:1012100007209093082081E08093062088898068C9 +:10122000888BDF91CF9108951F920F920FB60F9286 +:1012300011248F9381E0809303018F910F900FBE53 +:101240000F901F9018951F920F920FB60F921124B6 +:101250008F9382E0809303018F910F900FBE0F90C8 +:101260001F901895E0E7F0E083818C7F8383848171 +:101270008C7F848380818D7F8083E0E8F1E080EC47 +:101280008283128688EC81831186A0E0B8E034E086 +:101290003C9323E011962C93119714961C9214976B +:1012A00085ED91E096968D939C93979716961C9258 +:1012B0001697E0E4F8E030832183148286A397A395 +:1012C0001682E0E6F6E0808180618083E0E4F9E068 +:1012D00083E18183148282E08683A6A3B7A310A64C +:1012E00011A681E0808308951F920F920FB60F928E +:1012F00011242F933F934F935F938F939F93CF939B +:10130000DF931F92CDB7DEB78FEF80934C098091AA +:101310000920873031F480912C02898390912D022D +:1013200002C090912C028091C320891B20916809F2 +:101330003091690982308CF02A3F374070F4209157 +:1013400068093091690989301CF481E090E002C09D +:1013500086E090E0820F931F18C0209168093091B9 +:1013600069098F3FB4F42730310598F0209168095E +:1013700030916909883F1CF081E090E002C086E06E +:1013800090E0A901481B590BCA01809378099093FA +:1013900079090F90DF91CF919F918F915F914F913C +:1013A0003F912F910F900FBE0F901F901895E0E77F +:1013B000F0E083818F7E8383E0E4F6E080818A6AB7 +:1013C00080838FEF848388E5828BE0EAF8E080E316 +:1013D000838384EC858387E08683178288E1848316 +:1013E0000895E0E7F0E08381877F8383E0ECF8E015 +:1013F00080E48083118288E58093550608951F92CA +:101400000F920FB60F92112400000F900FBE0F9095 +:101410001F9018951F920F920FB60F9211248F9361 +:10142000EF93FF93E0EAF8E080818083FF91EF91F2 +:101430008F910F900FBE0F901F9018959FB7F89443 +:10144000A0E5B0E016968C911697897F16968C933E +:101450001697E0E6F0E080E885838BEB86831696AE +:101460008C911697846016968C938081816080831E +:101470009FBF08959FB7F894E82FF0E0E059FF4F21 +:1014800060958081682360839FBF0895CF938630E5 +:1014900011F0C0E001C0C8E18091510081FD0DC094 +:1014A0009FB7F894809150008260809350009FBF56 +:1014B0008091510081FFFCCFC1DF6C2F636084E419 +:1014C00090E0BCD460E480E0CF91D4CF8091C8207C +:1014D00008958091C820813009F45BCA0895F0D046 +:1014E000FC0183818093C820811101C015CA81E06D +:1014F00008959091C625892F807697FF07C0803484 +:1015000091F48091C72581110EC048CA803459F4E6 +:101510008091C725811107C08091CC259091CD2560 +:10152000892B09F039CA80E008958091C8258F770A +:101530000C94CD129091D020911102C080E00895BA +:10154000E091CD20F091CE200190F081E02D9481AA +:101550008917A0F7E093CB20F093CC202281338130 +:101560002E0F3F1FE217F30798F49181943061F436 +:101570009281891309C09381691306C0E093CB203F +:10158000F093CC2081E008959081E90FF11DEACF1E +:10159000E093CB20F093CC20D1CFE091CD20F091FF +:1015A000CE200190F081E02D228133812E0F3F1F4C +:1015B000FC014081E40FF11DE217F30748F481813B +:1015C000843031F0853039F08081E80FF11DF4CF9F +:1015D00080E090E00895CF0108951F93CF93DF93AB +:1015E000182FA8DF882339F1C091CB20D091CC20CF +:1015F000CE01D3DFEC01892B41F04C815D816B8101 +:101600008A81D8D78111F4CF16C0E091CD20F09116 +:10161000CE2092818381E92FF82FE10FF11DE10F98 +:10162000F11D0190F081E02D0190F081E02DDF911E +:10163000CF911F91099480E0DF91CF911F91089580 +:10164000EF92FF921F93CF93DF93C82F60E072DF7A +:10165000811102C010E02DC0E091CD20F091CE208C +:1016600092818381E92FF82FEC0FF11DEC0FF11D12 +:10167000E080F180D7011696ED91FC9117970995BE +:10168000682F8C2F57DF182F882321F3C091CB2090 +:10169000D091CC20CE0181DFEC01892B21F08A8111 +:1016A0000E940714F7CFD7011296ED91FC91139782 +:1016B0000995812FDF91CF911F91FF90EF900895B1 +:1016C0008091CB209091CC200895FBC6CF93809140 +:1016D000D020811108C01092D0201092D4201092F6 +:1016E000D520CF910895C0E0E091CD20F091CE209B +:1016F0000190F081E02D8481C81768F78C2FA0DF5E +:10170000CF5FF2CFCF938091D0208823F1F0C0E05B +:10171000E091CD20F091CE20A081B18114968C91E2 +:10172000C81798F492818381E92FF82FEC0FF11DEF +:10173000EC0FF11D0190F081E02D0084F185E02D8A +:10174000309709F00995CF5FE3CFCF910895EF92DD +:10175000FF920F931F93CF93DF931F92CDB7DEB706 +:101760001092D0251092D1251092D2251092D32517 +:101770001092D4251092D5258091C62587FF07C0E9 +:101780002091CC253091CD25232B09F44EC3982FE1 +:101790009076903409F00BC1E091C7258E2F90E030 +:1017A000FC01E05AF109EA30F10508F0CDC2EA5F28 +:1017B000FE4F0C94D11581E08093C02080910720CA +:1017C000909108208093B723809107209091082062 +:1017D0009093B82380919E238093B92380919B237B +:1017E0008093BA2380916A008093BB2380916B0021 +:1017F0008093BC236091CC257091CD258AEA93E239 +:10180000D4C0109200088091C8259091C92580937A +:101810003608909337088091CA258F70809300080E +:101820006091CC257091CD2586EC93E2BCD62091B9 +:101830000D2030910E208091CC259091CD25281738 +:10184000390709F4F0C280930D2090930E2026C032 +:10185000109240088091C8259091C9258093760800 +:10186000909377088091CA258F708093400860918B +:10187000CC257091CD2587ED95E295D620910B2052 +:1018800030910C208091CC259091CD2528173907D7 +:1018900009F4C9C280930B2090930C2080910920F9 +:1018A00051C010926809109269098091C8258093EF +:1018B000C320B9C28091C82580932406B4C2E091A8 +:1018C000C825F091C925E830F10508F03DC2E05F78 +:1018D000FE4F0C94D11560E080E095D88091CA2528 +:1018E0005FD880E02FC060E080E08DD88091CA256D +:1018F00057D881E027C061E081E085D88091CA2572 +:101900004FD88091CB2562D882E01CC083E01AC0FA +:1019100084E018C060E080E076D88091CA2540D885 +:1019200085E010C061E080E06ED88091CA2538D88B +:1019300086E008C062E080E066D88091CA258068B1 +:101940002FD887E0ECD86FC28091C8258093840699 +:101950006AC28091C8259091C925892B91F00E9477 +:10196000650380E2E4EDFDE2A7EDB7E201900D92A0 +:101970008A95E1F781E08093D7270E947A030E943D +:101980006503E9E7F0E091E088EDF89484BF908387 +:101990006091CC257091CD258AEA90E206C06091D5 +:1019A000CC257091CD2589EA90E2FDD53CC29111FC +:1019B000CBC187FFFCC02091CC253091CD252115CE +:1019C000310509F4C1C18F7109F09EC08091C7250E +:1019D000863071F0883009F48EC08111B5C1223093 +:1019E000310509F0B1C162E070E084ED90E2DDCF35 +:1019F0008091C8259091C925292F332722303105A0 +:101A0000A1F064F42130310509F09EC180911920C4 +:101A100090911A20DC016C9170E05BC0233031059D +:101A200089F12F30310509F18FC1E0911920F09132 +:101A30001A202189821708F087C19927880F991FDA +:101A4000880F991FE0911B20F0911C20E80FF91FCF +:101A500080819181FC0162817381A5D5E091CE25C1 +:101A6000F091CF2582E0818335C080911D20909137 +:101A70001E20009709F468C1DC0112966D917C91DB +:101A8000139727C099278130910569F038F00297A4 +:101A900009F05AC168E08AE890E208C064E070E0AA +:101AA0008CE990E216C067E083E990E2282FAAE76C +:101AB000B0E2FC01819190E08D939D938E2F821B6B +:101AC0008617C0F3660F6E5F6093782070E088E73A +:101AD00090E269D58091CC259091CD252091D0259B +:101AE0003091D1258217930708F09DC18093D025AE +:101AF0009093D12598C12130310509F025C161E0CD +:101B000070E080ED90E251CF8130C9F58091C7251A +:101B10008A3009F019C12130310509F015C18091D1 +:101B2000D020882309F410C1E090CA25F090CB257D +:101B30000091CD201091CE20D801ED91FC918481AF +:101B4000E81608F001C160E08E2DF4DC882309F46A +:101B5000FBC0FF24EE0CFF1CF801828193818E0DE7 +:101B60009F1DDC01ED91FC910680F781E02D099528 +:101B70008093D22061E070E082ED90E216CF823057 +:101B800009F0E2C08091C7258111DEC02230310505 +:101B900009F0DAC08091CA255ED590E08093C92013 +:101BA0009093CA2062E070E089EC90E2FECE8F71E3 +:101BB00009F07DC08091C725833009F4C5C018F4B1 +:101BC0008130A1F0C1C0853019F0893039F1BCC035 +:101BD0008091CC259091CD25892B09F0B5C085E960 +:101BE0009AE08093D2259093D3251DC18091CC2576 +:101BF0009091CD25892B09F0A7C08091C82590919F +:101C0000C925019709F0A0C08091D4209091D520DA +:101C10008D7F8093D4209093D52005C18091CC25D1 +:101C20009091CD25892B09F08FC0BAD4882309F46F +:101C30008BC02091C8253091C9253327E091192008 +:101C4000F0911A20818990E08217930708F47CC0F4 +:101C50003DDD8091C8259091C9258093D0208823AF +:101C600009F4E1C099278150904C880F991F880F83 +:101C7000991F20911B2030911C20820F931F80936D +:101C8000CD209093CE2010E0E091CD20F091CE2099 +:101C90000190F081E02D8481181708F0C4C060E045 +:101CA000812F9BDC882309F44FC01F5FEDCF81306B +:101CB000F1F48091C7258B3009F046C08091CC2586 +:101CC0009091CD25892B09F03FC08091D0208823A9 +:101CD00009F43AC01091CA256091C825812F698303 +:101CE000AFDC6981882381F1812F77DC2BC08230C2 +:101CF00059F58091C725813019F0833089F024C0CF +:101D00008091CC259091CD25892BF1F48091C82527 +:101D10009091C925892BC1F48091CA25A3D412C002 +:101D20008091CC259091CD25892B71F48091C82587 +:101D30009091C925892B41F48091CA2538D580918D +:101D4000CA256ED581116FC08091C6258F718130F3 +:101D5000B9F58091D020882399F1E090CA25F090C0 +:101D6000CB250091CD201091CE20D801ED91FC9192 +:101D70008481E81628F560E08E2DDCDB882301F1F4 +:101D8000F701FF27EE0FFF1FD80112968D919C914E +:101D90001397E80FF91F00811181D8011696ED9174 +:101DA000FC9117970995682F8E2DC4DB882341F08D +:101DB000D8011496ED91FC9115970995811133C0C6 +:101DC0008091C6258F71823081F58091D020882343 +:101DD00061F1F12CE091CD20F091CE20A081B18174 +:101DE00014968C91F81608F592818381E92FF82FCB +:101DF000EF0DF11DEF0DF11D00811181D801169637 +:101E0000ED91FC9117970995682F8F2D93DB88230F +:101E100061F0D8011496ED91FC9115970995811107 +:101E200002C0F394D7CF81E001C080E00F90DF9132 +:101E3000CF911F910F91FF90EF9008951BBEFC0171 +:101E400028ED24BF608308958091CF0187FDFCCFEA +:101E500008951F93CF93DF93C0ECD1E01A858A8752 +:101E600061E08BEC91E0EADF1A87DF91CF911F915F +:101E70000895CF92DF92EF92FF920F931F93CF932B +:101E8000DF9300D0CDB7DEB78C017B0149835A8345 +:101E9000DBDF8CECC82EDD24D394F60190819860B2 +:101EA0009083B801705F49815A81C70180D6F601DD +:101EB0008081877F80830F900F90DF91CF911F915A +:101EC0000F91FF90EF90DF90CF900895CF93DF9325 +:101ED00000D0CDB7DEB76A838983B6DFACECB1E062 +:101EE0009C9198609C938981E82FF0E0F05F6A8173 +:101EF00060838C91877F8C930F900F90DF91CF91AF +:101F000008950F931F93CF938C019EDFC0E0F801DB +:101F100061918F018C2FDADFCF5FC032C1F7CF9193 +:101F20001F910F910895CF93DF931F92CDB7DEB726 +:101F300089838ADF898120E2829FC0011124E0EC3D +:101F4000F1E012829183808385E30F90DF91CF913E +:101F500080CF4091CA01E62FF72F8093CA01849168 +:101F60004093CA010895E82FF0E0EA50F24D8081D5 +:101F70008F3F09F4FFCF9FB7F89480818F5F8083F4 +:101F80009FBF0895E82FF0E0EA50F24D8081811163 +:101F900001C0FFCF9FB7F8948081815080839FBF9D +:101FA0000895CF93C82F80919823C11105C088232D +:101FB00039F081E0E7DF04C0811102C081E0D3DFA6 +:101FC000C0939823CF910895282F2F70082E000CCE +:101FD000990B392F331F3327331F832F90E0820F44 +:101FE000911D820F911D23E0880F991F2A95E1F71B +:101FF0008C5D9C4D08950F93E8ECF4E080818F7D1B +:10200000808380818F7D8083ECE2F3E202E00593A0 +:1020100010922E2310922F2300E2069300E40693E1 +:10202000E4E2F3E200E2069300E40693E6ECF5E274 +:102030001486158616861786128613861092072335 +:102040000F9108950F9385E080930723EDE2F3E26B +:1020500004E00593E5E2F3E204E005930F910895AF +:102060000F9383E08093072310922E2310922F2347 +:10207000ECE2F3E202E006930F910895E091D2259D +:10208000F091D325309709F009940895282F2F70E7 +:10209000082E000C990B392F331F3327331F832F42 +:1020A00090E0820F911D820F911D029749E0489F99 +:1020B0009001499F300D1124C901895A9D4D089501 +:1020C0008F929F92AF92BF92DF92EF92FF920F9307 +:1020D0001F93CF93DF93D82ED9DFEC018D2D74DFC2 +:1020E0007C01DC011196EC91E770E150E73040F49F +:1020F000F0E0EE0FFF1FE455FF4D0081118102C09B +:1021000008E010E0ED81FE812B813C814881D70100 +:10211000D7FE48C016968D919C9117978E0F9F1FE2 +:102120008D839E838217930761F1281B390B21153C +:10213000B4E03B0738F02FEF33E0C901B8010AD50E +:10214000281B390B41FF0AC0C901B80103D5AC01F6 +:1021500091E0452B09F090E0892F01C080E0988143 +:1021600080FB91F99883F7011682178222833383CB +:1021700029813A818D819E81820F931F848395836B +:102180000EC041FF71C04D7F4883D70116961D9246 +:102190001C92179712961D921C921397F70102E05A +:1021A00006937BC01296AD90BC90139742FF10C06F +:1021B00089809A80C901B801CDD4B0E4DB9EB0011A +:1021C000112469567F4DAC01C4018E0F9F1FEFD4BF +:1021D0008D819E818A0D9B1D8D839E832B813C81E9 +:1021E0002817390710F42D833E83F70186819781E4 +:1021F000A816B906C9F58D819E8182179307A1F1B2 +:10220000281B390B2115F4E03F0710F02FEF33E0C6 +:10221000C901B8019FD4281B390BD70112961D9212 +:102220001C9213972017310778F488818460888383 +:10223000B0E4DB9EC001112489569F4DF7018483D1 +:10224000958306831783AACF49815A818D819E8108 +:10225000840F951FD70114968D939C93159716960E +:102260002D933C9317979ACF888180FF16C08E7F5D +:102270008883EF81F885309781F06D817E814D2DC7 +:1022800080E0DF91CF911F910F91FF90EF90DF9051 +:10229000BF90AF909F908F900994DF91CF911F9145 +:1022A0000F91FF90EF90DF90BF90AF909F908F9035 +:1022B00008950F93CF93DF9380910723833029F400 +:1022C000DDDEDF91CF910F9196CE209103233091E7 +:1022D0000423C091D025D091D125C21BD30B61F529 +:1022E0008091052390910623820F931F80930523ED +:1022F000909306232091CC253091CD2528173907BE +:1023000021F08091D620882331F084E08093072348 +:10231000E4E2F3E236C0E091D425F091D525309780 +:1023200099F00995882381F01092032310920423D9 +:10233000C091D025D091D125C034D10528F010927C +:10234000D620C0E4D0E003C081E08093D620C093C3 +:102350002E23D0932F238091032390910423209147 +:10236000CE253091CF25280F391F2093302330936D +:102370003123C80FD91FC0930323D0930423ECE269 +:10238000F3E202E00693DF91CF910F9108950F934E +:10239000CF93DF931F92CDB7DEB78091CC0480FF3F +:1023A00065C021E02093CC0484E293E2FC0100E8C4 +:1023B0000693ECE2F3E200E806932093CA04FC01E2 +:1023C00000E1069380910723882329F0835082300F +:1023D00008F454DE10DE809126239091272308977D +:1023E00009F046C088E0E3ECF2E2A6ECB5E2019029 +:1023F0000D928A95E1F78091C80480628093C804A9 +:102400008091C80480628093C804A1D9811102C060 +:1024100019DE2EC09091C62597FF0EC0109205239D +:1024200010920623109203231092042392E09093BB +:10243000072389833EDF08C02091CC253091CD252C +:10244000232B21F489830CDE898113C0109205238C +:1024500010920623109203231092042391E090938C +:102460000723E4E2F3E202E0069303C080E001C048 +:1024700081E00F90DF91CF910F910895CF93CFB767 +:10248000F89481E08EDDEAECF4E080E4808380E281 +:102490008083E1ECF4E0808181608083A9ECB4E08A +:1024A0008C9182608C93E8ECF4E08081806480837E +:1024B0008C9181608C93808180688083CFBFCF9125 +:1024C0000895CF931092600080E30E94460A8091A5 +:1024D000C00480648093C00481E080936000CFB723 +:1024E000F89480E090E0FC0123E0EE0FFF1F2A95B6 +:1024F000E1F7E85FFC4D158E01968E30910599F756 +:1025000080E090E039E0389FF001399FF00D112410 +:10251000E95AFD4D20812E7F208301968C30910554 +:1025200091F76AE170E082E014DD8F3F09F48FE1FA +:102530008093FA046BE170E082E00BDD8F3F09F4D9 +:102540008FE18093FB048091C00486608093C00477 +:102550008091C00480688093C0048091C004806131 +:102560008093C00484E293E28093C6049093C704EE +:102570008091C00480628093C0048FEF8093C50473 +:102580008091C80482608093C8041092982385E0EB +:10259000EADC74DFCFBFCF9108958093C304089520 +:1025A0008091C3040895E6ECF5E280879187628705 +:1025B000738708950F931F93CF93DF931F92CDB727 +:1025C000DEB78A01698300DDFC018181807C69813D +:1025D00081113AC06370613019F020F080E803C0C7 +:1025E00080EC01C080E400381105E9F058F40032B5 +:1025F0001105A9F000341105A1F000311105C9F44D +:1026000091E018C0011592E0190779F00F3F93E0AF +:10261000190769F00115114061F495E00BC092E0D3 +:1026200009C093E007C094E005C096E003C097E0BE +:1026300001C090E0118226E02083982B9183818154 +:102640008062818381E001C080E00F90DF91CF91B3 +:102650001F910F910895B8DCFC01818182FB8827CE +:1026600080F90895CF93C82FAFDCFC01818182FFF0 +:102670000FC091819B7F91838C2F08DDFC0190819D +:1026800090FF06C09E7F90830780F085E02D09951E +:1026900081E0CF9108958F929F92AF92BF92DF9287 +:1026A000EF92FF920F931F93CF93DF931F92CDB7BB +:1026B000DEB7D82E5A0179016983E8DC4C018D2DF3 +:1026C00083DC9C01DC0111968C911197807C6981DF +:1026D000882309F45EC011968C911197807C803C10 +:1026E00021F011968C9182FD54C09FB7F894F401AB +:1026F000808180FF02C09FBF4CC0816080839FBFEC +:10270000F401A182B282E382F482158216820783E9 +:10271000108791E0611104C0E114F10409F090E028 +:10272000D4018C9190FB81F98B7F8C93D7FE04C0F0 +:10273000F9011682178229C0D90111968C9111973F +:10274000807C803CC9F41196EC91E770E150E73051 +:1027500040F4F0E0EE0FFF1FE455FF4D6081718102 +:1027600002C068E070E0C701F5D1892B29F0F401BF +:1027700080818E7F80830DC0D90112961D921C929C +:10278000139716961D921C9217978D2D99DC81E058 +:1027900001C080E00F90DF91CF911F910F91FF90CA +:1027A000EF90DF90BF90AF909F908F900895EF9241 +:1027B000FF920F93CF93C82F07DC7C018C2F66DC30 +:1027C000DC01F70102E005939C9190FF1BC09E7F06 +:1027D0009C931796ED91FC911897309799F0D7013B +:1027E000C7FF05C016966D917C91179704C012968D +:1027F0006D917C9113974C2F81E0CF910F91FF90B9 +:10280000EF900994CF910F91FF90EF900895CF939F +:10281000C82FCDDF8C2FD8DBFC011182CF9108951A +:102820000F93CF93C82FD0DBFC01918194609183EB +:1028300001E006938C2FBBDF81E0CF910F910895CB +:102840001F920F920FB60F9211240F932F933F9365 +:102850004F935F936F937F938F939F93AF93BF93A8 +:10286000CF93EF93FF938091CB0487FF08C080E85C +:102870008093CA040E94820B0E94230486C0809128 +:10288000CB0482FF18C084E08093CA0480912C237B +:1028900086FF7BC08091CC0481FD77C078DD8111FB +:1028A00074C080910723813011F4DADB6EC084306C +:1028B00009F06BC021C08091CB0481FF26C082E06B +:1028C0008093CA048091242386FF5FC08091CC044A +:1028D00081FD5BC05CDD811158C08091072382308F +:1028E00041F484E080930723E4E2F3E202E00693FC +:1028F0004CC0833009F049C0EDE2F3E204E00593F7 +:10290000E5E2F3E204E0059340C08091CB0484FF4C +:1029100025C080E18093CA04C1E08C2F48DF8C2F52 +:10292000806845DFCF5FC630C1F70E94660B10920A +:10293000C30410922523C093242383E4809325238A +:1029400010922D23C0932C2380932D2383EC92E2AD +:1029500080932823909329234EDB17C08091CB04CA +:1029600086FF08C080E48093CA0480E01ADB0E94DE +:1029700021040BC08091CB0485FF07C080E28093C7 +:10298000CA0481E00EDB0E942204FF91EF91CF91F7 +:10299000BF91AF919F918F917F916F915F914F9177 +:1029A0003F912F910F910F900FBE0F901F90189590 +:1029B0001F920F920FB60F9211240F931F932F9314 +:1029C0003F934F935F936F937F938F939F93AF93B7 +:1029D000BF93CF93DF93EF93FF938091CC0481FF5C +:1029E0001AC082E08093CC048091C5048195880F41 +:1029F000E4E2F3E2E81BF109208131812452334201 +:102A000083E0369527958A95E1F7822F869520FDFC +:102A100006C0C0E005C0BBDC882319F386C0C0E84F +:102A2000C80F8C2FD1DAFC01208125FF7EC000E287 +:102A30000693C11174C080910723843019F41EDB02 +:102A4000DADA73C000912623109127238091D025D4 +:102A50009091D125C0910323D09104239E01200F92 +:102A6000311F8217930718F48C010C1B1D0B8091EA +:102A7000CE259091CF25A80163EC72E28C0F9D1FAB +:102A800096D0C00FD11FC0930323D09304230034EA +:102A9000110569F480910523909106238C0F9D1FE9 +:102AA0002091CC253091CD258217930788F0C093D3 +:102AB000D025D093D125E091D425F091D52530971C +:102AC00029F00995811102C0BDDA2FC0C9DA2DC0E5 +:102AD0008091D0259091D1258C179D07D9F4E09154 +:102AE000D425F091D525309779F30995882361F3A2 +:102AF0002091052330910623809103239091042394 +:102B0000820F931F80930523909306231092032333 +:102B100010920423E4E2F3E202E0069306C0C03818 +:102B200011F4C7DB02C08C2FCBDAFF91EF91DF915C +:102B3000CF91BF91AF919F918F917F916F915F9155 +:102B40004F913F912F911F910F910F900FBE0F90BA +:102B50001F901895AA1BBB1B51E107C0AA1FBB1FE2 +:102B6000A617B70710F0A61BB70B881F991F5A9519 +:102B7000A9F780959095BC01CD01089597FB072E8C +:102B800016F4009406D077FD08D0E4DF07FC05D0EA +:102B90003EF4909581959F4F0895709561957F4F74 +:102BA0000895EE0FFF1F0590F491E02D0994FB01AD +:102BB000DC0102C001900D9241505040D8F70895B9 +:102BC000FB01DC0101900D920020E1F70895F894DB +:022BD000FFCF35 +:102BD20040000CE02E0AFFFFFFFF55800080006FCF +:102BE2000A690A790A660A000064201F2000002888 +:102BF2002023200F2000000009023C000101008078 +:102C0200FA0904000006FFFFFF00070581018000AA +:102C12000107058201800001070583018000010789 +:102C220005840180000107058501800001070586F2 +:102C3200018000011201000200000040EB0394BA7F +:102C42000002010200010000000300000000000079 +:102C5200000000000000000000004C61627261642C +:102C62006F72004573706F54656B000004030904B2 +:102C72006465627567313233000103001000200081 +:0A2C82004000800000010002FF0383 +:00000001FF diff --git a/Desktop_Interface/bin/firmware/labrafirm_0003_01.hex.REMOVED.git-id b/Desktop_Interface/bin/firmware/labrafirm_0003_01.hex.REMOVED.git-id deleted file mode 100644 index b3667a22..00000000 --- a/Desktop_Interface/bin/firmware/labrafirm_0003_01.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f7946fd762c2bf7eaa4b76d5eb68948870244c19 \ No newline at end of file diff --git a/Desktop_Interface/bin/firmware/labrafirm_0003_02.hex b/Desktop_Interface/bin/firmware/labrafirm_0003_02.hex new file mode 100644 index 00000000..879125a9 --- /dev/null +++ b/Desktop_Interface/bin/firmware/labrafirm_0003_02.hex @@ -0,0 +1,714 @@ +:100000001FC1000039C1000037C1000035C1000028 +:1000100033C1000031C100000C94F3080C94230993 +:100020002BC1000029C1000027C1000025C100002C +:1000300023C1000021C100001FC100001DC100003C +:100040001BC1000019C1000017C1000015C100004C +:1000500013C1000011C100000FC100000DC100005C +:100060000C94200A0C942B0A07C1000005C1000063 +:1000700003C1000001C10000FFC00000FDC000007E +:10008000FBC00000F9C00000F7C00000F5C0000090 +:10009000F3C00000F1C00000EFC00000EDC00000A0 +:1000A000EBC00000E9C00000E7C00000E5C00000B0 +:1000B000E3C00000E1C00000DFC00000DDC00000C0 +:1000C000DBC00000D9C00000D7C00000D5C00000D0 +:1000D000D3C00000D1C00000CFC00000CDC00000E0 +:1000E000CBC00000C9C00000C7C00000C5C00000F0 +:1000F000C3C00000C1C00000BFC00000BDC0000000 +:10010000BBC00000B9C00000B7C00000B5C000000F +:10011000B3C00000B1C00000AFC0000074C4000054 +:10012000ABC00000A9C00000A7C00000A5C000002F +:10013000A3C00000A1C000009FC000009DC000003F +:100140009BC0000099C0000097C000000C94950966 +:1001500093C0000091C000008FC000008DC000005F +:100160008BC0000089C0000087C0000085C000006F +:1001700083C0000081C000007FC000007DC000007F +:100180007BC0000079C0000077C0000075C000008F +:1001900073C0000071C000006FC000006DC000009F +:1001A0006BC0000069C0000067C0000065C00000AF +:1001B00063C0000061C000005FC000005DC00000BF +:1001C0005BC0000059C0000057C0000055C00000CF +:1001D00053C0000051C000004FC000004DC00000DF +:1001E0004BC0000049C0000047C0000045C00000EF +:1001F00043C000000C9437140C94E514FC03FE0378 +:10020000000402040404060408040A041C041E0476 +:10021000200422042404290426042804FC0B220CB4 +:10022000490C720C7B0C800CC90CCE0CED0CF40C40 +:100230008C0C940C9C0CA80CAA0CAC0CB50CBE0C31 +:1002400011241FBECFEFCDBFDFE2DEBF10E2A0E082 +:10025000B0E2ECEEFBE202C005900D92AA39B107C4 +:10026000D9F72BE2AAE9B0E201C01D92A03EB20785 +:10027000E1F779D20C94F415C3CE84E08093560054 +:100280008CE189D3809363008BEB8093660080E8D8 +:100290008093650081E08093600088ED84BF1092B8 +:1002A000410083E080935000809151008330E1F75A +:1002B0008091500081608093500088E180935500C8 +:1002C0008091510080FFFCCF80915000806180932D +:1002D00050008091510084FFFCCF88ED84BF84E002 +:1002E000809340000895E0E7F0E085818E7F85836C +:1002F000E0E0FAE08FEB9DE586A397A380EE9EE217 +:1003000080A391A382E0808308958091200A909138 +:10031000210A813E2EE2920718F02091822106C028 +:10032000803E2EE2920721F020917F2120936A00E7 +:1003300020910520222321F080910520815033C097 +:10034000885F9A42813D974080F110929A20809177 +:100350009B2090919C20A0919D20B0919E20019681 +:10036000A11DB11D80939B2090939C20A0939D2064 +:10037000B0939E2080919B2090919C20A0919D20E5 +:10038000B0919E20892F9A2FAB2FBB278093A2215B +:1003900080919B2090919C20A0919D20B0919E20C7 +:1003A0008093A12186E08093052080910720909181 +:1003B00008200196B1F4809109208F3F91F080913F +:1003C0000620811106C0809106208150809306206E +:1003D00008958091140190911501809307209093C6 +:1003E00008200895009709F45EC00CF457C040E05F +:1003F00020916B0030E02093802130938121209167 +:100400008021309181213695322F222737952795EB +:10041000209380213093812150916A002091802186 +:1004200030918121250F311D20938021309381212E +:10043000000020918021309181212817390728F46C +:100440001092802110928121089520918021309175 +:100450008121280F391F2115304238F08FEF9FE19D +:100460008093802190938121089520918021309163 +:100470008121442329F0A901481B590BCA0102C05C +:10048000820F931F809380219093812180918021FE +:10049000909181218F7780936A000895919581953D +:1004A000910941E0A5CF0895CF93DF93C091200A31 +:1004B000D091210A80910320909104209E01281B55 +:1004C000390B209383213093842180919A208111CC +:1004D0004BC080918321909184218E3C9F4FD4F416 +:1004E00080918321909184218B369F4F9CF0809145 +:1004F0000220882321F080910220815008C0809141 +:100500006A008093822181E080939A208CE080931E +:1005100002202AC08CE08093022080918321909158 +:1005200084218A369F4F1CF08FEF9FEF02C081E03D +:1005300090E080937D2190937E2180918321909102 +:10054000842120917D2130917E2160E370E00E9422 +:10055000CB15261B370B20937D2130937E21809174 +:100560007D2190917E213EDF80919A20813029F576 +:100570008091832190918421C39794F080910220EF +:10058000882331F08091022081508093022015C091 +:1005900080916A0080937F2183E080939A200DC030 +:1005A0008091832190918421873991051CF481E009 +:1005B00090E002C08FEF9FEF15DFC0930320D09330 +:1005C0000420DF91CF9108958617970779F0681777 +:1005D000790728F49C01261B370BB90109C086173F +:1005E000970718F4681B790B03C0089560E070E06A +:1005F000CB010895CF93DF9380910020909101204B +:10060000892B51F0809100209091012001978093D7 +:1006100000209093012043C080E490E0809300206C +:100620009093012080910720909108200196B9F1C4 +:10063000809114019091150120910920263018F421 +:1006400067E771E002C06EEE72E00E94B715EC0140 +:1006500080910720909108208C179D0758F4609195 +:10066000072070910820CE01AFDF029718F080ECD0 +:100670009DE511C08091072090910820C817D907E7 +:1006800070F46091072070910820CE019DDF0297E1 +:1006900030F08FEB9DE58093360A9093370ADF9117 +:1006A000CF910895AC01460F571F861B970B2091E1 +:1006B000200A3091210A24173507C8F72091200A13 +:1006C0003091210A8217930790F70895E0E8F6E049 +:1006D0008FE0808385E0848308951F93CF93DF9319 +:1006E000C0E4D0E0198180E4898340E250E068EB07 +:1006F0007BE280E290E00E945E0F1983DF91CF9150 +:100700001F9108951F93CF93DF93C0E4D0E0198128 +:1007100080E489838BEB95E20E94A60F81E00E9422 +:10072000B80F1983DF91CF911F91089508950F930A +:100730001F932091A4208EEE92E0289FA001299F74 +:10074000500D112444525A4D07E913E02EEE32E0C9 +:1007500060E081E80E9462131F910F9108951CBE12 +:10076000EEEFF0E40994B9DF8091B82B882369F0AB +:1007700080E2E8EBFBE2ABEBB5E201900D928A95EB +:10078000E1F71092BB25BEDFEADF87E08093A2008D +:10079000789473DDCBDFBAD749D16CD160E080E0CB +:1007A00003D1EFD08CE0E3D07ED522D63BD68EDFCE +:1007B00060E870E28EE891E20E94ED150000000012 +:1007C0000000000000000000000000000000000029 +:1007D000000000000000000080919F20882371F33A +:1007E000E091BA238E2F90E088309105A0F4FC01AF +:1007F000E250FF4F0C94DE1568D10DC0DAD10BC06A +:1008000068D209C0EED207C07BD305C002D403C0B2 +:1008100001D401C073D410929F20D0CF08950895C1 +:10082000E09109208E2F90E08830910590F4FC0132 +:10083000EA5FFE4F0C94DE15BBD10BC049D209C054 +:10084000CFD207C05CD305C0E3D303C056D401C0E8 +:10085000C9D48091140180939721809115018093D0 +:100860009821809124018093992180912501809382 +:100870009A218091200A8093A3218091210A80935C +:10088000A42180911401909115018634914080F04B +:100890008091140190911501893A914048F480911A +:1008A0001401909115018093D82B9093D92B0000BF +:1008B0008091A220882339F016DD1092A22081E0D9 +:1008C0008093A12008958091A120882341F08091F8 +:1008D0009A20833019F419DD8DDE01C0E5DD8091A9 +:1008E000A020882351F080911401909115018093EC +:1008F000D82B9093D92B1092A0209091A42081E026 +:10090000911180E08093A42008950F931F9381E0BC +:100910008093A7208093A22007E913E02DE730E021 +:100920004CED55E260E081E80E94621381E01F9186 +:100930000F9108951092A720089581E0089581E015 +:10094000089510922002982F9C7193689093200232 +:1009500087FF03C090E182E002C090E080E0892B35 +:100960008093210210922202109226020895E0E064 +:10097000F2E010AA836880AB80E181AB12AA16AACC +:100980000895E0E0F2E010A683E880A78FE281A757 +:1009900012A616A60895AAECB1E092E09C93E82F67 +:1009A000F0E084911C920895909171009D7F909346 +:1009B000710010920002623011F09CE101C09EE1D2 +:1009C0009093010290E490930202811102C080E4AE +:1009D00001C080EC80930302613011F084E001C01B +:1009E00083E08093040280E2D6DF80930C0281E2F0 +:1009F000D2DF80930D02109218021092190281E04A +:100A000080930002BECF1F920F920FB60F92112457 +:100A10008F93000000000000000081E0809323021B +:100A20008F910F900FBE0F901F901895CF93DF936B +:100A3000E0E7F0E082818B7F8283C0E2D3E08DE04B +:100A4000888380E4898389E08A8383E3A4DF8887BD +:100A500082E3A1DF898787E39EDF8A8786E39BDFC6 +:100A60008B87E0E2F6E08081836080831482DF91EF +:100A7000CF910895E0E7F0E080818E7F808380E869 +:100A8000809300010895E0E0F1E0108A80E4808B1B +:100A900010A280A310AA80ABE0E4F1E01082808372 +:100AA0001092A6201092A5201092A42010928C21C2 +:100AB00010928D2110928A2110928B21089580939B +:100AC000BA2381E080939F200895CF93DF93109203 +:100AD0000920D9DFC0E0D1E01EAA94E298AB19AAA0 +:100AE00049E54AAB32E03BAB60910B2070910C20A2 +:100AF0006CAB7DAB6BEB73E268AF79AF1AAE8BE397 +:100B00008CAF83E080933D0110923E0128A92068BC +:100B100028AB10924601E0E4F1E09083109241018D +:100B2000409342018093430140910D2050910E204B +:100B300040934401509345014AEA51E240934801F1 +:100B40005093490110924A0129E320934C0180936C +:100B50004D0110924E01208120682083188A20E4E4 +:100B6000288B24E0288B898B85E98A8B80E18B8B0D +:100B700047E751E04C8B5D8B988F398F1A8E8CED47 +:100B800095E28C8F9D8F1E8E68EC70E084EF91E073 +:100B900089DD88EC90E0809307209093082081E025 +:100BA0008093062088898068888BDF91CF91089593 +:100BB0000895EF92FF921F93CF93DF9311E010936C +:100BC000092061DFC0E0D1E018AA80E488AB94E09E +:100BD00098AB19AA1AAA6BE46BAB1CAA1DAA1EAA91 +:100BE0002AE030E228AF39AF1AAEA0EAACAF58E045 +:100BF00050933D0110923E0188A9806A88ABE0EADB +:100C0000F8E085E58083808310924601E0E4F1E01E +:100C100044E240831092410189E58093420132E031 +:100C200030934301E0900B20F0900C20E0924401BF +:100C3000F09245018BEBE82E83E2F82EE09248011A +:100C4000F092490110924A018BE380934C0183E0BA +:100C500080934D0110924E0120812068208398A33B +:100C600089A325E92AA36BA367E771E06CA37DA3A1 +:100C7000A8A759A71AA6EAECF8E2ECA7FDA71EA6BA +:100C8000988B898B2A8B80E18B8B6C8B7D8B488F2B +:100C9000398F1A8E8CED95E28C8F9D8F1E8E68ECAD +:100CA00070E084EF91E0FEDC88EC90E08093072018 +:100CB000909308201093062088A1806888A38889D3 +:100CC0008068888BDF91CF911F91FF90EF900895FE +:100CD00008951F93CF93DF9312E010930920D3DE82 +:100CE000C0E0D1E01EAA94E298AB19AA39E53AAB6C +:100CF0001BAB40910B2050910C204CAB5DAB4BEBF0 +:100D000053E248AF59AF1AAE8BE38CAF83E08093C8 +:100D10003D0110923E0128A9206828AB109246019F +:100D2000E0E4F1E09083109241013093420180931E +:100D3000430120910D2030910E20209344013093E7 +:100D400045012AEA31E2209348013093490110928B +:100D50004A0129E320934C0180934D0110924E01EA +:100D6000208120682083188A20E4288B64E0688B27 +:100D7000898B55E95A8B40E14B8B27E731E02C8B6F +:100D80003D8B988F198F1A8EECEDF5E2EC8FFD8F6D +:100D90001E8E68A389A35AA34BA32CA33DA384E36F +:100DA00088A719A71AA68AEC98E28CA79DA71EA669 +:100DB00068EC70E084EF91E075DC88EC90E0809363 +:100DC00007209093082081E080930620888980681E +:100DD000888B88A1806888A3DF91CF911F910895A7 +:100DE00008951F93CF93DF9313E0109309204BDEF8 +:100DF000C0E0D1E010924601E0E4F1E024E220837B +:100E00001092410199E59093420182E08093430161 +:100E100040910B2050910C20409344015093450188 +:100E20004BEB53E2409348015093490110924A0121 +:100E30008BE380934C0110934D0110924E01808101 +:100E4000806880831EAA28AB19AA9AAB1BAB80913D +:100E50000D2090910E208CAB9DAB8AEA91E288AF79 +:100E600099AF1AAE89E38CAF10933D0110923E0109 +:100E700088A9806888AB18A250E458A344E048A32E +:100E800019A21AA23BE43BA31CA21DA21EA28AE047 +:100E900090E288A799A71AA620EA2CA798E09DA718 +:100EA0001EA688A1806A88A385E58093A008188A79 +:100EB000588B488B198B85E98A8B3B8B47E751E030 +:100EC0004C8B5D8B288F998F1A8E8CED95E28C8FD1 +:100ED0009D8F1E8E68EC70E084EF91E0E3DB88EC80 +:100EE00090E0809307209093082081E08093062073 +:100EF00088898068888BDF91CF911F91089508952C +:100F00001F93CF93DF9314E010930920BCDDC0E062 +:100F1000D1E018AA80E488AB18AB19AA1AAA3BE45E +:100F20003BAB1CAA1DAA1EAA8AE090E288AF99AF2B +:100F30001AAE50EA5CAF88E080933D0110923E010A +:100F400098A9906A98AB95E59093A00810924601F5 +:100F5000E0E4F1E094E290831092410199E59093EE +:100F6000420192E09093430160910B2070910C201C +:100F700060934401709345016BEB73E26093480109 +:100F80007093490110924A019BE390934C0193E0C6 +:100F900090934D0110924E01208120682083188B80 +:100FA000998B45E94A8B3B8B27E731E02C8B3D8BB6 +:100FB000588F898F1A8E6CED75E26C8F7D8F1E8E27 +:100FC00018A399A34AA39AE49BA32CA33DA393EC53 +:100FD00098A789A71AA68AEC98E28CA79DA71EA6B7 +:100FE00068EC70E084EF91E05DDB88EC90E080934A +:100FF00007209093082081E08093062088898068EC +:10100000888B88A1806888A3DF91CF911F91089574 +:101010000895FFCFCF93DF9386E08093092033DDDF +:10102000C0E0D1E01EAA84E288AB19AA39E53AAB48 +:1010300093E09BAB40910D2050910E204CAB5DABEB +:101040004AEA51E248AF59AF1AAE29E32CAF909368 +:101050003D0110923E0128A9206828AB109246015C +:10106000E0E4F1E08083109241013093420122E0FC +:101070002093430140910B2050910C204093440158 +:10108000509345014BEB53E2409348015093490183 +:1010900010924A013BE330934C0190934D01109222 +:1010A0004E01908190689083188A90E4988B888B89 +:1010B000198A95E99A8B90E19B8B4CED55E04C8B0E +:1010C0005D8B888F298F1A8E8CED95E28C8F9D8F8A +:1010D0001E8E68EC70E084EF91E0E4DA80E991E044 +:1010E000809307209093082081E0809306208889D0 +:1010F0008068888BDF91CF9108950895CF93DF9317 +:1011000087E080930920BFDCC0E0D1E01EAA84E222 +:1011100088AB19AA39E53AAB93E09BAB40910D201F +:1011200050910E204CAB5DAB4AEA51E248AF59AF4B +:101130001AAE29E32CAF90933D0110923E0128A9ED +:10114000206828AB10924601E0E4F1E08083109221 +:1011500041013093420122E02093430140910B2052 +:1011600050910C2040934401509345014BEB53E2C6 +:10117000409348015093490110924A013BE3309358 +:101180004C0190934D0110924E0190819068908394 +:10119000188A90E4988B95E2988B198A95E99A8B36 +:1011A00090E19B8B4CED55E04C8B5D8B888F298FAC +:1011B0001A8E8CED95E28C8F9D8F1E8E68EC70E000 +:1011C00084EF91E06FDA80E991E0809307209093BB +:1011D000082081E08093062088898068888BDF91D1 +:1011E000CF91089508951F920F920FB60F92112478 +:1011F0008F939F9381E0809303011092100184E00C +:101200008093100187E791E080931401909315017A +:101210008091A420811103C08EEE92E002C080E094 +:1012200090E084529A4D80931C0190931D0180910F +:1012300010018068809310019F918F910F900FBED5 +:101240000F901F9018951F920F920FB60F921124B6 +:101250008F939F9382E0809303011092200184E09A +:101260008093200187E791E08093240190932501EA +:101270008091A420811103C085E694E002C087E735 +:1012800091E084529A4D80932C0190932D0180918E +:1012900020018068809320019F918F910F900FBE55 +:1012A0000F901F901895E0E7F0E083818C7F838397 +:1012B00084818C7F848380818D7F8083E0E8F1E06E +:1012C00080EC8283128688EC81831186A0E0B8E0EE +:1012D00034E03C9323E011962C93119714961C92C2 +:1012E000149785ED91E096968D939C93979716961B +:1012F0001C921697E0E4F8E030832183148286A3E1 +:1013000097A31682E0E6F6E0808180618083E0E4C6 +:10131000F9E083E18183148282E08683A6A3B7A3E8 +:1013200010A611A681E0808308951F920F920FB638 +:101330000F9211242F933F934F935F938F939F931B +:10134000CF93DF931F92CDB7DEB78FEF80934C0919 +:1013500080910920873031F480912C02898390910B +:101360002D0202C090912C028091A320891B209114 +:1013700068093091690982308CF02A3F374070F457 +:10138000209168093091690989301CF481E090E06E +:1013900002C086E090E0820F931F18C02091680978 +:1013A000309169098F3FB4F42730310598F02091CE +:1013B000680930916909883F1CF081E090E002C023 +:1013C00086E090E0A901481B590BCA018093780977 +:1013D000909379090F90DF91CF919F918F915F91B9 +:1013E0004F913F912F910F900FBE0F901F90189526 +:1013F000E0E7F0E083818F7E8383E0E4F6E08081A4 +:101400008A6A80838FEF848388E5828BE0EAF8E044 +:1014100080E3838384EC858387E08683178288E179 +:1014200084830895E0E7F0E08381877F8383E0ECA5 +:10143000F8E080E48083118288E580935506089562 +:101440001F920F920FB60F92112400000F900FBE43 +:101450000F901F9018951F920F920FB60F921124A4 +:101460008F93EF93FF93E0EAF8E080818083FF9110 +:10147000EF918F910F900FBE0F901F9018959FB70F +:10148000F894A0E5B0E016968C911697897F169691 +:101490008C931697E0E6F0E080E885838BEB8683FB +:1014A00016968C911697846016968C938081816035 +:1014B00080839FBF08959FB7F894E82FF0E0E0592C +:1014C000FF4F60958081682360839FBF0895CF930D +:1014D000863011F0C0E001C0C8E18091510081FD6B +:1014E0000DC09FB7F89480915000826080935000A7 +:1014F0009FBF8091510081FFFCCFC1DF6C2F6360E3 +:1015000084E490E0C0D460E480E0CF91D4CF8091B7 +:10151000A82008958091A820813009F40BCA08956D +:10152000F0D0FC0183818093A820811101C0EDC916 +:1015300081E008959091AA23892F807697FF07C0B4 +:10154000803491F48091AB2381110EC0F8C98034AE +:1015500059F48091AB23811107C08091B023909101 +:10156000B123892B09F0E9C980E008958091AC236B +:101570008F770C94E4129091B020911102C080E01A +:101580000895E091AD20F091AE200190F081E02D22 +:1015900094818917A0F7E093AB20F093AC202281CF +:1015A00033812E0F3F1FE217F30798F49181943097 +:1015B00061F49281891309C09381691306C0E09395 +:1015C000AB20F093AC2081E008959081E90FF11DEC +:1015D000EACFE093AB20F093AC20D1CFE091AD20E7 +:1015E000F091AE200190F081E02D228133812E0F09 +:1015F0003F1FFC014081E40FF11DE217F30748F49F +:101600008181843031F0853039F08081E80FF11D1F +:10161000F4CF80E090E00895CF0108951F93CF9319 +:10162000DF93182FA8DF882339F1C091AB20D09128 +:10163000AC20CE01D3DFEC01892B41F04C815D81E0 +:101640006B818A81CED78111F4CF16C0E091AD2095 +:10165000F091AE2092818381E92FF82FE10FF11DE7 +:10166000E10FF11D0190F081E02D0190F081E02D5E +:10167000DF91CF911F91099480E0DF91CF911F916D +:101680000895EF92FF921F93CF93DF93C82F60E0EE +:1016900072DF811102C010E02DC0E091AD20F09109 +:1016A000AE2092818381E92FF82FEC0FF11DEC0F12 +:1016B000F11DE080F180D7011696ED91FC9117970E +:1016C0000995682F8C2F57DF182F882321F3C0919D +:1016D000AB20D091AC20CE0181DFEC01892B21F031 +:1016E0008A810E941E14F7CFD7011296ED91FC91CA +:1016F00013970995812FDF91CF911F91FF90EF9064 +:1017000008958091AB209091AC200895FFC6CF93AF +:101710008091B020811108C01092B0201092B420A6 +:101720001092B520CF910895C0E0E091AD20F091E6 +:10173000AE200190F081E02D8481C81768F78C2FCE +:10174000A0DFCF5FF2CFCF938091B0208823F1F05C +:10175000C0E0E091AD20F091AE20A081B18114965F +:101760008C91C81798F492818381E92FF82FEC0FA0 +:10177000F11DEC0FF11D0190F081E02D0084F18549 +:10178000E02D309709F00995CF5FE3CFCF91089511 +:10179000EF92FF920F931F93CF93DF931F92CDB7DA +:1017A000DEB71092B4231092B5231092B623109294 +:1017B000B7231092B8231092B9238091AA2387FFF0 +:1017C00007C02091B0233091B123232B09F452C3D9 +:1017D000982F9076903409F00FC1E091AB238E2FB3 +:1017E00090E0FC01E05AF109EA30F10508F0D1C2BD +:1017F000E25FFE4F0C94DE1581E08093A020809183 +:1018000007209091082080939B2180910720909140 +:10181000082090939C218091822180939D2180912A +:101820007F2180939E2180916A0080939F218091E7 +:101830006B008093A0216091B0237091B1238EE85A +:1018400091E2D8C0109200088091AC239091AD2312 +:1018500080933608909337088091AE238F708093E1 +:1018600000086091B0237091B1238AEA91E2B2D668 +:1018700020910D2030910E208091B0239091B123C2 +:101880002817390709F4F4C280930D2090930E2095 +:1018900026C0109240088091AC239091AD23809394 +:1018A0007608909377088091AE238F7080934008DC +:1018B0006091B0237091B1238BEB93E28BD6209192 +:1018C0000B2030910C208091B0239091B1232817E8 +:1018D000390709F4CDC280930B2090930C2080919E +:1018E000092055C010926809109269098091AC23B3 +:1018F0008093A320BDC28091AC2380932406B8C2FC +:10190000E091AC23F091AD23E830F10508F041C23D +:10191000E85EFE4F0C94DE1560E080E045D88091D3 +:10192000AE230FD880E033C060E080E03DD88091E6 +:10193000AE2307D881E02BC061E081E035D88091EB +:10194000AE230E94A1048091AF2311D882E01FC072 +:1019500083E01DC084E01BC060E080E025D880915A +:10196000AE230E94A10485E012C061E080E01CD893 +:101970008091AE230E94A10486E009C062E080E06D +:1019800013D88091AE2380680E94A10487E097D885 +:101990006FC28091AC23809384066AC28091AC238D +:1019A0009091AD23892B91F00E946D0380E2E8EBCA +:1019B000FBE2ABEBB5E201900D928A95E1F781E095 +:1019C0008093BB250E9482030E946D03E9E7F0E04B +:1019D00091E088EDF89484BF90836091B02370917A +:1019E000B1238AE890E206C06091B0237091B123E0 +:1019F00089E890E2EFD53CC29111CBC187FFFCC0D2 +:101A00002091B0233091B1232115310509F4C1C1D2 +:101A10008F7109F09EC08091AB23863071F08830C1 +:101A200009F48EC08111B5C12230310509F0B1C170 +:101A300062E070E084EB90E2DDCF8091AC23909186 +:101A4000AD23292F332722303105A1F064F4213052 +:101A5000310509F09EC18091192090911A20DC0176 +:101A60006C9170E05BC02330310589F12F30310576 +:101A700009F18FC1E0911920F0911A202189821774 +:101A800008F087C19927880F991F880F991FE09147 +:101A90001B20F0911C20E80FF91F80819181FC012F +:101AA0006281738197D5E091B223F091B32382E0F4 +:101AB000818335C080911D2090911E20009709F4EC +:101AC00068C1DC0112966D917C91139727C099270C +:101AD0008130910569F038F0029709F05AC168E049 +:101AE0008AE690E208C064E070E08CE790E216C0FD +:101AF00067E083E790E2282FAAE5B0E2FC0181913C +:101B000090E08D939D938E2F821B8617C0F3660FF6 +:101B10006E5F6093582070E088E590E25BD580911D +:101B2000B0239091B1232091B4233091B523821733 +:101B3000930708F09DC18093B4239093B52398C177 +:101B40002130310509F025C161E070E080EB90E2C1 +:101B500051CF8130C9F58091AB238A3009F019C18A +:101B60002130310509F015C18091B020882309F496 +:101B700010C1E090AE23F090AF230091AD20109102 +:101B8000AE20D801ED91FC918481E81608F001C1E6 +:101B900060E08E2DF0DC882309F4FBC0FF24EE0CFE +:101BA000FF1CF801828193818E0D9F1DDC01ED9158 +:101BB000FC910680F781E02D09958093B22061E0C9 +:101BC00070E082EB90E216CF823009F0E2C08091A3 +:101BD000AB238111DEC02230310509F0DAC08091DB +:101BE000AE2350D590E08093A9209093AA2062E084 +:101BF00070E089EA90E2FECE8F7109F07DC080919D +:101C0000AB23833009F4C5C018F48130A1F0C1C002 +:101C1000853019F0893039F1BCC08091B0239091A2 +:101C2000B123892B09F0B5C086EB9AE08093B623E7 +:101C30009093B7231DC18091B0239091B123892B3C +:101C400009F0A7C08091AC239091AD23019709F0D2 +:101C5000A0C08091B4209091B5208D7F8093B42056 +:101C60009093B52005C18091B0239091B123892B29 +:101C700009F08FC0ACD4882309F48BC02091AC2329 +:101C80003091AD233327E0911920F0911A208189FA +:101C900090E08217930708F47CC039DD8091AC2373 +:101CA0009091AD238093B020882309F4E1C0992757 +:101CB0008150904C880F991F880F991F20911B20ED +:101CC00030911C20820F931F8093AD209093AE2003 +:101CD00010E0E091AD20F091AE200190F081E02D78 +:101CE0008481181708F0C4C060E0812F97DC882336 +:101CF00009F44FC01F5FEDCF8130F1F48091AB2329 +:101D00008B3009F046C08091B0239091B123892B8C +:101D100009F03FC08091B020882309F43AC01091A7 +:101D2000AE236091AC23812F6983ABDC698188236A +:101D300081F1812F73DC2BC0823059F58091AB2368 +:101D4000813019F0833089F024C08091B0239091C4 +:101D5000B123892BF1F48091AC239091AD23892B91 +:101D6000C1F48091AE2395D412C08091B02390919C +:101D7000B123892B71F48091AC239091AD23892BF1 +:101D800041F48091AE232AD58091AE2360D5811194 +:101D90006FC08091AA238F718130B9F58091B020F6 +:101DA000882399F1E090AE23F090AF230091AD200D +:101DB0001091AE20D801ED91FC918481E81628F5B0 +:101DC00060E08E2DD8DB882301F1F701FF27EE0FAD +:101DD000FF1FD80112968D919C911397E80FF91F60 +:101DE00000811181D8011696ED91FC911797099504 +:101DF000682F8E2DC0DB882341F0D8011496ED9119 +:101E0000FC9115970995811133C08091AA238F7198 +:101E1000823081F58091B020882361F1F12CE0912E +:101E2000AD20F091AE20A081B18114968C91F8166E +:101E300008F592818381E92FF82FEF0DF11DEF0D49 +:101E4000F11D00811181D8011696ED91FC91179733 +:101E50000995682F8F2D8FDB882361F0D8011496A8 +:101E6000ED91FC9115970995811102C0F394D7CF9C +:101E700081E001C080E00F90DF91CF911F910F9121 +:101E8000FF90EF9008951BBEFC0128ED24BF6083F6 +:101E900008958091CF0187FDFCCF08951F93CF93C4 +:101EA000DF93C0ECD1E01A858A8761E08BEC91E08A +:101EB000EADF1A87DF91CF911F910895CF92DF92C9 +:101EC000EF92FF920F931F93CF93DF9300D0CDB784 +:101ED000DEB78C017B0149835A83DBDF8CECC82E93 +:101EE000DD24D394F601908198609083B801705FEF +:101EF00049815A81C70168D6F6018081877F808336 +:101F00000F900F90DF91CF911F910F91FF90EF9065 +:101F1000DF90CF900895CF93DF9300D0CDB7DEB799 +:101F20006A838983B6DFACECB1E09C9198609C93A6 +:101F30008981E82FF0E0F05F6A8160838C91877F70 +:101F40008C930F900F90DF91CF9108950F931F9373 +:101F5000CF938C019EDFC0E0F80161918F018C2F3F +:101F6000DADFCF5FC032C1F7CF911F910F91089593 +:101F7000CF93DF931F92CDB7DEB789838ADF898144 +:101F800020E2829FC0011124E0ECF1E012829183F3 +:101F9000808385E30F90DF91CF9180CF4091CA017C +:101FA000E62FF72F8093CA0184914093CA010895C8 +:101FB000E82FF0E0E652F44D80818F3F09F4FFCF27 +:101FC0009FB7F89480818F5F80839FBF0895E82F2B +:101FD000F0E0E652F44D8081811101C0FFCF9FB740 +:101FE000F8948081815080839FBF0895CF93C82F3C +:101FF00080917C21C11105C0882339F081E0E7DFA1 +:1020000004C0811102C081E0D3DFC0937C21CF9155 +:102010000895282F2F70082E000C990B392F331F8D +:102020003327331F832F90E0820F911D820F911D64 +:1020300023E0880F991F2A95E1F7885A9E4D08954D +:102040000F93E8ECF4E080818F7D808380818F7D29 +:102050008083E0E6F1E202E00593109262211092A3 +:10206000632100E2069300E40693E8E5F1E200E272 +:10207000069300E40693EAEAF3E2148615861686D0 +:1020800017861286138610924D210F9108950F9393 +:1020900085E080934D21E1E6F1E204E00593E9E576 +:1020A000F1E204E005930F9108950F9383E080938C +:1020B0004D211092622110926321E0E6F1E202E0EC +:1020C00006930F910895E091B623F091B7233097CE +:1020D00009F009940895282F2F70082E000C990BF1 +:1020E000392F331F3327331F832F90E0820F911D29 +:1020F000820F911D029749E0489F9001499F300D42 +:102100001124C90189509F4D08958F929F92AF92DB +:10211000BF92DF92EF92FF920F931F93CF93DF93C3 +:10212000D82ED9DFEC018D2D74DF7C01DC011196F6 +:10213000EC91E770E150E73040F4F0E0EE0FFF1F64 +:10214000E457FF4D0081118102C008E010E0ED81ED +:10215000FE812B813C814881D701D7FE48C016966D +:102160008D919C9117978E0F9F1F8D839E83821751 +:10217000930761F1281B390B2115B4E03B0738F0B8 +:102180002FEF33E0C901B801F2D4281B390B41FF0E +:102190000AC0C901B801EBD4AC0191E0452B09F0AC +:1021A00090E0892F01C080E0988180FB91F99883AD +:1021B000F701168217822283338329813A818D8128 +:1021C0009E81820F931F848395830EC041FF71C04F +:1021D0004D7F4883D70116961D921C921797129631 +:1021E0001D921C921397F70102E006937BC0129692 +:1021F000AD90BC90139742FF10C089809A80C901AE +:10220000B801B5D4B0E4DB9EB001112469587F4D0C +:10221000AC01C4018E0F9F1FD7D48D819E818A0D82 +:102220009B1D8D839E832B813C812817390710F4D9 +:102230002D833E83F70186819781A816B906C9F5DB +:102240008D819E8182179307A1F1281B390B2115DF +:10225000F4E03F0710F02FEF33E0C901B80187D455 +:10226000281B390BD70112961D921C921397201729 +:10227000310778F4888184608883B0E4DB9EC001F4 +:10228000112489589F4DF701848395830683178312 +:10229000AACF49815A818D819E81840F951FD701D4 +:1022A00014968D939C93159716962D933C931797A0 +:1022B0009ACF888180FF16C08E7F8883EF81F88552 +:1022C000309781F06D817E814D2D80E0DF91CF913F +:1022D0001F910F91FF90EF90DF90BF90AF909F9074 +:1022E0008F900994DF91CF911F910F91FF90EF9004 +:1022F000DF90BF90AF909F908F9008950F93CF93F2 +:10230000DF9380914D21833029F4DDDEDF91CF9181 +:102310000F9196CE2091492130914A21C091B4234A +:10232000D091B523C21BD30B61F580914B219091C5 +:102330004C21820F931F80934B2190934C2120912D +:10234000B0233091B1232817390721F08091B620AE +:10235000882331F084E080934D21E8E5F1E236C036 +:10236000E091B823F091B923309799F0099588232B +:1023700081F01092492110924A21C091B423D0914A +:10238000B523C034D10528F01092B620C0E4D0E0C7 +:1023900003C081E08093B620C0936221D093632173 +:1023A0008091492190914A212091B2233091B32309 +:1023B000280F391F2093642130936521C80FD91F3E +:1023C000C0934921D0934A21E0E6F1E202E006936E +:1023D000DF91CF910F9108950F93CF93DF931F92C9 +:1023E000CDB7DEB78091CC0480FF65C021E020939B +:1023F000CC0488E591E2FC0100E80693E0E6F1E216 +:1024000000E806932093CA04FC0100E10693809142 +:102410004D21882329F08350823008F454DE10DEE9 +:1024200080915A2190915B21089709F046C088E07D +:10243000E9E0F1E2AAEAB3E201900D928A95E1F7B0 +:102440008091C80480628093C8048091C80480622F +:102450008093C8049DD9811102C019DE2EC09091CD +:10246000AA2397FF0EC010924B2110924C2110927C +:10247000492110924A2192E090934D2189833EDFB9 +:1024800008C02091B0233091B123232B21F48983FC +:102490000CDE898113C010924B2110924C211092B6 +:1024A000492110924A2191E090934D21E8E5F1E213 +:1024B00002E0069303C080E001C081E00F90DF914D +:1024C000CF910F910895CF93CFB7F89481E08EDD2F +:1024D000EAECF4E080E4808380E28083E1ECF4E0E5 +:1024E000808181608083A9ECB4E08C9182608C93C0 +:1024F000E8ECF4E08081806480838C9181608C932F +:10250000808180688083CFBFCF910895CF93109250 +:10251000600080E30E94670A8091C0048064809319 +:10252000C00481E080936000CFB7F89410925921E5 +:102530001092612110926921109271218091F720EF +:102540008E7F8093F720809100218E7F80930021E1 +:102550006AE170E082E022DD8F3F09F48FE1809331 +:10256000FA046BE170E082E019DD8F3F09F48FE13E +:102570008093FB048091C00481608093C0048091AB +:10258000C00480688093C0048091C00480618093FF +:10259000C00488E591E28093C6049093C7048091BB +:1025A000C00480628093C0048FEF8093C504809143 +:1025B000C80482608093C80410927C2185E0F8DC16 +:1025C00082DFCFBFCF9108958093C3040895809197 +:1025D000C3040895EAEAF3E28087918762877387EC +:1025E00008950F931F93CF93DF931F92CDB7DEB75C +:1025F0008A0169830EDDFC018181807C6981811102 +:102600003AC06370613019F020F080E803C080ECBC +:1026100001C080E400381105E9F058F400321105DA +:10262000A9F000341105A1F000311105C9F491E0C1 +:1026300018C0011592E0190779F00F3F93E01907D0 +:1026400069F00115114061F495E00BC092E009C0FA +:1026500093E007C094E005C096E003C097E001C096 +:1026600090E0118226E02083982B91838181806203 +:10267000818381E001C080E00F90DF91CF911F91B5 +:102680000F910895C6DCFC01818182FB882780F9C7 +:102690000895CF93C82FBDDCFC01818182FF0FC05C +:1026A00091819B7F91838C2F16DDFC01908190FF9F +:1026B00006C09E7F90830780F085E02D099581E01C +:1026C000CF9108958F929F92AF92BF92DF92EF9237 +:1026D000FF920F931F93CF93DF931F92CDB7DEB777 +:1026E000D82E5A0179016983F6DC4C018D2D91DCDD +:1026F0009C01DC0111968C911197807C6981882363 +:1027000009F45EC011968C911197807C803C21F079 +:1027100011968C9182FD54C09FB7F894F40180818A +:1027200080FF02C09FBF4CC0816080839FBFF401C7 +:10273000A182B282E382F482158216820783108717 +:1027400091E0611104C0E114F10409F090E0D401BA +:102750008C9190FB81F98B7F8C93D7FE04C0F9019B +:102760001682178229C0D90111968C911197807C0D +:10277000803CC9F41196EC91E770E150E73040F4E9 +:10278000F0E0EE0FFF1FE457FF4D6081718102C042 +:1027900068E070E0C701EBD1892B29F0F40180815A +:1027A0008E7F80830DC0D90112961D921C921397C3 +:1027B00016961D921C9217978D2DA7DC81E001C003 +:1027C00080E00F90DF91CF911F910F91FF90EF90DC +:1027D000DF90BF90AF909F908F900895EF92FF92FF +:1027E0000F93CF93C82F15DC7C018C2F74DCDC0198 +:1027F000F70102E005939C9190FF1BC09E7F9C9384 +:102800001796ED91FC911897309799F0D701C7FF73 +:1028100005C016966D917C91179704C012966D9124 +:102820007C9113974C2F81E0CF910F91FF90EF9007 +:102830000994CF910F91FF90EF900895CF93C82FF7 +:10284000CDDF8C2FE6DBFC011182CF9108950F9331 +:10285000CF93C82FDEDBFC0191819460918301E06E +:1028600006938C2FBBDF81E0CF910F9108951F92CB +:102870000F920FB60F9211240F932F933F934F9304 +:102880005F936F937F938F939F93AF93BF93EF93D8 +:10289000FF938091CB0487FF08C080E88093CA042F +:1028A0000E94A30B0E9410047EC08091CB0482FF83 +:1028B00018C084E08093CA048091602186FF73C0B1 +:1028C0008091CC0481FD6FC087DD81116CC0809147 +:1028D0004D21813011F4E9DB66C0843009F063C01A +:1028E00021C08091CB0481FF26C082E08093CA047E +:1028F0008091582186FF57C08091CC0481FD53C040 +:102900006BDD811150C080914D21823041F484E013 +:1029100080934D21E8E5F1E202E0069344C0833064 +:1029200009F041C0E1E6F1E204E00593E9E5F1E2F6 +:1029300004E0059338C08091CB0484FF1DC080E182 +:102940008093CA040E94870B1092C30410925921ED +:1029500096E09093582183E480935921109261214D +:10296000909360218093612189E091E280935C21C2 +:1029700090935D2165DB17C08091CB0486FF08C072 +:1029800080E48093CA0480E031DB0E940E040BC017 +:102990008091CB0485FF07C080E28093CA0481E068 +:1029A00025DB0E940F04FF91EF91BF91AF919F91A2 +:1029B0008F917F916F915F914F913F912F910F91E7 +:1029C0000F900FBE0F901F9018951F920F920FB689 +:1029D0000F9211240F931F932F933F934F935F9365 +:1029E0006F937F938F939F93AF93BF93CF93DF9317 +:1029F000EF93FF938091CC0481FF1AC082E0809313 +:102A0000CC048091C5048195880FE8E5F1E2E81BCC +:102A1000F109208131812855314283E0369527958F +:102A20008A95E1F7822F869520FD06C0C0E005C09B +:102A3000D3DC882319F386C0C0E8C80F8C2FE9DAED +:102A4000FC01208125FF7EC000E20693C11174C005 +:102A500080914D21843019F436DBF2DA73C0009195 +:102A60005A2110915B218091B4239091B523C0919C +:102A70004921D0914A219E01200F311F82179307CF +:102A800018F48C010C1B1D0B8091B2239091B32381 +:102A9000A80169E071E28C0F9D1F96D0C00FD11F75 +:102AA000C0934921D0934A210034110569F48091E3 +:102AB0004B2190914C218C0F9D1F2091B023309180 +:102AC000B1238217930788F0C093B423D093B52322 +:102AD000E091B823F091B923309729F0099581113D +:102AE00002C0D5DA2FC0E1DA2DC08091B4239091D5 +:102AF000B5238C179D07D9F4E091B823F091B92341 +:102B0000309779F30995882361F320914B21309117 +:102B10004C218091492190914A21820F931F8093EB +:102B20004B2190934C211092492110924A21E8E5C3 +:102B3000F1E202E0069306C0C03811F4DFDB02C008 +:102B40008C2FE3DAFF91EF91DF91CF91BF91AF919D +:102B50009F918F917F916F915F914F913F912F91B5 +:102B60001F910F910F900FBE0F901F901895AA1BE9 +:102B7000BB1B51E107C0AA1FBB1FA617B70710F068 +:102B8000A61BB70B881F991F5A95A9F7809590959A +:102B9000BC01CD01089597FB072E16F4009406D0D2 +:102BA00077FD08D0E4DF07FC05D03EF490958195D1 +:102BB0009F4F0895709561957F4F0895EE0FFF1F09 +:102BC0000590F491E02D0994FB01DC0102C0019015 +:102BD0000D9241505040D8F70895FB01DC0101905F +:0C2BE0000D920020E1F70895F894FFCF5B +:102BEC0040000CE02E0AFFFFFFFF55800080009094 +:102BFC000A8A0A9A0A870A000044201F200000282B +:102C0C002023200F20000000090219000101008080 +:102C1C00FA0904000001FFFFFF0007058101FF0313 +:102C2C00010000001201000200000040EB0394BA06 +:102C3C00000201020001000000030000000000007F +:102C4C00000000000000000000004C616272616432 +:102C5C006F72004573706F54656B000004030904B8 +:102C6C006465627567313233000203001000200086 +:0A2C7C004000800000010002FF0389 +:00000001FF diff --git a/Desktop_Interface/bin/firmware/labrafirm_0003_02.hex.REMOVED.git-id b/Desktop_Interface/bin/firmware/labrafirm_0003_02.hex.REMOVED.git-id deleted file mode 100644 index 42c42b45..00000000 --- a/Desktop_Interface/bin/firmware/labrafirm_0003_02.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -879125a9685d89a7f05bd38994079919338f49b6 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/QtCore.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/QtCore.REMOVED.git-id deleted file mode 100644 index b2c04bb6..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/QtCore.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4e97581784c6d56b5004ece88c211f6eaa629cf2 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/Resources.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/Resources.REMOVED.git-id deleted file mode 100644 index bcf4bd23..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/Resources.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ae77f62d81117de42e136af77f502ad195f40c8c \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/Versions/5/QtCore.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/Versions/5/QtCore.REMOVED.git-id deleted file mode 100644 index efb907b5..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/Versions/5/QtCore.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3c83c4b4bda97bc27a5fcdc74c0486761f044941 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/Versions/5/Resources/Info.plist.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/Versions/5/Resources/Info.plist.REMOVED.git-id deleted file mode 100644 index 0ae9073b..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/Versions/5/Resources/Info.plist.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -200ded4f26d05ba79b78a0ccbd85fe1383d52531 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/Versions/Current.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/Versions/Current.REMOVED.git-id deleted file mode 100644 index 28fe224a..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtCore.framework/Versions/Current.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e2414360b5d614e7aa142f7afec0e641250ad76e \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/QtDBus.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/QtDBus.REMOVED.git-id deleted file mode 100644 index 46800d3e..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/QtDBus.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0bc3bf862127fa45dfd8a960ff95edc2e6b68f2a \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/Resources.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/Resources.REMOVED.git-id deleted file mode 100644 index bcf4bd23..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/Resources.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ae77f62d81117de42e136af77f502ad195f40c8c \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/Versions/5/QtDBus.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/Versions/5/QtDBus.REMOVED.git-id deleted file mode 100644 index 4a9f15c9..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/Versions/5/QtDBus.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f0139f680d289ba0330ff86a9af03cdcaa732e8d \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/Versions/5/Resources/Info.plist.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/Versions/5/Resources/Info.plist.REMOVED.git-id deleted file mode 100644 index 38f4cfb6..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/Versions/5/Resources/Info.plist.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c16610f29f104c9b9cba2251d7b3421a81b96b65 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/Versions/Current.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/Versions/Current.REMOVED.git-id deleted file mode 100644 index 28fe224a..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtDBus.framework/Versions/Current.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e2414360b5d614e7aa142f7afec0e641250ad76e \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/QtGui.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/QtGui.REMOVED.git-id deleted file mode 100644 index ce1cd079..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/QtGui.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2c8183e63c528e766abb75d5266660a02b637506 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/Resources.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/Resources.REMOVED.git-id deleted file mode 100644 index bcf4bd23..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/Resources.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ae77f62d81117de42e136af77f502ad195f40c8c \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/Versions/5/QtGui.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/Versions/5/QtGui.REMOVED.git-id deleted file mode 100644 index d148d854..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/Versions/5/QtGui.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1212997f96a7998a5d07a5e69f3ee641deca2b21 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/Versions/5/Resources/Info.plist.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/Versions/5/Resources/Info.plist.REMOVED.git-id deleted file mode 100644 index dc968a59..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/Versions/5/Resources/Info.plist.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8cc6edbfc275e203fc18ee59193c0675d49da836 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/Versions/Current.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/Versions/Current.REMOVED.git-id deleted file mode 100644 index 28fe224a..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtGui.framework/Versions/Current.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e2414360b5d614e7aa142f7afec0e641250ad76e \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/QtPrintSupport.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/QtPrintSupport.REMOVED.git-id deleted file mode 100644 index f563bb21..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/QtPrintSupport.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d04c873ffe1192b07f10735c98f0ef154907dbb0 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/Resources.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/Resources.REMOVED.git-id deleted file mode 100644 index bcf4bd23..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/Resources.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ae77f62d81117de42e136af77f502ad195f40c8c \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/Versions/5/QtPrintSupport.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/Versions/5/QtPrintSupport.REMOVED.git-id deleted file mode 100644 index 808f9d49..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/Versions/5/QtPrintSupport.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6d73790b3479fb873f6a5a82d30d5cfc157bde03 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/Versions/5/Resources/Info.plist.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/Versions/5/Resources/Info.plist.REMOVED.git-id deleted file mode 100644 index b03b5296..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/Versions/5/Resources/Info.plist.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3ef8098ab9fe3b4a25345c44e249de8bb7a08614 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/Versions/Current.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/Versions/Current.REMOVED.git-id deleted file mode 100644 index 28fe224a..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtPrintSupport.framework/Versions/Current.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e2414360b5d614e7aa142f7afec0e641250ad76e \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/QtWidgets.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/QtWidgets.REMOVED.git-id deleted file mode 100644 index 1867fb43..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/QtWidgets.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -da28f76975d83c8487c95b17f6a4d2e409fb24ca \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/Resources.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/Resources.REMOVED.git-id deleted file mode 100644 index bcf4bd23..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/Resources.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ae77f62d81117de42e136af77f502ad195f40c8c \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/Versions/5/QtWidgets.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/Versions/5/QtWidgets.REMOVED.git-id deleted file mode 100644 index de116611..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/Versions/5/QtWidgets.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9c627dec33d2a24cb7aca78d8db8c641ad16f391 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/Versions/5/Resources/Info.plist.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/Versions/5/Resources/Info.plist.REMOVED.git-id deleted file mode 100644 index facf7bd9..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/Versions/5/Resources/Info.plist.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4bf529155850e8fb0aca883e52d551c9edd10c76 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/Versions/Current.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/Versions/Current.REMOVED.git-id deleted file mode 100644 index 28fe224a..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/QtWidgets.framework/Versions/Current.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e2414360b5d614e7aa142f7afec0e641250ad76e \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/libdfuprog-0.9.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/libdfuprog-0.9.dylib.REMOVED.git-id deleted file mode 100644 index 086e2d46..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/libdfuprog-0.9.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -af43fdf3d1e1d18f6ad80f3f6abae64315d673b2 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/libgcc_s.1.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/libgcc_s.1.dylib.REMOVED.git-id deleted file mode 100644 index 5d331b06..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/libgcc_s.1.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -da5320ffb129abfe60b570a632ee76ade361190a \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/libusb-1.0.0.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Frameworks/libusb-1.0.0.dylib.REMOVED.git-id deleted file mode 100644 index f9a549a4..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Frameworks/libusb-1.0.0.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9dfcb90a4e84af3c8f9da32a40a2fa3e50e057fc \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Info.plist.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Info.plist.REMOVED.git-id deleted file mode 100644 index 90d5ce92..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Info.plist.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4c69e89c9374b98c16829b05c52a2e48d9c75e60 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/MacOS/Labrador.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/MacOS/Labrador.REMOVED.git-id deleted file mode 100644 index 07d63776..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/MacOS/Labrador.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -93eea4b26dfb3fa7cccb657b0ce6c6b2309dadb9 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/dfu-programmer.exe.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/dfu-programmer.exe.REMOVED.git-id deleted file mode 100644 index b819c11c..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/dfu-programmer.exe.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b27d99e3b1bb4ec243a6f22881053dd6e6e94334 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/flash.bat.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/flash.bat.REMOVED.git-id deleted file mode 100644 index c0361a58..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/flash.bat.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -33b4424dfe12584fb5dffb5e26758a13d7b57b57 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/labrafirm_0001_01.hex.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/labrafirm_0001_01.hex.REMOVED.git-id deleted file mode 100644 index 07d97bdc..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/labrafirm_0001_01.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -044f2051fdfc79136bee11c6968cf73fa30eb572 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/labrafirm_0003_01.hex.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/labrafirm_0003_01.hex.REMOVED.git-id deleted file mode 100644 index b3667a22..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/labrafirm_0003_01.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f7946fd762c2bf7eaa4b76d5eb68948870244c19 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/labrafirm_0003_02.hex.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/labrafirm_0003_02.hex.REMOVED.git-id deleted file mode 100644 index 42c42b45..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/MacOS/firmware/labrafirm_0003_02.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -879125a9685d89a7f05bd38994079919338f49b6 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/MacOS/settings.set.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/MacOS/settings.set.REMOVED.git-id deleted file mode 100644 index b3c06306..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/MacOS/settings.set.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -816d01be5ca04d952ce4d347befefed997133065 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/Sawtooth.tlw.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/Sawtooth.tlw.REMOVED.git-id deleted file mode 100644 index 87e86502..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/Sawtooth.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e989a81be4fb7a2d79495ce7e96db776b0366a94 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/Sin.tlw.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/Sin.tlw.REMOVED.git-id deleted file mode 100644 index ceeb1ad1..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/Sin.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e376c35388394ccfa4a86cb5bc6f9961e00fef20 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/Square.tlw.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/Square.tlw.REMOVED.git-id deleted file mode 100644 index 25d85bc6..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/Square.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7bdd30bee84b15cc3fe88dd02751316a2016060c \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/Triangle.tlw.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/Triangle.tlw.REMOVED.git-id deleted file mode 100644 index 768d2ac7..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/Triangle.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -420ac92c2c292688434b3987874cc98a9180e336 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/_list.wfl.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/_list.wfl.REMOVED.git-id deleted file mode 100644 index 91e06b43..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/MacOS/waveforms/_list.wfl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -488a0133badf9d48927f82bcc9fcf039e36d2065 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/PkgInfo.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/PkgInfo.REMOVED.git-id deleted file mode 100644 index 70df2297..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/PkgInfo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6f749b0f376443ea266383322cc2d934f791bbee \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqdds.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqdds.dylib.REMOVED.git-id deleted file mode 100644 index ca811a6f..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqdds.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9d40ddc8a41872996ef2c3102528c88798d0434c \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqgif.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqgif.dylib.REMOVED.git-id deleted file mode 100644 index 065e0b85..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqgif.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6320e6ed60ccdffbe9e129c9614ca5742defc37c \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqicns.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqicns.dylib.REMOVED.git-id deleted file mode 100644 index 9c5d1364..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqicns.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e5699a7b7690f41d9e658b42317e40ba372107f4 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqico.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqico.dylib.REMOVED.git-id deleted file mode 100644 index 42eace8c..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqico.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a91d2c59441590a6e195611820af0a59837cb30e \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqjpeg.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqjpeg.dylib.REMOVED.git-id deleted file mode 100644 index 93f9a36e..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqjpeg.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4c742a0d77ec8512f6c0c5d29dbf5c0c05ce910d \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqmacjp2.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqmacjp2.dylib.REMOVED.git-id deleted file mode 100644 index 49f796ea..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqmacjp2.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4a8ffbc7131321ed725899999aba5fc17e91f074 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqtga.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqtga.dylib.REMOVED.git-id deleted file mode 100644 index 1fd14664..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqtga.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ddb2b7983af07df97147948be39f34392dac815f \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqtiff.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqtiff.dylib.REMOVED.git-id deleted file mode 100644 index de7be742..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqtiff.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -836dece992c8a4bed4752b9d364bd058c17b43e4 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqwbmp.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqwbmp.dylib.REMOVED.git-id deleted file mode 100644 index ac65ea9b..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqwbmp.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -df30a4b465f360b8b8f4e0a18c3f04d2f4d260b7 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqwebp.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqwebp.dylib.REMOVED.git-id deleted file mode 100644 index ac96f986..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/imageformats/libqwebp.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -295982f5ae94be523dca5f5cde09722383277127 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/platforms/libqcocoa.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/PlugIns/platforms/libqcocoa.dylib.REMOVED.git-id deleted file mode 100644 index 910b8d29..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/platforms/libqcocoa.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4b2eb691b56dcb687c21ee3a9bace4ce95dce8c1 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/printsupport/libcocoaprintersupport.dylib.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/PlugIns/printsupport/libcocoaprintersupport.dylib.REMOVED.git-id deleted file mode 100644 index fc881011..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/PlugIns/printsupport/libcocoaprintersupport.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -95d66968b46f5f12329a8d5314d3366d7d756a9e \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.app/Contents/Resources/empty.lproj b/Desktop_Interface/bin/labrador.app/Contents/Resources/empty.lproj deleted file mode 100644 index e69de29b..00000000 diff --git a/Desktop_Interface/bin/labrador.app/Contents/Resources/qt.conf.REMOVED.git-id b/Desktop_Interface/bin/labrador.app/Contents/Resources/qt.conf.REMOVED.git-id deleted file mode 100644 index 85ec01ac..00000000 --- a/Desktop_Interface/bin/labrador.app/Contents/Resources/qt.conf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -02408febaa4e6b8e05e99a75bffff4da23e38bf2 \ No newline at end of file diff --git a/Desktop_Interface/bin/labrador.dmg.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/bin/labrador.dmg.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index a2a26c34..00000000 --- a/Desktop_Interface/bin/labrador.dmg.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -238d8bcf3f37f4a5b4188aa25d3683859eb7adc4 \ No newline at end of file diff --git a/Desktop_Interface/bin/libLabrador.so.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/bin/libLabrador.so.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 4db4cc14..00000000 --- a/Desktop_Interface/bin/libLabrador.so.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -23e225605ce39e3c104bb47eeaadecac22c40841 \ No newline at end of file diff --git a/Desktop_Interface/bin/libdfuprog-0.9.so.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/bin/libdfuprog-0.9.so.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index f1ae5942..00000000 --- a/Desktop_Interface/bin/libdfuprog-0.9.so.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2f86926facec11998ed268298507e49cd380a706 \ No newline at end of file diff --git a/Desktop_Interface/bin/libusbK.dll.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/bin/libusbK.dll.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index d32da3ad..00000000 --- a/Desktop_Interface/bin/libusbK.dll.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -14163cc73c3d3ad6821a58dc4653522543fb7532 \ No newline at end of file diff --git a/Desktop_Interface/bin/settings.ini.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/bin/settings.ini.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 5a068e8f..00000000 --- a/Desktop_Interface/bin/settings.ini.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3d8b3b0054ce4bdfcad1bb468f00c91184f5307f \ No newline at end of file diff --git a/Desktop_Interface/bin/settings.set.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/bin/settings.set.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 0392c099..00000000 --- a/Desktop_Interface/bin/settings.set.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b3c0630690de19fac3e0f05664149163f8a25913 \ No newline at end of file diff --git a/Desktop_Interface/bin/waveforms/DC.tlw b/Desktop_Interface/bin/waveforms/DC.tlw new file mode 100644 index 00000000..69f322d2 --- /dev/null +++ b/Desktop_Interface/bin/waveforms/DC.tlw @@ -0,0 +1,3 @@ +1 +1 +255 \ No newline at end of file diff --git a/Desktop_Interface/bin/waveforms/DC.tlw.REMOVED.git-id b/Desktop_Interface/bin/waveforms/DC.tlw.REMOVED.git-id deleted file mode 100644 index e3326948..00000000 --- a/Desktop_Interface/bin/waveforms/DC.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -69f322d2c3c6452561c8232b20784828fc438399 \ No newline at end of file diff --git a/Desktop_Interface/bin/waveforms/Sawtooth.tlw b/Desktop_Interface/bin/waveforms/Sawtooth.tlw new file mode 100644 index 00000000..e989a81b --- /dev/null +++ b/Desktop_Interface/bin/waveforms/Sawtooth.tlw @@ -0,0 +1,3 @@ +128 +3 +0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 129 131 133 135 137 139 141 143 145 147 149 151 153 155 157 159 161 163 165 167 169 171 173 175 177 179 181 183 185 187 189 191 193 195 197 199 201 203 205 207 209 211 213 215 217 219 221 223 225 227 229 231 233 235 237 239 241 243 245 247 249 251 253 255 diff --git a/Desktop_Interface/bin/waveforms/Sawtooth.tlw.REMOVED.git-id b/Desktop_Interface/bin/waveforms/Sawtooth.tlw.REMOVED.git-id deleted file mode 100644 index 87e86502..00000000 --- a/Desktop_Interface/bin/waveforms/Sawtooth.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e989a81be4fb7a2d79495ce7e96db776b0366a94 \ No newline at end of file diff --git a/Desktop_Interface/bin/waveforms/Sin.tlw b/Desktop_Interface/bin/waveforms/Sin.tlw new file mode 100644 index 00000000..e376c353 --- /dev/null +++ b/Desktop_Interface/bin/waveforms/Sin.tlw @@ -0,0 +1,3 @@ +128 +4 +128 134 140 146 153 159 165 171 177 182 188 194 199 204 209 214 218 223 227 230 234 237 240 243 246 248 250 251 253 254 255 255 255 255 254 253 252 251 249 247 245 242 239 236 232 229 225 220 216 211 206 201 196 191 185 180 174 168 162 156 149 143 137 131 124 118 112 106 99 93 87 81 75 70 64 59 54 49 44 39 35 30 26 23 19 16 13 10 8 6 4 3 2 1 0 0 0 0 1 2 4 5 7 9 12 15 18 21 25 28 32 37 41 46 51 56 61 67 73 78 84 90 96 102 109 115 121 127 \ No newline at end of file diff --git a/Desktop_Interface/bin/waveforms/Sin.tlw.REMOVED.git-id b/Desktop_Interface/bin/waveforms/Sin.tlw.REMOVED.git-id deleted file mode 100644 index ceeb1ad1..00000000 --- a/Desktop_Interface/bin/waveforms/Sin.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e376c35388394ccfa4a86cb5bc6f9961e00fef20 \ No newline at end of file diff --git a/Desktop_Interface/bin/waveforms/Square.tlw b/Desktop_Interface/bin/waveforms/Square.tlw new file mode 100644 index 00000000..7bdd30be --- /dev/null +++ b/Desktop_Interface/bin/waveforms/Square.tlw @@ -0,0 +1,3 @@ +128 +5 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 diff --git a/Desktop_Interface/bin/waveforms/Square.tlw.REMOVED.git-id b/Desktop_Interface/bin/waveforms/Square.tlw.REMOVED.git-id deleted file mode 100644 index 25d85bc6..00000000 --- a/Desktop_Interface/bin/waveforms/Square.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7bdd30bee84b15cc3fe88dd02751316a2016060c \ No newline at end of file diff --git a/Desktop_Interface/bin/waveforms/Triangle.tlw b/Desktop_Interface/bin/waveforms/Triangle.tlw new file mode 100644 index 00000000..420ac92c --- /dev/null +++ b/Desktop_Interface/bin/waveforms/Triangle.tlw @@ -0,0 +1,3 @@ +128 +4 +0 4 8 12 16 20 24 28 32 36 40 45 49 53 57 61 65 69 73 77 81 85 89 93 97 101 105 109 113 117 121 125 130 134 138 142 146 150 154 158 162 166 170 174 178 182 186 190 194 198 202 206 210 215 219 223 227 231 235 239 243 247 251 255 255 251 247 243 239 235 231 227 223 219 215 210 206 202 198 194 190 186 182 178 174 170 166 162 158 154 150 146 142 138 134 130 125 121 117 113 109 105 101 97 93 89 85 81 77 73 69 65 61 57 53 49 45 40 36 32 28 24 20 16 12 8 4 0 diff --git a/Desktop_Interface/bin/waveforms/Triangle.tlw.REMOVED.git-id b/Desktop_Interface/bin/waveforms/Triangle.tlw.REMOVED.git-id deleted file mode 100644 index 768d2ac7..00000000 --- a/Desktop_Interface/bin/waveforms/Triangle.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -420ac92c2c292688434b3987874cc98a9180e336 \ No newline at end of file diff --git a/Desktop_Interface/bin/waveforms/_list.wfl b/Desktop_Interface/bin/waveforms/_list.wfl new file mode 100644 index 00000000..d9c5ca2b --- /dev/null +++ b/Desktop_Interface/bin/waveforms/_list.wfl @@ -0,0 +1,5 @@ +Sin +Square +Triangle +Sawtooth +DC \ No newline at end of file diff --git a/Desktop_Interface/bin/waveforms/_list.wfl.REMOVED.git-id b/Desktop_Interface/bin/waveforms/_list.wfl.REMOVED.git-id deleted file mode 100644 index 2b3bbd46..00000000 --- a/Desktop_Interface/bin/waveforms/_list.wfl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d9c5ca2b7e1352538debad0a17885fc4355864fc \ No newline at end of file diff --git a/Desktop_Interface/bin/waveforms_OLD_20170628/Sawtooth.tlw.REMOVED.git-id b/Desktop_Interface/bin/waveforms_OLD_20170628/Sawtooth.tlw.REMOVED.git-id deleted file mode 100644 index 87e86502..00000000 --- a/Desktop_Interface/bin/waveforms_OLD_20170628/Sawtooth.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e989a81be4fb7a2d79495ce7e96db776b0366a94 \ No newline at end of file diff --git a/Desktop_Interface/bin/waveforms_OLD_20170628/Sin.tlw.REMOVED.git-id b/Desktop_Interface/bin/waveforms_OLD_20170628/Sin.tlw.REMOVED.git-id deleted file mode 100644 index ceeb1ad1..00000000 --- a/Desktop_Interface/bin/waveforms_OLD_20170628/Sin.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e376c35388394ccfa4a86cb5bc6f9961e00fef20 \ No newline at end of file diff --git a/Desktop_Interface/bin/waveforms_OLD_20170628/Square.tlw.REMOVED.git-id b/Desktop_Interface/bin/waveforms_OLD_20170628/Square.tlw.REMOVED.git-id deleted file mode 100644 index 25d85bc6..00000000 --- a/Desktop_Interface/bin/waveforms_OLD_20170628/Square.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7bdd30bee84b15cc3fe88dd02751316a2016060c \ No newline at end of file diff --git a/Desktop_Interface/bin/waveforms_OLD_20170628/Triangle.tlw.REMOVED.git-id b/Desktop_Interface/bin/waveforms_OLD_20170628/Triangle.tlw.REMOVED.git-id deleted file mode 100644 index 768d2ac7..00000000 --- a/Desktop_Interface/bin/waveforms_OLD_20170628/Triangle.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -420ac92c2c292688434b3987874cc98a9180e336 \ No newline at end of file diff --git a/Desktop_Interface/bin/waveforms_OLD_20170628/_list.wfl.REMOVED.git-id b/Desktop_Interface/bin/waveforms_OLD_20170628/_list.wfl.REMOVED.git-id deleted file mode 100644 index 91e06b43..00000000 --- a/Desktop_Interface/bin/waveforms_OLD_20170628/_list.wfl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -488a0133badf9d48927f82bcc9fcf039e36d2065 \ No newline at end of file diff --git a/Desktop_Interface/buffer_0.bmp b/Desktop_Interface/buffer_0.bmp new file mode 100644 index 00000000..8d8e3b91 Binary files /dev/null and b/Desktop_Interface/buffer_0.bmp differ diff --git a/Desktop_Interface/buffer_0.bmp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/buffer_0.bmp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 2e64c63d..00000000 --- a/Desktop_Interface/buffer_0.bmp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -66befbdd3be8426d02c58c9a939ecd4c1507469a \ No newline at end of file diff --git a/Desktop_Interface/buffer_1.bmp b/Desktop_Interface/buffer_1.bmp new file mode 100644 index 00000000..7d348291 Binary files /dev/null and b/Desktop_Interface/buffer_1.bmp differ diff --git a/Desktop_Interface/buffer_1.bmp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/buffer_1.bmp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index b54a2424..00000000 --- a/Desktop_Interface/buffer_1.bmp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aafbeff0370e10df86165b544f441ccc80163fac \ No newline at end of file diff --git a/Desktop_Interface/buffer_2.bmp b/Desktop_Interface/buffer_2.bmp new file mode 100644 index 00000000..b47a9187 Binary files /dev/null and b/Desktop_Interface/buffer_2.bmp differ diff --git a/Desktop_Interface/buffer_2.bmp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/buffer_2.bmp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index af9d95af..00000000 --- a/Desktop_Interface/buffer_2.bmp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f582bc8fdcd1dbe7fb84dab90f1b6737e1c67198 \ No newline at end of file diff --git a/Desktop_Interface/buffercontrol.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/buffercontrol.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index c2804307..00000000 --- a/Desktop_Interface/buffercontrol.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -45c975654e008f3df8e9d5baaedbcd8d212e8056 \ No newline at end of file diff --git a/Desktop_Interface/buffercontrol.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/buffercontrol.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 4be5c9a8..00000000 --- a/Desktop_Interface/buffercontrol.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7d90edecf26e58c77144365ffaf74b43d759bc6e \ No newline at end of file diff --git a/Desktop_Interface/build_android/libdfuprog/include/libdfuprog.h b/Desktop_Interface/build_android/libdfuprog/include/libdfuprog.h new file mode 100644 index 00000000..44aec9df --- /dev/null +++ b/Desktop_Interface/build_android/libdfuprog/include/libdfuprog.h @@ -0,0 +1 @@ +int dfuprog_virtual_cmd(char* commandLine, libusb_device *device, libusb_device_handle *handle, libusb_context *parentContext, int32_t interface); diff --git a/Desktop_Interface/build_android/libdfuprog/include/libdfuprog.h.REMOVED.git-id b/Desktop_Interface/build_android/libdfuprog/include/libdfuprog.h.REMOVED.git-id deleted file mode 100644 index 7a325fd8..00000000 --- a/Desktop_Interface/build_android/libdfuprog/include/libdfuprog.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -44aec9df35696b724c717b0854724fc39fbdfde9 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libdfuprog/lib/libdfuprog-0.9.so b/Desktop_Interface/build_android/libdfuprog/lib/libdfuprog-0.9.so new file mode 100644 index 00000000..fade7ac0 Binary files /dev/null and b/Desktop_Interface/build_android/libdfuprog/lib/libdfuprog-0.9.so differ diff --git a/Desktop_Interface/build_android/libdfuprog/lib/libdfuprog-0.9.so.REMOVED.git-id b/Desktop_Interface/build_android/libdfuprog/lib/libdfuprog-0.9.so.REMOVED.git-id deleted file mode 100644 index bbe29cd9..00000000 --- a/Desktop_Interface/build_android/libdfuprog/lib/libdfuprog-0.9.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fade7ac08a64af9903c0cc5d5186308fb5f0948d \ No newline at end of file diff --git a/Desktop_Interface/build_android/libdfuprog/lib/libdfuprog-0.9.so.old b/Desktop_Interface/build_android/libdfuprog/lib/libdfuprog-0.9.so.old new file mode 100644 index 00000000..cf8f9482 Binary files /dev/null and b/Desktop_Interface/build_android/libdfuprog/lib/libdfuprog-0.9.so.old differ diff --git a/Desktop_Interface/build_android/libdfuprog/lib/libdfuprog-0.9.so.old.REMOVED.git-id b/Desktop_Interface/build_android/libdfuprog/lib/libdfuprog-0.9.so.old.REMOVED.git-id deleted file mode 100644 index 0e744381..00000000 --- a/Desktop_Interface/build_android/libdfuprog/lib/libdfuprog-0.9.so.old.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cf8f948208f14e3593004fad5e1d0a1a089f307e \ No newline at end of file diff --git a/Desktop_Interface/build_android/liblog/lib/liblog.so b/Desktop_Interface/build_android/liblog/lib/liblog.so new file mode 100644 index 00000000..1f34f47d Binary files /dev/null and b/Desktop_Interface/build_android/liblog/lib/liblog.so differ diff --git a/Desktop_Interface/build_android/liblog/lib/liblog.so.REMOVED.git-id b/Desktop_Interface/build_android/liblog/lib/liblog.so.REMOVED.git-id deleted file mode 100644 index c625b882..00000000 --- a/Desktop_Interface/build_android/liblog/lib/liblog.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1f34f47d01e4892db5afd11c918afc6ebb912367 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/dpfp b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/dpfp new file mode 100644 index 00000000..c41ac9e6 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/dpfp differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/dpfp.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/dpfp.REMOVED.git-id deleted file mode 100644 index 3d816425..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/dpfp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c41ac9e6eccd40af7a4ea35bd3cbcd54fcf15cbb \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/dpfp_threaded b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/dpfp_threaded new file mode 100644 index 00000000..7494d657 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/dpfp_threaded differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/dpfp_threaded.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/dpfp_threaded.REMOVED.git-id deleted file mode 100644 index f8e55484..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/dpfp_threaded.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7494d657a9a98577dad4dfae606b616e1513eae8 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/fxload b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/fxload new file mode 100644 index 00000000..e80ac646 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/fxload differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/fxload.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/fxload.REMOVED.git-id deleted file mode 100644 index ca6df357..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/fxload.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e80ac64681d58d2ebbd6be21feb5119eff32ad00 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/hotplugtest b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/hotplugtest new file mode 100644 index 00000000..f1711b9b Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/hotplugtest differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/hotplugtest.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/hotplugtest.REMOVED.git-id deleted file mode 100644 index 756eaec7..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/hotplugtest.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f1711b9b72b221653e43e30028470c9e5a445096 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/libusb1.0.so b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/libusb1.0.so new file mode 100644 index 00000000..ffddb4b3 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/libusb1.0.so differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/libusb1.0.so.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/libusb1.0.so.REMOVED.git-id deleted file mode 100644 index 2e8bcfd7..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/libusb1.0.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ffddb4b3cece1f758e4971f6932f19562175acd1 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/listdevs b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/listdevs new file mode 100644 index 00000000..f45a3376 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/listdevs differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/listdevs.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/listdevs.REMOVED.git-id deleted file mode 100644 index d22bea97..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/listdevs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f45a337631dd40ff8f705d9afdebcbff9e1e6923 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/sam3u_benchmark b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/sam3u_benchmark new file mode 100644 index 00000000..ed99e422 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/sam3u_benchmark differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/sam3u_benchmark.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/sam3u_benchmark.REMOVED.git-id deleted file mode 100644 index eacc6c65..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/sam3u_benchmark.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ed99e4227659aa9fa9797446770f4f7b8a9194ef \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/stress b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/stress new file mode 100644 index 00000000..62fd1740 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/stress differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/stress.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/stress.REMOVED.git-id deleted file mode 100644 index 39884c52..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/stress.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -62fd17409539184ac769d7e5e13049cd902763d3 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/xusb b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/xusb new file mode 100644 index 00000000..9aa2e139 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/xusb differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/xusb.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/xusb.REMOVED.git-id deleted file mode 100644 index 73e7f267..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/armeabi-v7a/xusb.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9aa2e1391c0ed3e1ec85e2685b77d7e94ff843a7 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/dpfp b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/dpfp new file mode 100644 index 00000000..871f4b09 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/dpfp differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/dpfp.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/dpfp.REMOVED.git-id deleted file mode 100644 index 2387815f..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/dpfp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -871f4b09faa7afadda34454ab915859b55bde181 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/dpfp_threaded b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/dpfp_threaded new file mode 100644 index 00000000..ad75cbb7 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/dpfp_threaded differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/dpfp_threaded.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/dpfp_threaded.REMOVED.git-id deleted file mode 100644 index a71b58f8..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/dpfp_threaded.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ad75cbb7d231b86ed3a6160084fdd7e951680096 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/fxload b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/fxload new file mode 100644 index 00000000..2ee317a9 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/fxload differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/fxload.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/fxload.REMOVED.git-id deleted file mode 100644 index 04fa9d7d..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/fxload.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2ee317a989de944816d54ac6820e4c99f99f9e91 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/hotplugtest b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/hotplugtest new file mode 100644 index 00000000..0985c7c1 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/hotplugtest differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/hotplugtest.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/hotplugtest.REMOVED.git-id deleted file mode 100644 index d721c244..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/hotplugtest.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0985c7c1a6610e5d6ed241e088587a33a77a2e00 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/libusb1.0.so b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/libusb1.0.so new file mode 100644 index 00000000..968deb85 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/libusb1.0.so differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/libusb1.0.so.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/libusb1.0.so.REMOVED.git-id deleted file mode 100644 index e0be131d..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/libusb1.0.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -968deb8584d1ff4e5e8a8c5fd07db5c7eccd5b2f \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/listdevs b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/listdevs new file mode 100644 index 00000000..995b86ed Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/listdevs differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/listdevs.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/listdevs.REMOVED.git-id deleted file mode 100644 index f13f3306..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/listdevs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -995b86edead37fd0f45031df2bf1ed72e131a267 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/sam3u_benchmark b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/sam3u_benchmark new file mode 100644 index 00000000..69b2ede1 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/sam3u_benchmark differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/sam3u_benchmark.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/sam3u_benchmark.REMOVED.git-id deleted file mode 100644 index 32679334..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/sam3u_benchmark.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -69b2ede1e75decf0af6dde11bbe5e19984a3dd21 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/stress b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/stress new file mode 100644 index 00000000..966bfe28 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/stress differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/stress.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/stress.REMOVED.git-id deleted file mode 100644 index d3f6bca2..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/stress.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -966bfe28ade447584ad600e02cb44a5734dfd7a3 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/xusb b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/xusb new file mode 100644 index 00000000..9b931875 Binary files /dev/null and b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/xusb differ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/xusb.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/xusb.REMOVED.git-id deleted file mode 100644 index 85b02144..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/android/x86/xusb.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9b931875ab18fe1cc791d1327611b4b06fdd1acb \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/core.c b/Desktop_Interface/build_android/libusb-martin-kuldeep/core.c new file mode 100644 index 00000000..38fb55aa --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/core.c @@ -0,0 +1,2517 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * Core functions for libusb + * Copyright © 2013-2016 Martin Marinov + * Copyright © 2012-2013 Nathan Hjelm + * Copyright © 2007-2008 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_SYSLOG_H +#include +#endif + +#ifdef __ANDROID__ +#include +#endif + +#include "libusbi.h" +#include "hotplug.h" + +#if defined(OS_LINUX) +const struct usbi_os_backend * const usbi_backend = &linux_usbfs_backend; +#elif defined(OS_DARWIN) +const struct usbi_os_backend * const usbi_backend = &darwin_backend; +#elif defined(OS_OPENBSD) +const struct usbi_os_backend * const usbi_backend = &openbsd_backend; +#elif defined(OS_NETBSD) +const struct usbi_os_backend * const usbi_backend = &netbsd_backend; +#elif defined(OS_WINDOWS) +const struct usbi_os_backend * const usbi_backend = &windows_backend; +#elif defined(OS_WINCE) +const struct usbi_os_backend * const usbi_backend = &wince_backend; +#elif defined(OS_HAIKU) +const struct usbi_os_backend * const usbi_backend = &haiku_usb_raw_backend; +#else +#error "Unsupported OS" +#endif + +struct libusb_context *usbi_default_context = NULL; +static const struct libusb_version libusb_version_internal = + { LIBUSB_MAJOR, LIBUSB_MINOR, LIBUSB_MICRO, LIBUSB_NANO, + LIBUSB_RC, "http://libusb.info" }; +static int default_context_refcnt = 0; +static usbi_mutex_static_t default_context_lock = USBI_MUTEX_INITIALIZER; +static struct timeval timestamp_origin = { 0, 0 }; + +usbi_mutex_static_t active_contexts_lock = USBI_MUTEX_INITIALIZER; +struct list_head active_contexts_list; + +/** + * \mainpage libusb-1.0 API Reference + * + * \section intro Introduction + * + * libusb is an open source library that allows you to communicate with USB + * devices from userspace. For more info, see the + * libusb homepage. + * + * This documentation is aimed at application developers wishing to + * communicate with USB peripherals from their own software. After reviewing + * this documentation, feedback and questions can be sent to the + * libusb-devel mailing list. + * + * This documentation assumes knowledge of how to operate USB devices from + * a software standpoint (descriptors, configurations, interfaces, endpoints, + * control/bulk/interrupt/isochronous transfers, etc). Full information + * can be found in the USB 3.0 + * Specification which is available for free download. You can probably + * find less verbose introductions by searching the web. + * + * \section API Application Programming Interface (API) + * + * See the \ref api page for a complete list of the libusb functions. + * + * \section features Library features + * + * - All transfer types supported (control/bulk/interrupt/isochronous) + * - 2 transfer interfaces: + * -# Synchronous (simple) + * -# Asynchronous (more complicated, but more powerful) + * - Thread safe (although the asynchronous interface means that you + * usually won't need to thread) + * - Lightweight with lean API + * - Compatible with libusb-0.1 through the libusb-compat-0.1 translation layer + * - Hotplug support (on some platforms). See \ref hotplug. + * + * \section gettingstarted Getting Started + * + * To begin reading the API documentation, start with the Modules page which + * links to the different categories of libusb's functionality. + * + * One decision you will have to make is whether to use the synchronous + * or the asynchronous data transfer interface. The \ref io documentation + * provides some insight into this topic. + * + * Some example programs can be found in the libusb source distribution under + * the "examples" subdirectory. The libusb homepage includes a list of + * real-life project examples which use libusb. + * + * \section errorhandling Error handling + * + * libusb functions typically return 0 on success or a negative error code + * on failure. These negative error codes relate to LIBUSB_ERROR constants + * which are listed on the \ref misc "miscellaneous" documentation page. + * + * \section msglog Debug message logging + * + * libusb uses stderr for all logging. By default, logging is set to NONE, + * which means that no output will be produced. However, unless the library + * has been compiled with logging disabled, then any application calls to + * libusb_set_debug(), or the setting of the environmental variable + * LIBUSB_DEBUG outside of the application, can result in logging being + * produced. Your application should therefore not close stderr, but instead + * direct it to the null device if its output is undesireable. + * + * The libusb_set_debug() function can be used to enable logging of certain + * messages. Under standard configuration, libusb doesn't really log much + * so you are advised to use this function to enable all error/warning/ + * informational messages. It will help debug problems with your software. + * + * The logged messages are unstructured. There is no one-to-one correspondence + * between messages being logged and success or failure return codes from + * libusb functions. There is no format to the messages, so you should not + * try to capture or parse them. They are not and will not be localized. + * These messages are not intended to being passed to your application user; + * instead, you should interpret the error codes returned from libusb functions + * and provide appropriate notification to the user. The messages are simply + * there to aid you as a programmer, and if you're confused because you're + * getting a strange error code from a libusb function, enabling message + * logging may give you a suitable explanation. + * + * The LIBUSB_DEBUG environment variable can be used to enable message logging + * at run-time. This environment variable should be set to a log level number, + * which is interpreted the same as the libusb_set_debug() parameter. When this + * environment variable is set, the message logging verbosity level is fixed + * and libusb_set_debug() effectively does nothing. + * + * libusb can be compiled without any logging functions, useful for embedded + * systems. In this case, libusb_set_debug() and the LIBUSB_DEBUG environment + * variable have no effects. + * + * libusb can also be compiled with verbose debugging messages always. When + * the library is compiled in this way, all messages of all verbosities are + * always logged. libusb_set_debug() and the LIBUSB_DEBUG environment variable + * have no effects. + * + * \section remarks Other remarks + * + * libusb does have imperfections. The \ref caveats "caveats" page attempts + * to document these. + */ + +/** + * \page caveats Caveats + * + * \section devresets Device resets + * + * The libusb_reset_device() function allows you to reset a device. If your + * program has to call such a function, it should obviously be aware that + * the reset will cause device state to change (e.g. register values may be + * reset). + * + * The problem is that any other program could reset the device your program + * is working with, at any time. libusb does not offer a mechanism to inform + * you when this has happened, so if someone else resets your device it will + * not be clear to your own program why the device state has changed. + * + * Ultimately, this is a limitation of writing drivers in userspace. + * Separation from the USB stack in the underlying kernel makes it difficult + * for the operating system to deliver such notifications to your program. + * The Linux kernel USB stack allows such reset notifications to be delivered + * to in-kernel USB drivers, but it is not clear how such notifications could + * be delivered to second-class drivers that live in userspace. + * + * \section blockonly Blocking-only functionality + * + * The functionality listed below is only available through synchronous, + * blocking functions. There are no asynchronous/non-blocking alternatives, + * and no clear ways of implementing these. + * + * - Configuration activation (libusb_set_configuration()) + * - Interface/alternate setting activation (libusb_set_interface_alt_setting()) + * - Releasing of interfaces (libusb_release_interface()) + * - Clearing of halt/stall condition (libusb_clear_halt()) + * - Device resets (libusb_reset_device()) + * + * \section configsel Configuration selection and handling + * + * When libusb presents a device handle to an application, there is a chance + * that the corresponding device may be in unconfigured state. For devices + * with multiple configurations, there is also a chance that the configuration + * currently selected is not the one that the application wants to use. + * + * The obvious solution is to add a call to libusb_set_configuration() early + * on during your device initialization routines, but there are caveats to + * be aware of: + * -# If the device is already in the desired configuration, calling + * libusb_set_configuration() using the same configuration value will cause + * a lightweight device reset. This may not be desirable behaviour. + * -# In the case where the desired configuration is already active, libusb + * may not even be able to perform a lightweight device reset. For example, + * take my USB keyboard with fingerprint reader: I'm interested in driving + * the fingerprint reader interface through libusb, but the kernel's + * USB-HID driver will almost always have claimed the keyboard interface. + * Because the kernel has claimed an interface, it is not even possible to + * perform the lightweight device reset, so libusb_set_configuration() will + * fail. (Luckily the device in question only has a single configuration.) + * -# libusb will be unable to set a configuration if other programs or + * drivers have claimed interfaces. In particular, this means that kernel + * drivers must be detached from all the interfaces before + * libusb_set_configuration() may succeed. + * + * One solution to some of the above problems is to consider the currently + * active configuration. If the configuration we want is already active, then + * we don't have to select any configuration: +\code +cfg = -1; +libusb_get_configuration(dev, &cfg); +if (cfg != desired) + libusb_set_configuration(dev, desired); +\endcode + * + * This is probably suitable for most scenarios, but is inherently racy: + * another application or driver may change the selected configuration + * after the libusb_get_configuration() call. + * + * Even in cases where libusb_set_configuration() succeeds, consider that other + * applications or drivers may change configuration after your application + * calls libusb_set_configuration(). + * + * One possible way to lock your device into a specific configuration is as + * follows: + * -# Set the desired configuration (or use the logic above to realise that + * it is already in the desired configuration) + * -# Claim the interface that you wish to use + * -# Check that the currently active configuration is the one that you want + * to use. + * + * The above method works because once an interface is claimed, no application + * or driver is able to select another configuration. + * + * \section earlycomp Early transfer completion + * + * NOTE: This section is currently Linux-centric. I am not sure if any of these + * considerations apply to Darwin or other platforms. + * + * When a transfer completes early (i.e. when less data is received/sent in + * any one packet than the transfer buffer allows for) then libusb is designed + * to terminate the transfer immediately, not transferring or receiving any + * more data unless other transfers have been queued by the user. + * + * On legacy platforms, libusb is unable to do this in all situations. After + * the incomplete packet occurs, "surplus" data may be transferred. For recent + * versions of libusb, this information is kept (the data length of the + * transfer is updated) and, for device-to-host transfers, any surplus data was + * added to the buffer. Still, this is not a nice solution because it loses the + * information about the end of the short packet, and the user probably wanted + * that surplus data to arrive in the next logical transfer. + * + * + * \section zlp Zero length packets + * + * - libusb is able to send a packet of zero length to an endpoint simply by + * submitting a transfer of zero length. + * - The \ref libusb_transfer_flags::LIBUSB_TRANSFER_ADD_ZERO_PACKET + * "LIBUSB_TRANSFER_ADD_ZERO_PACKET" flag is currently only supported on Linux. + */ + +/** + * \page contexts Contexts + * + * It is possible that libusb may be used simultaneously from two independent + * libraries linked into the same executable. For example, if your application + * has a plugin-like system which allows the user to dynamically load a range + * of modules into your program, it is feasible that two independently + * developed modules may both use libusb. + * + * libusb is written to allow for these multiple user scenarios. The two + * "instances" of libusb will not interfere: libusb_set_debug() calls + * from one user will not affect the same settings for other users, other + * users can continue using libusb after one of them calls libusb_exit(), etc. + * + * This is made possible through libusb's context concept. When you + * call libusb_init(), you are (optionally) given a context. You can then pass + * this context pointer back into future libusb functions. + * + * In order to keep things simple for more simplistic applications, it is + * legal to pass NULL to all functions requiring a context pointer (as long as + * you're sure no other code will attempt to use libusb from the same process). + * When you pass NULL, the default context will be used. The default context + * is created the first time a process calls libusb_init() when no other + * context is alive. Contexts are destroyed during libusb_exit(). + * + * The default context is reference-counted and can be shared. That means that + * if libusb_init(NULL) is called twice within the same process, the two + * users end up sharing the same context. The deinitialization and freeing of + * the default context will only happen when the last user calls libusb_exit(). + * In other words, the default context is created and initialized when its + * reference count goes from 0 to 1, and is deinitialized and destroyed when + * its reference count goes from 1 to 0. + * + * You may be wondering why only a subset of libusb functions require a + * context pointer in their function definition. Internally, libusb stores + * context pointers in other objects (e.g. libusb_device instances) and hence + * can infer the context from those objects. + */ + + /** + * \page api Application Programming Interface + * + * This is the complete list of libusb functions, structures and + * enumerations in alphabetical order. + * + * \section Functions + * - libusb_alloc_streams() + * - libusb_alloc_transfer() + * - libusb_attach_kernel_driver() + * - libusb_bulk_transfer() + * - libusb_cancel_transfer() + * - libusb_claim_interface() + * - libusb_clear_halt() + * - libusb_close() + * - libusb_control_transfer() + * - libusb_control_transfer_get_data() + * - libusb_control_transfer_get_setup() + * - libusb_cpu_to_le16() + * - libusb_detach_kernel_driver() + * - libusb_error_name() + * - libusb_event_handler_active() + * - libusb_event_handling_ok() + * - libusb_exit() + * - libusb_fill_bulk_stream_transfer() + * - libusb_fill_bulk_transfer() + * - libusb_fill_control_setup() + * - libusb_fill_control_transfer() + * - libusb_fill_interrupt_transfer() + * - libusb_fill_iso_transfer() + * - libusb_free_bos_descriptor() + * - libusb_free_config_descriptor() + * - libusb_free_container_id_descriptor() + * - libusb_free_device_list() + * - libusb_free_pollfds() + * - libusb_free_ss_endpoint_companion_descriptor() + * - libusb_free_ss_usb_device_capability_descriptor() + * - libusb_free_streams() + * - libusb_free_transfer() + * - libusb_free_usb_2_0_extension_descriptor() + * - libusb_get_active_config_descriptor() + * - libusb_get_bos_descriptor() + * - libusb_get_bus_number() + * - libusb_get_config_descriptor() + * - libusb_get_config_descriptor_by_value() + * - libusb_get_configuration() + * - libusb_get_container_id_descriptor() + * - libusb_get_descriptor() + * - libusb_get_device() + * - libusb_get_device_address() + * - libusb_get_device_descriptor() + * - libusb_get_device_list() + * - libusb_get_device_speed() + * - libusb_get_iso_packet_buffer() + * - libusb_get_iso_packet_buffer_simple() + * - libusb_get_max_iso_packet_size() + * - libusb_get_max_packet_size() + * - libusb_get_next_timeout() + * - libusb_get_parent() + * - libusb_get_pollfds() + * - libusb_get_port_number() + * - libusb_get_port_numbers() + * - libusb_get_port_path() + * - libusb_get_ss_endpoint_companion_descriptor() + * - libusb_get_ss_usb_device_capability_descriptor() + * - libusb_get_string_descriptor() + * - libusb_get_string_descriptor_ascii() + * - libusb_get_usb_2_0_extension_descriptor() + * - libusb_get_version() + * - libusb_handle_events() + * - libusb_handle_events_completed() + * - libusb_handle_events_locked() + * - libusb_handle_events_timeout() + * - libusb_handle_events_timeout_completed() + * - libusb_has_capability() + * - libusb_hotplug_deregister_callback() + * - libusb_hotplug_register_callback() + * - libusb_init() + * - libusb_interrupt_transfer() + * - libusb_kernel_driver_active() + * - libusb_lock_events() + * - libusb_lock_event_waiters() + * - libusb_open() + * - libusb_open_device_with_vid_pid() + * - libusb_pollfds_handle_timeouts() + * - libusb_ref_device() + * - libusb_release_interface() + * - libusb_reset_device() + * - libusb_set_auto_detach_kernel_driver() + * - libusb_set_configuration() + * - libusb_set_debug() + * - libusb_set_interface_alt_setting() + * - libusb_set_iso_packet_lengths() + * - libusb_setlocale() + * - libusb_set_pollfd_notifiers() + * - libusb_strerror() + * - libusb_submit_transfer() + * - libusb_transfer_get_stream_id() + * - libusb_transfer_set_stream_id() + * - libusb_try_lock_events() + * - libusb_unlock_events() + * - libusb_unlock_event_waiters() + * - libusb_unref_device() + * - libusb_wait_for_event() + * + * \section Structures + * - libusb_bos_descriptor + * - libusb_bos_dev_capability_descriptor + * - libusb_config_descriptor + * - libusb_container_id_descriptor + * - \ref libusb_context + * - libusb_control_setup + * - \ref libusb_device + * - libusb_device_descriptor + * - \ref libusb_device_handle + * - libusb_endpoint_descriptor + * - libusb_interface + * - libusb_interface_descriptor + * - libusb_iso_packet_descriptor + * - libusb_pollfd + * - libusb_ss_endpoint_companion_descriptor + * - libusb_ss_usb_device_capability_descriptor + * - libusb_transfer + * - libusb_usb_2_0_extension_descriptor + * - libusb_version + * + * \section Enums + * - \ref libusb_bos_type + * - \ref libusb_capability + * - \ref libusb_class_code + * - \ref libusb_descriptor_type + * - \ref libusb_endpoint_direction + * - \ref libusb_error + * - \ref libusb_iso_sync_type + * - \ref libusb_iso_usage_type + * - \ref libusb_log_level + * - \ref libusb_request_recipient + * - \ref libusb_request_type + * - \ref libusb_speed + * - \ref libusb_ss_usb_device_capability_attributes + * - \ref libusb_standard_request + * - \ref libusb_supported_speed + * - \ref libusb_transfer_flags + * - \ref libusb_transfer_status + * - \ref libusb_transfer_type + * - \ref libusb_usb_2_0_extension_attributes + */ + +/** + * @defgroup lib Library initialization/deinitialization + * This page details how to initialize and deinitialize libusb. Initialization + * must be performed before using any libusb functionality, and similarly you + * must not call any libusb functions after deinitialization. + */ + +/** + * @defgroup dev Device handling and enumeration + * The functionality documented below is designed to help with the following + * operations: + * - Enumerating the USB devices currently attached to the system + * - Choosing a device to operate from your software + * - Opening and closing the chosen device + * + * \section nutshell In a nutshell... + * + * The description below really makes things sound more complicated than they + * actually are. The following sequence of function calls will be suitable + * for almost all scenarios and does not require you to have such a deep + * understanding of the resource management issues: + * \code +// discover devices +libusb_device **list; +libusb_device *found = NULL; +ssize_t cnt = libusb_get_device_list(NULL, &list); +ssize_t i = 0; +int err = 0; +if (cnt < 0) + error(); + +for (i = 0; i < cnt; i++) { + libusb_device *device = list[i]; + if (is_interesting(device)) { + found = device; + break; + } +} + +if (found) { + libusb_device_handle *handle; + + err = libusb_open(found, &handle); + if (err) + error(); + // etc +} + +libusb_free_device_list(list, 1); +\endcode + * + * The two important points: + * - You asked libusb_free_device_list() to unreference the devices (2nd + * parameter) + * - You opened the device before freeing the list and unreferencing the + * devices + * + * If you ended up with a handle, you can now proceed to perform I/O on the + * device. + * + * \section devshandles Devices and device handles + * libusb has a concept of a USB device, represented by the + * \ref libusb_device opaque type. A device represents a USB device that + * is currently or was previously connected to the system. Using a reference + * to a device, you can determine certain information about the device (e.g. + * you can read the descriptor data). + * + * The libusb_get_device_list() function can be used to obtain a list of + * devices currently connected to the system. This is known as device + * discovery. + * + * Just because you have a reference to a device does not mean it is + * necessarily usable. The device may have been unplugged, you may not have + * permission to operate such device, or another program or driver may be + * using the device. + * + * When you've found a device that you'd like to operate, you must ask + * libusb to open the device using the libusb_open() function. Assuming + * success, libusb then returns you a device handle + * (a \ref libusb_device_handle pointer). All "real" I/O operations then + * operate on the handle rather than the original device pointer. + * + * \section devref Device discovery and reference counting + * + * Device discovery (i.e. calling libusb_get_device_list()) returns a + * freshly-allocated list of devices. The list itself must be freed when + * you are done with it. libusb also needs to know when it is OK to free + * the contents of the list - the devices themselves. + * + * To handle these issues, libusb provides you with two separate items: + * - A function to free the list itself + * - A reference counting system for the devices inside + * + * New devices presented by the libusb_get_device_list() function all have a + * reference count of 1. You can increase and decrease reference count using + * libusb_ref_device() and libusb_unref_device(). A device is destroyed when + * its reference count reaches 0. + * + * With the above information in mind, the process of opening a device can + * be viewed as follows: + * -# Discover devices using libusb_get_device_list(). + * -# Choose the device that you want to operate, and call libusb_open(). + * -# Unref all devices in the discovered device list. + * -# Free the discovered device list. + * + * The order is important - you must not unreference the device before + * attempting to open it, because unreferencing it may destroy the device. + * + * For convenience, the libusb_free_device_list() function includes a + * parameter to optionally unreference all the devices in the list before + * freeing the list itself. This combines steps 3 and 4 above. + * + * As an implementation detail, libusb_open() actually adds a reference to + * the device in question. This is because the device remains available + * through the handle via libusb_get_device(). The reference is deleted during + * libusb_close(). + */ + +/** @defgroup misc Miscellaneous */ + +/* we traverse usbfs without knowing how many devices we are going to find. + * so we create this discovered_devs model which is similar to a linked-list + * which grows when required. it can be freed once discovery has completed, + * eliminating the need for a list node in the libusb_device structure + * itself. */ +#define DISCOVERED_DEVICES_SIZE_STEP 8 + +static struct discovered_devs *discovered_devs_alloc(void) +{ + struct discovered_devs *ret = + malloc(sizeof(*ret) + (sizeof(void *) * DISCOVERED_DEVICES_SIZE_STEP)); + + if (ret) { + ret->len = 0; + ret->capacity = DISCOVERED_DEVICES_SIZE_STEP; + } + return ret; +} + +/* append a device to the discovered devices collection. may realloc itself, + * returning new discdevs. returns NULL on realloc failure. */ +struct discovered_devs *discovered_devs_append( + struct discovered_devs *discdevs, struct libusb_device *dev) +{ + size_t len = discdevs->len; + size_t capacity; + + /* if there is space, just append the device */ + if (len < discdevs->capacity) { + discdevs->devices[len] = libusb_ref_device(dev); + discdevs->len++; + return discdevs; + } + + /* exceeded capacity, need to grow */ + usbi_dbg("need to increase capacity"); + capacity = discdevs->capacity + DISCOVERED_DEVICES_SIZE_STEP; + discdevs = usbi_reallocf(discdevs, + sizeof(*discdevs) + (sizeof(void *) * capacity)); + if (discdevs) { + discdevs->capacity = capacity; + discdevs->devices[len] = libusb_ref_device(dev); + discdevs->len++; + } + + return discdevs; +} + +static void discovered_devs_free(struct discovered_devs *discdevs) +{ + size_t i; + + for (i = 0; i < discdevs->len; i++) + libusb_unref_device(discdevs->devices[i]); + + free(discdevs); +} + +/* Allocate a new device with a specific session ID. The returned device has + * a reference count of 1. */ +struct libusb_device *usbi_alloc_device(struct libusb_context *ctx, + unsigned long session_id) +{ + size_t priv_size = usbi_backend->device_priv_size; + struct libusb_device *dev = calloc(1, sizeof(*dev) + priv_size); + int r; + + if (!dev) + return NULL; + + r = usbi_mutex_init(&dev->lock, NULL); + if (r) { + free(dev); + return NULL; + } + + dev->ctx = ctx; + dev->refcnt = 1; + dev->session_data = session_id; + dev->speed = LIBUSB_SPEED_UNKNOWN; + + if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + usbi_connect_device (dev); + } + + return dev; +} + +void usbi_connect_device(struct libusb_device *dev) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + + dev->attached = 1; + + usbi_mutex_lock(&dev->ctx->usb_devs_lock); + list_add(&dev->list, &dev->ctx->usb_devs); + usbi_mutex_unlock(&dev->ctx->usb_devs_lock); + + /* Signal that an event has occurred for this device if we support hotplug AND + * the hotplug message list is ready. This prevents an event from getting raised + * during initial enumeration. */ + if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_msgs.next) { + usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED); + } +} + +void usbi_disconnect_device(struct libusb_device *dev) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + + usbi_mutex_lock(&dev->lock); + dev->attached = 0; + usbi_mutex_unlock(&dev->lock); + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_del(&dev->list); + usbi_mutex_unlock(&ctx->usb_devs_lock); + + /* Signal that an event has occurred for this device if we support hotplug AND + * the hotplug message list is ready. This prevents an event from getting raised + * during initial enumeration. libusb_handle_events will take care of dereferencing + * the device. */ + if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_msgs.next) { + usbi_hotplug_notification(ctx, dev, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT); + } +} + +/* Perform some final sanity checks on a newly discovered device. If this + * function fails (negative return code), the device should not be added + * to the discovered device list. */ +int usbi_sanitize_device(struct libusb_device *dev) +{ + int r; + uint8_t num_configurations; + + r = usbi_device_cache_descriptor(dev); + if (r < 0) + return r; + + num_configurations = dev->device_descriptor.bNumConfigurations; + if (num_configurations > USB_MAXCONFIG) { + usbi_err(DEVICE_CTX(dev), "too many configurations"); + return LIBUSB_ERROR_IO; + } else if (0 == num_configurations) + usbi_dbg("zero configurations, maybe an unauthorized device"); + + dev->num_configurations = num_configurations; + return 0; +} + +/* Examine libusb's internal list of known devices, looking for one with + * a specific session ID. Returns the matching device if it was found, and + * NULL otherwise. */ +struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx, + unsigned long session_id) +{ + struct libusb_device *dev; + struct libusb_device *ret = NULL; + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device) + if (dev->session_data == session_id) { + ret = libusb_ref_device(dev); + break; + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + + return ret; +} + +/** @ingroup dev + * Returns a list of USB devices currently attached to the system. This is + * your entry point into finding a USB device to operate. + * + * You are expected to unreference all the devices when you are done with + * them, and then free the list with libusb_free_device_list(). Note that + * libusb_free_device_list() can unref all the devices for you. Be careful + * not to unreference a device you are about to open until after you have + * opened it. + * + * This return value of this function indicates the number of devices in + * the resultant list. The list is actually one element larger, as it is + * NULL-terminated. + * + * \param ctx the context to operate on, or NULL for the default context + * \param list output location for a list of devices. Must be later freed with + * libusb_free_device_list(). + * \returns the number of devices in the outputted list, or any + * \ref libusb_error according to errors encountered by the backend. + */ +ssize_t API_EXPORTED libusb_get_device_list(libusb_context *ctx, + libusb_device ***list) +{ + struct discovered_devs *discdevs = discovered_devs_alloc(); + struct libusb_device **ret; + int r = 0; + ssize_t i, len; + USBI_GET_CONTEXT(ctx); + usbi_dbg(""); + + if (!discdevs) + return LIBUSB_ERROR_NO_MEM; + + if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + /* backend provides hotplug support */ + struct libusb_device *dev; + + if (usbi_backend->hotplug_poll) + usbi_backend->hotplug_poll(); + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device) { + discdevs = discovered_devs_append(discdevs, dev); + + if (!discdevs) { + r = LIBUSB_ERROR_NO_MEM; + break; + } + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + } else { + /* backend does not provide hotplug support */ + r = usbi_backend->get_device_list(ctx, &discdevs); + } + + if (r < 0) { + len = r; + goto out; + } + + /* convert discovered_devs into a list */ + len = discdevs->len; + ret = calloc(len + 1, sizeof(struct libusb_device *)); + if (!ret) { + len = LIBUSB_ERROR_NO_MEM; + goto out; + } + + ret[len] = NULL; + for (i = 0; i < len; i++) { + struct libusb_device *dev = discdevs->devices[i]; + ret[i] = libusb_ref_device(dev); + } + *list = ret; + +out: + discovered_devs_free(discdevs); + return len; +} + +/** \ingroup dev + * Frees a list of devices previously discovered using + * libusb_get_device_list(). If the unref_devices parameter is set, the + * reference count of each device in the list is decremented by 1. + * \param list the list to free + * \param unref_devices whether to unref the devices in the list + */ +void API_EXPORTED libusb_free_device_list(libusb_device **list, + int unref_devices) +{ + if (!list) + return; + + if (unref_devices) { + int i = 0; + struct libusb_device *dev; + + while ((dev = list[i++]) != NULL) + libusb_unref_device(dev); + } + free(list); +} + +/** \ingroup dev + * Get the number of the bus that a device is connected to. + * \param dev a device + * \returns the bus number + */ +uint8_t API_EXPORTED libusb_get_bus_number(libusb_device *dev) +{ + return dev->bus_number; +} + +/** \ingroup dev + * Get the number of the port that a device is connected to. + * Unless the OS does something funky, or you are hot-plugging USB extension cards, + * the port number returned by this call is usually guaranteed to be uniquely tied + * to a physical port, meaning that different devices plugged on the same physical + * port should return the same port number. + * + * But outside of this, there is no guarantee that the port number returned by this + * call will remain the same, or even match the order in which ports have been + * numbered by the HUB/HCD manufacturer. + * + * \param dev a device + * \returns the port number (0 if not available) + */ +uint8_t API_EXPORTED libusb_get_port_number(libusb_device *dev) +{ + return dev->port_number; +} + +/** \ingroup dev + * Get the list of all port numbers from root for the specified device + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * \param dev a device + * \param port_numbers the array that should contain the port numbers + * \param port_numbers_len the maximum length of the array. As per the USB 3.0 + * specs, the current maximum limit for the depth is 7. + * \returns the number of elements filled + * \returns LIBUSB_ERROR_OVERFLOW if the array is too small + */ +int API_EXPORTED libusb_get_port_numbers(libusb_device *dev, + uint8_t* port_numbers, int port_numbers_len) +{ + int i = port_numbers_len; + struct libusb_context *ctx = DEVICE_CTX(dev); + + if (port_numbers_len <= 0) + return LIBUSB_ERROR_INVALID_PARAM; + + // HCDs can be listed as devices with port #0 + while((dev) && (dev->port_number != 0)) { + if (--i < 0) { + usbi_warn(ctx, "port numbers array is too small"); + return LIBUSB_ERROR_OVERFLOW; + } + port_numbers[i] = dev->port_number; + dev = dev->parent_dev; + } + if (i < port_numbers_len) + memmove(port_numbers, &port_numbers[i], port_numbers_len - i); + return port_numbers_len - i; +} + +/** \ingroup dev + * Deprecated please use libusb_get_port_numbers instead. + */ +int API_EXPORTED libusb_get_port_path(libusb_context *ctx, libusb_device *dev, + uint8_t* port_numbers, uint8_t port_numbers_len) +{ + UNUSED(ctx); + + return libusb_get_port_numbers(dev, port_numbers, port_numbers_len); +} + +/** \ingroup dev + * Get the the parent from the specified device. + * \param dev a device + * \returns the device parent or NULL if not available + * You should issue a \ref libusb_get_device_list() before calling this + * function and make sure that you only access the parent before issuing + * \ref libusb_free_device_list(). The reason is that libusb currently does + * not maintain a permanent list of device instances, and therefore can + * only guarantee that parents are fully instantiated within a + * libusb_get_device_list() - libusb_free_device_list() block. + */ +DEFAULT_VISIBILITY +libusb_device * LIBUSB_CALL libusb_get_parent(libusb_device *dev) +{ + return dev->parent_dev; +} + +/** \ingroup dev + * Get the address of the device on the bus it is connected to. + * \param dev a device + * \returns the device address + */ +uint8_t API_EXPORTED libusb_get_device_address(libusb_device *dev) +{ + return dev->device_address; +} + +/** \ingroup dev + * Get the negotiated connection speed for a device. + * \param dev a device + * \returns a \ref libusb_speed code, where LIBUSB_SPEED_UNKNOWN means that + * the OS doesn't know or doesn't support returning the negotiated speed. + */ +int API_EXPORTED libusb_get_device_speed(libusb_device *dev) +{ + return dev->speed; +} + +static const struct libusb_endpoint_descriptor *find_endpoint( + struct libusb_config_descriptor *config, unsigned char endpoint) +{ + int iface_idx; + for (iface_idx = 0; iface_idx < config->bNumInterfaces; iface_idx++) { + const struct libusb_interface *iface = &config->interface[iface_idx]; + int altsetting_idx; + + for (altsetting_idx = 0; altsetting_idx < iface->num_altsetting; + altsetting_idx++) { + const struct libusb_interface_descriptor *altsetting + = &iface->altsetting[altsetting_idx]; + int ep_idx; + + for (ep_idx = 0; ep_idx < altsetting->bNumEndpoints; ep_idx++) { + const struct libusb_endpoint_descriptor *ep = + &altsetting->endpoint[ep_idx]; + if (ep->bEndpointAddress == endpoint) + return ep; + } + } + } + return NULL; +} + +/** \ingroup dev + * Convenience function to retrieve the wMaxPacketSize value for a particular + * endpoint in the active device configuration. + * + * This function was originally intended to be of assistance when setting up + * isochronous transfers, but a design mistake resulted in this function + * instead. It simply returns the wMaxPacketSize value without considering + * its contents. If you're dealing with isochronous transfers, you probably + * want libusb_get_max_iso_packet_size() instead. + * + * \param dev a device + * \param endpoint address of the endpoint in question + * \returns the wMaxPacketSize value + * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist + * \returns LIBUSB_ERROR_OTHER on other failure + */ +int API_EXPORTED libusb_get_max_packet_size(libusb_device *dev, + unsigned char endpoint) +{ + struct libusb_config_descriptor *config; + const struct libusb_endpoint_descriptor *ep; + int r; + + r = libusb_get_active_config_descriptor(dev, &config); + if (r < 0) { + usbi_err(DEVICE_CTX(dev), + "could not retrieve active config descriptor"); + return LIBUSB_ERROR_OTHER; + } + + ep = find_endpoint(config, endpoint); + if (!ep) { + r = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + + r = ep->wMaxPacketSize; + +out: + libusb_free_config_descriptor(config); + return r; +} + +/** \ingroup dev + * Calculate the maximum packet size which a specific endpoint is capable is + * sending or receiving in the duration of 1 microframe + * + * Only the active configuration is examined. The calculation is based on the + * wMaxPacketSize field in the endpoint descriptor as described in section + * 9.6.6 in the USB 2.0 specifications. + * + * If acting on an isochronous or interrupt endpoint, this function will + * multiply the value found in bits 0:10 by the number of transactions per + * microframe (determined by bits 11:12). Otherwise, this function just + * returns the numeric value found in bits 0:10. + * + * This function is useful for setting up isochronous transfers, for example + * you might pass the return value from this function to + * libusb_set_iso_packet_lengths() in order to set the length field of every + * isochronous packet in a transfer. + * + * Since v1.0.3. + * + * \param dev a device + * \param endpoint address of the endpoint in question + * \returns the maximum packet size which can be sent/received on this endpoint + * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist + * \returns LIBUSB_ERROR_OTHER on other failure + */ +int API_EXPORTED libusb_get_max_iso_packet_size(libusb_device *dev, + unsigned char endpoint) +{ + struct libusb_config_descriptor *config; + const struct libusb_endpoint_descriptor *ep; + enum libusb_transfer_type ep_type; + uint16_t val; + int r; + + r = libusb_get_active_config_descriptor(dev, &config); + if (r < 0) { + usbi_err(DEVICE_CTX(dev), + "could not retrieve active config descriptor"); + return LIBUSB_ERROR_OTHER; + } + + ep = find_endpoint(config, endpoint); + if (!ep) { + r = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + + val = ep->wMaxPacketSize; + ep_type = (enum libusb_transfer_type) (ep->bmAttributes & 0x3); + + r = val & 0x07ff; + if (ep_type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS + || ep_type == LIBUSB_TRANSFER_TYPE_INTERRUPT) + r *= (1 + ((val >> 11) & 3)); + +out: + libusb_free_config_descriptor(config); + return r; +} + +/** \ingroup dev + * Increment the reference count of a device. + * \param dev the device to reference + * \returns the same device + */ +DEFAULT_VISIBILITY +libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev) +{ + usbi_mutex_lock(&dev->lock); + dev->refcnt++; + usbi_mutex_unlock(&dev->lock); + return dev; +} + +/** \ingroup dev + * Decrement the reference count of a device. If the decrement operation + * causes the reference count to reach zero, the device shall be destroyed. + * \param dev the device to unreference + */ +void API_EXPORTED libusb_unref_device(libusb_device *dev) +{ + int refcnt; + + if (!dev) + return; + + usbi_mutex_lock(&dev->lock); + refcnt = --dev->refcnt; + usbi_mutex_unlock(&dev->lock); + + if (refcnt == 0) { + usbi_dbg("destroy device %d.%d", dev->bus_number, dev->device_address); + + libusb_unref_device(dev->parent_dev); + + if (usbi_backend->destroy_device) + usbi_backend->destroy_device(dev); + + if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + /* backend does not support hotplug */ + usbi_disconnect_device(dev); + } + + usbi_mutex_destroy(&dev->lock); + free(dev); + } +} + +/* + * Signal the event pipe so that the event handling thread will be + * interrupted to process an internal event. + */ +int usbi_signal_event(struct libusb_context *ctx) +{ + unsigned char dummy = 1; + ssize_t r; + + /* write some data on event pipe to interrupt event handlers */ + r = usbi_write(ctx->event_pipe[1], &dummy, sizeof(dummy)); + if (r != sizeof(dummy)) { + usbi_warn(ctx, "internal signalling write failed"); + return LIBUSB_ERROR_IO; + } + + return 0; +} + +/* + * Clear the event pipe so that the event handling will no longer be + * interrupted. + */ +int usbi_clear_event(struct libusb_context *ctx) +{ + unsigned char dummy; + ssize_t r; + + /* read some data on event pipe to clear it */ + r = usbi_read(ctx->event_pipe[0], &dummy, sizeof(dummy)); + if (r != sizeof(dummy)) { + usbi_warn(ctx, "internal signalling read failed"); + return LIBUSB_ERROR_IO; + } + + return 0; +} + +/** \ingroup dev + * Open a device and obtain a device handle. A handle allows you to perform + * I/O on the device in question. + * + * Internally, this function adds a reference to the device and makes it + * available to you through libusb_get_device(). This reference is removed + * during libusb_close(). + * + * This is a non-blocking function; no requests are sent over the bus. + * + * \param dev the device to open + * \param handle output location for the returned device handle pointer. Only + * populated when the return code is 0. + * \returns 0 on success + * \returns LIBUSB_ERROR_NO_MEM on memory allocation failure + * \returns LIBUSB_ERROR_ACCESS if the user has insufficient permissions + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_open(libusb_device *dev, + libusb_device_handle **handle) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + struct libusb_device_handle *_handle; + size_t priv_size = usbi_backend->device_handle_priv_size; + int r; + usbi_dbg("open %d.%d", dev->bus_number, dev->device_address); + + if (!dev->attached) { + return LIBUSB_ERROR_NO_DEVICE; + } + + _handle = malloc(sizeof(*_handle) + priv_size); + if (!_handle) + return LIBUSB_ERROR_NO_MEM; + + r = usbi_mutex_init(&_handle->lock, NULL); + if (r) { + free(_handle); + return LIBUSB_ERROR_OTHER; + } + + _handle->dev = libusb_ref_device(dev); + _handle->auto_detach_kernel_driver = 0; + _handle->claimed_interfaces = 0; + memset(&_handle->os_priv, 0, priv_size); + + r = usbi_backend->open(_handle); + if (r < 0) { + usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r); + libusb_unref_device(dev); + usbi_mutex_destroy(&_handle->lock); + free(_handle); + return r; + } + + usbi_mutex_lock(&ctx->open_devs_lock); + list_add(&_handle->list, &ctx->open_devs); + usbi_mutex_unlock(&ctx->open_devs_lock); + *handle = _handle; + + return 0; +} + +/** \ingroup dev + * Construct a libusb device from fd. + * UseCase: Android, after permission granted from Android Device + * Manager, using Java device fd can be extracted and pass on to NDK. + */ +int API_EXPORTED libusb_open2(libusb_device *dev, libusb_device_handle **handle, int fd) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + struct libusb_device_handle *_handle; + size_t priv_size = usbi_backend->device_handle_priv_size; + int r; + usbi_dbg("open %d.%d", dev->bus_number, dev->device_address); + + _handle = malloc(sizeof(*_handle) + priv_size); + if (!_handle) + return LIBUSB_ERROR_NO_MEM; + + r = usbi_mutex_init(&_handle->lock, NULL); + if (r) { + free(_handle); + return LIBUSB_ERROR_OTHER; + } + + _handle->dev = libusb_ref_device(dev); + _handle->claimed_interfaces = 0; + memset(&_handle->os_priv, 0, priv_size); + + r = usbi_backend->open2(_handle, fd); + if (r < 0) { + usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r); + libusb_unref_device(dev); + usbi_mutex_destroy(&_handle->lock); + free(_handle); + return r; + } + + usbi_mutex_lock(&ctx->open_devs_lock); + list_add(&_handle->list, &ctx->open_devs); + usbi_mutex_unlock(&ctx->open_devs_lock); + *handle = _handle; + + return 0; +} + +/** \ingroup dev + * Convenience function for finding a device with a particular + * idVendor/idProduct combination. This function is intended + * for those scenarios where you are using libusb to knock up a quick test + * application - it allows you to avoid calling libusb_get_device_list() and + * worrying about traversing/freeing the list. + * + * This function has limitations and is hence not intended for use in real + * applications: if multiple devices have the same IDs it will only + * give you the first one, etc. + * + * \param ctx the context to operate on, or NULL for the default context + * \param vendor_id the idVendor value to search for + * \param product_id the idProduct value to search for + * \returns a handle for the first found device, or NULL on error or if the + * device could not be found. */ +DEFAULT_VISIBILITY +libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid( + libusb_context *ctx, uint16_t vendor_id, uint16_t product_id) +{ + struct libusb_device **devs; + struct libusb_device *found = NULL; + struct libusb_device *dev; + struct libusb_device_handle *handle = NULL; + size_t i = 0; + int r; + + if (libusb_get_device_list(ctx, &devs) < 0) + return NULL; + + while ((dev = devs[i++]) != NULL) { + struct libusb_device_descriptor desc; + r = libusb_get_device_descriptor(dev, &desc); + if (r < 0) + goto out; + if (desc.idVendor == vendor_id && desc.idProduct == product_id) { + found = dev; + break; + } + } + + if (found) { + r = libusb_open(found, &handle); + if (r < 0) + handle = NULL; + } + +out: + libusb_free_device_list(devs, 1); + return handle; +} + +static void do_close(struct libusb_context *ctx, + struct libusb_device_handle *dev_handle) +{ + struct usbi_transfer *itransfer; + struct usbi_transfer *tmp; + + libusb_lock_events(ctx); + + /* remove any transfers in flight that are for this device */ + usbi_mutex_lock(&ctx->flying_transfers_lock); + + /* safe iteration because transfers may be being deleted */ + list_for_each_entry_safe(itransfer, tmp, &ctx->flying_transfers, list, struct usbi_transfer) { + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + if (transfer->dev_handle != dev_handle) + continue; + + if (!(itransfer->flags & USBI_TRANSFER_DEVICE_DISAPPEARED)) { + usbi_err(ctx, "Device handle closed while transfer was still being processed, but the device is still connected as far as we know"); + + if (itransfer->flags & USBI_TRANSFER_CANCELLING) + usbi_warn(ctx, "A cancellation for an in-flight transfer hasn't completed but closing the device handle"); + else + usbi_err(ctx, "A cancellation hasn't even been scheduled on the transfer for which the device is closing"); + } + + /* remove from the list of in-flight transfers and make sure + * we don't accidentally use the device handle in the future + * (or that such accesses will be easily caught and identified as a crash) + */ + usbi_mutex_lock(&itransfer->lock); + list_del(&itransfer->list); + transfer->dev_handle = NULL; + usbi_mutex_unlock(&itransfer->lock); + + /* it is up to the user to free up the actual transfer struct. this is + * just making sure that we don't attempt to process the transfer after + * the device handle is invalid + */ + usbi_dbg("Removed transfer %p from the in-flight list because device handle %p closed", + transfer, dev_handle); + } + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + libusb_unlock_events(ctx); + + usbi_mutex_lock(&ctx->open_devs_lock); + list_del(&dev_handle->list); + usbi_mutex_unlock(&ctx->open_devs_lock); + + usbi_backend->close(dev_handle); + libusb_unref_device(dev_handle->dev); + usbi_mutex_destroy(&dev_handle->lock); + free(dev_handle); +} + +/** \ingroup dev + * Close a device handle. Should be called on all open handles before your + * application exits. + * + * Internally, this function destroys the reference that was added by + * libusb_open() on the given device. + * + * This is a non-blocking function; no requests are sent over the bus. + * + * \param dev_handle the handle to close + */ +void API_EXPORTED libusb_close(libusb_device_handle *dev_handle) +{ + struct libusb_context *ctx; + int pending_events; + + if (!dev_handle) + return; + usbi_dbg(""); + + ctx = HANDLE_CTX(dev_handle); + + /* Similarly to libusb_open(), we want to interrupt all event handlers + * at this point. More importantly, we want to perform the actual close of + * the device while holding the event handling lock (preventing any other + * thread from doing event handling) because we will be removing a file + * descriptor from the polling loop. */ + + /* Record that we are closing a device. + * Only signal an event if there are no prior pending events. */ + usbi_mutex_lock(&ctx->event_data_lock); + pending_events = usbi_pending_events(ctx); + ctx->device_close++; + if (!pending_events) + usbi_signal_event(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); + + /* take event handling lock */ + libusb_lock_events(ctx); + + /* Close the device */ + do_close(ctx, dev_handle); + + /* We're done with closing this device. + * Clear the event pipe if there are no further pending events. */ + usbi_mutex_lock(&ctx->event_data_lock); + ctx->device_close--; + pending_events = usbi_pending_events(ctx); + if (!pending_events) + usbi_clear_event(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); + + /* Release event handling lock and wake up event waiters */ + libusb_unlock_events(ctx); +} + +/** \ingroup dev + * Get the underlying device for a handle. This function does not modify + * the reference count of the returned device, so do not feel compelled to + * unreference it when you are done. + * \param dev_handle a device handle + * \returns the underlying device + */ +DEFAULT_VISIBILITY +libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle) +{ + return dev_handle->dev; +} + +/** \ingroup dev + * Get the underlying device for a \a dev_node. + * UseCase: Android + * \param \a dev_node device path + * \returns allocate a device from \a dev_node + */ +DEFAULT_VISIBILITY +libusb_device * LIBUSB_CALL libusb_get_device2(libusb_context *ctx, const char *dev_node) +{ + if(usbi_backend->device2 == NULL) { + /* Not supported on this platform */ + return NULL; + } + + return usbi_backend->device2(ctx, dev_node); +} + +/** \ingroup dev + * Determine the bConfigurationValue of the currently active configuration. + * + * You could formulate your own control request to obtain this information, + * but this function has the advantage that it may be able to retrieve the + * information from operating system caches (no I/O involved). + * + * If the OS does not cache this information, then this function will block + * while a control transfer is submitted to retrieve the information. + * + * This function will return a value of 0 in the config output + * parameter if the device is in unconfigured state. + * + * \param dev a device handle + * \param config output location for the bConfigurationValue of the active + * configuration (only valid for return code 0) + * \returns 0 on success + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_get_configuration(libusb_device_handle *dev, + int *config) +{ + int r = LIBUSB_ERROR_NOT_SUPPORTED; + + usbi_dbg(""); + if (usbi_backend->get_configuration) + r = usbi_backend->get_configuration(dev, config); + + if (r == LIBUSB_ERROR_NOT_SUPPORTED) { + uint8_t tmp = 0; + usbi_dbg("falling back to control message"); + r = libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_CONFIGURATION, 0, 0, &tmp, 1, 1000); + if (r == 0) { + usbi_err(HANDLE_CTX(dev), "zero bytes returned in ctrl transfer?"); + r = LIBUSB_ERROR_IO; + } else if (r == 1) { + r = 0; + *config = tmp; + } else { + usbi_dbg("control failed, error %d", r); + } + } + + if (r == 0) + usbi_dbg("active config %d", *config); + + return r; +} + +/** \ingroup dev + * Set the active configuration for a device. + * + * The operating system may or may not have already set an active + * configuration on the device. It is up to your application to ensure the + * correct configuration is selected before you attempt to claim interfaces + * and perform other operations. + * + * If you call this function on a device already configured with the selected + * configuration, then this function will act as a lightweight device reset: + * it will issue a SET_CONFIGURATION request using the current configuration, + * causing most USB-related device state to be reset (altsetting reset to zero, + * endpoint halts cleared, toggles reset). + * + * You cannot change/reset configuration if your application has claimed + * interfaces. It is advised to set the desired configuration before claiming + * interfaces. + * + * Alternatively you can call libusb_release_interface() first. Note if you + * do things this way you must ensure that auto_detach_kernel_driver for + * dev is 0, otherwise the kernel driver will be re-attached when you + * release the interface(s). + * + * You cannot change/reset configuration if other applications or drivers have + * claimed interfaces. + * + * A configuration value of -1 will put the device in unconfigured state. + * The USB specifications state that a configuration value of 0 does this, + * however buggy devices exist which actually have a configuration 0. + * + * You should always use this function rather than formulating your own + * SET_CONFIGURATION control request. This is because the underlying operating + * system needs to know when such changes happen. + * + * This is a blocking function. + * + * \param dev a device handle + * \param configuration the bConfigurationValue of the configuration you + * wish to activate, or -1 if you wish to put the device in an unconfigured + * state + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the requested configuration does not exist + * \returns LIBUSB_ERROR_BUSY if interfaces are currently claimed + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_set_auto_detach_kernel_driver() + */ +int API_EXPORTED libusb_set_configuration(libusb_device_handle *dev, + int configuration) +{ + usbi_dbg("configuration %d", configuration); + return usbi_backend->set_configuration(dev, configuration); +} + +/** \ingroup dev + * Claim an interface on a given device handle. You must claim the interface + * you wish to use before you can perform I/O on any of its endpoints. + * + * It is legal to attempt to claim an already-claimed interface, in which + * case libusb just returns 0 without doing anything. + * + * If auto_detach_kernel_driver is set to 1 for dev, the kernel driver + * will be detached if necessary, on failure the detach error is returned. + * + * Claiming of interfaces is a purely logical operation; it does not cause + * any requests to be sent over the bus. Interface claiming is used to + * instruct the underlying operating system that your application wishes + * to take ownership of the interface. + * + * This is a non-blocking function. + * + * \param dev a device handle + * \param interface_number the bInterfaceNumber of the interface you + * wish to claim + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the requested interface does not exist + * \returns LIBUSB_ERROR_BUSY if another program or driver has claimed the + * interface + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns a LIBUSB_ERROR code on other failure + * \see libusb_set_auto_detach_kernel_driver() + */ +int API_EXPORTED libusb_claim_interface(libusb_device_handle *dev, + int interface_number) +{ + int r = 0; + + usbi_dbg("interface %d", interface_number); + if (interface_number >= USB_MAXINTERFACES) + return LIBUSB_ERROR_INVALID_PARAM; + + if (!dev->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_mutex_lock(&dev->lock); + if (dev->claimed_interfaces & (1 << interface_number)) + goto out; + + r = usbi_backend->claim_interface(dev, interface_number); + if (r == 0) + dev->claimed_interfaces |= 1 << interface_number; + +out: + usbi_mutex_unlock(&dev->lock); + return r; +} + +/** \ingroup dev + * Release an interface previously claimed with libusb_claim_interface(). You + * should release all claimed interfaces before closing a device handle. + * + * This is a blocking function. A SET_INTERFACE control request will be sent + * to the device, resetting interface state to the first alternate setting. + * + * If auto_detach_kernel_driver is set to 1 for dev, the kernel + * driver will be re-attached after releasing the interface. + * + * \param dev a device handle + * \param interface_number the bInterfaceNumber of the + * previously-claimed interface + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the interface was not claimed + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_set_auto_detach_kernel_driver() + */ +int API_EXPORTED libusb_release_interface(libusb_device_handle *dev, + int interface_number) +{ + int r; + + usbi_dbg("interface %d", interface_number); + if (interface_number >= USB_MAXINTERFACES) + return LIBUSB_ERROR_INVALID_PARAM; + + usbi_mutex_lock(&dev->lock); + if (!(dev->claimed_interfaces & (1 << interface_number))) { + r = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + + r = usbi_backend->release_interface(dev, interface_number); + if (r == 0) + dev->claimed_interfaces &= ~(1 << interface_number); + +out: + usbi_mutex_unlock(&dev->lock); + return r; +} + +/** \ingroup dev + * Activate an alternate setting for an interface. The interface must have + * been previously claimed with libusb_claim_interface(). + * + * You should always use this function rather than formulating your own + * SET_INTERFACE control request. This is because the underlying operating + * system needs to know when such changes happen. + * + * This is a blocking function. + * + * \param dev a device handle + * \param interface_number the bInterfaceNumber of the + * previously-claimed interface + * \param alternate_setting the bAlternateSetting of the alternate + * setting to activate + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the interface was not claimed, or the + * requested alternate setting does not exist + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_set_interface_alt_setting(libusb_device_handle *dev, + int interface_number, int alternate_setting) +{ + usbi_dbg("interface %d altsetting %d", + interface_number, alternate_setting); + if (interface_number >= USB_MAXINTERFACES) + return LIBUSB_ERROR_INVALID_PARAM; + + usbi_mutex_lock(&dev->lock); + if (!dev->dev->attached) { + usbi_mutex_unlock(&dev->lock); + return LIBUSB_ERROR_NO_DEVICE; + } + + if (!(dev->claimed_interfaces & (1 << interface_number))) { + usbi_mutex_unlock(&dev->lock); + return LIBUSB_ERROR_NOT_FOUND; + } + usbi_mutex_unlock(&dev->lock); + + return usbi_backend->set_interface_altsetting(dev, interface_number, + alternate_setting); +} + +/** \ingroup dev + * Clear the halt/stall condition for an endpoint. Endpoints with halt status + * are unable to receive or transmit data until the halt condition is stalled. + * + * You should cancel all pending transfers before attempting to clear the halt + * condition. + * + * This is a blocking function. + * + * \param dev a device handle + * \param endpoint the endpoint to clear halt status + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_clear_halt(libusb_device_handle *dev, + unsigned char endpoint) +{ + usbi_dbg("endpoint %x", endpoint); + if (!dev->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + return usbi_backend->clear_halt(dev, endpoint); +} + +/** \ingroup dev + * Perform a USB port reset to reinitialize a device. The system will attempt + * to restore the previous configuration and alternate settings after the + * reset has completed. + * + * If the reset fails, the descriptors change, or the previous state cannot be + * restored, the device will appear to be disconnected and reconnected. This + * means that the device handle is no longer valid (you should close it) and + * rediscover the device. A return code of LIBUSB_ERROR_NOT_FOUND indicates + * when this is the case. + * + * This is a blocking function which usually incurs a noticeable delay. + * + * \param dev a handle of the device to reset + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if re-enumeration is required, or if the + * device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_reset_device(libusb_device_handle *dev) +{ + usbi_dbg(""); + if (!dev->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + return usbi_backend->reset_device(dev); +} + +/** \ingroup asyncio + * Allocate up to num_streams usb bulk streams on the specified endpoints. This + * function takes an array of endpoints rather then a single endpoint because + * some protocols require that endpoints are setup with similar stream ids. + * All endpoints passed in must belong to the same interface. + * + * Note this function may return less streams then requested. Also note that the + * same number of streams are allocated for each endpoint in the endpoint array. + * + * Stream id 0 is reserved, and should not be used to communicate with devices. + * If libusb_alloc_streams() returns with a value of N, you may use stream ids + * 1 to N. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param dev a device handle + * \param num_streams number of streams to try to allocate + * \param endpoints array of endpoints to allocate streams on + * \param num_endpoints length of the endpoints array + * \returns number of streams allocated, or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_alloc_streams(libusb_device_handle *dev, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints) +{ + usbi_dbg("streams %u eps %d", (unsigned) num_streams, num_endpoints); + + if (!dev->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend->alloc_streams) + return usbi_backend->alloc_streams(dev, num_streams, endpoints, + num_endpoints); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup asyncio + * Free usb bulk streams allocated with libusb_alloc_streams(). + * + * Note streams are automatically free-ed when releasing an interface. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param dev a device handle + * \param endpoints array of endpoints to free streams on + * \param num_endpoints length of the endpoints array + * \returns LIBUSB_SUCCESS, or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_free_streams(libusb_device_handle *dev, + unsigned char *endpoints, int num_endpoints) +{ + usbi_dbg("eps %d", num_endpoints); + + if (!dev->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend->free_streams) + return usbi_backend->free_streams(dev, endpoints, + num_endpoints); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup dev + * Determine if a kernel driver is active on an interface. If a kernel driver + * is active, you cannot claim the interface, and libusb will be unable to + * perform I/O. + * + * This functionality is not available on Windows. + * + * \param dev a device handle + * \param interface_number the interface to check + * \returns 0 if no kernel driver is active + * \returns 1 if a kernel driver is active + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality + * is not available + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_detach_kernel_driver() + */ +int API_EXPORTED libusb_kernel_driver_active(libusb_device_handle *dev, + int interface_number) +{ + usbi_dbg("interface %d", interface_number); + + if (!dev->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend->kernel_driver_active) + return usbi_backend->kernel_driver_active(dev, interface_number); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup dev + * Detach a kernel driver from an interface. If successful, you will then be + * able to claim the interface and perform I/O. + * + * This functionality is not available on Darwin or Windows. + * + * Note that libusb itself also talks to the device through a special kernel + * driver, if this driver is already attached to the device, this call will + * not detach it and return LIBUSB_ERROR_NOT_FOUND. + * + * \param dev a device handle + * \param interface_number the interface to detach the driver from + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if no kernel driver was active + * \returns LIBUSB_ERROR_INVALID_PARAM if the interface does not exist + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality + * is not available + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_kernel_driver_active() + */ +int API_EXPORTED libusb_detach_kernel_driver(libusb_device_handle *dev, + int interface_number) +{ + usbi_dbg("interface %d", interface_number); + + if (!dev->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend->detach_kernel_driver) + return usbi_backend->detach_kernel_driver(dev, interface_number); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup dev + * Re-attach an interface's kernel driver, which was previously detached + * using libusb_detach_kernel_driver(). This call is only effective on + * Linux and returns LIBUSB_ERROR_NOT_SUPPORTED on all other platforms. + * + * This functionality is not available on Darwin or Windows. + * + * \param dev a device handle + * \param interface_number the interface to attach the driver from + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if no kernel driver was active + * \returns LIBUSB_ERROR_INVALID_PARAM if the interface does not exist + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality + * is not available + * \returns LIBUSB_ERROR_BUSY if the driver cannot be attached because the + * interface is claimed by a program or driver + * \returns another LIBUSB_ERROR code on other failure + * \see libusb_kernel_driver_active() + */ +int API_EXPORTED libusb_attach_kernel_driver(libusb_device_handle *dev, + int interface_number) +{ + usbi_dbg("interface %d", interface_number); + + if (!dev->dev->attached) + return LIBUSB_ERROR_NO_DEVICE; + + if (usbi_backend->attach_kernel_driver) + return usbi_backend->attach_kernel_driver(dev, interface_number); + else + return LIBUSB_ERROR_NOT_SUPPORTED; +} + +/** \ingroup dev + * Enable/disable libusb's automatic kernel driver detachment. When this is + * enabled libusb will automatically detach the kernel driver on an interface + * when claiming the interface, and attach it when releasing the interface. + * + * Automatic kernel driver detachment is disabled on newly opened device + * handles by default. + * + * On platforms which do not have LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER + * this function will return LIBUSB_ERROR_NOT_SUPPORTED, and libusb will + * continue as if this function was never called. + * + * \param dev a device handle + * \param enable whether to enable or disable auto kernel driver detachment + * + * \returns LIBUSB_SUCCESS on success + * \returns LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality + * is not available + * \see libusb_claim_interface() + * \see libusb_release_interface() + * \see libusb_set_configuration() + */ +int API_EXPORTED libusb_set_auto_detach_kernel_driver( + libusb_device_handle *dev, int enable) +{ + if (!(usbi_backend->caps & USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER)) + return LIBUSB_ERROR_NOT_SUPPORTED; + + dev->auto_detach_kernel_driver = enable; + return LIBUSB_SUCCESS; +} + +/** \ingroup lib + * Set log message verbosity. + * + * The default level is LIBUSB_LOG_LEVEL_NONE, which means no messages are ever + * printed. If you choose to increase the message verbosity level, ensure + * that your application does not close the stdout/stderr file descriptors. + * + * You are advised to use level LIBUSB_LOG_LEVEL_WARNING. libusb is conservative + * with its message logging and most of the time, will only log messages that + * explain error conditions and other oddities. This will help you debug + * your software. + * + * If the LIBUSB_DEBUG environment variable was set when libusb was + * initialized, this function does nothing: the message verbosity is fixed + * to the value in the environment variable. + * + * If libusb was compiled without any message logging, this function does + * nothing: you'll never get any messages. + * + * If libusb was compiled with verbose debug message logging, this function + * does nothing: you'll always get messages from all levels. + * + * \param ctx the context to operate on, or NULL for the default context + * \param level debug level to set + */ +void API_EXPORTED libusb_set_debug(libusb_context *ctx, int level) +{ + USBI_GET_CONTEXT(ctx); + if (!ctx->debug_fixed) + ctx->debug = level; +} + +/** \ingroup lib + * Initialize libusb. This function must be called before calling any other + * libusb function. + * + * If you do not provide an output location for a context pointer, a default + * context will be created. If there was already a default context, it will + * be reused (and nothing will be initialized/reinitialized). + * + * \param context Optional output location for context pointer. + * Only valid on return code 0. + * \returns 0 on success, or a LIBUSB_ERROR code on failure + * \see contexts + */ +int API_EXPORTED libusb_init(libusb_context **context) +{ + struct libusb_device *dev, *next; + char *dbg = getenv("LIBUSB_DEBUG"); + struct libusb_context *ctx; + static int first_init = 1; + int r = 0; + + usbi_mutex_static_lock(&default_context_lock); + + if (!timestamp_origin.tv_sec) { + usbi_gettimeofday(×tamp_origin, NULL); + } + + if (!context && usbi_default_context) { + usbi_dbg("reusing default context"); + default_context_refcnt++; + usbi_mutex_static_unlock(&default_context_lock); + return 0; + } + + ctx = calloc(1, sizeof(*ctx)); + if (!ctx) { + r = LIBUSB_ERROR_NO_MEM; + goto err_unlock; + } + +#ifdef ENABLE_DEBUG_LOGGING + ctx->debug = LIBUSB_LOG_LEVEL_DEBUG; +#endif + + if (dbg) { + ctx->debug = atoi(dbg); + if (ctx->debug) + ctx->debug_fixed = 1; + } + + /* default context should be initialized before calling usbi_dbg */ + if (!usbi_default_context) { + usbi_default_context = ctx; + default_context_refcnt++; + usbi_dbg("created default context"); + } + + usbi_dbg("libusb v%u.%u.%u.%u%s", libusb_version_internal.major, libusb_version_internal.minor, + libusb_version_internal.micro, libusb_version_internal.nano, libusb_version_internal.rc); + + usbi_mutex_init(&ctx->usb_devs_lock, NULL); + usbi_mutex_init(&ctx->open_devs_lock, NULL); + usbi_mutex_init(&ctx->hotplug_cbs_lock, NULL); + list_init(&ctx->usb_devs); + list_init(&ctx->open_devs); + list_init(&ctx->hotplug_cbs); + + usbi_mutex_static_lock(&active_contexts_lock); + if (first_init) { + first_init = 0; + list_init (&active_contexts_list); + } + list_add (&ctx->list, &active_contexts_list); + usbi_mutex_static_unlock(&active_contexts_lock); + + if (usbi_backend->init) { + r = usbi_backend->init(ctx); + if (r) + goto err_free_ctx; + } + + r = usbi_io_init(ctx); + if (r < 0) + goto err_backend_exit; + + usbi_mutex_static_unlock(&default_context_lock); + + if (context) + *context = ctx; + + return 0; + +err_backend_exit: + if (usbi_backend->exit) + usbi_backend->exit(); +err_free_ctx: + if (ctx == usbi_default_context) { + usbi_default_context = NULL; + default_context_refcnt--; + } + + usbi_mutex_static_lock(&active_contexts_lock); + list_del (&ctx->list); + usbi_mutex_static_unlock(&active_contexts_lock); + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry_safe(dev, next, &ctx->usb_devs, list, struct libusb_device) { + list_del(&dev->list); + libusb_unref_device(dev); + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + + usbi_mutex_destroy(&ctx->open_devs_lock); + usbi_mutex_destroy(&ctx->usb_devs_lock); + usbi_mutex_destroy(&ctx->hotplug_cbs_lock); + + free(ctx); +err_unlock: + usbi_mutex_static_unlock(&default_context_lock); + return r; +} + +/** \ingroup lib + * Deinitialize libusb. Should be called after closing all open devices and + * before your application terminates. + * \param ctx the context to deinitialize, or NULL for the default context + */ +void API_EXPORTED libusb_exit(struct libusb_context *ctx) +{ + struct libusb_device *dev, *next; + struct timeval tv = { 0, 0 }; + + usbi_dbg(""); + USBI_GET_CONTEXT(ctx); + + /* if working with default context, only actually do the deinitialization + * if we're the last user */ + usbi_mutex_static_lock(&default_context_lock); + if (ctx == usbi_default_context) { + if (--default_context_refcnt > 0) { + usbi_dbg("not destroying default context"); + usbi_mutex_static_unlock(&default_context_lock); + return; + } + usbi_dbg("destroying default context"); + usbi_default_context = NULL; + } + usbi_mutex_static_unlock(&default_context_lock); + + usbi_mutex_static_lock(&active_contexts_lock); + list_del (&ctx->list); + usbi_mutex_static_unlock(&active_contexts_lock); + + if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + usbi_hotplug_deregister_all(ctx); + + /* + * Ensure any pending unplug events are read from the hotplug + * pipe. The usb_device-s hold in the events are no longer part + * of usb_devs, but the events still hold a reference! + * + * Note we don't do this if the application has left devices + * open (which implies a buggy app) to avoid packet completion + * handlers running when the app does not expect them to run. + */ + if (list_empty(&ctx->open_devs)) + libusb_handle_events_timeout(ctx, &tv); + + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry_safe(dev, next, &ctx->usb_devs, list, struct libusb_device) { + list_del(&dev->list); + libusb_unref_device(dev); + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + } + + /* a few sanity checks. don't bother with locking because unless + * there is an application bug, nobody will be accessing these. */ + if (!list_empty(&ctx->usb_devs)) + usbi_warn(ctx, "some libusb_devices were leaked"); + if (!list_empty(&ctx->open_devs)) + usbi_warn(ctx, "application left some devices open"); + + usbi_io_exit(ctx); + if (usbi_backend->exit) + usbi_backend->exit(); + + usbi_mutex_destroy(&ctx->open_devs_lock); + usbi_mutex_destroy(&ctx->usb_devs_lock); + usbi_mutex_destroy(&ctx->hotplug_cbs_lock); + free(ctx); +} + +/** \ingroup misc + * Check at runtime if the loaded library has a given capability. + * This call should be performed after \ref libusb_init(), to ensure the + * backend has updated its capability set. + * + * \param capability the \ref libusb_capability to check for + * \returns nonzero if the running library has the capability, 0 otherwise + */ +int API_EXPORTED libusb_has_capability(uint32_t capability) +{ + switch (capability) { + case LIBUSB_CAP_HAS_CAPABILITY: + return 1; + case LIBUSB_CAP_HAS_HOTPLUG: + return !(usbi_backend->get_device_list); + case LIBUSB_CAP_HAS_HID_ACCESS: + return (usbi_backend->caps & USBI_CAP_HAS_HID_ACCESS); + case LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER: + return (usbi_backend->caps & USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER); + } + return 0; +} + +/* this is defined in libusbi.h if needed */ +#ifdef LIBUSB_GETTIMEOFDAY_WIN32 +/* + * gettimeofday + * Implementation according to: + * The Open Group Base Specifications Issue 6 + * IEEE Std 1003.1, 2004 Edition + */ + +/* + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Contributed by: + * Danny Smith + */ + +/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ +#define _W32_FT_OFFSET (116444736000000000) + +int usbi_gettimeofday(struct timeval *tp, void *tzp) +{ + union { + unsigned __int64 ns100; /* Time since 1 Jan 1601, in 100ns units */ + FILETIME ft; + } _now; + UNUSED(tzp); + + if(tp) { +#if defined(OS_WINCE) + SYSTEMTIME st; + GetSystemTime(&st); + SystemTimeToFileTime(&st, &_now.ft); +#else + GetSystemTimeAsFileTime (&_now.ft); +#endif + tp->tv_usec=(long)((_now.ns100 / 10) % 1000000 ); + tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000); + } + /* Always return 0 as per Open Group Base Specifications Issue 6. + Do not set errno on error. */ + return 0; +} +#endif + +static void usbi_log_str(struct libusb_context *ctx, + enum libusb_log_level level, const char * str) +{ +#if defined(USE_SYSTEM_LOGGING_FACILITY) +#if defined(OS_WINDOWS) || defined(OS_WINCE) + /* Windows CE only supports the Unicode version of OutputDebugString. */ + WCHAR wbuf[USBI_MAX_LOG_LEN]; + MultiByteToWideChar(CP_UTF8, 0, str, -1, wbuf, sizeof(wbuf)); + OutputDebugStringW(wbuf); +#elif defined(__ANDROID__) + int priority = ANDROID_LOG_UNKNOWN; + switch (level) { + case LIBUSB_LOG_LEVEL_INFO: priority = ANDROID_LOG_INFO; break; + case LIBUSB_LOG_LEVEL_WARNING: priority = ANDROID_LOG_WARN; break; + case LIBUSB_LOG_LEVEL_ERROR: priority = ANDROID_LOG_ERROR; break; + case LIBUSB_LOG_LEVEL_DEBUG: priority = ANDROID_LOG_DEBUG; break; + } + __android_log_write(priority, "libusb", str); +#elif defined(HAVE_SYSLOG_FUNC) + int syslog_level = LOG_INFO; + switch (level) { + case LIBUSB_LOG_LEVEL_INFO: syslog_level = LOG_INFO; break; + case LIBUSB_LOG_LEVEL_WARNING: syslog_level = LOG_WARNING; break; + case LIBUSB_LOG_LEVEL_ERROR: syslog_level = LOG_ERR; break; + case LIBUSB_LOG_LEVEL_DEBUG: syslog_level = LOG_DEBUG; break; + } + syslog(syslog_level, "%s", str); +#else /* All of gcc, Clang, XCode seem to use #warning */ +#warning System logging is not supported on this platform. Logging to stderr will be used instead. + fputs(str, stderr); +#endif +#else + fputs(str, stderr); +#endif /* USE_SYSTEM_LOGGING_FACILITY */ + UNUSED(ctx); + UNUSED(level); +} + +void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level, + const char *function, const char *format, va_list args) +{ + const char *prefix = ""; + char buf[USBI_MAX_LOG_LEN]; + struct timeval now; + int global_debug, header_len, text_len; + static int has_debug_header_been_displayed = 0; + +#ifdef ENABLE_DEBUG_LOGGING + global_debug = 1; + UNUSED(ctx); +#else + int ctx_level = 0; + + USBI_GET_CONTEXT(ctx); + if (ctx) { + ctx_level = ctx->debug; + } else { + char *dbg = getenv("LIBUSB_DEBUG"); + if (dbg) + ctx_level = atoi(dbg); + } + global_debug = (ctx_level == LIBUSB_LOG_LEVEL_DEBUG); + if (!ctx_level) + return; + if (level == LIBUSB_LOG_LEVEL_WARNING && ctx_level < LIBUSB_LOG_LEVEL_WARNING) + return; + if (level == LIBUSB_LOG_LEVEL_INFO && ctx_level < LIBUSB_LOG_LEVEL_INFO) + return; + if (level == LIBUSB_LOG_LEVEL_DEBUG && ctx_level < LIBUSB_LOG_LEVEL_DEBUG) + return; +#endif + + usbi_gettimeofday(&now, NULL); + if ((global_debug) && (!has_debug_header_been_displayed)) { + has_debug_header_been_displayed = 1; + usbi_log_str(ctx, LIBUSB_LOG_LEVEL_DEBUG, "[timestamp] [threadID] facility level [function call] " USBI_LOG_LINE_END); + usbi_log_str(ctx, LIBUSB_LOG_LEVEL_DEBUG, "--------------------------------------------------------------------------------" USBI_LOG_LINE_END); + } + if (now.tv_usec < timestamp_origin.tv_usec) { + now.tv_sec--; + now.tv_usec += 1000000; + } + now.tv_sec -= timestamp_origin.tv_sec; + now.tv_usec -= timestamp_origin.tv_usec; + + switch (level) { + case LIBUSB_LOG_LEVEL_INFO: + prefix = "info"; + break; + case LIBUSB_LOG_LEVEL_WARNING: + prefix = "warning"; + break; + case LIBUSB_LOG_LEVEL_ERROR: + prefix = "error"; + break; + case LIBUSB_LOG_LEVEL_DEBUG: + prefix = "debug"; + break; + case LIBUSB_LOG_LEVEL_NONE: + return; + default: + prefix = "unknown"; + break; + } + + if (global_debug) { + header_len = snprintf(buf, sizeof(buf), + "[%2d.%06d] [%08x] libusb: %s [%s] ", + (int)now.tv_sec, (int)now.tv_usec, usbi_get_tid(), prefix, function); + } else { + header_len = snprintf(buf, sizeof(buf), + "libusb: %s [%s] ", prefix, function); + } + + if (header_len < 0 || header_len >= sizeof(buf)) { + /* Somehow snprintf failed to write to the buffer, + * remove the header so something useful is output. */ + header_len = 0; + } + /* Make sure buffer is NUL terminated */ + buf[header_len] = '\0'; + text_len = vsnprintf(buf + header_len, sizeof(buf) - header_len, + format, args); + if (text_len < 0 || text_len + header_len >= sizeof(buf)) { + /* Truncated log output. On some platforms a -1 return value means + * that the output was truncated. */ + text_len = sizeof(buf) - header_len; + } + if (header_len + text_len + sizeof(USBI_LOG_LINE_END) >= sizeof(buf)) { + /* Need to truncate the text slightly to fit on the terminator. */ + text_len -= (header_len + text_len + sizeof(USBI_LOG_LINE_END)) - sizeof(buf); + } + strcpy(buf + header_len + text_len, USBI_LOG_LINE_END); + + usbi_log_str(ctx, level, buf); +} + +void usbi_log(struct libusb_context *ctx, enum libusb_log_level level, + const char *function, const char *format, ...) +{ + va_list args; + + va_start (args, format); + usbi_log_v(ctx, level, function, format, args); + va_end (args); +} + +/** \ingroup misc + * Returns a constant NULL-terminated string with the ASCII name of a libusb + * error or transfer status code. The caller must not free() the returned + * string. + * + * \param error_code The \ref libusb_error or libusb_transfer_status code to + * return the name of. + * \returns The error name, or the string **UNKNOWN** if the value of + * error_code is not a known error / status code. + */ +DEFAULT_VISIBILITY const char * LIBUSB_CALL libusb_error_name(int error_code) +{ + switch (error_code) { + case LIBUSB_ERROR_IO: + return "LIBUSB_ERROR_IO"; + case LIBUSB_ERROR_INVALID_PARAM: + return "LIBUSB_ERROR_INVALID_PARAM"; + case LIBUSB_ERROR_ACCESS: + return "LIBUSB_ERROR_ACCESS"; + case LIBUSB_ERROR_NO_DEVICE: + return "LIBUSB_ERROR_NO_DEVICE"; + case LIBUSB_ERROR_NOT_FOUND: + return "LIBUSB_ERROR_NOT_FOUND"; + case LIBUSB_ERROR_BUSY: + return "LIBUSB_ERROR_BUSY"; + case LIBUSB_ERROR_TIMEOUT: + return "LIBUSB_ERROR_TIMEOUT"; + case LIBUSB_ERROR_OVERFLOW: + return "LIBUSB_ERROR_OVERFLOW"; + case LIBUSB_ERROR_PIPE: + return "LIBUSB_ERROR_PIPE"; + case LIBUSB_ERROR_INTERRUPTED: + return "LIBUSB_ERROR_INTERRUPTED"; + case LIBUSB_ERROR_NO_MEM: + return "LIBUSB_ERROR_NO_MEM"; + case LIBUSB_ERROR_NOT_SUPPORTED: + return "LIBUSB_ERROR_NOT_SUPPORTED"; + case LIBUSB_ERROR_OTHER: + return "LIBUSB_ERROR_OTHER"; + + case LIBUSB_TRANSFER_ERROR: + return "LIBUSB_TRANSFER_ERROR"; + case LIBUSB_TRANSFER_TIMED_OUT: + return "LIBUSB_TRANSFER_TIMED_OUT"; + case LIBUSB_TRANSFER_CANCELLED: + return "LIBUSB_TRANSFER_CANCELLED"; + case LIBUSB_TRANSFER_STALL: + return "LIBUSB_TRANSFER_STALL"; + case LIBUSB_TRANSFER_NO_DEVICE: + return "LIBUSB_TRANSFER_NO_DEVICE"; + case LIBUSB_TRANSFER_OVERFLOW: + return "LIBUSB_TRANSFER_OVERFLOW"; + + case 0: + return "LIBUSB_SUCCESS / LIBUSB_TRANSFER_COMPLETED"; + default: + return "**UNKNOWN**"; + } +} + +/** \ingroup misc + * Returns a pointer to const struct libusb_version with the version + * (major, minor, micro, nano and rc) of the running library. + */ +DEFAULT_VISIBILITY +const struct libusb_version * LIBUSB_CALL libusb_get_version(void) +{ + return &libusb_version_internal; +} diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/core.c.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/core.c.REMOVED.git-id deleted file mode 100644 index 6e95beaa..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/core.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -38fb55aac6a528da207efdd8aea0c405d0903307 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/descriptor.c b/Desktop_Interface/build_android/libusb-martin-kuldeep/descriptor.c new file mode 100644 index 00000000..defcacb1 --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/descriptor.c @@ -0,0 +1,1195 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * USB descriptor handling functions for libusb + * Copyright © 2007 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include + +#include "libusbi.h" + +#define DESC_HEADER_LENGTH 2 +#define DEVICE_DESC_LENGTH 18 +#define CONFIG_DESC_LENGTH 9 +#define INTERFACE_DESC_LENGTH 9 +#define ENDPOINT_DESC_LENGTH 7 +#define ENDPOINT_AUDIO_DESC_LENGTH 9 + +/** @defgroup desc USB descriptors + * This page details how to examine the various standard USB descriptors + * for detected devices + */ + +/* set host_endian if the w values are already in host endian format, + * as opposed to bus endian. */ +int usbi_parse_descriptor(const unsigned char *source, const char *descriptor, + void *dest, int host_endian) +{ + const unsigned char *sp = source; + unsigned char *dp = dest; + uint16_t w; + const char *cp; + uint32_t d; + + for (cp = descriptor; *cp; cp++) { + switch (*cp) { + case 'b': /* 8-bit byte */ + *dp++ = *sp++; + break; + case 'w': /* 16-bit word, convert from little endian to CPU */ + dp += ((uintptr_t)dp & 1); /* Align to word boundary */ + + if (host_endian) { + memcpy(dp, sp, 2); + } else { + w = (sp[1] << 8) | sp[0]; + *((uint16_t *)dp) = w; + } + sp += 2; + dp += 2; + break; + case 'd': /* 32-bit word, convert from little endian to CPU */ + dp += ((uintptr_t)dp & 1); /* Align to word boundary */ + + if (host_endian) { + memcpy(dp, sp, 4); + } else { + d = (sp[3] << 24) | (sp[2] << 16) | + (sp[1] << 8) | sp[0]; + *((uint32_t *)dp) = d; + } + sp += 4; + dp += 4; + break; + case 'u': /* 16 byte UUID */ + memcpy(dp, sp, 16); + sp += 16; + dp += 16; + break; + } + } + + return (int) (sp - source); +} + +static void clear_endpoint(struct libusb_endpoint_descriptor *endpoint) +{ + if (endpoint->extra) + free((unsigned char *) endpoint->extra); +} + +static int parse_endpoint(struct libusb_context *ctx, + struct libusb_endpoint_descriptor *endpoint, unsigned char *buffer, + int size, int host_endian) +{ + struct usb_descriptor_header header; + unsigned char *extra; + unsigned char *begin; + int parsed = 0; + int len; + + if (size < DESC_HEADER_LENGTH) { + usbi_err(ctx, "short endpoint descriptor read %d/%d", + size, DESC_HEADER_LENGTH); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(buffer, "bb", &header, 0); + if (header.bDescriptorType != LIBUSB_DT_ENDPOINT) { + usbi_err(ctx, "unexpected descriptor %x (expected %x)", + header.bDescriptorType, LIBUSB_DT_ENDPOINT); + return parsed; + } + if (header.bLength > size) { + usbi_warn(ctx, "short endpoint descriptor read %d/%d", + size, header.bLength); + return parsed; + } + if (header.bLength >= ENDPOINT_AUDIO_DESC_LENGTH) + usbi_parse_descriptor(buffer, "bbbbwbbb", endpoint, host_endian); + else if (header.bLength >= ENDPOINT_DESC_LENGTH) + usbi_parse_descriptor(buffer, "bbbbwb", endpoint, host_endian); + else { + usbi_err(ctx, "invalid endpoint bLength (%d)", header.bLength); + return LIBUSB_ERROR_IO; + } + + buffer += header.bLength; + size -= header.bLength; + parsed += header.bLength; + + /* Skip over the rest of the Class Specific or Vendor Specific */ + /* descriptors */ + begin = buffer; + while (size >= DESC_HEADER_LENGTH) { + usbi_parse_descriptor(buffer, "bb", &header, 0); + if (header.bLength < DESC_HEADER_LENGTH) { + usbi_err(ctx, "invalid extra ep desc len (%d)", + header.bLength); + return LIBUSB_ERROR_IO; + } else if (header.bLength > size) { + usbi_warn(ctx, "short extra ep desc read %d/%d", + size, header.bLength); + return parsed; + } + + /* If we find another "proper" descriptor then we're done */ + if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) || + (header.bDescriptorType == LIBUSB_DT_INTERFACE) || + (header.bDescriptorType == LIBUSB_DT_CONFIG) || + (header.bDescriptorType == LIBUSB_DT_DEVICE)) + break; + + usbi_dbg("skipping descriptor %x", header.bDescriptorType); + buffer += header.bLength; + size -= header.bLength; + parsed += header.bLength; + } + + /* Copy any unknown descriptors into a storage area for drivers */ + /* to later parse */ + len = (int)(buffer - begin); + if (!len) { + endpoint->extra = NULL; + endpoint->extra_length = 0; + return parsed; + } + + extra = malloc(len); + endpoint->extra = extra; + if (!extra) { + endpoint->extra_length = 0; + return LIBUSB_ERROR_NO_MEM; + } + + memcpy(extra, begin, len); + endpoint->extra_length = len; + + return parsed; +} + +static void clear_interface(struct libusb_interface *usb_interface) +{ + int i; + int j; + + if (usb_interface->altsetting) { + for (i = 0; i < usb_interface->num_altsetting; i++) { + struct libusb_interface_descriptor *ifp = + (struct libusb_interface_descriptor *) + usb_interface->altsetting + i; + if (ifp->extra) + free((void *) ifp->extra); + if (ifp->endpoint) { + for (j = 0; j < ifp->bNumEndpoints; j++) + clear_endpoint((struct libusb_endpoint_descriptor *) + ifp->endpoint + j); + free((void *) ifp->endpoint); + } + } + free((void *) usb_interface->altsetting); + usb_interface->altsetting = NULL; + } + +} + +static int parse_interface(libusb_context *ctx, + struct libusb_interface *usb_interface, unsigned char *buffer, int size, + int host_endian) +{ + int i; + int len; + int r; + int parsed = 0; + int interface_number = -1; + struct usb_descriptor_header header; + struct libusb_interface_descriptor *ifp; + unsigned char *begin; + + usb_interface->num_altsetting = 0; + + while (size >= INTERFACE_DESC_LENGTH) { + struct libusb_interface_descriptor *altsetting = + (struct libusb_interface_descriptor *) usb_interface->altsetting; + altsetting = usbi_reallocf(altsetting, + sizeof(struct libusb_interface_descriptor) * + (usb_interface->num_altsetting + 1)); + if (!altsetting) { + r = LIBUSB_ERROR_NO_MEM; + goto err; + } + usb_interface->altsetting = altsetting; + + ifp = altsetting + usb_interface->num_altsetting; + usbi_parse_descriptor(buffer, "bbbbbbbbb", ifp, 0); + if (ifp->bDescriptorType != LIBUSB_DT_INTERFACE) { + usbi_err(ctx, "unexpected descriptor %x (expected %x)", + ifp->bDescriptorType, LIBUSB_DT_INTERFACE); + return parsed; + } + if (ifp->bLength < INTERFACE_DESC_LENGTH) { + usbi_err(ctx, "invalid interface bLength (%d)", + ifp->bLength); + r = LIBUSB_ERROR_IO; + goto err; + } + if (ifp->bLength > size) { + usbi_warn(ctx, "short intf descriptor read %d/%d", + size, ifp->bLength); + return parsed; + } + if (ifp->bNumEndpoints > USB_MAXENDPOINTS) { + usbi_err(ctx, "too many endpoints (%d)", ifp->bNumEndpoints); + r = LIBUSB_ERROR_IO; + goto err; + } + + usb_interface->num_altsetting++; + ifp->extra = NULL; + ifp->extra_length = 0; + ifp->endpoint = NULL; + + if (interface_number == -1) + interface_number = ifp->bInterfaceNumber; + + /* Skip over the interface */ + buffer += ifp->bLength; + parsed += ifp->bLength; + size -= ifp->bLength; + + begin = buffer; + + /* Skip over any interface, class or vendor descriptors */ + while (size >= DESC_HEADER_LENGTH) { + usbi_parse_descriptor(buffer, "bb", &header, 0); + if (header.bLength < DESC_HEADER_LENGTH) { + usbi_err(ctx, + "invalid extra intf desc len (%d)", + header.bLength); + r = LIBUSB_ERROR_IO; + goto err; + } else if (header.bLength > size) { + usbi_warn(ctx, + "short extra intf desc read %d/%d", + size, header.bLength); + return parsed; + } + + /* If we find another "proper" descriptor then we're done */ + if ((header.bDescriptorType == LIBUSB_DT_INTERFACE) || + (header.bDescriptorType == LIBUSB_DT_ENDPOINT) || + (header.bDescriptorType == LIBUSB_DT_CONFIG) || + (header.bDescriptorType == LIBUSB_DT_DEVICE)) + break; + + buffer += header.bLength; + parsed += header.bLength; + size -= header.bLength; + } + + /* Copy any unknown descriptors into a storage area for */ + /* drivers to later parse */ + len = (int)(buffer - begin); + if (len) { + ifp->extra = malloc(len); + if (!ifp->extra) { + r = LIBUSB_ERROR_NO_MEM; + goto err; + } + memcpy((unsigned char *) ifp->extra, begin, len); + ifp->extra_length = len; + } + + if (ifp->bNumEndpoints > 0) { + struct libusb_endpoint_descriptor *endpoint; + endpoint = calloc(ifp->bNumEndpoints, sizeof(struct libusb_endpoint_descriptor)); + ifp->endpoint = endpoint; + if (!endpoint) { + r = LIBUSB_ERROR_NO_MEM; + goto err; + } + + for (i = 0; i < ifp->bNumEndpoints; i++) { + r = parse_endpoint(ctx, endpoint + i, buffer, size, + host_endian); + if (r < 0) + goto err; + if (r == 0) { + ifp->bNumEndpoints = (uint8_t)i; + break;; + } + + buffer += r; + parsed += r; + size -= r; + } + } + + /* We check to see if it's an alternate to this one */ + ifp = (struct libusb_interface_descriptor *) buffer; + if (size < LIBUSB_DT_INTERFACE_SIZE || + ifp->bDescriptorType != LIBUSB_DT_INTERFACE || + ifp->bInterfaceNumber != interface_number) + return parsed; + } + + return parsed; +err: + clear_interface(usb_interface); + return r; +} + +static void clear_configuration(struct libusb_config_descriptor *config) +{ + if (config->interface) { + int i; + for (i = 0; i < config->bNumInterfaces; i++) + clear_interface((struct libusb_interface *) + config->interface + i); + free((void *) config->interface); + } + if (config->extra) + free((void *) config->extra); +} + +static int parse_configuration(struct libusb_context *ctx, + struct libusb_config_descriptor *config, unsigned char *buffer, + int size, int host_endian) +{ + int i; + int r; + struct usb_descriptor_header header; + struct libusb_interface *usb_interface; + + if (size < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(ctx, "short config descriptor read %d/%d", + size, LIBUSB_DT_CONFIG_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(buffer, "bbwbbbbb", config, host_endian); + if (config->bDescriptorType != LIBUSB_DT_CONFIG) { + usbi_err(ctx, "unexpected descriptor %x (expected %x)", + config->bDescriptorType, LIBUSB_DT_CONFIG); + return LIBUSB_ERROR_IO; + } + if (config->bLength < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(ctx, "invalid config bLength (%d)", config->bLength); + return LIBUSB_ERROR_IO; + } + if (config->bLength > size) { + usbi_err(ctx, "short config descriptor read %d/%d", + size, config->bLength); + return LIBUSB_ERROR_IO; + } + if (config->bNumInterfaces > USB_MAXINTERFACES) { + usbi_err(ctx, "too many interfaces (%d)", config->bNumInterfaces); + return LIBUSB_ERROR_IO; + } + + usb_interface = calloc(config->bNumInterfaces, sizeof(struct libusb_interface)); + config->interface = usb_interface; + if (!usb_interface) + return LIBUSB_ERROR_NO_MEM; + + buffer += config->bLength; + size -= config->bLength; + + config->extra = NULL; + config->extra_length = 0; + + for (i = 0; i < config->bNumInterfaces; i++) { + int len; + unsigned char *begin; + + /* Skip over the rest of the Class Specific or Vendor */ + /* Specific descriptors */ + begin = buffer; + while (size >= DESC_HEADER_LENGTH) { + usbi_parse_descriptor(buffer, "bb", &header, 0); + + if (header.bLength < DESC_HEADER_LENGTH) { + usbi_err(ctx, + "invalid extra config desc len (%d)", + header.bLength); + r = LIBUSB_ERROR_IO; + goto err; + } else if (header.bLength > size) { + usbi_warn(ctx, + "short extra config desc read %d/%d", + size, header.bLength); + config->bNumInterfaces = (uint8_t)i; + return size; + } + + /* If we find another "proper" descriptor then we're done */ + if ((header.bDescriptorType == LIBUSB_DT_ENDPOINT) || + (header.bDescriptorType == LIBUSB_DT_INTERFACE) || + (header.bDescriptorType == LIBUSB_DT_CONFIG) || + (header.bDescriptorType == LIBUSB_DT_DEVICE)) + break; + + usbi_dbg("skipping descriptor 0x%x", header.bDescriptorType); + buffer += header.bLength; + size -= header.bLength; + } + + /* Copy any unknown descriptors into a storage area for */ + /* drivers to later parse */ + len = (int)(buffer - begin); + if (len) { + /* FIXME: We should realloc and append here */ + if (!config->extra_length) { + config->extra = malloc(len); + if (!config->extra) { + r = LIBUSB_ERROR_NO_MEM; + goto err; + } + + memcpy((unsigned char *) config->extra, begin, len); + config->extra_length = len; + } + } + + r = parse_interface(ctx, usb_interface + i, buffer, size, host_endian); + if (r < 0) + goto err; + if (r == 0) { + config->bNumInterfaces = (uint8_t)i; + break; + } + + buffer += r; + size -= r; + } + + return size; + +err: + clear_configuration(config); + return r; +} + +static int raw_desc_to_config(struct libusb_context *ctx, + unsigned char *buf, int size, int host_endian, + struct libusb_config_descriptor **config) +{ + struct libusb_config_descriptor *_config = malloc(sizeof(*_config)); + int r; + + if (!_config) + return LIBUSB_ERROR_NO_MEM; + + r = parse_configuration(ctx, _config, buf, size, host_endian); + if (r < 0) { + usbi_err(ctx, "parse_configuration failed with error %d", r); + free(_config); + return r; + } else if (r > 0) { + usbi_warn(ctx, "still %d bytes of descriptor data left", r); + } + + *config = _config; + return LIBUSB_SUCCESS; +} + +int usbi_device_cache_descriptor(libusb_device *dev) +{ + int r, host_endian = 0; + + r = usbi_backend->get_device_descriptor(dev, (unsigned char *) &dev->device_descriptor, + &host_endian); + if (r < 0) + return r; + + if (!host_endian) { + dev->device_descriptor.bcdUSB = libusb_le16_to_cpu(dev->device_descriptor.bcdUSB); + dev->device_descriptor.idVendor = libusb_le16_to_cpu(dev->device_descriptor.idVendor); + dev->device_descriptor.idProduct = libusb_le16_to_cpu(dev->device_descriptor.idProduct); + dev->device_descriptor.bcdDevice = libusb_le16_to_cpu(dev->device_descriptor.bcdDevice); + } + + return LIBUSB_SUCCESS; +} + +/** \ingroup desc + * Get the USB device descriptor for a given device. + * + * This is a non-blocking function; the device descriptor is cached in memory. + * + * Note since libusb-1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, this + * function always succeeds. + * + * \param dev the device + * \param desc output location for the descriptor data + * \returns 0 on success or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev, + struct libusb_device_descriptor *desc) +{ + usbi_dbg(""); + memcpy((unsigned char *) desc, (unsigned char *) &dev->device_descriptor, + sizeof (dev->device_descriptor)); + return 0; +} + +/** \ingroup desc + * Get the USB configuration descriptor for the currently active configuration. + * This is a non-blocking function which does not involve any requests being + * sent to the device. + * + * \param dev a device + * \param config output location for the USB configuration descriptor. Only + * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() + * after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state + * \returns another LIBUSB_ERROR code on error + * \see libusb_get_config_descriptor + */ +int API_EXPORTED libusb_get_active_config_descriptor(libusb_device *dev, + struct libusb_config_descriptor **config) +{ + struct libusb_config_descriptor _config; + unsigned char tmp[LIBUSB_DT_CONFIG_SIZE]; + unsigned char *buf = NULL; + int host_endian = 0; + int r; + + r = usbi_backend->get_active_config_descriptor(dev, tmp, + LIBUSB_DT_CONFIG_SIZE, &host_endian); + if (r < 0) + return r; + if (r < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(dev->ctx, "short config descriptor read %d/%d", + r, LIBUSB_DT_CONFIG_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(tmp, "bbw", &_config, host_endian); + buf = malloc(_config.wTotalLength); + if (!buf) + return LIBUSB_ERROR_NO_MEM; + + r = usbi_backend->get_active_config_descriptor(dev, buf, + _config.wTotalLength, &host_endian); + if (r >= 0) + r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config); + + free(buf); + return r; +} + +/** \ingroup desc + * Get a USB configuration descriptor based on its index. + * This is a non-blocking function which does not involve any requests being + * sent to the device. + * + * \param dev a device + * \param config_index the index of the configuration you wish to retrieve + * \param config output location for the USB configuration descriptor. Only + * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() + * after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist + * \returns another LIBUSB_ERROR code on error + * \see libusb_get_active_config_descriptor() + * \see libusb_get_config_descriptor_by_value() + */ +int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev, + uint8_t config_index, struct libusb_config_descriptor **config) +{ + struct libusb_config_descriptor _config; + unsigned char tmp[LIBUSB_DT_CONFIG_SIZE]; + unsigned char *buf = NULL; + int host_endian = 0; + int r; + + usbi_dbg("index %d", config_index); + if (config_index >= dev->num_configurations) + return LIBUSB_ERROR_NOT_FOUND; + + r = usbi_backend->get_config_descriptor(dev, config_index, tmp, + LIBUSB_DT_CONFIG_SIZE, &host_endian); + if (r < 0) + return r; + if (r < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(dev->ctx, "short config descriptor read %d/%d", + r, LIBUSB_DT_CONFIG_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(tmp, "bbw", &_config, host_endian); + buf = malloc(_config.wTotalLength); + if (!buf) + return LIBUSB_ERROR_NO_MEM; + + r = usbi_backend->get_config_descriptor(dev, config_index, buf, + _config.wTotalLength, &host_endian); + if (r >= 0) + r = raw_desc_to_config(dev->ctx, buf, r, host_endian, config); + + free(buf); + return r; +} + +/* iterate through all configurations, returning the index of the configuration + * matching a specific bConfigurationValue in the idx output parameter, or -1 + * if the config was not found. + * returns 0 on success or a LIBUSB_ERROR code + */ +int usbi_get_config_index_by_value(struct libusb_device *dev, + uint8_t bConfigurationValue, int *idx) +{ + uint8_t i; + + usbi_dbg("value %d", bConfigurationValue); + for (i = 0; i < dev->num_configurations; i++) { + unsigned char tmp[6]; + int host_endian; + int r = usbi_backend->get_config_descriptor(dev, i, tmp, sizeof(tmp), + &host_endian); + if (r < 0) { + *idx = -1; + return r; + } + if (tmp[5] == bConfigurationValue) { + *idx = i; + return 0; + } + } + + *idx = -1; + return 0; +} + +/** \ingroup desc + * Get a USB configuration descriptor with a specific bConfigurationValue. + * This is a non-blocking function which does not involve any requests being + * sent to the device. + * + * \param dev a device + * \param bConfigurationValue the bConfigurationValue of the configuration you + * wish to retrieve + * \param config output location for the USB configuration descriptor. Only + * valid if 0 was returned. Must be freed with libusb_free_config_descriptor() + * after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist + * \returns another LIBUSB_ERROR code on error + * \see libusb_get_active_config_descriptor() + * \see libusb_get_config_descriptor() + */ +int API_EXPORTED libusb_get_config_descriptor_by_value(libusb_device *dev, + uint8_t bConfigurationValue, struct libusb_config_descriptor **config) +{ + int r, idx, host_endian; + unsigned char *buf = NULL; + + if (usbi_backend->get_config_descriptor_by_value) { + r = usbi_backend->get_config_descriptor_by_value(dev, + bConfigurationValue, &buf, &host_endian); + if (r < 0) + return r; + return raw_desc_to_config(dev->ctx, buf, r, host_endian, config); + } + + r = usbi_get_config_index_by_value(dev, bConfigurationValue, &idx); + if (r < 0) + return r; + else if (idx == -1) + return LIBUSB_ERROR_NOT_FOUND; + else + return libusb_get_config_descriptor(dev, (uint8_t) idx, config); +} + +/** \ingroup desc + * Free a configuration descriptor obtained from + * libusb_get_active_config_descriptor() or libusb_get_config_descriptor(). + * It is safe to call this function with a NULL config parameter, in which + * case the function simply returns. + * + * \param config the configuration descriptor to free + */ +void API_EXPORTED libusb_free_config_descriptor( + struct libusb_config_descriptor *config) +{ + if (!config) + return; + + clear_configuration(config); + free(config); +} + +/** \ingroup desc + * Get an endpoints superspeed endpoint companion descriptor (if any) + * + * \param ctx the context to operate on, or NULL for the default context + * \param endpoint endpoint descriptor from which to get the superspeed + * endpoint companion descriptor + * \param ep_comp output location for the superspeed endpoint companion + * descriptor. Only valid if 0 was returned. Must be freed with + * libusb_free_ss_endpoint_companion_descriptor() after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist + * \returns another LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_ss_endpoint_companion_descriptor( + struct libusb_context *ctx, + const struct libusb_endpoint_descriptor *endpoint, + struct libusb_ss_endpoint_companion_descriptor **ep_comp) +{ + struct usb_descriptor_header header; + int size = endpoint->extra_length; + const unsigned char *buffer = endpoint->extra; + + *ep_comp = NULL; + + while (size >= DESC_HEADER_LENGTH) { + usbi_parse_descriptor(buffer, "bb", &header, 0); + if (header.bLength < 2 || header.bLength > size) { + usbi_err(ctx, "invalid descriptor length %d", + header.bLength); + return LIBUSB_ERROR_IO; + } + if (header.bDescriptorType != LIBUSB_DT_SS_ENDPOINT_COMPANION) { + buffer += header.bLength; + size -= header.bLength; + continue; + } + if (header.bLength < LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE) { + usbi_err(ctx, "invalid ss-ep-comp-desc length %d", + header.bLength); + return LIBUSB_ERROR_IO; + } + *ep_comp = malloc(sizeof(**ep_comp)); + if (*ep_comp == NULL) + return LIBUSB_ERROR_NO_MEM; + usbi_parse_descriptor(buffer, "bbbbw", *ep_comp, 0); + return LIBUSB_SUCCESS; + } + return LIBUSB_ERROR_NOT_FOUND; +} + +/** \ingroup desc + * Free a superspeed endpoint companion descriptor obtained from + * libusb_get_ss_endpoint_companion_descriptor(). + * It is safe to call this function with a NULL ep_comp parameter, in which + * case the function simply returns. + * + * \param ep_comp the superspeed endpoint companion descriptor to free + */ +void API_EXPORTED libusb_free_ss_endpoint_companion_descriptor( + struct libusb_ss_endpoint_companion_descriptor *ep_comp) +{ + free(ep_comp); +} + +static int parse_bos(struct libusb_context *ctx, + struct libusb_bos_descriptor **bos, + unsigned char *buffer, int size, int host_endian) +{ + struct libusb_bos_descriptor bos_header, *_bos; + struct libusb_bos_dev_capability_descriptor dev_cap; + int i; + + if (size < LIBUSB_DT_BOS_SIZE) { + usbi_err(ctx, "short bos descriptor read %d/%d", + size, LIBUSB_DT_BOS_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(buffer, "bbwb", &bos_header, host_endian); + if (bos_header.bDescriptorType != LIBUSB_DT_BOS) { + usbi_err(ctx, "unexpected descriptor %x (expected %x)", + bos_header.bDescriptorType, LIBUSB_DT_BOS); + return LIBUSB_ERROR_IO; + } + if (bos_header.bLength < LIBUSB_DT_BOS_SIZE) { + usbi_err(ctx, "invalid bos bLength (%d)", bos_header.bLength); + return LIBUSB_ERROR_IO; + } + if (bos_header.bLength > size) { + usbi_err(ctx, "short bos descriptor read %d/%d", + size, bos_header.bLength); + return LIBUSB_ERROR_IO; + } + + _bos = calloc (1, + sizeof(*_bos) + bos_header.bNumDeviceCaps * sizeof(void *)); + if (!_bos) + return LIBUSB_ERROR_NO_MEM; + + usbi_parse_descriptor(buffer, "bbwb", _bos, host_endian); + buffer += bos_header.bLength; + size -= bos_header.bLength; + + /* Get the device capability descriptors */ + for (i = 0; i < bos_header.bNumDeviceCaps; i++) { + if (size < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) { + usbi_warn(ctx, "short dev-cap descriptor read %d/%d", + size, LIBUSB_DT_DEVICE_CAPABILITY_SIZE); + break; + } + usbi_parse_descriptor(buffer, "bbb", &dev_cap, host_endian); + if (dev_cap.bDescriptorType != LIBUSB_DT_DEVICE_CAPABILITY) { + usbi_warn(ctx, "unexpected descriptor %x (expected %x)", + dev_cap.bDescriptorType, LIBUSB_DT_DEVICE_CAPABILITY); + break; + } + if (dev_cap.bLength < LIBUSB_DT_DEVICE_CAPABILITY_SIZE) { + usbi_err(ctx, "invalid dev-cap bLength (%d)", + dev_cap.bLength); + libusb_free_bos_descriptor(_bos); + return LIBUSB_ERROR_IO; + } + if (dev_cap.bLength > size) { + usbi_warn(ctx, "short dev-cap descriptor read %d/%d", + size, dev_cap.bLength); + break; + } + + _bos->dev_capability[i] = malloc(dev_cap.bLength); + if (!_bos->dev_capability[i]) { + libusb_free_bos_descriptor(_bos); + return LIBUSB_ERROR_NO_MEM; + } + memcpy(_bos->dev_capability[i], buffer, dev_cap.bLength); + buffer += dev_cap.bLength; + size -= dev_cap.bLength; + } + _bos->bNumDeviceCaps = (uint8_t)i; + *bos = _bos; + + return LIBUSB_SUCCESS; +} + +/** \ingroup desc + * Get a Binary Object Store (BOS) descriptor + * This is a BLOCKING function, which will send requests to the device. + * + * \param handle the handle of an open libusb device + * \param bos output location for the BOS descriptor. Only valid if 0 was returned. + * Must be freed with \ref libusb_free_bos_descriptor() after use. + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the device doesn't have a BOS descriptor + * \returns another LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_bos_descriptor(libusb_device_handle *handle, + struct libusb_bos_descriptor **bos) +{ + struct libusb_bos_descriptor _bos; + uint8_t bos_header[LIBUSB_DT_BOS_SIZE] = {0}; + unsigned char *bos_data = NULL; + const int host_endian = 0; + int r; + + /* Read the BOS. This generates 2 requests on the bus, + * one for the header, and one for the full BOS */ + r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_header, + LIBUSB_DT_BOS_SIZE); + if (r < 0) { + if (r != LIBUSB_ERROR_PIPE) + usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r); + return r; + } + if (r < LIBUSB_DT_BOS_SIZE) { + usbi_err(handle->dev->ctx, "short BOS read %d/%d", + r, LIBUSB_DT_BOS_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(bos_header, "bbwb", &_bos, host_endian); + usbi_dbg("found BOS descriptor: size %d bytes, %d capabilities", + _bos.wTotalLength, _bos.bNumDeviceCaps); + bos_data = calloc(_bos.wTotalLength, 1); + if (bos_data == NULL) + return LIBUSB_ERROR_NO_MEM; + + r = libusb_get_descriptor(handle, LIBUSB_DT_BOS, 0, bos_data, + _bos.wTotalLength); + if (r >= 0) + r = parse_bos(handle->dev->ctx, bos, bos_data, r, host_endian); + else + usbi_err(handle->dev->ctx, "failed to read BOS (%d)", r); + + free(bos_data); + return r; +} + +/** \ingroup desc + * Free a BOS descriptor obtained from libusb_get_bos_descriptor(). + * It is safe to call this function with a NULL bos parameter, in which + * case the function simply returns. + * + * \param bos the BOS descriptor to free + */ +void API_EXPORTED libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos) +{ + int i; + + if (!bos) + return; + + for (i = 0; i < bos->bNumDeviceCaps; i++) + free(bos->dev_capability[i]); + free(bos); +} + +/** \ingroup desc + * Get an USB 2.0 Extension descriptor + * + * \param ctx the context to operate on, or NULL for the default context + * \param dev_cap Device Capability descriptor with a bDevCapabilityType of + * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION + * LIBUSB_BT_USB_2_0_EXTENSION + * \param usb_2_0_extension output location for the USB 2.0 Extension + * descriptor. Only valid if 0 was returned. Must be freed with + * libusb_free_usb_2_0_extension_descriptor() after use. + * \returns 0 on success + * \returns a LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_usb_2_0_extension_descriptor( + struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension) +{ + struct libusb_usb_2_0_extension_descriptor *_usb_2_0_extension; + const int host_endian = 0; + + if (dev_cap->bDevCapabilityType != LIBUSB_BT_USB_2_0_EXTENSION) { + usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)", + dev_cap->bDevCapabilityType, + LIBUSB_BT_USB_2_0_EXTENSION); + return LIBUSB_ERROR_INVALID_PARAM; + } + if (dev_cap->bLength < LIBUSB_BT_USB_2_0_EXTENSION_SIZE) { + usbi_err(ctx, "short dev-cap descriptor read %d/%d", + dev_cap->bLength, LIBUSB_BT_USB_2_0_EXTENSION_SIZE); + return LIBUSB_ERROR_IO; + } + + _usb_2_0_extension = malloc(sizeof(*_usb_2_0_extension)); + if (!_usb_2_0_extension) + return LIBUSB_ERROR_NO_MEM; + + usbi_parse_descriptor((unsigned char *)dev_cap, "bbbd", + _usb_2_0_extension, host_endian); + + *usb_2_0_extension = _usb_2_0_extension; + return LIBUSB_SUCCESS; +} + +/** \ingroup desc + * Free a USB 2.0 Extension descriptor obtained from + * libusb_get_usb_2_0_extension_descriptor(). + * It is safe to call this function with a NULL usb_2_0_extension parameter, + * in which case the function simply returns. + * + * \param usb_2_0_extension the USB 2.0 Extension descriptor to free + */ +void API_EXPORTED libusb_free_usb_2_0_extension_descriptor( + struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension) +{ + free(usb_2_0_extension); +} + +/** \ingroup desc + * Get a SuperSpeed USB Device Capability descriptor + * + * \param ctx the context to operate on, or NULL for the default context + * \param dev_cap Device Capability descriptor with a bDevCapabilityType of + * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY + * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY + * \param ss_usb_device_cap output location for the SuperSpeed USB Device + * Capability descriptor. Only valid if 0 was returned. Must be freed with + * libusb_free_ss_usb_device_capability_descriptor() after use. + * \returns 0 on success + * \returns a LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor( + struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap) +{ + struct libusb_ss_usb_device_capability_descriptor *_ss_usb_device_cap; + const int host_endian = 0; + + if (dev_cap->bDevCapabilityType != LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) { + usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)", + dev_cap->bDevCapabilityType, + LIBUSB_BT_SS_USB_DEVICE_CAPABILITY); + return LIBUSB_ERROR_INVALID_PARAM; + } + if (dev_cap->bLength < LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) { + usbi_err(ctx, "short dev-cap descriptor read %d/%d", + dev_cap->bLength, LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE); + return LIBUSB_ERROR_IO; + } + + _ss_usb_device_cap = malloc(sizeof(*_ss_usb_device_cap)); + if (!_ss_usb_device_cap) + return LIBUSB_ERROR_NO_MEM; + + usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbwbbw", + _ss_usb_device_cap, host_endian); + + *ss_usb_device_cap = _ss_usb_device_cap; + return LIBUSB_SUCCESS; +} + +/** \ingroup desc + * Free a SuperSpeed USB Device Capability descriptor obtained from + * libusb_get_ss_usb_device_capability_descriptor(). + * It is safe to call this function with a NULL ss_usb_device_cap + * parameter, in which case the function simply returns. + * + * \param ss_usb_device_cap the USB 2.0 Extension descriptor to free + */ +void API_EXPORTED libusb_free_ss_usb_device_capability_descriptor( + struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap) +{ + free(ss_usb_device_cap); +} + +/** \ingroup desc + * Get a Container ID descriptor + * + * \param ctx the context to operate on, or NULL for the default context + * \param dev_cap Device Capability descriptor with a bDevCapabilityType of + * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID + * LIBUSB_BT_CONTAINER_ID + * \param container_id output location for the Container ID descriptor. + * Only valid if 0 was returned. Must be freed with + * libusb_free_container_id_descriptor() after use. + * \returns 0 on success + * \returns a LIBUSB_ERROR code on error + */ +int API_EXPORTED libusb_get_container_id_descriptor(struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_container_id_descriptor **container_id) +{ + struct libusb_container_id_descriptor *_container_id; + const int host_endian = 0; + + if (dev_cap->bDevCapabilityType != LIBUSB_BT_CONTAINER_ID) { + usbi_err(ctx, "unexpected bDevCapabilityType %x (expected %x)", + dev_cap->bDevCapabilityType, + LIBUSB_BT_CONTAINER_ID); + return LIBUSB_ERROR_INVALID_PARAM; + } + if (dev_cap->bLength < LIBUSB_BT_CONTAINER_ID_SIZE) { + usbi_err(ctx, "short dev-cap descriptor read %d/%d", + dev_cap->bLength, LIBUSB_BT_CONTAINER_ID_SIZE); + return LIBUSB_ERROR_IO; + } + + _container_id = malloc(sizeof(*_container_id)); + if (!_container_id) + return LIBUSB_ERROR_NO_MEM; + + usbi_parse_descriptor((unsigned char *)dev_cap, "bbbbu", + _container_id, host_endian); + + *container_id = _container_id; + return LIBUSB_SUCCESS; +} + +/** \ingroup desc + * Free a Container ID descriptor obtained from + * libusb_get_container_id_descriptor(). + * It is safe to call this function with a NULL container_id parameter, + * in which case the function simply returns. + * + * \param container_id the USB 2.0 Extension descriptor to free + */ +void API_EXPORTED libusb_free_container_id_descriptor( + struct libusb_container_id_descriptor *container_id) +{ + free(container_id); +} + +/** \ingroup desc + * Retrieve a string descriptor in C style ASCII. + * + * Wrapper around libusb_get_string_descriptor(). Uses the first language + * supported by the device. + * + * \param dev a device handle + * \param desc_index the index of the descriptor to retrieve + * \param data output buffer for ASCII string descriptor + * \param length size of data buffer + * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev, + uint8_t desc_index, unsigned char *data, int length) +{ + unsigned char tbuf[255]; /* Some devices choke on size > 255 */ + int r, si, di; + uint16_t langid; + + /* Asking for the zero'th index is special - it returns a string + * descriptor that contains all the language IDs supported by the + * device. Typically there aren't many - often only one. Language + * IDs are 16 bit numbers, and they start at the third byte in the + * descriptor. There's also no point in trying to read descriptor 0 + * with this function. See USB 2.0 specification section 9.6.7 for + * more information. + */ + + if (desc_index == 0) + return LIBUSB_ERROR_INVALID_PARAM; + + r = libusb_get_string_descriptor(dev, 0, 0, tbuf, sizeof(tbuf)); + if (r < 0) + return r; + + if (r < 4) + return LIBUSB_ERROR_IO; + + langid = tbuf[2] | (tbuf[3] << 8); + + r = libusb_get_string_descriptor(dev, desc_index, langid, tbuf, + sizeof(tbuf)); + if (r < 0) + return r; + + if (tbuf[1] != LIBUSB_DT_STRING) + return LIBUSB_ERROR_IO; + + if (tbuf[0] > r) + return LIBUSB_ERROR_IO; + + for (di = 0, si = 2; si < tbuf[0]; si += 2) { + if (di >= (length - 1)) + break; + + if ((tbuf[si] & 0x80) || (tbuf[si + 1])) /* non-ASCII */ + data[di++] = '?'; + else + data[di++] = tbuf[si]; + } + + data[di] = 0; + return di; +} diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/descriptor.c.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/descriptor.c.REMOVED.git-id deleted file mode 100644 index 9f8a2167..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/descriptor.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -defcacb1fcaa82a0396e79dc2cb68dc5e908a681 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/hotplug.c b/Desktop_Interface/build_android/libusb-martin-kuldeep/hotplug.c new file mode 100644 index 00000000..779cb6b3 --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/hotplug.c @@ -0,0 +1,350 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * Hotplug functions for libusb + * Copyright © 2012-2013 Nathan Hjelm + * Copyright © 2012-2013 Peter Stuge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#include + +#include "libusbi.h" +#include "hotplug.h" + +/** + * @defgroup hotplug Device hotplug event notification + * This page details how to use the libusb hotplug interface, where available. + * + * Be mindful that not all platforms currently implement hotplug notification and + * that you should first call on \ref libusb_has_capability() with parameter + * \ref LIBUSB_CAP_HAS_HOTPLUG to confirm that hotplug support is available. + * + * \page hotplug Device hotplug event notification + * + * \section hotplug_intro Introduction + * + * Version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, has added support + * for hotplug events on some platforms (you should test if your platform + * supports hotplug notification by calling \ref libusb_has_capability() with + * parameter \ref LIBUSB_CAP_HAS_HOTPLUG). + * + * This interface allows you to request notification for the arrival and departure + * of matching USB devices. + * + * To receive hotplug notification you register a callback by calling + * \ref libusb_hotplug_register_callback(). This function will optionally return + * a handle that can be passed to \ref libusb_hotplug_deregister_callback(). + * + * A callback function must return an int (0 or 1) indicating whether the callback is + * expecting additional events. Returning 0 will rearm the callback and 1 will cause + * the callback to be deregistered. Note that when callbacks are called from + * libusb_hotplug_register_callback() because of the \ref LIBUSB_HOTPLUG_ENUMERATE + * flag, the callback return value is ignored, iow you cannot cause a callback + * to be deregistered by returning 1 when it is called from + * libusb_hotplug_register_callback(). + * + * Callbacks for a particular context are automatically deregistered by libusb_exit(). + * + * As of 1.0.16 there are two supported hotplug events: + * - LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: A device has arrived and is ready to use + * - LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: A device has left and is no longer available + * + * A hotplug event can listen for either or both of these events. + * + * Note: If you receive notification that a device has left and you have any + * a libusb_device_handles for the device it is up to you to call libusb_close() + * on each handle to free up any remaining resources associated with the device. + * Once a device has left any libusb_device_handle associated with the device + * are invalid and will remain so even if the device comes back. + * + * When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED event it is considered + * safe to call any libusb function that takes a libusb_device. It also safe to + * open a device and submit asynchronous transfers. However, most other functions + * that take a libusb_device_handle are not safe to call. Examples of such + * functions are any of the \ref syncio "synchronous API" functions or the blocking + * functions that retrieve various \ref desc "USB descriptors". These functions must + * be used outside of the context of the hotplug callback. + * + * When handling a LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT event the only safe function + * is libusb_get_device_descriptor(). + * + * The following code provides an example of the usage of the hotplug interface: +\code +#include +#include +#include + +static int count = 0; + +int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event, void *user_data) { + static libusb_device_handle *handle = NULL; + struct libusb_device_descriptor desc; + int rc; + + (void)libusb_get_device_descriptor(dev, &desc); + + if (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED == event) { + rc = libusb_open(dev, &handle); + if (LIBUSB_SUCCESS != rc) { + printf("Could not open USB device\n"); + } + } else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) { + if (handle) { + libusb_close(handle); + handle = NULL; + } + } else { + printf("Unhandled event %d\n", event); + } + count++; + + return 0; +} + +int main (void) { + libusb_hotplug_callback_handle handle; + int rc; + + libusb_init(NULL); + + rc = libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | + LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, 0x045a, 0x5005, + LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL, + &handle); + if (LIBUSB_SUCCESS != rc) { + printf("Error creating a hotplug callback\n"); + libusb_exit(NULL); + return EXIT_FAILURE; + } + + while (count < 2) { + libusb_handle_events_completed(NULL, NULL); + usleep(10000); + } + + libusb_hotplug_deregister_callback(NULL, handle); + libusb_exit(NULL); + + return 0; +} +\endcode + */ + +static int usbi_hotplug_match_cb (struct libusb_context *ctx, + struct libusb_device *dev, libusb_hotplug_event event, + struct libusb_hotplug_callback *hotplug_cb) +{ + /* Handle lazy deregistration of callback */ + if (hotplug_cb->needs_free) { + /* Free callback */ + return 1; + } + + if (!(hotplug_cb->events & event)) { + return 0; + } + + if (LIBUSB_HOTPLUG_MATCH_ANY != hotplug_cb->vendor_id && + hotplug_cb->vendor_id != dev->device_descriptor.idVendor) { + return 0; + } + + if (LIBUSB_HOTPLUG_MATCH_ANY != hotplug_cb->product_id && + hotplug_cb->product_id != dev->device_descriptor.idProduct) { + return 0; + } + + if (LIBUSB_HOTPLUG_MATCH_ANY != hotplug_cb->dev_class && + hotplug_cb->dev_class != dev->device_descriptor.bDeviceClass) { + return 0; + } + + return hotplug_cb->cb (ctx, dev, event, hotplug_cb->user_data); +} + +void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event) +{ + struct libusb_hotplug_callback *hotplug_cb, *next; + int ret; + + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + + list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, struct libusb_hotplug_callback) { + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); + ret = usbi_hotplug_match_cb (ctx, dev, event, hotplug_cb); + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + + if (ret) { + list_del(&hotplug_cb->list); + free(hotplug_cb); + } + } + + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); + + /* the backend is expected to call the callback for each active transfer */ +} + +void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event) +{ + int pending_events; + libusb_hotplug_message *message = calloc(1, sizeof(*message)); + + if (!message) { + usbi_err(ctx, "error allocating hotplug message"); + return; + } + + message->event = event; + message->device = dev; + + /* Take the event data lock and add this message to the list. + * Only signal an event if there are no prior pending events. */ + usbi_mutex_lock(&ctx->event_data_lock); + pending_events = usbi_pending_events(ctx); + list_add_tail(&message->list, &ctx->hotplug_msgs); + if (!pending_events) + usbi_signal_event(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); +} + +int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx, + libusb_hotplug_event events, libusb_hotplug_flag flags, + int vendor_id, int product_id, int dev_class, + libusb_hotplug_callback_fn cb_fn, void *user_data, + libusb_hotplug_callback_handle *handle) +{ + libusb_hotplug_callback *new_callback; + static int handle_id = 1; + + /* check for hotplug support */ + if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + return LIBUSB_ERROR_NOT_SUPPORTED; + } + + /* check for sane values */ + if ((LIBUSB_HOTPLUG_MATCH_ANY != vendor_id && (~0xffff & vendor_id)) || + (LIBUSB_HOTPLUG_MATCH_ANY != product_id && (~0xffff & product_id)) || + (LIBUSB_HOTPLUG_MATCH_ANY != dev_class && (~0xff & dev_class)) || + !cb_fn) { + return LIBUSB_ERROR_INVALID_PARAM; + } + + USBI_GET_CONTEXT(ctx); + + new_callback = (libusb_hotplug_callback *)calloc(1, sizeof (*new_callback)); + if (!new_callback) { + return LIBUSB_ERROR_NO_MEM; + } + + new_callback->ctx = ctx; + new_callback->vendor_id = vendor_id; + new_callback->product_id = product_id; + new_callback->dev_class = dev_class; + new_callback->flags = flags; + new_callback->events = events; + new_callback->cb = cb_fn; + new_callback->user_data = user_data; + new_callback->needs_free = 0; + + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + + /* protect the handle by the context hotplug lock. it doesn't matter if the same handle + * is used for different contexts only that the handle is unique for this context */ + new_callback->handle = handle_id++; + + list_add(&new_callback->list, &ctx->hotplug_cbs); + + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); + + + if (flags & LIBUSB_HOTPLUG_ENUMERATE) { + int i, len; + struct libusb_device **devs; + + len = (int) libusb_get_device_list(ctx, &devs); + if (len < 0) { + libusb_hotplug_deregister_callback(ctx, + new_callback->handle); + return len; + } + + for (i = 0; i < len; i++) { + usbi_hotplug_match_cb(ctx, devs[i], + LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, + new_callback); + } + + libusb_free_device_list(devs, 1); + } + + + if (handle) { + *handle = new_callback->handle; + } + + return LIBUSB_SUCCESS; +} + +void API_EXPORTED libusb_hotplug_deregister_callback (struct libusb_context *ctx, + libusb_hotplug_callback_handle handle) +{ + struct libusb_hotplug_callback *hotplug_cb; + + /* check for hotplug support */ + if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) { + return; + } + + USBI_GET_CONTEXT(ctx); + + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list, + struct libusb_hotplug_callback) { + if (handle == hotplug_cb->handle) { + /* Mark this callback for deregistration */ + hotplug_cb->needs_free = 1; + } + } + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); + + usbi_hotplug_notification(ctx, NULL, 0); +} + +void usbi_hotplug_deregister_all(struct libusb_context *ctx) { + struct libusb_hotplug_callback *hotplug_cb, *next; + + usbi_mutex_lock(&ctx->hotplug_cbs_lock); + list_for_each_entry_safe(hotplug_cb, next, &ctx->hotplug_cbs, list, + struct libusb_hotplug_callback) { + list_del(&hotplug_cb->list); + free(hotplug_cb); + } + + usbi_mutex_unlock(&ctx->hotplug_cbs_lock); +} diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/hotplug.c.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/hotplug.c.REMOVED.git-id deleted file mode 100644 index cdf82b55..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/hotplug.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -779cb6b3249990ea0142232a58a73b1bf0a0233a \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/hotplug.h b/Desktop_Interface/build_android/libusb-martin-kuldeep/hotplug.h new file mode 100644 index 00000000..2bec81b0 --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/hotplug.h @@ -0,0 +1,90 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * Hotplug support for libusb + * Copyright © 2012-2013 Nathan Hjelm + * Copyright © 2012-2013 Peter Stuge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined(USBI_HOTPLUG_H) +#define USBI_HOTPLUG_H + +#ifndef LIBUSBI_H +#include "libusbi.h" +#endif + +/** \ingroup hotplug + * The hotplug callback structure. The user populates this structure with + * libusb_hotplug_prepare_callback() and then calls libusb_hotplug_register_callback() + * to receive notification of hotplug events. + */ +struct libusb_hotplug_callback { + /** Context this callback is associated with */ + struct libusb_context *ctx; + + /** Vendor ID to match or LIBUSB_HOTPLUG_MATCH_ANY */ + int vendor_id; + + /** Product ID to match or LIBUSB_HOTPLUG_MATCH_ANY */ + int product_id; + + /** Device class to match or LIBUSB_HOTPLUG_MATCH_ANY */ + int dev_class; + + /** Hotplug callback flags */ + libusb_hotplug_flag flags; + + /** Event(s) that will trigger this callback */ + libusb_hotplug_event events; + + /** Callback function to invoke for matching event/device */ + libusb_hotplug_callback_fn cb; + + /** Handle for this callback (used to match on deregister) */ + libusb_hotplug_callback_handle handle; + + /** User data that will be passed to the callback function */ + void *user_data; + + /** Callback is marked for deletion */ + int needs_free; + + /** List this callback is registered in (ctx->hotplug_cbs) */ + struct list_head list; +}; + +typedef struct libusb_hotplug_callback libusb_hotplug_callback; + +struct libusb_hotplug_message { + /** The hotplug event that occurred */ + libusb_hotplug_event event; + + /** The device for which this hotplug event occurred */ + struct libusb_device *device; + + /** List this message is contained in (ctx->hotplug_msgs) */ + struct list_head list; +}; + +typedef struct libusb_hotplug_message libusb_hotplug_message; + +void usbi_hotplug_deregister_all(struct libusb_context *ctx); +void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event); +void usbi_hotplug_notification(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event); + +#endif diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/hotplug.h.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/hotplug.h.REMOVED.git-id deleted file mode 100644 index 60b9ff15..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/hotplug.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2bec81b06c4275c332e76a2fa8acde12b91e7aac \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/io.c b/Desktop_Interface/build_android/libusb-martin-kuldeep/io.c new file mode 100644 index 00000000..01cf5bec --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/io.c @@ -0,0 +1,2783 @@ +/* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */ +/* + * I/O functions for libusb + * Copyright © 2007-2009 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SIGNAL_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef USBI_TIMERFD_AVAILABLE +#include +#endif + +#include "libusbi.h" +#include "hotplug.h" + +/** + * \page io Synchronous and asynchronous device I/O + * + * \section io_intro Introduction + * + * If you're using libusb in your application, you're probably wanting to + * perform I/O with devices - you want to perform USB data transfers. + * + * libusb offers two separate interfaces for device I/O. This page aims to + * introduce the two in order to help you decide which one is more suitable + * for your application. You can also choose to use both interfaces in your + * application by considering each transfer on a case-by-case basis. + * + * Once you have read through the following discussion, you should consult the + * detailed API documentation pages for the details: + * - \ref syncio + * - \ref asyncio + * + * \section theory Transfers at a logical level + * + * At a logical level, USB transfers typically happen in two parts. For + * example, when reading data from a endpoint: + * -# A request for data is sent to the device + * -# Some time later, the incoming data is received by the host + * + * or when writing data to an endpoint: + * + * -# The data is sent to the device + * -# Some time later, the host receives acknowledgement from the device that + * the data has been transferred. + * + * There may be an indefinite delay between the two steps. Consider a + * fictional USB input device with a button that the user can press. In order + * to determine when the button is pressed, you would likely submit a request + * to read data on a bulk or interrupt endpoint and wait for data to arrive. + * Data will arrive when the button is pressed by the user, which is + * potentially hours later. + * + * libusb offers both a synchronous and an asynchronous interface to performing + * USB transfers. The main difference is that the synchronous interface + * combines both steps indicated above into a single function call, whereas + * the asynchronous interface separates them. + * + * \section sync The synchronous interface + * + * The synchronous I/O interface allows you to perform a USB transfer with + * a single function call. When the function call returns, the transfer has + * completed and you can parse the results. + * + * If you have used the libusb-0.1 before, this I/O style will seem familar to + * you. libusb-0.1 only offered a synchronous interface. + * + * In our input device example, to read button presses you might write code + * in the following style: +\code +unsigned char data[4]; +int actual_length; +int r = libusb_bulk_transfer(handle, LIBUSB_ENDPOINT_IN, data, sizeof(data), &actual_length, 0); +if (r == 0 && actual_length == sizeof(data)) { + // results of the transaction can now be found in the data buffer + // parse them here and report button press +} else { + error(); +} +\endcode + * + * The main advantage of this model is simplicity: you did everything with + * a single simple function call. + * + * However, this interface has its limitations. Your application will sleep + * inside libusb_bulk_transfer() until the transaction has completed. If it + * takes the user 3 hours to press the button, your application will be + * sleeping for that long. Execution will be tied up inside the library - + * the entire thread will be useless for that duration. + * + * Another issue is that by tieing up the thread with that single transaction + * there is no possibility of performing I/O with multiple endpoints and/or + * multiple devices simultaneously, unless you resort to creating one thread + * per transaction. + * + * Additionally, there is no opportunity to cancel the transfer after the + * request has been submitted. + * + * For details on how to use the synchronous API, see the + * \ref syncio "synchronous I/O API documentation" pages. + * + * \section async The asynchronous interface + * + * Asynchronous I/O is the most significant new feature in libusb-1.0. + * Although it is a more complex interface, it solves all the issues detailed + * above. + * + * Instead of providing which functions that block until the I/O has complete, + * libusb's asynchronous interface presents non-blocking functions which + * begin a transfer and then return immediately. Your application passes a + * callback function pointer to this non-blocking function, which libusb will + * call with the results of the transaction when it has completed. + * + * Transfers which have been submitted through the non-blocking functions + * can be cancelled with a separate function call. + * + * The non-blocking nature of this interface allows you to be simultaneously + * performing I/O to multiple endpoints on multiple devices, without having + * to use threads. + * + * This added flexibility does come with some complications though: + * - In the interest of being a lightweight library, libusb does not create + * threads and can only operate when your application is calling into it. Your + * application must call into libusb from it's main loop when events are ready + * to be handled, or you must use some other scheme to allow libusb to + * undertake whatever work needs to be done. + * - libusb also needs to be called into at certain fixed points in time in + * order to accurately handle transfer timeouts. + * - Memory handling becomes more complex. You cannot use stack memory unless + * the function with that stack is guaranteed not to return until the transfer + * callback has finished executing. + * - You generally lose some linearity from your code flow because submitting + * the transfer request is done in a separate function from where the transfer + * results are handled. This becomes particularly obvious when you want to + * submit a second transfer based on the results of an earlier transfer. + * + * Internally, libusb's synchronous interface is expressed in terms of function + * calls to the asynchronous interface. + * + * For details on how to use the asynchronous API, see the + * \ref asyncio "asynchronous I/O API" documentation pages. + */ + + +/** + * \page packetoverflow Packets and overflows + * + * \section packets Packet abstraction + * + * The USB specifications describe how data is transmitted in packets, with + * constraints on packet size defined by endpoint descriptors. The host must + * not send data payloads larger than the endpoint's maximum packet size. + * + * libusb and the underlying OS abstract out the packet concept, allowing you + * to request transfers of any size. Internally, the request will be divided + * up into correctly-sized packets. You do not have to be concerned with + * packet sizes, but there is one exception when considering overflows. + * + * \section overflow Bulk/interrupt transfer overflows + * + * When requesting data on a bulk endpoint, libusb requires you to supply a + * buffer and the maximum number of bytes of data that libusb can put in that + * buffer. However, the size of the buffer is not communicated to the device - + * the device is just asked to send any amount of data. + * + * There is no problem if the device sends an amount of data that is less than + * or equal to the buffer size. libusb reports this condition to you through + * the \ref libusb_transfer::actual_length "libusb_transfer.actual_length" + * field. + * + * Problems may occur if the device attempts to send more data than can fit in + * the buffer. libusb reports LIBUSB_TRANSFER_OVERFLOW for this condition but + * other behaviour is largely undefined: actual_length may or may not be + * accurate, the chunk of data that can fit in the buffer (before overflow) + * may or may not have been transferred. + * + * Overflows are nasty, but can be avoided. Even though you were told to + * ignore packets above, think about the lower level details: each transfer is + * split into packets (typically small, with a maximum size of 512 bytes). + * Overflows can only happen if the final packet in an incoming data transfer + * is smaller than the actual packet that the device wants to transfer. + * Therefore, you will never see an overflow if your transfer buffer size is a + * multiple of the endpoint's packet size: the final packet will either + * fill up completely or will be only partially filled. + */ + +/** + * @defgroup asyncio Asynchronous device I/O + * + * This page details libusb's asynchronous (non-blocking) API for USB device + * I/O. This interface is very powerful but is also quite complex - you will + * need to read this page carefully to understand the necessary considerations + * and issues surrounding use of this interface. Simplistic applications + * may wish to consider the \ref syncio "synchronous I/O API" instead. + * + * The asynchronous interface is built around the idea of separating transfer + * submission and handling of transfer completion (the synchronous model + * combines both of these into one). There may be a long delay between + * submission and completion, however the asynchronous submission function + * is non-blocking so will return control to your application during that + * potentially long delay. + * + * \section asyncabstraction Transfer abstraction + * + * For the asynchronous I/O, libusb implements the concept of a generic + * transfer entity for all types of I/O (control, bulk, interrupt, + * isochronous). The generic transfer object must be treated slightly + * differently depending on which type of I/O you are performing with it. + * + * This is represented by the public libusb_transfer structure type. + * + * \section asynctrf Asynchronous transfers + * + * We can view asynchronous I/O as a 5 step process: + * -# Allocation: allocate a libusb_transfer + * -# Filling: populate the libusb_transfer instance with information + * about the transfer you wish to perform + * -# Submission: ask libusb to submit the transfer + * -# Completion handling: examine transfer results in the + * libusb_transfer structure + * -# Deallocation: clean up resources + * + * + * \subsection asyncalloc Allocation + * + * This step involves allocating memory for a USB transfer. This is the + * generic transfer object mentioned above. At this stage, the transfer + * is "blank" with no details about what type of I/O it will be used for. + * + * Allocation is done with the libusb_alloc_transfer() function. You must use + * this function rather than allocating your own transfers. + * + * \subsection asyncfill Filling + * + * This step is where you take a previously allocated transfer and fill it + * with information to determine the message type and direction, data buffer, + * callback function, etc. + * + * You can either fill the required fields yourself or you can use the + * helper functions: libusb_fill_control_transfer(), libusb_fill_bulk_transfer() + * and libusb_fill_interrupt_transfer(). + * + * \subsection asyncsubmit Submission + * + * When you have allocated a transfer and filled it, you can submit it using + * libusb_submit_transfer(). This function returns immediately but can be + * regarded as firing off the I/O request in the background. + * + * \subsection asynccomplete Completion handling + * + * After a transfer has been submitted, one of four things can happen to it: + * + * - The transfer completes (i.e. some data was transferred) + * - The transfer has a timeout and the timeout expires before all data is + * transferred + * - The transfer fails due to an error + * - The transfer is cancelled + * + * Each of these will cause the user-specified transfer callback function to + * be invoked. It is up to the callback function to determine which of the + * above actually happened and to act accordingly. + * + * The user-specified callback is passed a pointer to the libusb_transfer + * structure which was used to setup and submit the transfer. At completion + * time, libusb has populated this structure with results of the transfer: + * success or failure reason, number of bytes of data transferred, etc. See + * the libusb_transfer structure documentation for more information. + * + * Important Note: The user-specified callback is called from an event + * handling context. It is therefore important that no calls are made into + * libusb that will attempt to perform any event handling. Examples of such + * functions are any listed in the \ref syncio "synchronous API" and any of + * the blocking functions that retrieve \ref desc "USB descriptors". + * + * \subsection Deallocation + * + * When a transfer has completed (i.e. the callback function has been invoked), + * you are advised to free the transfer (unless you wish to resubmit it, see + * below). Transfers are deallocated with libusb_free_transfer(). + * + * It is undefined behaviour to free a transfer which has not completed. + * + * \section asyncresubmit Resubmission + * + * You may be wondering why allocation, filling, and submission are all + * separated above where they could reasonably be combined into a single + * operation. + * + * The reason for separation is to allow you to resubmit transfers without + * having to allocate new ones every time. This is especially useful for + * common situations dealing with interrupt endpoints - you allocate one + * transfer, fill and submit it, and when it returns with results you just + * resubmit it for the next interrupt. + * + * \section asynccancel Cancellation + * + * Another advantage of using the asynchronous interface is that you have + * the ability to cancel transfers which have not yet completed. This is + * done by calling the libusb_cancel_transfer() function. + * + * libusb_cancel_transfer() is asynchronous/non-blocking in itself. When the + * cancellation actually completes, the transfer's callback function will + * be invoked, and the callback function should check the transfer status to + * determine that it was cancelled. + * + * Freeing the transfer after it has been cancelled but before cancellation + * has completed will result in undefined behaviour. + * + * When a transfer is cancelled, some of the data may have been transferred. + * libusb will communicate this to you in the transfer callback. Do not assume + * that no data was transferred. + * + * \section bulk_overflows Overflows on device-to-host bulk/interrupt endpoints + * + * If your device does not have predictable transfer sizes (or it misbehaves), + * your application may submit a request for data on an IN endpoint which is + * smaller than the data that the device wishes to send. In some circumstances + * this will cause an overflow, which is a nasty condition to deal with. See + * the \ref packetoverflow page for discussion. + * + * \section asyncctrl Considerations for control transfers + * + * The libusb_transfer structure is generic and hence does not + * include specific fields for the control-specific setup packet structure. + * + * In order to perform a control transfer, you must place the 8-byte setup + * packet at the start of the data buffer. To simplify this, you could + * cast the buffer pointer to type struct libusb_control_setup, or you can + * use the helper function libusb_fill_control_setup(). + * + * The wLength field placed in the setup packet must be the length you would + * expect to be sent in the setup packet: the length of the payload that + * follows (or the expected maximum number of bytes to receive). However, + * the length field of the libusb_transfer object must be the length of + * the data buffer - i.e. it should be wLength plus the size of + * the setup packet (LIBUSB_CONTROL_SETUP_SIZE). + * + * If you use the helper functions, this is simplified for you: + * -# Allocate a buffer of size LIBUSB_CONTROL_SETUP_SIZE plus the size of the + * data you are sending/requesting. + * -# Call libusb_fill_control_setup() on the data buffer, using the transfer + * request size as the wLength value (i.e. do not include the extra space you + * allocated for the control setup). + * -# If this is a host-to-device transfer, place the data to be transferred + * in the data buffer, starting at offset LIBUSB_CONTROL_SETUP_SIZE. + * -# Call libusb_fill_control_transfer() to associate the data buffer with + * the transfer (and to set the remaining details such as callback and timeout). + * - Note that there is no parameter to set the length field of the transfer. + * The length is automatically inferred from the wLength field of the setup + * packet. + * -# Submit the transfer. + * + * The multi-byte control setup fields (wValue, wIndex and wLength) must + * be given in little-endian byte order (the endianness of the USB bus). + * Endianness conversion is transparently handled by + * libusb_fill_control_setup() which is documented to accept host-endian + * values. + * + * Further considerations are needed when handling transfer completion in + * your callback function: + * - As you might expect, the setup packet will still be sitting at the start + * of the data buffer. + * - If this was a device-to-host transfer, the received data will be sitting + * at offset LIBUSB_CONTROL_SETUP_SIZE into the buffer. + * - The actual_length field of the transfer structure is relative to the + * wLength of the setup packet, rather than the size of the data buffer. So, + * if your wLength was 4, your transfer's length was 12, then you + * should expect an actual_length of 4 to indicate that the data was + * transferred in entirity. + * + * To simplify parsing of setup packets and obtaining the data from the + * correct offset, you may wish to use the libusb_control_transfer_get_data() + * and libusb_control_transfer_get_setup() functions within your transfer + * callback. + * + * Even though control endpoints do not halt, a completed control transfer + * may have a LIBUSB_TRANSFER_STALL status code. This indicates the control + * request was not supported. + * + * \section asyncintr Considerations for interrupt transfers + * + * All interrupt transfers are performed using the polling interval presented + * by the bInterval value of the endpoint descriptor. + * + * \section asynciso Considerations for isochronous transfers + * + * Isochronous transfers are more complicated than transfers to + * non-isochronous endpoints. + * + * To perform I/O to an isochronous endpoint, allocate the transfer by calling + * libusb_alloc_transfer() with an appropriate number of isochronous packets. + * + * During filling, set \ref libusb_transfer::type "type" to + * \ref libusb_transfer_type::LIBUSB_TRANSFER_TYPE_ISOCHRONOUS + * "LIBUSB_TRANSFER_TYPE_ISOCHRONOUS", and set + * \ref libusb_transfer::num_iso_packets "num_iso_packets" to a value less than + * or equal to the number of packets you requested during allocation. + * libusb_alloc_transfer() does not set either of these fields for you, given + * that you might not even use the transfer on an isochronous endpoint. + * + * Next, populate the length field for the first num_iso_packets entries in + * the \ref libusb_transfer::iso_packet_desc "iso_packet_desc" array. Section + * 5.6.3 of the USB2 specifications describe how the maximum isochronous + * packet length is determined by the wMaxPacketSize field in the endpoint + * descriptor. + * Two functions can help you here: + * + * - libusb_get_max_iso_packet_size() is an easy way to determine the max + * packet size for an isochronous endpoint. Note that the maximum packet + * size is actually the maximum number of bytes that can be transmitted in + * a single microframe, therefore this function multiplies the maximum number + * of bytes per transaction by the number of transaction opportunities per + * microframe. + * - libusb_set_iso_packet_lengths() assigns the same length to all packets + * within a transfer, which is usually what you want. + * + * For outgoing transfers, you'll obviously fill the buffer and populate the + * packet descriptors in hope that all the data gets transferred. For incoming + * transfers, you must ensure the buffer has sufficient capacity for + * the situation where all packets transfer the full amount of requested data. + * + * Completion handling requires some extra consideration. The + * \ref libusb_transfer::actual_length "actual_length" field of the transfer + * is meaningless and should not be examined; instead you must refer to the + * \ref libusb_iso_packet_descriptor::actual_length "actual_length" field of + * each individual packet. + * + * The \ref libusb_transfer::status "status" field of the transfer is also a + * little misleading: + * - If the packets were submitted and the isochronous data microframes + * completed normally, status will have value + * \ref libusb_transfer_status::LIBUSB_TRANSFER_COMPLETED + * "LIBUSB_TRANSFER_COMPLETED". Note that bus errors and software-incurred + * delays are not counted as transfer errors; the transfer.status field may + * indicate COMPLETED even if some or all of the packets failed. Refer to + * the \ref libusb_iso_packet_descriptor::status "status" field of each + * individual packet to determine packet failures. + * - The status field will have value + * \ref libusb_transfer_status::LIBUSB_TRANSFER_ERROR + * "LIBUSB_TRANSFER_ERROR" only when serious errors were encountered. + * - Other transfer status codes occur with normal behaviour. + * + * The data for each packet will be found at an offset into the buffer that + * can be calculated as if each prior packet completed in full. The + * libusb_get_iso_packet_buffer() and libusb_get_iso_packet_buffer_simple() + * functions may help you here. + * + * Note: Some operating systems (e.g. Linux) may impose limits on the + * length of individual isochronous packets and/or the total length of the + * isochronous transfer. Such limits can be difficult for libusb to detect, + * so the library will simply try and submit the transfer as set up by you. + * If the transfer fails to submit because it is too large, + * libusb_submit_transfer() will return + * \ref libusb_error::LIBUSB_ERROR_INVALID_PARAM "LIBUSB_ERROR_INVALID_PARAM". + * + * \section asyncmem Memory caveats + * + * In most circumstances, it is not safe to use stack memory for transfer + * buffers. This is because the function that fired off the asynchronous + * transfer may return before libusb has finished using the buffer, and when + * the function returns it's stack gets destroyed. This is true for both + * host-to-device and device-to-host transfers. + * + * The only case in which it is safe to use stack memory is where you can + * guarantee that the function owning the stack space for the buffer does not + * return until after the transfer's callback function has completed. In every + * other case, you need to use heap memory instead. + * + * \section asyncflags Fine control + * + * Through using this asynchronous interface, you may find yourself repeating + * a few simple operations many times. You can apply a bitwise OR of certain + * flags to a transfer to simplify certain things: + * - \ref libusb_transfer_flags::LIBUSB_TRANSFER_SHORT_NOT_OK + * "LIBUSB_TRANSFER_SHORT_NOT_OK" results in transfers which transferred + * less than the requested amount of data being marked with status + * \ref libusb_transfer_status::LIBUSB_TRANSFER_ERROR "LIBUSB_TRANSFER_ERROR" + * (they would normally be regarded as COMPLETED) + * - \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_BUFFER + * "LIBUSB_TRANSFER_FREE_BUFFER" allows you to ask libusb to free the transfer + * buffer when freeing the transfer. + * - \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_TRANSFER + * "LIBUSB_TRANSFER_FREE_TRANSFER" causes libusb to automatically free the + * transfer after the transfer callback returns. + * + * \section asyncevent Event handling + * + * An asynchronous model requires that libusb perform work at various + * points in time - namely processing the results of previously-submitted + * transfers and invoking the user-supplied callback function. + * + * This gives rise to the libusb_handle_events() function which your + * application must call into when libusb has work do to. This gives libusb + * the opportunity to reap pending transfers, invoke callbacks, etc. + * + * There are 2 different approaches to dealing with libusb_handle_events: + * + * -# Repeatedly call libusb_handle_events() in blocking mode from a dedicated + * thread. + * -# Integrate libusb with your application's main event loop. libusb + * exposes a set of file descriptors which allow you to do this. + * + * The first approach has the big advantage that it will also work on Windows + * were libusb' poll API for select / poll integration is not available. So + * if you want to support Windows and use the async API, you must use this + * approach, see the \ref eventthread "Using an event handling thread" section + * below for details. + * + * If you prefer a single threaded approach with a single central event loop, + * see the \ref poll "polling and timing" section for how to integrate libusb + * into your application's main event loop. + * + * \section eventthread Using an event handling thread + * + * Lets begin with stating the obvious: If you're going to use a separate + * thread for libusb event handling, your callback functions MUST be + * threadsafe. + * + * Other then that doing event handling from a separate thread, is mostly + * simple. You can use an event thread function as follows: +\code +void *event_thread_func(void *ctx) +{ + while (event_thread_run) + libusb_handle_events(ctx); + + return NULL; +} +\endcode + * + * There is one caveat though, stopping this thread requires setting the + * event_thread_run variable to 0, and after that libusb_handle_events() needs + * to return control to event_thread_func. But unless some event happens, + * libusb_handle_events() will not return. + * + * There are 2 different ways of dealing with this, depending on if your + * application uses libusb' \ref hotplug "hotplug" support or not. + * + * Applications which do not use hotplug support, should not start the event + * thread until after their first call to libusb_open(), and should stop the + * thread when closing the last open device as follows: +\code +void my_close_handle(libusb_device_handle *handle) +{ + if (open_devs == 1) + event_thread_run = 0; + + libusb_close(handle); // This wakes up libusb_handle_events() + + if (open_devs == 1) + pthread_join(event_thread); + + open_devs--; +} +\endcode + * + * Applications using hotplug support should start the thread at program init, + * after having successfully called libusb_hotplug_register_callback(), and + * should stop the thread at program exit as follows: +\code +void my_libusb_exit(void) +{ + event_thread_run = 0; + libusb_hotplug_deregister_callback(ctx, hotplug_cb_handle); // This wakes up libusb_handle_events() + pthread_join(event_thread); + libusb_exit(ctx); +} +\endcode + */ + +/** + * @defgroup poll Polling and timing + * + * This page documents libusb's functions for polling events and timing. + * These functions are only necessary for users of the + * \ref asyncio "asynchronous API". If you are only using the simpler + * \ref syncio "synchronous API" then you do not need to ever call these + * functions. + * + * The justification for the functionality described here has already been + * discussed in the \ref asyncevent "event handling" section of the + * asynchronous API documentation. In summary, libusb does not create internal + * threads for event processing and hence relies on your application calling + * into libusb at certain points in time so that pending events can be handled. + * + * Your main loop is probably already calling poll() or select() or a + * variant on a set of file descriptors for other event sources (e.g. keyboard + * button presses, mouse movements, network sockets, etc). You then add + * libusb's file descriptors to your poll()/select() calls, and when activity + * is detected on such descriptors you know it is time to call + * libusb_handle_events(). + * + * There is one final event handling complication. libusb supports + * asynchronous transfers which time out after a specified time period. + * + * On some platforms a timerfd is used, so the timeout handling is just another + * fd, on other platforms this requires that libusb is called into at or after + * the timeout to handle it. So, in addition to considering libusb's file + * descriptors in your main event loop, you must also consider that libusb + * sometimes needs to be called into at fixed points in time even when there + * is no file descriptor activity, see \ref polltime details. + * + * In order to know precisely when libusb needs to be called into, libusb + * offers you a set of pollable file descriptors and information about when + * the next timeout expires. + * + * If you are using the asynchronous I/O API, you must take one of the two + * following options, otherwise your I/O will not complete. + * + * \section pollsimple The simple option + * + * If your application revolves solely around libusb and does not need to + * handle other event sources, you can have a program structure as follows: +\code +// initialize libusb +// find and open device +// maybe fire off some initial async I/O + +while (user_has_not_requested_exit) + libusb_handle_events(ctx); + +// clean up and exit +\endcode + * + * With such a simple main loop, you do not have to worry about managing + * sets of file descriptors or handling timeouts. libusb_handle_events() will + * handle those details internally. + * + * \section pollmain The more advanced option + * + * \note This functionality is currently only available on Unix-like platforms. + * On Windows, libusb_get_pollfds() simply returns NULL. Applications which + * want to support Windows are advised to use an \ref eventthread + * "event handling thread" instead. + * + * In more advanced applications, you will already have a main loop which + * is monitoring other event sources: network sockets, X11 events, mouse + * movements, etc. Through exposing a set of file descriptors, libusb is + * designed to cleanly integrate into such main loops. + * + * In addition to polling file descriptors for the other event sources, you + * take a set of file descriptors from libusb and monitor those too. When you + * detect activity on libusb's file descriptors, you call + * libusb_handle_events_timeout() in non-blocking mode. + * + * What's more, libusb may also need to handle events at specific moments in + * time. No file descriptor activity is generated at these times, so your + * own application needs to be continually aware of when the next one of these + * moments occurs (through calling libusb_get_next_timeout()), and then it + * needs to call libusb_handle_events_timeout() in non-blocking mode when + * these moments occur. This means that you need to adjust your + * poll()/select() timeout accordingly. + * + * libusb provides you with a set of file descriptors to poll and expects you + * to poll all of them, treating them as a single entity. The meaning of each + * file descriptor in the set is an internal implementation detail, + * platform-dependent and may vary from release to release. Don't try and + * interpret the meaning of the file descriptors, just do as libusb indicates, + * polling all of them at once. + * + * In pseudo-code, you want something that looks like: +\code +// initialise libusb + +libusb_get_pollfds(ctx) +while (user has not requested application exit) { + libusb_get_next_timeout(ctx); + poll(on libusb file descriptors plus any other event sources of interest, + using a timeout no larger than the value libusb just suggested) + if (poll() indicated activity on libusb file descriptors) + libusb_handle_events_timeout(ctx, &zero_tv); + if (time has elapsed to or beyond the libusb timeout) + libusb_handle_events_timeout(ctx, &zero_tv); + // handle events from other sources here +} + +// clean up and exit +\endcode + * + * \subsection polltime Notes on time-based events + * + * The above complication with having to track time and call into libusb at + * specific moments is a bit of a headache. For maximum compatibility, you do + * need to write your main loop as above, but you may decide that you can + * restrict the supported platforms of your application and get away with + * a more simplistic scheme. + * + * These time-based event complications are \b not required on the following + * platforms: + * - Darwin + * - Linux, provided that the following version requirements are satisfied: + * - Linux v2.6.27 or newer, compiled with timerfd support + * - glibc v2.9 or newer + * - libusb v1.0.5 or newer + * + * Under these configurations, libusb_get_next_timeout() will \em always return + * 0, so your main loop can be simplified to: +\code +// initialise libusb + +libusb_get_pollfds(ctx) +while (user has not requested application exit) { + poll(on libusb file descriptors plus any other event sources of interest, + using any timeout that you like) + if (poll() indicated activity on libusb file descriptors) + libusb_handle_events_timeout(ctx, &zero_tv); + // handle events from other sources here +} + +// clean up and exit +\endcode + * + * Do remember that if you simplify your main loop to the above, you will + * lose compatibility with some platforms (including legacy Linux platforms, + * and any future platforms supported by libusb which may have time-based + * event requirements). The resultant problems will likely appear as + * strange bugs in your application. + * + * You can use the libusb_pollfds_handle_timeouts() function to do a runtime + * check to see if it is safe to ignore the time-based event complications. + * If your application has taken the shortcut of ignoring libusb's next timeout + * in your main loop, then you are advised to check the return value of + * libusb_pollfds_handle_timeouts() during application startup, and to abort + * if the platform does suffer from these timing complications. + * + * \subsection fdsetchange Changes in the file descriptor set + * + * The set of file descriptors that libusb uses as event sources may change + * during the life of your application. Rather than having to repeatedly + * call libusb_get_pollfds(), you can set up notification functions for when + * the file descriptor set changes using libusb_set_pollfd_notifiers(). + * + * \subsection mtissues Multi-threaded considerations + * + * Unfortunately, the situation is complicated further when multiple threads + * come into play. If two threads are monitoring the same file descriptors, + * the fact that only one thread will be woken up when an event occurs causes + * some headaches. + * + * The events lock, event waiters lock, and libusb_handle_events_locked() + * entities are added to solve these problems. You do not need to be concerned + * with these entities otherwise. + * + * See the extra documentation: \ref mtasync + */ + +/** \page mtasync Multi-threaded applications and asynchronous I/O + * + * libusb is a thread-safe library, but extra considerations must be applied + * to applications which interact with libusb from multiple threads. + * + * The underlying issue that must be addressed is that all libusb I/O + * revolves around monitoring file descriptors through the poll()/select() + * system calls. This is directly exposed at the + * \ref asyncio "asynchronous interface" but it is important to note that the + * \ref syncio "synchronous interface" is implemented on top of the + * asynchonrous interface, therefore the same considerations apply. + * + * The issue is that if two or more threads are concurrently calling poll() + * or select() on libusb's file descriptors then only one of those threads + * will be woken up when an event arrives. The others will be completely + * oblivious that anything has happened. + * + * Consider the following pseudo-code, which submits an asynchronous transfer + * then waits for its completion. This style is one way you could implement a + * synchronous interface on top of the asynchronous interface (and libusb + * does something similar, albeit more advanced due to the complications + * explained on this page). + * +\code +void cb(struct libusb_transfer *transfer) +{ + int *completed = transfer->user_data; + *completed = 1; +} + +void myfunc() { + struct libusb_transfer *transfer; + unsigned char buffer[LIBUSB_CONTROL_SETUP_SIZE] __attribute__ ((aligned (2))); + int completed = 0; + + transfer = libusb_alloc_transfer(0); + libusb_fill_control_setup(buffer, + LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT, 0x04, 0x01, 0, 0); + libusb_fill_control_transfer(transfer, dev, buffer, cb, &completed, 1000); + libusb_submit_transfer(transfer); + + while (!completed) { + poll(libusb file descriptors, 120*1000); + if (poll indicates activity) + libusb_handle_events_timeout(ctx, &zero_tv); + } + printf("completed!"); + // other code here +} +\endcode + * + * Here we are serializing completion of an asynchronous event + * against a condition - the condition being completion of a specific transfer. + * The poll() loop has a long timeout to minimize CPU usage during situations + * when nothing is happening (it could reasonably be unlimited). + * + * If this is the only thread that is polling libusb's file descriptors, there + * is no problem: there is no danger that another thread will swallow up the + * event that we are interested in. On the other hand, if there is another + * thread polling the same descriptors, there is a chance that it will receive + * the event that we were interested in. In this situation, myfunc() + * will only realise that the transfer has completed on the next iteration of + * the loop, up to 120 seconds later. Clearly a two-minute delay is + * undesirable, and don't even think about using short timeouts to circumvent + * this issue! + * + * The solution here is to ensure that no two threads are ever polling the + * file descriptors at the same time. A naive implementation of this would + * impact the capabilities of the library, so libusb offers the scheme + * documented below to ensure no loss of functionality. + * + * Before we go any further, it is worth mentioning that all libusb-wrapped + * event handling procedures fully adhere to the scheme documented below. + * This includes libusb_handle_events() and its variants, and all the + * synchronous I/O functions - libusb hides this headache from you. + * + * \section Using libusb_handle_events() from multiple threads + * + * Even when only using libusb_handle_events() and synchronous I/O functions, + * you can still have a race condition. You might be tempted to solve the + * above with libusb_handle_events() like so: + * +\code + libusb_submit_transfer(transfer); + + while (!completed) { + libusb_handle_events(ctx); + } + printf("completed!"); +\endcode + * + * This however has a race between the checking of completed and + * libusb_handle_events() acquiring the events lock, so another thread + * could have completed the transfer, resulting in this thread hanging + * until either a timeout or another event occurs. See also commit + * 6696512aade99bb15d6792af90ae329af270eba6 which fixes this in the + * synchronous API implementation of libusb. + * + * Fixing this race requires checking the variable completed only after + * taking the event lock, which defeats the concept of just calling + * libusb_handle_events() without worrying about locking. This is why + * libusb-1.0.9 introduces the new libusb_handle_events_timeout_completed() + * and libusb_handle_events_completed() functions, which handles doing the + * completion check for you after they have acquired the lock: + * +\code + libusb_submit_transfer(transfer); + + while (!completed) { + libusb_handle_events_completed(ctx, &completed); + } + printf("completed!"); +\endcode + * + * This nicely fixes the race in our example. Note that if all you want to + * do is submit a single transfer and wait for its completion, then using + * one of the synchronous I/O functions is much easier. + * + * \section eventlock The events lock + * + * The problem is when we consider the fact that libusb exposes file + * descriptors to allow for you to integrate asynchronous USB I/O into + * existing main loops, effectively allowing you to do some work behind + * libusb's back. If you do take libusb's file descriptors and pass them to + * poll()/select() yourself, you need to be aware of the associated issues. + * + * The first concept to be introduced is the events lock. The events lock + * is used to serialize threads that want to handle events, such that only + * one thread is handling events at any one time. + * + * You must take the events lock before polling libusb file descriptors, + * using libusb_lock_events(). You must release the lock as soon as you have + * aborted your poll()/select() loop, using libusb_unlock_events(). + * + * \section threadwait Letting other threads do the work for you + * + * Although the events lock is a critical part of the solution, it is not + * enough on it's own. You might wonder if the following is sufficient... +\code + libusb_lock_events(ctx); + while (!completed) { + poll(libusb file descriptors, 120*1000); + if (poll indicates activity) + libusb_handle_events_timeout(ctx, &zero_tv); + } + libusb_unlock_events(ctx); +\endcode + * ...and the answer is that it is not. This is because the transfer in the + * code shown above may take a long time (say 30 seconds) to complete, and + * the lock is not released until the transfer is completed. + * + * Another thread with similar code that wants to do event handling may be + * working with a transfer that completes after a few milliseconds. Despite + * having such a quick completion time, the other thread cannot check that + * status of its transfer until the code above has finished (30 seconds later) + * due to contention on the lock. + * + * To solve this, libusb offers you a mechanism to determine when another + * thread is handling events. It also offers a mechanism to block your thread + * until the event handling thread has completed an event (and this mechanism + * does not involve polling of file descriptors). + * + * After determining that another thread is currently handling events, you + * obtain the event waiters lock using libusb_lock_event_waiters(). + * You then re-check that some other thread is still handling events, and if + * so, you call libusb_wait_for_event(). + * + * libusb_wait_for_event() puts your application to sleep until an event + * occurs, or until a thread releases the events lock. When either of these + * things happen, your thread is woken up, and should re-check the condition + * it was waiting on. It should also re-check that another thread is handling + * events, and if not, it should start handling events itself. + * + * This looks like the following, as pseudo-code: +\code +retry: +if (libusb_try_lock_events(ctx) == 0) { + // we obtained the event lock: do our own event handling + while (!completed) { + if (!libusb_event_handling_ok(ctx)) { + libusb_unlock_events(ctx); + goto retry; + } + poll(libusb file descriptors, 120*1000); + if (poll indicates activity) + libusb_handle_events_locked(ctx, 0); + } + libusb_unlock_events(ctx); +} else { + // another thread is doing event handling. wait for it to signal us that + // an event has completed + libusb_lock_event_waiters(ctx); + + while (!completed) { + // now that we have the event waiters lock, double check that another + // thread is still handling events for us. (it may have ceased handling + // events in the time it took us to reach this point) + if (!libusb_event_handler_active(ctx)) { + // whoever was handling events is no longer doing so, try again + libusb_unlock_event_waiters(ctx); + goto retry; + } + + libusb_wait_for_event(ctx, NULL); + } + libusb_unlock_event_waiters(ctx); +} +printf("completed!\n"); +\endcode + * + * A naive look at the above code may suggest that this can only support + * one event waiter (hence a total of 2 competing threads, the other doing + * event handling), because the event waiter seems to have taken the event + * waiters lock while waiting for an event. However, the system does support + * multiple event waiters, because libusb_wait_for_event() actually drops + * the lock while waiting, and reaquires it before continuing. + * + * We have now implemented code which can dynamically handle situations where + * nobody is handling events (so we should do it ourselves), and it can also + * handle situations where another thread is doing event handling (so we can + * piggyback onto them). It is also equipped to handle a combination of + * the two, for example, another thread is doing event handling, but for + * whatever reason it stops doing so before our condition is met, so we take + * over the event handling. + * + * Four functions were introduced in the above pseudo-code. Their importance + * should be apparent from the code shown above. + * -# libusb_try_lock_events() is a non-blocking function which attempts + * to acquire the events lock but returns a failure code if it is contended. + * -# libusb_event_handling_ok() checks that libusb is still happy for your + * thread to be performing event handling. Sometimes, libusb needs to + * interrupt the event handler, and this is how you can check if you have + * been interrupted. If this function returns 0, the correct behaviour is + * for you to give up the event handling lock, and then to repeat the cycle. + * The following libusb_try_lock_events() will fail, so you will become an + * events waiter. For more information on this, read \ref fullstory below. + * -# libusb_handle_events_locked() is a variant of + * libusb_handle_events_timeout() that you can call while holding the + * events lock. libusb_handle_events_timeout() itself implements similar + * logic to the above, so be sure not to call it when you are + * "working behind libusb's back", as is the case here. + * -# libusb_event_handler_active() determines if someone is currently + * holding the events lock + * + * You might be wondering why there is no function to wake up all threads + * blocked on libusb_wait_for_event(). This is because libusb can do this + * internally: it will wake up all such threads when someone calls + * libusb_unlock_events() or when a transfer completes (at the point after its + * callback has returned). + * + * \subsection fullstory The full story + * + * The above explanation should be enough to get you going, but if you're + * really thinking through the issues then you may be left with some more + * questions regarding libusb's internals. If you're curious, read on, and if + * not, skip to the next section to avoid confusing yourself! + * + * The immediate question that may spring to mind is: what if one thread + * modifies the set of file descriptors that need to be polled while another + * thread is doing event handling? + * + * There are 2 situations in which this may happen. + * -# libusb_open() will add another file descriptor to the poll set, + * therefore it is desirable to interrupt the event handler so that it + * restarts, picking up the new descriptor. + * -# libusb_close() will remove a file descriptor from the poll set. There + * are all kinds of race conditions that could arise here, so it is + * important that nobody is doing event handling at this time. + * + * libusb handles these issues internally, so application developers do not + * have to stop their event handlers while opening/closing devices. Here's how + * it works, focusing on the libusb_close() situation first: + * + * -# During initialization, libusb opens an internal pipe, and it adds the read + * end of this pipe to the set of file descriptors to be polled. + * -# During libusb_close(), libusb writes some dummy data on this event pipe. + * This immediately interrupts the event handler. libusb also records + * internally that it is trying to interrupt event handlers for this + * high-priority event. + * -# At this point, some of the functions described above start behaving + * differently: + * - libusb_event_handling_ok() starts returning 1, indicating that it is NOT + * OK for event handling to continue. + * - libusb_try_lock_events() starts returning 1, indicating that another + * thread holds the event handling lock, even if the lock is uncontended. + * - libusb_event_handler_active() starts returning 1, indicating that + * another thread is doing event handling, even if that is not true. + * -# The above changes in behaviour result in the event handler stopping and + * giving up the events lock very quickly, giving the high-priority + * libusb_close() operation a "free ride" to acquire the events lock. All + * threads that are competing to do event handling become event waiters. + * -# With the events lock held inside libusb_close(), libusb can safely remove + * a file descriptor from the poll set, in the safety of knowledge that + * nobody is polling those descriptors or trying to access the poll set. + * -# After obtaining the events lock, the close operation completes very + * quickly (usually a matter of milliseconds) and then immediately releases + * the events lock. + * -# At the same time, the behaviour of libusb_event_handling_ok() and friends + * reverts to the original, documented behaviour. + * -# The release of the events lock causes the threads that are waiting for + * events to be woken up and to start competing to become event handlers + * again. One of them will succeed; it will then re-obtain the list of poll + * descriptors, and USB I/O will then continue as normal. + * + * libusb_open() is similar, and is actually a more simplistic case. Upon a + * call to libusb_open(): + * + * -# The device is opened and a file descriptor is added to the poll set. + * -# libusb sends some dummy data on the event pipe, and records that it + * is trying to modify the poll descriptor set. + * -# The event handler is interrupted, and the same behaviour change as for + * libusb_close() takes effect, causing all event handling threads to become + * event waiters. + * -# The libusb_open() implementation takes its free ride to the events lock. + * -# Happy that it has successfully paused the events handler, libusb_open() + * releases the events lock. + * -# The event waiter threads are all woken up and compete to become event + * handlers again. The one that succeeds will obtain the list of poll + * descriptors again, which will include the addition of the new device. + * + * \subsection concl Closing remarks + * + * The above may seem a little complicated, but hopefully I have made it clear + * why such complications are necessary. Also, do not forget that this only + * applies to applications that take libusb's file descriptors and integrate + * them into their own polling loops. + * + * You may decide that it is OK for your multi-threaded application to ignore + * some of the rules and locks detailed above, because you don't think that + * two threads can ever be polling the descriptors at the same time. If that + * is the case, then that's good news for you because you don't have to worry. + * But be careful here; remember that the synchronous I/O functions do event + * handling internally. If you have one thread doing event handling in a loop + * (without implementing the rules and locking semantics documented above) + * and another trying to send a synchronous USB transfer, you will end up with + * two threads monitoring the same descriptors, and the above-described + * undesirable behaviour occuring. The solution is for your polling thread to + * play by the rules; the synchronous I/O functions do so, and this will result + * in them getting along in perfect harmony. + * + * If you do have a dedicated thread doing event handling, it is perfectly + * legal for it to take the event handling lock for long periods of time. Any + * synchronous I/O functions you call from other threads will transparently + * fall back to the "event waiters" mechanism detailed above. The only + * consideration that your event handling thread must apply is the one related + * to libusb_event_handling_ok(): you must call this before every poll(), and + * give up the events lock if instructed. + */ + +int usbi_io_init(struct libusb_context *ctx) +{ + int r; + + usbi_mutex_init(&ctx->flying_transfers_lock, NULL); + usbi_mutex_init_recursive(&ctx->events_lock, NULL); + usbi_mutex_init(&ctx->event_waiters_lock, NULL); + usbi_cond_init(&ctx->event_waiters_cond, NULL); + usbi_mutex_init(&ctx->event_data_lock, NULL); + usbi_tls_key_create(&ctx->event_handling_key, NULL); + list_init(&ctx->flying_transfers); + list_init(&ctx->ipollfds); + list_init(&ctx->hotplug_msgs); + list_init(&ctx->completed_transfers); + + /* FIXME should use an eventfd on kernels that support it */ + r = usbi_pipe(ctx->event_pipe); + if (r < 0) { + r = LIBUSB_ERROR_OTHER; + goto err; + } + + r = usbi_add_pollfd(ctx, ctx->event_pipe[0], POLLIN); + if (r < 0) + goto err_close_pipe; + +#ifdef USBI_TIMERFD_AVAILABLE + ctx->timerfd = timerfd_create(usbi_backend->get_timerfd_clockid(), + TFD_NONBLOCK); + if (ctx->timerfd >= 0) { + usbi_dbg("using timerfd for timeouts"); + r = usbi_add_pollfd(ctx, ctx->timerfd, POLLIN); + if (r < 0) + goto err_close_timerfd; + } else { + usbi_dbg("timerfd not available (code %d error %d)", ctx->timerfd, errno); + ctx->timerfd = -1; + } +#endif + + return 0; + +#ifdef USBI_TIMERFD_AVAILABLE +err_close_timerfd: + close(ctx->timerfd); + usbi_remove_pollfd(ctx, ctx->event_pipe[0]); +#endif +err_close_pipe: + usbi_close(ctx->event_pipe[0]); + usbi_close(ctx->event_pipe[1]); +err: + usbi_mutex_destroy(&ctx->flying_transfers_lock); + usbi_mutex_destroy(&ctx->events_lock); + usbi_mutex_destroy(&ctx->event_waiters_lock); + usbi_cond_destroy(&ctx->event_waiters_cond); + usbi_mutex_destroy(&ctx->event_data_lock); + usbi_tls_key_delete(ctx->event_handling_key); + return r; +} + +void usbi_io_exit(struct libusb_context *ctx) +{ + usbi_remove_pollfd(ctx, ctx->event_pipe[0]); + usbi_close(ctx->event_pipe[0]); + usbi_close(ctx->event_pipe[1]); +#ifdef USBI_TIMERFD_AVAILABLE + if (usbi_using_timerfd(ctx)) { + usbi_remove_pollfd(ctx, ctx->timerfd); + close(ctx->timerfd); + } +#endif + usbi_mutex_destroy(&ctx->flying_transfers_lock); + usbi_mutex_destroy(&ctx->events_lock); + usbi_mutex_destroy(&ctx->event_waiters_lock); + usbi_cond_destroy(&ctx->event_waiters_cond); + usbi_mutex_destroy(&ctx->event_data_lock); + usbi_tls_key_delete(ctx->event_handling_key); + if (ctx->pollfds) + free(ctx->pollfds); +} + +static int calculate_timeout(struct usbi_transfer *transfer) +{ + int r; + struct timespec current_time; + unsigned int timeout = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout; + + if (!timeout) + return 0; + + r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, ¤t_time); + if (r < 0) { + usbi_err(ITRANSFER_CTX(transfer), + "failed to read monotonic clock, errno=%d", errno); + return r; + } + + current_time.tv_sec += timeout / 1000; + current_time.tv_nsec += (timeout % 1000) * 1000000; + + while (current_time.tv_nsec >= 1000000000) { + current_time.tv_nsec -= 1000000000; + current_time.tv_sec++; + } + + TIMESPEC_TO_TIMEVAL(&transfer->timeout, ¤t_time); + return 0; +} + +/** \ingroup asyncio + * Allocate a libusb transfer with a specified number of isochronous packet + * descriptors. The returned transfer is pre-initialized for you. When the new + * transfer is no longer needed, it should be freed with + * libusb_free_transfer(). + * + * Transfers intended for non-isochronous endpoints (e.g. control, bulk, + * interrupt) should specify an iso_packets count of zero. + * + * For transfers intended for isochronous endpoints, specify an appropriate + * number of packet descriptors to be allocated as part of the transfer. + * The returned transfer is not specially initialized for isochronous I/O; + * you are still required to set the + * \ref libusb_transfer::num_iso_packets "num_iso_packets" and + * \ref libusb_transfer::type "type" fields accordingly. + * + * It is safe to allocate a transfer with some isochronous packets and then + * use it on a non-isochronous endpoint. If you do this, ensure that at time + * of submission, num_iso_packets is 0 and that type is set appropriately. + * + * \param iso_packets number of isochronous packet descriptors to allocate + * \returns a newly allocated transfer, or NULL on error + */ +DEFAULT_VISIBILITY +struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer( + int iso_packets) +{ + struct libusb_transfer *transfer; + size_t os_alloc_size = usbi_backend->transfer_priv_size; + size_t alloc_size = sizeof(struct usbi_transfer) + + sizeof(struct libusb_transfer) + + (sizeof(struct libusb_iso_packet_descriptor) * iso_packets) + + os_alloc_size; + struct usbi_transfer *itransfer = calloc(1, alloc_size); + if (!itransfer) + return NULL; + + itransfer->num_iso_packets = iso_packets; + usbi_mutex_init(&itransfer->lock, NULL); + usbi_mutex_init(&itransfer->flags_lock, NULL); + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + usbi_dbg("transfer %p", transfer); + return transfer; +} + +/** \ingroup asyncio + * Free a transfer structure. This should be called for all transfers + * allocated with libusb_alloc_transfer(). + * + * If the \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_BUFFER + * "LIBUSB_TRANSFER_FREE_BUFFER" flag is set and the transfer buffer is + * non-NULL, this function will also free the transfer buffer using the + * standard system memory allocator (e.g. free()). + * + * It is legal to call this function with a NULL transfer. In this case, + * the function will simply return safely. + * + * It is not legal to free an active transfer (one which has been submitted + * and has not yet completed). + * + * \param transfer the transfer to free + */ +void API_EXPORTED libusb_free_transfer(struct libusb_transfer *transfer) +{ + struct usbi_transfer *itransfer; + if (!transfer) + return; + + usbi_dbg("transfer %p", transfer); + if (transfer->flags & LIBUSB_TRANSFER_FREE_BUFFER && transfer->buffer) + free(transfer->buffer); + + itransfer = LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + usbi_mutex_destroy(&itransfer->lock); + usbi_mutex_destroy(&itransfer->flags_lock); + free(itransfer); +} + +#ifdef USBI_TIMERFD_AVAILABLE +static int disarm_timerfd(struct libusb_context *ctx) +{ + const struct itimerspec disarm_timer = { { 0, 0 }, { 0, 0 } }; + int r; + + usbi_dbg(""); + r = timerfd_settime(ctx->timerfd, 0, &disarm_timer, NULL); + if (r < 0) + return LIBUSB_ERROR_OTHER; + else + return 0; +} + +/* iterates through the flying transfers, and rearms the timerfd based on the + * next upcoming timeout. + * must be called with flying_list locked. + * returns 0 on success or a LIBUSB_ERROR code on failure. + */ +static int arm_timerfd_for_next_timeout(struct libusb_context *ctx) +{ + struct usbi_transfer *transfer; + + list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { + struct timeval *cur_tv = &transfer->timeout; + + /* if we've reached transfers of infinite timeout, then we have no + * arming to do */ + if (!timerisset(cur_tv)) + goto disarm; + + /* act on first transfer that is not already cancelled */ + if (!(transfer->flags & USBI_TRANSFER_TIMEOUT_HANDLED)) { + int r; + const struct itimerspec it = { {0, 0}, + { cur_tv->tv_sec, cur_tv->tv_usec * 1000 } }; + usbi_dbg("next timeout originally %dms", USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout); + r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL); + if (r < 0) + return LIBUSB_ERROR_OTHER; + return 0; + } + } + +disarm: + return disarm_timerfd(ctx); +} +#else +static int arm_timerfd_for_next_timeout(struct libusb_context *ctx) +{ + UNUSED(ctx); + return 0; +} +#endif + +/* add a transfer to the (timeout-sorted) active transfers list. + * This function will return non 0 if fails to update the timer, + * in which case the transfer is *not* on the flying_transfers list. */ +static int add_to_flying_list(struct usbi_transfer *transfer) +{ + struct usbi_transfer *cur; + struct timeval *timeout = &transfer->timeout; + struct libusb_context *ctx = ITRANSFER_CTX(transfer); + int r = 0; + int first = 1; + + usbi_mutex_lock(&ctx->flying_transfers_lock); + + /* if we have no other flying transfers, start the list with this one */ + if (list_empty(&ctx->flying_transfers)) { + list_add(&transfer->list, &ctx->flying_transfers); + goto out; + } + + /* if we have infinite timeout, append to end of list */ + if (!timerisset(timeout)) { + list_add_tail(&transfer->list, &ctx->flying_transfers); + /* first is irrelevant in this case */ + goto out; + } + + /* otherwise, find appropriate place in list */ + list_for_each_entry(cur, &ctx->flying_transfers, list, struct usbi_transfer) { + /* find first timeout that occurs after the transfer in question */ + struct timeval *cur_tv = &cur->timeout; + + if (!timerisset(cur_tv) || (cur_tv->tv_sec > timeout->tv_sec) || + (cur_tv->tv_sec == timeout->tv_sec && + cur_tv->tv_usec > timeout->tv_usec)) { + list_add_tail(&transfer->list, &cur->list); + goto out; + } + first = 0; + } + /* first is 0 at this stage (list not empty) */ + + /* otherwise we need to be inserted at the end */ + list_add_tail(&transfer->list, &ctx->flying_transfers); +out: +#ifdef USBI_TIMERFD_AVAILABLE + if (first && usbi_using_timerfd(ctx) && timerisset(timeout)) { + /* if this transfer has the lowest timeout of all active transfers, + * rearm the timerfd with this transfer's timeout */ + const struct itimerspec it = { {0, 0}, + { timeout->tv_sec, timeout->tv_usec * 1000 } }; + usbi_dbg("arm timerfd for timeout in %dms (first in line)", + USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)->timeout); + r = timerfd_settime(ctx->timerfd, TFD_TIMER_ABSTIME, &it, NULL); + if (r < 0) { + usbi_warn(ctx, "failed to arm first timerfd (errno %d)", errno); + r = LIBUSB_ERROR_OTHER; + } + } +#else + UNUSED(first); +#endif + + if (r) + list_del(&transfer->list); + + usbi_mutex_unlock(&ctx->flying_transfers_lock); + return r; +} + +/* remove a transfer from the active transfers list. + * This function will *always* remove the transfer from the + * flying_transfers list. It will return a LIBUSB_ERROR code + * if it fails to update the timer for the next timeout. */ +static int remove_from_flying_list(struct usbi_transfer *transfer) +{ + struct libusb_context *ctx = ITRANSFER_CTX(transfer); + int rearm_timerfd; + int r = 0; + + usbi_mutex_lock(&ctx->flying_transfers_lock); + rearm_timerfd = (timerisset(&transfer->timeout) && + list_first_entry(&ctx->flying_transfers, struct usbi_transfer, list) == transfer); + list_del(&transfer->list); + if (usbi_using_timerfd(ctx) && rearm_timerfd) + r = arm_timerfd_for_next_timeout(ctx); + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + return r; +} + +/** \ingroup asyncio + * Submit a transfer. This function will fire off the USB transfer and then + * return immediately. + * + * \param transfer the transfer to submit + * \returns 0 on success + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_BUSY if the transfer has already been submitted. + * \returns LIBUSB_ERROR_NOT_SUPPORTED if the transfer flags are not supported + * by the operating system. + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer) +{ + struct usbi_transfer *itransfer = + LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + int remove = 0; + int r; + + usbi_dbg("transfer %p", transfer); + usbi_mutex_lock(&itransfer->lock); + usbi_mutex_lock(&itransfer->flags_lock); + if (itransfer->flags & USBI_TRANSFER_IN_FLIGHT) { + r = LIBUSB_ERROR_BUSY; + goto out; + } + itransfer->transferred = 0; + itransfer->flags = 0; + r = calculate_timeout(itransfer); + if (r < 0) { + r = LIBUSB_ERROR_OTHER; + goto out; + } + itransfer->flags |= USBI_TRANSFER_SUBMITTING; + usbi_mutex_unlock(&itransfer->flags_lock); + + r = add_to_flying_list(itransfer); + if (r) { + usbi_mutex_lock(&itransfer->flags_lock); + itransfer->flags = 0; + goto out; + } + + /* keep a reference to this device */ + libusb_ref_device(transfer->dev_handle->dev); + r = usbi_backend->submit_transfer(itransfer); + + usbi_mutex_lock(&itransfer->flags_lock); + itransfer->flags &= ~USBI_TRANSFER_SUBMITTING; + if (r == LIBUSB_SUCCESS) { + /* check for two possible special conditions: + * 1) device disconnect occurred immediately after submission + * 2) transfer completed before we got here to update the flags + */ + if (itransfer->flags & USBI_TRANSFER_DEVICE_DISAPPEARED) { + usbi_backend->clear_transfer_priv(itransfer); + remove = 1; + r = LIBUSB_ERROR_NO_DEVICE; + } + else if (!(itransfer->flags & USBI_TRANSFER_COMPLETED)) { + itransfer->flags |= USBI_TRANSFER_IN_FLIGHT; + } + } else { + remove = 1; + } +out: + usbi_mutex_unlock(&itransfer->flags_lock); + if (remove) { + libusb_unref_device(transfer->dev_handle->dev); + remove_from_flying_list(itransfer); + } + usbi_mutex_unlock(&itransfer->lock); + return r; +} + +/** \ingroup asyncio + * Asynchronously cancel a previously submitted transfer. + * This function returns immediately, but this does not indicate cancellation + * is complete. Your callback function will be invoked at some later time + * with a transfer status of + * \ref libusb_transfer_status::LIBUSB_TRANSFER_CANCELLED + * "LIBUSB_TRANSFER_CANCELLED." + * + * \param transfer the transfer to cancel + * \returns 0 on success + * \returns LIBUSB_ERROR_NOT_FOUND if the transfer is not in progress, + * already complete, or already cancelled. + * \returns a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_cancel_transfer(struct libusb_transfer *transfer) +{ + struct usbi_transfer *itransfer = + LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + int r; + + usbi_dbg("transfer %p", transfer ); + usbi_mutex_lock(&itransfer->lock); + usbi_mutex_lock(&itransfer->flags_lock); + if (!(itransfer->flags & USBI_TRANSFER_IN_FLIGHT) + || (itransfer->flags & USBI_TRANSFER_CANCELLING)) { + r = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + r = usbi_backend->cancel_transfer(itransfer); + if (r < 0) { + if (r != LIBUSB_ERROR_NOT_FOUND && + r != LIBUSB_ERROR_NO_DEVICE) + usbi_err(TRANSFER_CTX(transfer), + "cancel transfer failed error %d", r); + else + usbi_dbg("cancel transfer failed error %d", r); + + if (r == LIBUSB_ERROR_NO_DEVICE) + itransfer->flags |= USBI_TRANSFER_DEVICE_DISAPPEARED; + } + + itransfer->flags |= USBI_TRANSFER_CANCELLING; + +out: + usbi_mutex_unlock(&itransfer->flags_lock); + usbi_mutex_unlock(&itransfer->lock); + return r; +} + +/** \ingroup asyncio + * Set a transfers bulk stream id. Note users are advised to use + * libusb_fill_bulk_stream_transfer() instead of calling this function + * directly. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param transfer the transfer to set the stream id for + * \param stream_id the stream id to set + * \see libusb_alloc_streams() + */ +void API_EXPORTED libusb_transfer_set_stream_id( + struct libusb_transfer *transfer, uint32_t stream_id) +{ + struct usbi_transfer *itransfer = + LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + + itransfer->stream_id = stream_id; +} + +/** \ingroup asyncio + * Get a transfers bulk stream id. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param transfer the transfer to get the stream id for + * \returns the stream id for the transfer + */ +uint32_t API_EXPORTED libusb_transfer_get_stream_id( + struct libusb_transfer *transfer) +{ + struct usbi_transfer *itransfer = + LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer); + + return itransfer->stream_id; +} + +/* Handle completion of a transfer (completion might be an error condition). + * This will invoke the user-supplied callback function, which may end up + * freeing the transfer. Therefore you cannot use the transfer structure + * after calling this function, and you should free all backend-specific + * data before calling it. + * Do not call this function with the usbi_transfer lock held. User-specified + * callback functions may attempt to directly resubmit the transfer, which + * will attempt to take the lock. */ +int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, + enum libusb_transfer_status status) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct libusb_device_handle *handle = transfer->dev_handle; + uint8_t flags; + int r; + + r = remove_from_flying_list(itransfer); + if (r < 0) + usbi_err(ITRANSFER_CTX(itransfer), "failed to set timer for next timeout, errno=%d", errno); + + usbi_mutex_lock(&itransfer->flags_lock); + itransfer->flags &= ~USBI_TRANSFER_IN_FLIGHT; + itransfer->flags |= USBI_TRANSFER_COMPLETED; + usbi_mutex_unlock(&itransfer->flags_lock); + + if (status == LIBUSB_TRANSFER_COMPLETED + && transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) { + int rqlen = transfer->length; + if (transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL) + rqlen -= LIBUSB_CONTROL_SETUP_SIZE; + if (rqlen != itransfer->transferred) { + usbi_dbg("interpreting short transfer as error"); + status = LIBUSB_TRANSFER_ERROR; + } + } + + flags = transfer->flags; + transfer->status = status; + transfer->actual_length = itransfer->transferred; + usbi_dbg("transfer %p has callback %p", transfer, transfer->callback); + if (transfer->callback) + transfer->callback(transfer); + /* transfer might have been freed by the above call, do not use from + * this point. */ + if (flags & LIBUSB_TRANSFER_FREE_TRANSFER) + libusb_free_transfer(transfer); + libusb_unref_device(handle->dev); + return r; +} + +/* Similar to usbi_handle_transfer_completion() but exclusively for transfers + * that were asynchronously cancelled. The same concerns w.r.t. freeing of + * transfers exist here. + * Do not call this function with the usbi_transfer lock held. User-specified + * callback functions may attempt to directly resubmit the transfer, which + * will attempt to take the lock. */ +int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer) +{ + /* if the URB was cancelled due to timeout, report timeout to the user */ + if (transfer->flags & USBI_TRANSFER_TIMED_OUT) { + usbi_dbg("detected timeout cancellation"); + return usbi_handle_transfer_completion(transfer, LIBUSB_TRANSFER_TIMED_OUT); + } + + /* otherwise its a normal async cancel */ + return usbi_handle_transfer_completion(transfer, LIBUSB_TRANSFER_CANCELLED); +} + +/* Add a completed transfer to the completed_transfers list of the + * context and signal the event. The backend's handle_transfer_completion() + * function will be called the next time an event handler runs. */ +void usbi_signal_transfer_completion(struct usbi_transfer *transfer) +{ + struct libusb_context *ctx = ITRANSFER_CTX(transfer); + int pending_events; + + usbi_mutex_lock(&ctx->event_data_lock); + pending_events = usbi_pending_events(ctx); + list_add_tail(&transfer->completed_list, &ctx->completed_transfers); + if (!pending_events) + usbi_signal_event(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); +} + +/** \ingroup poll + * Attempt to acquire the event handling lock. This lock is used to ensure that + * only one thread is monitoring libusb event sources at any one time. + * + * You only need to use this lock if you are developing an application + * which calls poll() or select() on libusb's file descriptors directly. + * If you stick to libusb's event handling loop functions (e.g. + * libusb_handle_events()) then you do not need to be concerned with this + * locking. + * + * While holding this lock, you are trusted to actually be handling events. + * If you are no longer handling events, you must call libusb_unlock_events() + * as soon as possible. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 0 if the lock was obtained successfully + * \returns 1 if the lock was not obtained (i.e. another thread holds the lock) + * \ref mtasync + */ +int API_EXPORTED libusb_try_lock_events(libusb_context *ctx) +{ + int r; + unsigned int ru; + USBI_GET_CONTEXT(ctx); + + /* is someone else waiting to close a device? if so, don't let this thread + * start event handling */ + usbi_mutex_lock(&ctx->event_data_lock); + ru = ctx->device_close; + usbi_mutex_unlock(&ctx->event_data_lock); + if (ru) { + usbi_dbg("someone else is closing a device"); + return 1; + } + + r = usbi_mutex_trylock(&ctx->events_lock); + if (r) + return 1; + + ctx->event_handler_active = 1; + return 0; +} + +/** \ingroup poll + * Acquire the event handling lock, blocking until successful acquisition if + * it is contended. This lock is used to ensure that only one thread is + * monitoring libusb event sources at any one time. + * + * You only need to use this lock if you are developing an application + * which calls poll() or select() on libusb's file descriptors directly. + * If you stick to libusb's event handling loop functions (e.g. + * libusb_handle_events()) then you do not need to be concerned with this + * locking. + * + * While holding this lock, you are trusted to actually be handling events. + * If you are no longer handling events, you must call libusb_unlock_events() + * as soon as possible. + * + * \param ctx the context to operate on, or NULL for the default context + * \ref mtasync + */ +void API_EXPORTED libusb_lock_events(libusb_context *ctx) +{ + USBI_GET_CONTEXT(ctx); + usbi_mutex_lock(&ctx->events_lock); + ctx->event_handler_active = 1; +} + +/** \ingroup poll + * Release the lock previously acquired with libusb_try_lock_events() or + * libusb_lock_events(). Releasing this lock will wake up any threads blocked + * on libusb_wait_for_event(). + * + * \param ctx the context to operate on, or NULL for the default context + * \ref mtasync + */ +void API_EXPORTED libusb_unlock_events(libusb_context *ctx) +{ + USBI_GET_CONTEXT(ctx); + ctx->event_handler_active = 0; + usbi_mutex_unlock(&ctx->events_lock); + + /* FIXME: perhaps we should be a bit more efficient by not broadcasting + * the availability of the events lock when we are modifying pollfds + * (check ctx->device_close)? */ + usbi_mutex_lock(&ctx->event_waiters_lock); + usbi_cond_broadcast(&ctx->event_waiters_cond); + usbi_mutex_unlock(&ctx->event_waiters_lock); +} + +/** \ingroup poll + * Determine if it is still OK for this thread to be doing event handling. + * + * Sometimes, libusb needs to temporarily pause all event handlers, and this + * is the function you should use before polling file descriptors to see if + * this is the case. + * + * If this function instructs your thread to give up the events lock, you + * should just continue the usual logic that is documented in \ref mtasync. + * On the next iteration, your thread will fail to obtain the events lock, + * and will hence become an event waiter. + * + * This function should be called while the events lock is held: you don't + * need to worry about the results of this function if your thread is not + * the current event handler. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 1 if event handling can start or continue + * \returns 0 if this thread must give up the events lock + * \ref fullstory "Multi-threaded I/O: the full story" + */ +int API_EXPORTED libusb_event_handling_ok(libusb_context *ctx) +{ + unsigned int r; + USBI_GET_CONTEXT(ctx); + + /* is someone else waiting to close a device? if so, don't let this thread + * continue event handling */ + usbi_mutex_lock(&ctx->event_data_lock); + r = ctx->device_close; + usbi_mutex_unlock(&ctx->event_data_lock); + if (r) { + usbi_dbg("someone else is closing a device"); + return 0; + } + + return 1; +} + + +/** \ingroup poll + * Determine if an active thread is handling events (i.e. if anyone is holding + * the event handling lock). + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 1 if a thread is handling events + * \returns 0 if there are no threads currently handling events + * \ref mtasync + */ +int API_EXPORTED libusb_event_handler_active(libusb_context *ctx) +{ + unsigned int r; + USBI_GET_CONTEXT(ctx); + + /* is someone else waiting to close a device? if so, don't let this thread + * start event handling -- indicate that event handling is happening */ + usbi_mutex_lock(&ctx->event_data_lock); + r = ctx->device_close; + usbi_mutex_unlock(&ctx->event_data_lock); + if (r) { + usbi_dbg("someone else is closing a device"); + return 1; + } + + return ctx->event_handler_active; +} + +/** \ingroup poll + * Acquire the event waiters lock. This lock is designed to be obtained under + * the situation where you want to be aware when events are completed, but + * some other thread is event handling so calling libusb_handle_events() is not + * allowed. + * + * You then obtain this lock, re-check that another thread is still handling + * events, then call libusb_wait_for_event(). + * + * You only need to use this lock if you are developing an application + * which calls poll() or select() on libusb's file descriptors directly, + * and may potentially be handling events from 2 threads simultaenously. + * If you stick to libusb's event handling loop functions (e.g. + * libusb_handle_events()) then you do not need to be concerned with this + * locking. + * + * \param ctx the context to operate on, or NULL for the default context + * \ref mtasync + */ +void API_EXPORTED libusb_lock_event_waiters(libusb_context *ctx) +{ + USBI_GET_CONTEXT(ctx); + usbi_mutex_lock(&ctx->event_waiters_lock); +} + +/** \ingroup poll + * Release the event waiters lock. + * \param ctx the context to operate on, or NULL for the default context + * \ref mtasync + */ +void API_EXPORTED libusb_unlock_event_waiters(libusb_context *ctx) +{ + USBI_GET_CONTEXT(ctx); + usbi_mutex_unlock(&ctx->event_waiters_lock); +} + +/** \ingroup poll + * Wait for another thread to signal completion of an event. Must be called + * with the event waiters lock held, see libusb_lock_event_waiters(). + * + * This function will block until any of the following conditions are met: + * -# The timeout expires + * -# A transfer completes + * -# A thread releases the event handling lock through libusb_unlock_events() + * + * Condition 1 is obvious. Condition 2 unblocks your thread after + * the callback for the transfer has completed. Condition 3 is important + * because it means that the thread that was previously handling events is no + * longer doing so, so if any events are to complete, another thread needs to + * step up and start event handling. + * + * This function releases the event waiters lock before putting your thread + * to sleep, and reacquires the lock as it is being woken up. + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv maximum timeout for this blocking function. A NULL value + * indicates unlimited timeout. + * \returns 0 after a transfer completes or another thread stops event handling + * \returns 1 if the timeout expired + * \ref mtasync + */ +int API_EXPORTED libusb_wait_for_event(libusb_context *ctx, struct timeval *tv) +{ + struct timespec timeout; + int r; + + USBI_GET_CONTEXT(ctx); + if (tv == NULL) { + usbi_cond_wait(&ctx->event_waiters_cond, &ctx->event_waiters_lock); + return 0; + } + + r = usbi_backend->clock_gettime(USBI_CLOCK_REALTIME, &timeout); + if (r < 0) { + usbi_err(ctx, "failed to read realtime clock, error %d", errno); + return LIBUSB_ERROR_OTHER; + } + + timeout.tv_sec += tv->tv_sec; + timeout.tv_nsec += tv->tv_usec * 1000; + while (timeout.tv_nsec >= 1000000000) { + timeout.tv_nsec -= 1000000000; + timeout.tv_sec++; + } + + r = usbi_cond_timedwait(&ctx->event_waiters_cond, + &ctx->event_waiters_lock, &timeout); + return (r == ETIMEDOUT); +} + +static void handle_timeout(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + int r; + + itransfer->flags |= USBI_TRANSFER_TIMEOUT_HANDLED; + r = libusb_cancel_transfer(transfer); + if (r == 0) + itransfer->flags |= USBI_TRANSFER_TIMED_OUT; + else + usbi_warn(TRANSFER_CTX(transfer), + "async cancel failed %d errno=%d", r, errno); +} + +static int handle_timeouts_locked(struct libusb_context *ctx) +{ + int r; + struct timespec systime_ts; + struct timeval systime; + struct usbi_transfer *transfer; + + if (list_empty(&ctx->flying_transfers)) + return 0; + + /* get current time */ + r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, &systime_ts); + if (r < 0) + return r; + + TIMESPEC_TO_TIMEVAL(&systime, &systime_ts); + + /* iterate through flying transfers list, finding all transfers that + * have expired timeouts */ + list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { + struct timeval *cur_tv = &transfer->timeout; + + /* if we've reached transfers of infinite timeout, we're all done */ + if (!timerisset(cur_tv)) + return 0; + + /* ignore timeouts we've already handled */ + if (transfer->flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT)) + continue; + + /* if transfer has non-expired timeout, nothing more to do */ + if ((cur_tv->tv_sec > systime.tv_sec) || + (cur_tv->tv_sec == systime.tv_sec && + cur_tv->tv_usec > systime.tv_usec)) + return 0; + + /* otherwise, we've got an expired timeout to handle */ + handle_timeout(transfer); + } + return 0; +} + +static int handle_timeouts(struct libusb_context *ctx) +{ + int r; + USBI_GET_CONTEXT(ctx); + usbi_mutex_lock(&ctx->flying_transfers_lock); + r = handle_timeouts_locked(ctx); + usbi_mutex_unlock(&ctx->flying_transfers_lock); + return r; +} + +#ifdef USBI_TIMERFD_AVAILABLE +static int handle_timerfd_trigger(struct libusb_context *ctx) +{ + int r; + + usbi_mutex_lock(&ctx->flying_transfers_lock); + + /* process the timeout that just happened */ + r = handle_timeouts_locked(ctx); + if (r < 0) + goto out; + + /* arm for next timeout*/ + r = arm_timerfd_for_next_timeout(ctx); + +out: + usbi_mutex_unlock(&ctx->flying_transfers_lock); + return r; +} +#endif + +/* do the actual event handling. assumes that no other thread is concurrently + * doing the same thing. */ +static int handle_events(struct libusb_context *ctx, struct timeval *tv) +{ + int r; + struct usbi_pollfd *ipollfd; + POLL_NFDS_TYPE nfds = 0; + POLL_NFDS_TYPE internal_nfds; + struct pollfd *fds = NULL; + int i = -1; + int timeout_ms; + int special_event; + + /* prevent attempts to recursively handle events (e.g. calling into + * libusb_handle_events() from within a hotplug or transfer callback) */ + if (usbi_handling_events(ctx)) + return LIBUSB_ERROR_BUSY; + usbi_start_event_handling(ctx); + + /* there are certain fds that libusb uses internally, currently: + * + * 1) event pipe + * 2) timerfd + * + * the backend will never need to attempt to handle events on these fds, so + * we determine how many fds are in use internally for this context and when + * handle_events() is called in the backend, the pollfd list and count will + * be adjusted to skip over these internal fds */ + if (usbi_using_timerfd(ctx)) + internal_nfds = 2; + else + internal_nfds = 1; + + /* only reallocate the poll fds when the list of poll fds has been modified + * since the last poll, otherwise reuse them to save the additional overhead */ + usbi_mutex_lock(&ctx->event_data_lock); + if (ctx->pollfds_modified) { + usbi_dbg("poll fds modified, reallocating"); + + if (ctx->pollfds) { + free(ctx->pollfds); + ctx->pollfds = NULL; + } + + /* sanity check - it is invalid for a context to have fewer than the + * required internal fds (memory corruption?) */ + assert(ctx->pollfds_cnt >= internal_nfds); + + ctx->pollfds = calloc(ctx->pollfds_cnt, sizeof(*ctx->pollfds)); + if (!ctx->pollfds) { + usbi_mutex_unlock(&ctx->event_data_lock); + r = LIBUSB_ERROR_NO_MEM; + goto done; + } + + list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd) { + struct libusb_pollfd *pollfd = &ipollfd->pollfd; + i++; + ctx->pollfds[i].fd = pollfd->fd; + ctx->pollfds[i].events = pollfd->events; + } + + /* reset the flag now that we have the updated list */ + ctx->pollfds_modified = 0; + + /* if no further pending events, clear the event pipe so that we do + * not immediately return from poll */ + if (!usbi_pending_events(ctx)) + usbi_clear_event(ctx); + } + fds = ctx->pollfds; + nfds = ctx->pollfds_cnt; + usbi_mutex_unlock(&ctx->event_data_lock); + + timeout_ms = (int)(tv->tv_sec * 1000) + (tv->tv_usec / 1000); + + /* round up to next millisecond */ + if (tv->tv_usec % 1000) + timeout_ms++; + +redo_poll: + usbi_dbg("poll() %d fds with timeout in %dms", nfds, timeout_ms); + r = usbi_poll(fds, nfds, timeout_ms); + usbi_dbg("poll() returned %d", r); + if (r == 0) { + r = handle_timeouts(ctx); + goto done; + } + else if (r == -1 && errno == EINTR) { + r = LIBUSB_ERROR_INTERRUPTED; + goto done; + } + else if (r < 0) { + usbi_err(ctx, "poll failed %d err=%d", r, errno); + r = LIBUSB_ERROR_IO; + goto done; + } + + special_event = 0; + + /* fds[0] is always the event pipe */ + if (fds[0].revents) { + libusb_hotplug_message *message = NULL; + struct usbi_transfer *itransfer; + int ret = 0; + + usbi_dbg("caught a fish on the event pipe"); + + /* take the the event data lock while processing events */ + usbi_mutex_lock(&ctx->event_data_lock); + + /* check if someone added a new poll fd */ + if (ctx->pollfds_modified) + usbi_dbg("someone updated the poll fds"); + + /* check if someone is closing a device */ + if (ctx->device_close) + usbi_dbg("someone is closing a device"); + + /* check for any pending hotplug messages */ + if (!list_empty(&ctx->hotplug_msgs)) { + usbi_dbg("hotplug message received"); + special_event = 1; + message = list_first_entry(&ctx->hotplug_msgs, libusb_hotplug_message, list); + list_del(&message->list); + } + + /* complete any pending transfers */ + while (ret == 0 && !list_empty(&ctx->completed_transfers)) { + itransfer = list_first_entry(&ctx->completed_transfers, struct usbi_transfer, completed_list); + list_del(&itransfer->completed_list); + usbi_mutex_unlock(&ctx->event_data_lock); + ret = usbi_backend->handle_transfer_completion(itransfer); + if (ret) + usbi_err(ctx, "backend handle_transfer_completion failed with error %d", ret); + usbi_mutex_lock(&ctx->event_data_lock); + } + + /* if no further pending events, clear the event pipe */ + if (!usbi_pending_events(ctx)) + usbi_clear_event(ctx); + + usbi_mutex_unlock(&ctx->event_data_lock); + + /* process the hotplug message, if any */ + if (message) { + usbi_hotplug_match(ctx, message->device, message->event); + + /* the device left, dereference the device */ + if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == message->event) + libusb_unref_device(message->device); + + free(message); + } + + if (ret) { + /* return error code */ + r = ret; + goto done; + } + + if (0 == --r) + goto handled; + } + +#ifdef USBI_TIMERFD_AVAILABLE + /* on timerfd configurations, fds[1] is the timerfd */ + if (usbi_using_timerfd(ctx) && fds[1].revents) { + /* timerfd indicates that a timeout has expired */ + int ret; + usbi_dbg("timerfd triggered"); + special_event = 1; + + ret = handle_timerfd_trigger(ctx); + if (ret < 0) { + /* return error code */ + r = ret; + goto done; + } + + if (0 == --r) + goto handled; + } +#endif + + r = usbi_backend->handle_events(ctx, fds + internal_nfds, nfds - internal_nfds, r); + if (r) + usbi_err(ctx, "backend handle_events failed with error %d", r); + +handled: + if (r == 0 && special_event) { + timeout_ms = 0; + goto redo_poll; + } + +done: + usbi_end_event_handling(ctx); + return r; +} + +/* returns the smallest of: + * 1. timeout of next URB + * 2. user-supplied timeout + * returns 1 if there is an already-expired timeout, otherwise returns 0 + * and populates out + */ +static int get_next_timeout(libusb_context *ctx, struct timeval *tv, + struct timeval *out) +{ + struct timeval timeout; + int r = libusb_get_next_timeout(ctx, &timeout); + if (r) { + /* timeout already expired? */ + if (!timerisset(&timeout)) + return 1; + + /* choose the smallest of next URB timeout or user specified timeout */ + if (timercmp(&timeout, tv, <)) + *out = timeout; + else + *out = *tv; + } else { + *out = *tv; + } + return 0; +} + +/** \ingroup poll + * Handle any pending events. + * + * libusb determines "pending events" by checking if any timeouts have expired + * and by checking the set of file descriptors for activity. + * + * If a zero timeval is passed, this function will handle any already-pending + * events and then immediately return in non-blocking style. + * + * If a non-zero timeval is passed and no events are currently pending, this + * function will block waiting for events to handle up until the specified + * timeout. If an event arrives or a signal is raised, this function will + * return early. + * + * If the parameter completed is not NULL then after obtaining the event + * handling lock this function will return immediately if the integer + * pointed to is not 0. This allows for race free waiting for the completion + * of a specific transfer. + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv the maximum time to block waiting for events, or an all zero + * timeval struct for non-blocking mode + * \param completed pointer to completion integer to check, or NULL + * \returns 0 on success, or a LIBUSB_ERROR code on failure + * \ref mtasync + */ +int API_EXPORTED libusb_handle_events_timeout_completed(libusb_context *ctx, + struct timeval *tv, int *completed) +{ + int r; + struct timeval poll_timeout; + + USBI_GET_CONTEXT(ctx); + r = get_next_timeout(ctx, tv, &poll_timeout); + if (r) { + /* timeout already expired */ + return handle_timeouts(ctx); + } + +retry: + if (libusb_try_lock_events(ctx) == 0) { + if (completed == NULL || !*completed) { + /* we obtained the event lock: do our own event handling */ + usbi_dbg("doing our own event handling"); + r = handle_events(ctx, &poll_timeout); + } + libusb_unlock_events(ctx); + return r; + } + + /* another thread is doing event handling. wait for thread events that + * notify event completion. */ + libusb_lock_event_waiters(ctx); + + if (completed && *completed) + goto already_done; + + if (!libusb_event_handler_active(ctx)) { + /* we hit a race: whoever was event handling earlier finished in the + * time it took us to reach this point. try the cycle again. */ + libusb_unlock_event_waiters(ctx); + usbi_dbg("event handler was active but went away, retrying"); + goto retry; + } + + usbi_dbg("another thread is doing event handling"); + r = libusb_wait_for_event(ctx, &poll_timeout); + +already_done: + libusb_unlock_event_waiters(ctx); + + if (r < 0) + return r; + else if (r == 1) + return handle_timeouts(ctx); + else + return 0; +} + +/** \ingroup poll + * Handle any pending events + * + * Like libusb_handle_events_timeout_completed(), but without the completed + * parameter, calling this function is equivalent to calling + * libusb_handle_events_timeout_completed() with a NULL completed parameter. + * + * This function is kept primarily for backwards compatibility. + * All new code should call libusb_handle_events_completed() or + * libusb_handle_events_timeout_completed() to avoid race conditions. + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv the maximum time to block waiting for events, or an all zero + * timeval struct for non-blocking mode + * \returns 0 on success, or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx, + struct timeval *tv) +{ + return libusb_handle_events_timeout_completed(ctx, tv, NULL); +} + +/** \ingroup poll + * Handle any pending events in blocking mode. There is currently a timeout + * hardcoded at 60 seconds but we plan to make it unlimited in future. For + * finer control over whether this function is blocking or non-blocking, or + * for control over the timeout, use libusb_handle_events_timeout_completed() + * instead. + * + * This function is kept primarily for backwards compatibility. + * All new code should call libusb_handle_events_completed() or + * libusb_handle_events_timeout_completed() to avoid race conditions. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 0 on success, or a LIBUSB_ERROR code on failure + */ +int API_EXPORTED libusb_handle_events(libusb_context *ctx) +{ + struct timeval tv; + tv.tv_sec = 60; + tv.tv_usec = 0; + return libusb_handle_events_timeout_completed(ctx, &tv, NULL); +} + +/** \ingroup poll + * Handle any pending events in blocking mode. + * + * Like libusb_handle_events(), with the addition of a completed parameter + * to allow for race free waiting for the completion of a specific transfer. + * + * See libusb_handle_events_timeout_completed() for details on the completed + * parameter. + * + * \param ctx the context to operate on, or NULL for the default context + * \param completed pointer to completion integer to check, or NULL + * \returns 0 on success, or a LIBUSB_ERROR code on failure + * \ref mtasync + */ +int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx, + int *completed) +{ + struct timeval tv; + tv.tv_sec = 60; + tv.tv_usec = 0; + return libusb_handle_events_timeout_completed(ctx, &tv, completed); +} + +/** \ingroup poll + * Handle any pending events by polling file descriptors, without checking if + * any other threads are already doing so. Must be called with the event lock + * held, see libusb_lock_events(). + * + * This function is designed to be called under the situation where you have + * taken the event lock and are calling poll()/select() directly on libusb's + * file descriptors (as opposed to using libusb_handle_events() or similar). + * You detect events on libusb's descriptors, so you then call this function + * with a zero timeout value (while still holding the event lock). + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv the maximum time to block waiting for events, or zero for + * non-blocking mode + * \returns 0 on success, or a LIBUSB_ERROR code on failure + * \ref mtasync + */ +int API_EXPORTED libusb_handle_events_locked(libusb_context *ctx, + struct timeval *tv) +{ + int r; + struct timeval poll_timeout; + + USBI_GET_CONTEXT(ctx); + r = get_next_timeout(ctx, tv, &poll_timeout); + if (r) { + /* timeout already expired */ + return handle_timeouts(ctx); + } + + return handle_events(ctx, &poll_timeout); +} + +/** \ingroup poll + * Determines whether your application must apply special timing considerations + * when monitoring libusb's file descriptors. + * + * This function is only useful for applications which retrieve and poll + * libusb's file descriptors in their own main loop (\ref pollmain). + * + * Ordinarily, libusb's event handler needs to be called into at specific + * moments in time (in addition to times when there is activity on the file + * descriptor set). The usual approach is to use libusb_get_next_timeout() + * to learn about when the next timeout occurs, and to adjust your + * poll()/select() timeout accordingly so that you can make a call into the + * library at that time. + * + * Some platforms supported by libusb do not come with this baggage - any + * events relevant to timing will be represented by activity on the file + * descriptor set, and libusb_get_next_timeout() will always return 0. + * This function allows you to detect whether you are running on such a + * platform. + * + * Since v1.0.5. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns 0 if you must call into libusb at times determined by + * libusb_get_next_timeout(), or 1 if all timeout events are handled internally + * or through regular activity on the file descriptors. + * \ref pollmain "Polling libusb file descriptors for event handling" + */ +int API_EXPORTED libusb_pollfds_handle_timeouts(libusb_context *ctx) +{ +#if defined(USBI_TIMERFD_AVAILABLE) + USBI_GET_CONTEXT(ctx); + return usbi_using_timerfd(ctx); +#else + UNUSED(ctx); + return 0; +#endif +} + +/** \ingroup poll + * Determine the next internal timeout that libusb needs to handle. You only + * need to use this function if you are calling poll() or select() or similar + * on libusb's file descriptors yourself - you do not need to use it if you + * are calling libusb_handle_events() or a variant directly. + * + * You should call this function in your main loop in order to determine how + * long to wait for select() or poll() to return results. libusb needs to be + * called into at this timeout, so you should use it as an upper bound on + * your select() or poll() call. + * + * When the timeout has expired, call into libusb_handle_events_timeout() + * (perhaps in non-blocking mode) so that libusb can handle the timeout. + * + * This function may return 1 (success) and an all-zero timeval. If this is + * the case, it indicates that libusb has a timeout that has already expired + * so you should call libusb_handle_events_timeout() or similar immediately. + * A return code of 0 indicates that there are no pending timeouts. + * + * On some platforms, this function will always returns 0 (no pending + * timeouts). See \ref polltime. + * + * \param ctx the context to operate on, or NULL for the default context + * \param tv output location for a relative time against the current + * clock in which libusb must be called into in order to process timeout events + * \returns 0 if there are no pending timeouts, 1 if a timeout was returned, + * or LIBUSB_ERROR_OTHER on failure + */ +int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx, + struct timeval *tv) +{ + struct usbi_transfer *transfer; + struct timespec cur_ts; + struct timeval cur_tv; + struct timeval next_timeout = { 0, 0 }; + int r; + + USBI_GET_CONTEXT(ctx); + if (usbi_using_timerfd(ctx)) + return 0; + + usbi_mutex_lock(&ctx->flying_transfers_lock); + if (list_empty(&ctx->flying_transfers)) { + usbi_mutex_unlock(&ctx->flying_transfers_lock); + usbi_dbg("no URBs, no timeout!"); + return 0; + } + + /* find next transfer which hasn't already been processed as timed out */ + list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) { + if (transfer->flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT)) + continue; + + /* if we've reached transfers of infinte timeout, we're done looking */ + if (!timerisset(&transfer->timeout)) + break; + + next_timeout = transfer->timeout; + break; + } + usbi_mutex_unlock(&ctx->flying_transfers_lock); + + if (!timerisset(&next_timeout)) { + usbi_dbg("no URB with timeout or all handled by OS; no timeout!"); + return 0; + } + + r = usbi_backend->clock_gettime(USBI_CLOCK_MONOTONIC, &cur_ts); + if (r < 0) { + usbi_err(ctx, "failed to read monotonic clock, errno=%d", errno); + return 0; + } + TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts); + + if (!timercmp(&cur_tv, &next_timeout, <)) { + usbi_dbg("first timeout already expired"); + timerclear(tv); + } else { + timersub(&next_timeout, &cur_tv, tv); + usbi_dbg("next timeout in %d.%06ds", tv->tv_sec, tv->tv_usec); + } + + return 1; +} + +/** \ingroup poll + * Register notification functions for file descriptor additions/removals. + * These functions will be invoked for every new or removed file descriptor + * that libusb uses as an event source. + * + * To remove notifiers, pass NULL values for the function pointers. + * + * Note that file descriptors may have been added even before you register + * these notifiers (e.g. at libusb_init() time). + * + * Additionally, note that the removal notifier may be called during + * libusb_exit() (e.g. when it is closing file descriptors that were opened + * and added to the poll set at libusb_init() time). If you don't want this, + * remove the notifiers immediately before calling libusb_exit(). + * + * \param ctx the context to operate on, or NULL for the default context + * \param added_cb pointer to function for addition notifications + * \param removed_cb pointer to function for removal notifications + * \param user_data User data to be passed back to callbacks (useful for + * passing context information) + */ +void API_EXPORTED libusb_set_pollfd_notifiers(libusb_context *ctx, + libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, + void *user_data) +{ + USBI_GET_CONTEXT(ctx); + ctx->fd_added_cb = added_cb; + ctx->fd_removed_cb = removed_cb; + ctx->fd_cb_user_data = user_data; +} + +/* + * Interrupt the iteration of the event handling thread, so that it picks + * up the fd change. Callers of this function must hold the event_data_lock. + */ +static void usbi_fd_notification(struct libusb_context *ctx) +{ + int pending_events; + + /* Record that there is a new poll fd. + * Only signal an event if there are no prior pending events. */ + pending_events = usbi_pending_events(ctx); + ctx->pollfds_modified = 1; + if (!pending_events) + usbi_signal_event(ctx); +} + +/* Add a file descriptor to the list of file descriptors to be monitored. + * events should be specified as a bitmask of events passed to poll(), e.g. + * POLLIN and/or POLLOUT. */ +int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events) +{ + struct usbi_pollfd *ipollfd = malloc(sizeof(*ipollfd)); + if (!ipollfd) + return LIBUSB_ERROR_NO_MEM; + + usbi_dbg("add fd %d events %d", fd, events); + ipollfd->pollfd.fd = fd; + ipollfd->pollfd.events = events; + usbi_mutex_lock(&ctx->event_data_lock); + list_add_tail(&ipollfd->list, &ctx->ipollfds); + ctx->pollfds_cnt++; + usbi_fd_notification(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); + + if (ctx->fd_added_cb) + ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data); + return 0; +} + +/* Remove a file descriptor from the list of file descriptors to be polled. */ +void usbi_remove_pollfd(struct libusb_context *ctx, int fd) +{ + struct usbi_pollfd *ipollfd; + int found = 0; + + usbi_dbg("remove fd %d", fd); + usbi_mutex_lock(&ctx->event_data_lock); + list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd) + if (ipollfd->pollfd.fd == fd) { + found = 1; + break; + } + + if (!found) { + usbi_dbg("couldn't find fd %d to remove", fd); + usbi_mutex_unlock(&ctx->event_data_lock); + return; + } + + list_del(&ipollfd->list); + ctx->pollfds_cnt--; + usbi_fd_notification(ctx); + usbi_mutex_unlock(&ctx->event_data_lock); + free(ipollfd); + if (ctx->fd_removed_cb) + ctx->fd_removed_cb(fd, ctx->fd_cb_user_data); +} + +/** \ingroup poll + * Retrieve a list of file descriptors that should be polled by your main loop + * as libusb event sources. + * + * The returned list is NULL-terminated and should be freed with libusb_free_pollfds() + * when done. The actual list contents must not be touched. + * + * As file descriptors are a Unix-specific concept, this function is not + * available on Windows and will always return NULL. + * + * \param ctx the context to operate on, or NULL for the default context + * \returns a NULL-terminated list of libusb_pollfd structures + * \returns NULL on error + * \returns NULL on platforms where the functionality is not available + */ +DEFAULT_VISIBILITY +const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds( + libusb_context *ctx) +{ +#ifndef OS_WINDOWS + struct libusb_pollfd **ret = NULL; + struct usbi_pollfd *ipollfd; + size_t i = 0; + USBI_GET_CONTEXT(ctx); + + usbi_mutex_lock(&ctx->event_data_lock); + + ret = calloc(ctx->pollfds_cnt + 1, sizeof(struct libusb_pollfd *)); + if (!ret) + goto out; + + list_for_each_entry(ipollfd, &ctx->ipollfds, list, struct usbi_pollfd) + ret[i++] = (struct libusb_pollfd *) ipollfd; + ret[ctx->pollfds_cnt] = NULL; + +out: + usbi_mutex_unlock(&ctx->event_data_lock); + return (const struct libusb_pollfd **) ret; +#else + usbi_err(ctx, "external polling of libusb's internal descriptors "\ + "is not yet supported on Windows platforms"); + return NULL; +#endif +} + +/** \ingroup poll + * Free a list of libusb_pollfd structures. This should be called for all + * pollfd lists allocated with libusb_get_pollfds(). + * + * Since version 1.0.20, \ref LIBUSB_API_VERSION >= 0x01000104 + * + * It is legal to call this function with a NULL pollfd list. In this case, + * the function will simply return safely. + * + * \param pollfds the list of libusb_pollfd structures to free + */ +void API_EXPORTED libusb_free_pollfds(const struct libusb_pollfd **pollfds) +{ + if (!pollfds) + return; + + free((void *)pollfds); +} + +/* Backends may call this from handle_events to report disconnection of a + * device. This function ensures transfers get cancelled appropriately. + * Callers of this function must hold the events_lock. + */ +void usbi_handle_disconnect(struct libusb_device_handle *handle) +{ + struct usbi_transfer *cur; + struct usbi_transfer *to_cancel; + + usbi_dbg("device %d.%d", + handle->dev->bus_number, handle->dev->device_address); + + /* terminate all pending transfers with the LIBUSB_TRANSFER_NO_DEVICE + * status code. + * + * when we find a transfer for this device on the list, there are two + * possible scenarios: + * 1. the transfer is currently in-flight, in which case we terminate the + * transfer here + * 2. the transfer is not in-flight (or is but hasn't been marked as such), + * in which case we record that the device disappeared and this will be + * handled by libusb_submit_transfer() + */ + + while (1) { + to_cancel = NULL; + usbi_mutex_lock(&HANDLE_CTX(handle)->flying_transfers_lock); + list_for_each_entry(cur, &HANDLE_CTX(handle)->flying_transfers, list, struct usbi_transfer) + if (USBI_TRANSFER_TO_LIBUSB_TRANSFER(cur)->dev_handle == handle) { + usbi_mutex_lock(&cur->flags_lock); + if (cur->flags & USBI_TRANSFER_IN_FLIGHT) + to_cancel = cur; + else + cur->flags |= USBI_TRANSFER_DEVICE_DISAPPEARED; + usbi_mutex_unlock(&cur->flags_lock); + + if (to_cancel) + break; + } + usbi_mutex_unlock(&HANDLE_CTX(handle)->flying_transfers_lock); + + if (!to_cancel) + break; + + usbi_dbg("cancelling transfer %p from disconnect", + USBI_TRANSFER_TO_LIBUSB_TRANSFER(to_cancel)); + + usbi_mutex_lock(&to_cancel->lock); + usbi_backend->clear_transfer_priv(to_cancel); + usbi_mutex_unlock(&to_cancel->lock); + usbi_handle_transfer_completion(to_cancel, LIBUSB_TRANSFER_NO_DEVICE); + } + +} diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/io.c.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/io.c.REMOVED.git-id deleted file mode 100644 index b3de3e70..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/io.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -01cf5bec2acd5b66fa8a0e5055c1f058c71ca9a1 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/libusb.h b/Desktop_Interface/build_android/libusb-martin-kuldeep/libusb.h new file mode 100644 index 00000000..6549d2eb --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/libusb.h @@ -0,0 +1,2002 @@ +/* + * Public libusb header file + * Copyright © 2001 Johannes Erdfelt + * Copyright © 2007-2008 Daniel Drake + * Copyright © 2012 Pete Batard + * Copyright © 2012 Nathan Hjelm + * Copyright © 2013-2016 Martin Marinov + * For more information, please visit: http://libusb.info + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_H +#define LIBUSB_H + +#ifdef _MSC_VER +/* on MS environments, the inline keyword is available in C++ only */ +#if !defined(__cplusplus) +#define inline __inline +#endif +/* ssize_t is also not available (copy/paste from MinGW) */ +#ifndef _SSIZE_T_DEFINED +#define _SSIZE_T_DEFINED +#undef ssize_t +#ifdef _WIN64 + typedef __int64 ssize_t; +#else + typedef int ssize_t; +#endif /* _WIN64 */ +#endif /* _SSIZE_T_DEFINED */ +#endif /* _MSC_VER */ + +/* stdint.h is not available on older MSVC */ +#if defined(_MSC_VER) && (_MSC_VER < 1600) && (!defined(_STDINT)) && (!defined(_STDINT_H)) +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +#else +#include +#endif + +#if !defined(_WIN32_WCE) +#include +#endif + +#if defined(__linux) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__HAIKU__) +#include +#endif + +#include +#include + +/* 'interface' might be defined as a macro on Windows, so we need to + * undefine it so as not to break the current libusb API, because + * libusb_config_descriptor has an 'interface' member + * As this can be problematic if you include windows.h after libusb.h + * in your sources, we force windows.h to be included first. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +#include +#if defined(interface) +#undef interface +#endif +#if !defined(__CYGWIN__) +#include +#endif +#endif + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#define LIBUSB_DEPRECATED_FOR(f) \ + __attribute__((deprecated("Use " #f " instead"))) +#else +#define LIBUSB_DEPRECATED_FOR(f) +#endif /* __GNUC__ */ + +/** \def LIBUSB_CALL + * \ingroup misc + * libusb's Windows calling convention. + * + * Under Windows, the selection of available compilers and configurations + * means that, unlike other platforms, there is not one true calling + * convention (calling convention: the manner in which parameters are + * passed to functions in the generated assembly code). + * + * Matching the Windows API itself, libusb uses the WINAPI convention (which + * translates to the stdcall convention) and guarantees that the + * library is compiled in this way. The public header file also includes + * appropriate annotations so that your own software will use the right + * convention, even if another convention is being used by default within + * your codebase. + * + * The one consideration that you must apply in your software is to mark + * all functions which you use as libusb callbacks with this LIBUSB_CALL + * annotation, so that they too get compiled for the correct calling + * convention. + * + * On non-Windows operating systems, this macro is defined as nothing. This + * means that you can apply it to your code without worrying about + * cross-platform compatibility. + */ +/* LIBUSB_CALL must be defined on both definition and declaration of libusb + * functions. You'd think that declaration would be enough, but cygwin will + * complain about conflicting types unless both are marked this way. + * The placement of this macro is important too; it must appear after the + * return type, before the function name. See internal documentation for + * API_EXPORTED. + */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +#define LIBUSB_CALL WINAPI +#else +#define LIBUSB_CALL +#endif + +/** \def LIBUSB_API_VERSION + * \ingroup misc + * libusb's API version. + * + * Since version 1.0.13, to help with feature detection, libusb defines + * a LIBUSB_API_VERSION macro that gets increased every time there is a + * significant change to the API, such as the introduction of a new call, + * the definition of a new macro/enum member, or any other element that + * libusb applications may want to detect at compilation time. + * + * The macro is typically used in an application as follows: + * \code + * #if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01001234) + * // Use one of the newer features from the libusb API + * #endif + * \endcode + * + * Internally, LIBUSB_API_VERSION is defined as follows: + * (libusb major << 24) | (libusb minor << 16) | (16 bit incremental) + */ +#define LIBUSB_API_VERSION 0x01000104 + +/* The following is kept for compatibility, but will be deprecated in the future */ +#define LIBUSBX_API_VERSION LIBUSB_API_VERSION + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup misc + * Convert a 16-bit value from host-endian to little-endian format. On + * little endian systems, this function does nothing. On big endian systems, + * the bytes are swapped. + * \param x the host-endian value to convert + * \returns the value in little-endian byte order + */ +static inline uint16_t libusb_cpu_to_le16(const uint16_t x) +{ + union { + uint8_t b8[2]; + uint16_t b16; + } _tmp; + _tmp.b8[1] = (uint8_t) (x >> 8); + _tmp.b8[0] = (uint8_t) (x & 0xff); + return _tmp.b16; +} + +/** \def libusb_le16_to_cpu + * \ingroup misc + * Convert a 16-bit value from little-endian to host-endian format. On + * little endian systems, this function does nothing. On big endian systems, + * the bytes are swapped. + * \param x the little-endian value to convert + * \returns the value in host-endian byte order + */ +#define libusb_le16_to_cpu libusb_cpu_to_le16 + +/* standard USB stuff */ + +/** \ingroup desc + * Device and/or Interface Class codes */ +enum libusb_class_code { + /** In the context of a \ref libusb_device_descriptor "device descriptor", + * this bDeviceClass value indicates that each interface specifies its + * own class information and all interfaces operate independently. + */ + LIBUSB_CLASS_PER_INTERFACE = 0, + + /** Audio class */ + LIBUSB_CLASS_AUDIO = 1, + + /** Communications class */ + LIBUSB_CLASS_COMM = 2, + + /** Human Interface Device class */ + LIBUSB_CLASS_HID = 3, + + /** Physical */ + LIBUSB_CLASS_PHYSICAL = 5, + + /** Printer class */ + LIBUSB_CLASS_PRINTER = 7, + + /** Image class */ + LIBUSB_CLASS_PTP = 6, /* legacy name from libusb-0.1 usb.h */ + LIBUSB_CLASS_IMAGE = 6, + + /** Mass storage class */ + LIBUSB_CLASS_MASS_STORAGE = 8, + + /** Hub class */ + LIBUSB_CLASS_HUB = 9, + + /** Data class */ + LIBUSB_CLASS_DATA = 10, + + /** Smart Card */ + LIBUSB_CLASS_SMART_CARD = 0x0b, + + /** Content Security */ + LIBUSB_CLASS_CONTENT_SECURITY = 0x0d, + + /** Video */ + LIBUSB_CLASS_VIDEO = 0x0e, + + /** Personal Healthcare */ + LIBUSB_CLASS_PERSONAL_HEALTHCARE = 0x0f, + + /** Diagnostic Device */ + LIBUSB_CLASS_DIAGNOSTIC_DEVICE = 0xdc, + + /** Wireless class */ + LIBUSB_CLASS_WIRELESS = 0xe0, + + /** Application class */ + LIBUSB_CLASS_APPLICATION = 0xfe, + + /** Class is vendor-specific */ + LIBUSB_CLASS_VENDOR_SPEC = 0xff +}; + +/** \ingroup desc + * Descriptor types as defined by the USB specification. */ +enum libusb_descriptor_type { + /** Device descriptor. See libusb_device_descriptor. */ + LIBUSB_DT_DEVICE = 0x01, + + /** Configuration descriptor. See libusb_config_descriptor. */ + LIBUSB_DT_CONFIG = 0x02, + + /** String descriptor */ + LIBUSB_DT_STRING = 0x03, + + /** Interface descriptor. See libusb_interface_descriptor. */ + LIBUSB_DT_INTERFACE = 0x04, + + /** Endpoint descriptor. See libusb_endpoint_descriptor. */ + LIBUSB_DT_ENDPOINT = 0x05, + + /** BOS descriptor */ + LIBUSB_DT_BOS = 0x0f, + + /** Device Capability descriptor */ + LIBUSB_DT_DEVICE_CAPABILITY = 0x10, + + /** HID descriptor */ + LIBUSB_DT_HID = 0x21, + + /** HID report descriptor */ + LIBUSB_DT_REPORT = 0x22, + + /** Physical descriptor */ + LIBUSB_DT_PHYSICAL = 0x23, + + /** Hub descriptor */ + LIBUSB_DT_HUB = 0x29, + + /** SuperSpeed Hub descriptor */ + LIBUSB_DT_SUPERSPEED_HUB = 0x2a, + + /** SuperSpeed Endpoint Companion descriptor */ + LIBUSB_DT_SS_ENDPOINT_COMPANION = 0x30 +}; + +/* Descriptor sizes per descriptor type */ +#define LIBUSB_DT_DEVICE_SIZE 18 +#define LIBUSB_DT_CONFIG_SIZE 9 +#define LIBUSB_DT_INTERFACE_SIZE 9 +#define LIBUSB_DT_ENDPOINT_SIZE 7 +#define LIBUSB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ +#define LIBUSB_DT_HUB_NONVAR_SIZE 7 +#define LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE 6 +#define LIBUSB_DT_BOS_SIZE 5 +#define LIBUSB_DT_DEVICE_CAPABILITY_SIZE 3 + +/* BOS descriptor sizes */ +#define LIBUSB_BT_USB_2_0_EXTENSION_SIZE 7 +#define LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE 10 +#define LIBUSB_BT_CONTAINER_ID_SIZE 20 + +/* We unwrap the BOS => define its max size */ +#define LIBUSB_DT_BOS_MAX_SIZE ((LIBUSB_DT_BOS_SIZE) +\ + (LIBUSB_BT_USB_2_0_EXTENSION_SIZE) +\ + (LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) +\ + (LIBUSB_BT_CONTAINER_ID_SIZE)) + +#define LIBUSB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ +#define LIBUSB_ENDPOINT_DIR_MASK 0x80 + +/** \ingroup desc + * Endpoint direction. Values for bit 7 of the + * \ref libusb_endpoint_descriptor::bEndpointAddress "endpoint address" scheme. + */ +enum libusb_endpoint_direction { + /** In: device-to-host */ + LIBUSB_ENDPOINT_IN = 0x80, + + /** Out: host-to-device */ + LIBUSB_ENDPOINT_OUT = 0x00 +}; + +#define LIBUSB_TRANSFER_TYPE_MASK 0x03 /* in bmAttributes */ + +/** \ingroup desc + * Endpoint transfer type. Values for bits 0:1 of the + * \ref libusb_endpoint_descriptor::bmAttributes "endpoint attributes" field. + */ +enum libusb_transfer_type { + /** Control endpoint */ + LIBUSB_TRANSFER_TYPE_CONTROL = 0, + + /** Isochronous endpoint */ + LIBUSB_TRANSFER_TYPE_ISOCHRONOUS = 1, + + /** Bulk endpoint */ + LIBUSB_TRANSFER_TYPE_BULK = 2, + + /** Interrupt endpoint */ + LIBUSB_TRANSFER_TYPE_INTERRUPT = 3, + + /** Stream endpoint */ + LIBUSB_TRANSFER_TYPE_BULK_STREAM = 4, +}; + +/** \ingroup misc + * Standard requests, as defined in table 9-5 of the USB 3.0 specifications */ +enum libusb_standard_request { + /** Request status of the specific recipient */ + LIBUSB_REQUEST_GET_STATUS = 0x00, + + /** Clear or disable a specific feature */ + LIBUSB_REQUEST_CLEAR_FEATURE = 0x01, + + /* 0x02 is reserved */ + + /** Set or enable a specific feature */ + LIBUSB_REQUEST_SET_FEATURE = 0x03, + + /* 0x04 is reserved */ + + /** Set device address for all future accesses */ + LIBUSB_REQUEST_SET_ADDRESS = 0x05, + + /** Get the specified descriptor */ + LIBUSB_REQUEST_GET_DESCRIPTOR = 0x06, + + /** Used to update existing descriptors or add new descriptors */ + LIBUSB_REQUEST_SET_DESCRIPTOR = 0x07, + + /** Get the current device configuration value */ + LIBUSB_REQUEST_GET_CONFIGURATION = 0x08, + + /** Set device configuration */ + LIBUSB_REQUEST_SET_CONFIGURATION = 0x09, + + /** Return the selected alternate setting for the specified interface */ + LIBUSB_REQUEST_GET_INTERFACE = 0x0A, + + /** Select an alternate interface for the specified interface */ + LIBUSB_REQUEST_SET_INTERFACE = 0x0B, + + /** Set then report an endpoint's synchronization frame */ + LIBUSB_REQUEST_SYNCH_FRAME = 0x0C, + + /** Sets both the U1 and U2 Exit Latency */ + LIBUSB_REQUEST_SET_SEL = 0x30, + + /** Delay from the time a host transmits a packet to the time it is + * received by the device. */ + LIBUSB_SET_ISOCH_DELAY = 0x31, +}; + +/** \ingroup misc + * Request type bits of the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field in control + * transfers. */ +enum libusb_request_type { + /** Standard */ + LIBUSB_REQUEST_TYPE_STANDARD = (0x00 << 5), + + /** Class */ + LIBUSB_REQUEST_TYPE_CLASS = (0x01 << 5), + + /** Vendor */ + LIBUSB_REQUEST_TYPE_VENDOR = (0x02 << 5), + + /** Reserved */ + LIBUSB_REQUEST_TYPE_RESERVED = (0x03 << 5) +}; + +/** \ingroup misc + * Recipient bits of the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field in control + * transfers. Values 4 through 31 are reserved. */ +enum libusb_request_recipient { + /** Device */ + LIBUSB_RECIPIENT_DEVICE = 0x00, + + /** Interface */ + LIBUSB_RECIPIENT_INTERFACE = 0x01, + + /** Endpoint */ + LIBUSB_RECIPIENT_ENDPOINT = 0x02, + + /** Other */ + LIBUSB_RECIPIENT_OTHER = 0x03, +}; + +#define LIBUSB_ISO_SYNC_TYPE_MASK 0x0C + +/** \ingroup desc + * Synchronization type for isochronous endpoints. Values for bits 2:3 of the + * \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in + * libusb_endpoint_descriptor. + */ +enum libusb_iso_sync_type { + /** No synchronization */ + LIBUSB_ISO_SYNC_TYPE_NONE = 0, + + /** Asynchronous */ + LIBUSB_ISO_SYNC_TYPE_ASYNC = 1, + + /** Adaptive */ + LIBUSB_ISO_SYNC_TYPE_ADAPTIVE = 2, + + /** Synchronous */ + LIBUSB_ISO_SYNC_TYPE_SYNC = 3 +}; + +#define LIBUSB_ISO_USAGE_TYPE_MASK 0x30 + +/** \ingroup desc + * Usage type for isochronous endpoints. Values for bits 4:5 of the + * \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in + * libusb_endpoint_descriptor. + */ +enum libusb_iso_usage_type { + /** Data endpoint */ + LIBUSB_ISO_USAGE_TYPE_DATA = 0, + + /** Feedback endpoint */ + LIBUSB_ISO_USAGE_TYPE_FEEDBACK = 1, + + /** Implicit feedback Data endpoint */ + LIBUSB_ISO_USAGE_TYPE_IMPLICIT = 2, +}; + +/** \ingroup desc + * A structure representing the standard USB device descriptor. This + * descriptor is documented in section 9.6.1 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_device_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE LIBUSB_DT_DEVICE in this + * context. */ + uint8_t bDescriptorType; + + /** USB specification release number in binary-coded decimal. A value of + * 0x0200 indicates USB 2.0, 0x0110 indicates USB 1.1, etc. */ + uint16_t bcdUSB; + + /** USB-IF class code for the device. See \ref libusb_class_code. */ + uint8_t bDeviceClass; + + /** USB-IF subclass code for the device, qualified by the bDeviceClass + * value */ + uint8_t bDeviceSubClass; + + /** USB-IF protocol code for the device, qualified by the bDeviceClass and + * bDeviceSubClass values */ + uint8_t bDeviceProtocol; + + /** Maximum packet size for endpoint 0 */ + uint8_t bMaxPacketSize0; + + /** USB-IF vendor ID */ + uint16_t idVendor; + + /** USB-IF product ID */ + uint16_t idProduct; + + /** Device release number in binary-coded decimal */ + uint16_t bcdDevice; + + /** Index of string descriptor describing manufacturer */ + uint8_t iManufacturer; + + /** Index of string descriptor describing product */ + uint8_t iProduct; + + /** Index of string descriptor containing device serial number */ + uint8_t iSerialNumber; + + /** Number of possible configurations */ + uint8_t bNumConfigurations; +}; + +/** \ingroup desc + * A structure representing the standard USB endpoint descriptor. This + * descriptor is documented in section 9.6.6 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_endpoint_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_ENDPOINT LIBUSB_DT_ENDPOINT in + * this context. */ + uint8_t bDescriptorType; + + /** The address of the endpoint described by this descriptor. Bits 0:3 are + * the endpoint number. Bits 4:6 are reserved. Bit 7 indicates direction, + * see \ref libusb_endpoint_direction. + */ + uint8_t bEndpointAddress; + + /** Attributes which apply to the endpoint when it is configured using + * the bConfigurationValue. Bits 0:1 determine the transfer type and + * correspond to \ref libusb_transfer_type. Bits 2:3 are only used for + * isochronous endpoints and correspond to \ref libusb_iso_sync_type. + * Bits 4:5 are also only used for isochronous endpoints and correspond to + * \ref libusb_iso_usage_type. Bits 6:7 are reserved. + */ + uint8_t bmAttributes; + + /** Maximum packet size this endpoint is capable of sending/receiving. */ + uint16_t wMaxPacketSize; + + /** Interval for polling endpoint for data transfers. */ + uint8_t bInterval; + + /** For audio devices only: the rate at which synchronization feedback + * is provided. */ + uint8_t bRefresh; + + /** For audio devices only: the address if the synch endpoint */ + uint8_t bSynchAddress; + + /** Extra descriptors. If libusb encounters unknown endpoint descriptors, + * it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup desc + * A structure representing the standard USB interface descriptor. This + * descriptor is documented in section 9.6.5 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_interface_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_INTERFACE LIBUSB_DT_INTERFACE + * in this context. */ + uint8_t bDescriptorType; + + /** Number of this interface */ + uint8_t bInterfaceNumber; + + /** Value used to select this alternate setting for this interface */ + uint8_t bAlternateSetting; + + /** Number of endpoints used by this interface (excluding the control + * endpoint). */ + uint8_t bNumEndpoints; + + /** USB-IF class code for this interface. See \ref libusb_class_code. */ + uint8_t bInterfaceClass; + + /** USB-IF subclass code for this interface, qualified by the + * bInterfaceClass value */ + uint8_t bInterfaceSubClass; + + /** USB-IF protocol code for this interface, qualified by the + * bInterfaceClass and bInterfaceSubClass values */ + uint8_t bInterfaceProtocol; + + /** Index of string descriptor describing this interface */ + uint8_t iInterface; + + /** Array of endpoint descriptors. This length of this array is determined + * by the bNumEndpoints field. */ + const struct libusb_endpoint_descriptor *endpoint; + + /** Extra descriptors. If libusb encounters unknown interface descriptors, + * it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup desc + * A collection of alternate settings for a particular USB interface. + */ +struct libusb_interface { + /** Array of interface descriptors. The length of this array is determined + * by the num_altsetting field. */ + const struct libusb_interface_descriptor *altsetting; + + /** The number of alternate settings that belong to this interface */ + int num_altsetting; +}; + +/** \ingroup desc + * A structure representing the standard USB configuration descriptor. This + * descriptor is documented in section 9.6.3 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_config_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_CONFIG LIBUSB_DT_CONFIG + * in this context. */ + uint8_t bDescriptorType; + + /** Total length of data returned for this configuration */ + uint16_t wTotalLength; + + /** Number of interfaces supported by this configuration */ + uint8_t bNumInterfaces; + + /** Identifier value for this configuration */ + uint8_t bConfigurationValue; + + /** Index of string descriptor describing this configuration */ + uint8_t iConfiguration; + + /** Configuration characteristics */ + uint8_t bmAttributes; + + /** Maximum power consumption of the USB device from this bus in this + * configuration when the device is fully operation. Expressed in units + * of 2 mA when the device is operating in high-speed mode and in units + * of 8 mA when the device is operating in super-speed mode. */ + uint8_t MaxPower; + + /** Array of interfaces supported by this configuration. The length of + * this array is determined by the bNumInterfaces field. */ + const struct libusb_interface *interface; + + /** Extra descriptors. If libusb encounters unknown configuration + * descriptors, it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup desc + * A structure representing the superspeed endpoint companion + * descriptor. This descriptor is documented in section 9.6.7 of + * the USB 3.0 specification. All multiple-byte fields are represented in + * host-endian format. + */ +struct libusb_ss_endpoint_companion_descriptor { + + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_SS_ENDPOINT_COMPANION in + * this context. */ + uint8_t bDescriptorType; + + + /** The maximum number of packets the endpoint can send or + * recieve as part of a burst. */ + uint8_t bMaxBurst; + + /** In bulk EP: bits 4:0 represents the maximum number of + * streams the EP supports. In isochronous EP: bits 1:0 + * represents the Mult - a zero based value that determines + * the maximum number of packets within a service interval */ + uint8_t bmAttributes; + + /** The total number of bytes this EP will transfer every + * service interval. valid only for periodic EPs. */ + uint16_t wBytesPerInterval; +}; + +/** \ingroup desc + * A generic representation of a BOS Device Capability descriptor. It is + * advised to check bDevCapabilityType and call the matching + * libusb_get_*_descriptor function to get a structure fully matching the type. + */ +struct libusb_bos_dev_capability_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + /** Device Capability type */ + uint8_t bDevCapabilityType; + /** Device Capability data (bLength - 3 bytes) */ + uint8_t dev_capability_data +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif + ; +}; + +/** \ingroup desc + * A structure representing the Binary Device Object Store (BOS) descriptor. + * This descriptor is documented in section 9.6.2 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_bos_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_BOS LIBUSB_DT_BOS + * in this context. */ + uint8_t bDescriptorType; + + /** Length of this descriptor and all of its sub descriptors */ + uint16_t wTotalLength; + + /** The number of separate device capability descriptors in + * the BOS */ + uint8_t bNumDeviceCaps; + + /** bNumDeviceCap Device Capability Descriptors */ + struct libusb_bos_dev_capability_descriptor *dev_capability +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif + ; +}; + +/** \ingroup desc + * A structure representing the USB 2.0 Extension descriptor + * This descriptor is documented in section 9.6.2.1 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_usb_2_0_extension_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + + /** Capability type. Will have value + * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION + * LIBUSB_BT_USB_2_0_EXTENSION in this context. */ + uint8_t bDevCapabilityType; + + /** Bitmap encoding of supported device level features. + * A value of one in a bit location indicates a feature is + * supported; a value of zero indicates it is not supported. + * See \ref libusb_usb_2_0_extension_attributes. */ + uint32_t bmAttributes; +}; + +/** \ingroup desc + * A structure representing the SuperSpeed USB Device Capability descriptor + * This descriptor is documented in section 9.6.2.2 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_ss_usb_device_capability_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + + /** Capability type. Will have value + * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY + * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY in this context. */ + uint8_t bDevCapabilityType; + + /** Bitmap encoding of supported device level features. + * A value of one in a bit location indicates a feature is + * supported; a value of zero indicates it is not supported. + * See \ref libusb_ss_usb_device_capability_attributes. */ + uint8_t bmAttributes; + + /** Bitmap encoding of the speed supported by this device when + * operating in SuperSpeed mode. See \ref libusb_supported_speed. */ + uint16_t wSpeedSupported; + + /** The lowest speed at which all the functionality supported + * by the device is available to the user. For example if the + * device supports all its functionality when connected at + * full speed and above then it sets this value to 1. */ + uint8_t bFunctionalitySupport; + + /** U1 Device Exit Latency. */ + uint8_t bU1DevExitLat; + + /** U2 Device Exit Latency. */ + uint16_t bU2DevExitLat; +}; + +/** \ingroup desc + * A structure representing the Container ID descriptor. + * This descriptor is documented in section 9.6.2.3 of the USB 3.0 specification. + * All multiple-byte fields, except UUIDs, are represented in host-endian format. + */ +struct libusb_container_id_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + + /** Capability type. Will have value + * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID + * LIBUSB_BT_CONTAINER_ID in this context. */ + uint8_t bDevCapabilityType; + + /** Reserved field */ + uint8_t bReserved; + + /** 128 bit UUID */ + uint8_t ContainerID[16]; +}; + +/** \ingroup asyncio + * Setup packet for control transfers. */ +struct libusb_control_setup { + /** Request type. Bits 0:4 determine recipient, see + * \ref libusb_request_recipient. Bits 5:6 determine type, see + * \ref libusb_request_type. Bit 7 determines data transfer direction, see + * \ref libusb_endpoint_direction. + */ + uint8_t bmRequestType; + + /** Request. If the type bits of bmRequestType are equal to + * \ref libusb_request_type::LIBUSB_REQUEST_TYPE_STANDARD + * "LIBUSB_REQUEST_TYPE_STANDARD" then this field refers to + * \ref libusb_standard_request. For other cases, use of this field is + * application-specific. */ + uint8_t bRequest; + + /** Value. Varies according to request */ + uint16_t wValue; + + /** Index. Varies according to request, typically used to pass an index + * or offset */ + uint16_t wIndex; + + /** Number of bytes to transfer */ + uint16_t wLength; +}; + +#define LIBUSB_CONTROL_SETUP_SIZE (sizeof(struct libusb_control_setup)) + +/* libusb */ + +struct libusb_context; +struct libusb_device; +struct libusb_device_handle; + +/** \ingroup lib + * Structure providing the version of the libusb runtime + */ +struct libusb_version { + /** Library major version. */ + const uint16_t major; + + /** Library minor version. */ + const uint16_t minor; + + /** Library micro version. */ + const uint16_t micro; + + /** Library nano version. */ + const uint16_t nano; + + /** Library release candidate suffix string, e.g. "-rc4". */ + const char *rc; + + /** For ABI compatibility only. */ + const char* describe; +}; + +/** \ingroup lib + * Structure representing a libusb session. The concept of individual libusb + * sessions allows for your program to use two libraries (or dynamically + * load two modules) which both independently use libusb. This will prevent + * interference between the individual libusb users - for example + * libusb_set_debug() will not affect the other user of the library, and + * libusb_exit() will not destroy resources that the other user is still + * using. + * + * Sessions are created by libusb_init() and destroyed through libusb_exit(). + * If your application is guaranteed to only ever include a single libusb + * user (i.e. you), you do not have to worry about contexts: pass NULL in + * every function call where a context is required. The default context + * will be used. + * + * For more information, see \ref contexts. + */ +typedef struct libusb_context libusb_context; + +/** \ingroup dev + * Structure representing a USB device detected on the system. This is an + * opaque type for which you are only ever provided with a pointer, usually + * originating from libusb_get_device_list(). + * + * Certain operations can be performed on a device, but in order to do any + * I/O you will have to first obtain a device handle using libusb_open(). + * + * Devices are reference counted with libusb_ref_device() and + * libusb_unref_device(), and are freed when the reference count reaches 0. + * New devices presented by libusb_get_device_list() have a reference count of + * 1, and libusb_free_device_list() can optionally decrease the reference count + * on all devices in the list. libusb_open() adds another reference which is + * later destroyed by libusb_close(). + */ +typedef struct libusb_device libusb_device; + + +/** \ingroup dev + * Structure representing a handle on a USB device. This is an opaque type for + * which you are only ever provided with a pointer, usually originating from + * libusb_open(). + * + * A device handle is used to perform I/O and other operations. When finished + * with a device handle, you should call libusb_close(). + */ +typedef struct libusb_device_handle libusb_device_handle; + +/** \ingroup dev + * Speed codes. Indicates the speed at which the device is operating. + */ +enum libusb_speed { + /** The OS doesn't report or know the device speed. */ + LIBUSB_SPEED_UNKNOWN = 0, + + /** The device is operating at low speed (1.5MBit/s). */ + LIBUSB_SPEED_LOW = 1, + + /** The device is operating at full speed (12MBit/s). */ + LIBUSB_SPEED_FULL = 2, + + /** The device is operating at high speed (480MBit/s). */ + LIBUSB_SPEED_HIGH = 3, + + /** The device is operating at super speed (5000MBit/s). */ + LIBUSB_SPEED_SUPER = 4, +}; + +/** \ingroup dev + * Supported speeds (wSpeedSupported) bitfield. Indicates what + * speeds the device supports. + */ +enum libusb_supported_speed { + /** Low speed operation supported (1.5MBit/s). */ + LIBUSB_LOW_SPEED_OPERATION = 1, + + /** Full speed operation supported (12MBit/s). */ + LIBUSB_FULL_SPEED_OPERATION = 2, + + /** High speed operation supported (480MBit/s). */ + LIBUSB_HIGH_SPEED_OPERATION = 4, + + /** Superspeed operation supported (5000MBit/s). */ + LIBUSB_SUPER_SPEED_OPERATION = 8, +}; + +/** \ingroup dev + * Masks for the bits of the + * \ref libusb_usb_2_0_extension_descriptor::bmAttributes "bmAttributes" field + * of the USB 2.0 Extension descriptor. + */ +enum libusb_usb_2_0_extension_attributes { + /** Supports Link Power Management (LPM) */ + LIBUSB_BM_LPM_SUPPORT = 2, +}; + +/** \ingroup dev + * Masks for the bits of the + * \ref libusb_ss_usb_device_capability_descriptor::bmAttributes "bmAttributes" field + * field of the SuperSpeed USB Device Capability descriptor. + */ +enum libusb_ss_usb_device_capability_attributes { + /** Supports Latency Tolerance Messages (LTM) */ + LIBUSB_BM_LTM_SUPPORT = 2, +}; + +/** \ingroup dev + * USB capability types + */ +enum libusb_bos_type { + /** Wireless USB device capability */ + LIBUSB_BT_WIRELESS_USB_DEVICE_CAPABILITY = 1, + + /** USB 2.0 extensions */ + LIBUSB_BT_USB_2_0_EXTENSION = 2, + + /** SuperSpeed USB device capability */ + LIBUSB_BT_SS_USB_DEVICE_CAPABILITY = 3, + + /** Container ID type */ + LIBUSB_BT_CONTAINER_ID = 4, +}; + +/** \ingroup misc + * Error codes. Most libusb functions return 0 on success or one of these + * codes on failure. + * You can call libusb_error_name() to retrieve a string representation of an + * error code or libusb_strerror() to get an end-user suitable description of + * an error code. + */ +enum libusb_error { + /** Success (no error) */ + LIBUSB_SUCCESS = 0, + + /** Input/output error */ + LIBUSB_ERROR_IO = -1, + + /** Invalid parameter */ + LIBUSB_ERROR_INVALID_PARAM = -2, + + /** Access denied (insufficient permissions) */ + LIBUSB_ERROR_ACCESS = -3, + + /** No such device (it may have been disconnected) */ + LIBUSB_ERROR_NO_DEVICE = -4, + + /** Entity not found */ + LIBUSB_ERROR_NOT_FOUND = -5, + + /** Resource busy */ + LIBUSB_ERROR_BUSY = -6, + + /** Operation timed out */ + LIBUSB_ERROR_TIMEOUT = -7, + + /** Overflow */ + LIBUSB_ERROR_OVERFLOW = -8, + + /** Pipe error */ + LIBUSB_ERROR_PIPE = -9, + + /** System call interrupted (perhaps due to signal) */ + LIBUSB_ERROR_INTERRUPTED = -10, + + /** Insufficient memory */ + LIBUSB_ERROR_NO_MEM = -11, + + /** Operation not supported or unimplemented on this platform */ + LIBUSB_ERROR_NOT_SUPPORTED = -12, + + /* NB: Remember to update LIBUSB_ERROR_COUNT below as well as the + message strings in strerror.c when adding new error codes here. */ + + /** Other error */ + LIBUSB_ERROR_OTHER = -99, +}; + +/* Total number of error codes in enum libusb_error */ +#define LIBUSB_ERROR_COUNT 14 + +/** \ingroup asyncio + * Transfer status codes */ +enum libusb_transfer_status { + /** Transfer completed without error. Note that this does not indicate + * that the entire amount of requested data was transferred. */ + LIBUSB_TRANSFER_COMPLETED, + + /** Transfer failed */ + LIBUSB_TRANSFER_ERROR, + + /** Transfer timed out */ + LIBUSB_TRANSFER_TIMED_OUT, + + /** Transfer was cancelled */ + LIBUSB_TRANSFER_CANCELLED, + + /** For bulk/interrupt endpoints: halt condition detected (endpoint + * stalled). For control endpoints: control request not supported. */ + LIBUSB_TRANSFER_STALL, + + /** Device was disconnected */ + LIBUSB_TRANSFER_NO_DEVICE, + + /** Device sent more data than requested */ + LIBUSB_TRANSFER_OVERFLOW, + + /* NB! Remember to update libusb_error_name() + when adding new status codes here. */ +}; + +/** \ingroup asyncio + * libusb_transfer.flags values */ +enum libusb_transfer_flags { + /** Report short frames as errors */ + LIBUSB_TRANSFER_SHORT_NOT_OK = 1<<0, + + /** Automatically free() transfer buffer during libusb_free_transfer() */ + LIBUSB_TRANSFER_FREE_BUFFER = 1<<1, + + /** Automatically call libusb_free_transfer() after callback returns. + * If this flag is set, it is illegal to call libusb_free_transfer() + * from your transfer callback, as this will result in a double-free + * when this flag is acted upon. */ + LIBUSB_TRANSFER_FREE_TRANSFER = 1<<2, + + /** Terminate transfers that are a multiple of the endpoint's + * wMaxPacketSize with an extra zero length packet. This is useful + * when a device protocol mandates that each logical request is + * terminated by an incomplete packet (i.e. the logical requests are + * not separated by other means). + * + * This flag only affects host-to-device transfers to bulk and interrupt + * endpoints. In other situations, it is ignored. + * + * This flag only affects transfers with a length that is a multiple of + * the endpoint's wMaxPacketSize. On transfers of other lengths, this + * flag has no effect. Therefore, if you are working with a device that + * needs a ZLP whenever the end of the logical request falls on a packet + * boundary, then it is sensible to set this flag on every + * transfer (you do not have to worry about only setting it on transfers + * that end on the boundary). + * + * This flag is currently only supported on Linux. + * On other systems, libusb_submit_transfer() will return + * LIBUSB_ERROR_NOT_SUPPORTED for every transfer where this flag is set. + * + * Available since libusb-1.0.9. + */ + LIBUSB_TRANSFER_ADD_ZERO_PACKET = 1 << 3, +}; + +/** \ingroup asyncio + * Isochronous packet descriptor. */ +struct libusb_iso_packet_descriptor { + /** Length of data to request in this packet */ + unsigned int length; + + /** Amount of data that was actually transferred */ + unsigned int actual_length; + + /** Status code for this packet */ + enum libusb_transfer_status status; +}; + +struct libusb_transfer; + +/** \ingroup asyncio + * Asynchronous transfer callback function type. When submitting asynchronous + * transfers, you pass a pointer to a callback function of this type via the + * \ref libusb_transfer::callback "callback" member of the libusb_transfer + * structure. libusb will call this function later, when the transfer has + * completed or failed. See \ref asyncio for more information. + * \param transfer The libusb_transfer struct the callback function is being + * notified about. + */ +typedef void (LIBUSB_CALL *libusb_transfer_cb_fn)(struct libusb_transfer *transfer); + +/** \ingroup asyncio + * The generic USB transfer structure. The user populates this structure and + * then submits it in order to request a transfer. After the transfer has + * completed, the library populates the transfer with the results and passes + * it back to the user. + */ +struct libusb_transfer { + /** Handle of the device that this transfer will be submitted to */ + libusb_device_handle *dev_handle; + + /** A bitwise OR combination of \ref libusb_transfer_flags. */ + uint8_t flags; + + /** Address of the endpoint where this transfer will be sent. */ + unsigned char endpoint; + + /** Type of the endpoint from \ref libusb_transfer_type */ + unsigned char type; + + /** Timeout for this transfer in millseconds. A value of 0 indicates no + * timeout. */ + unsigned int timeout; + + /** The status of the transfer. Read-only, and only for use within + * transfer callback function. + * + * If this is an isochronous transfer, this field may read COMPLETED even + * if there were errors in the frames. Use the + * \ref libusb_iso_packet_descriptor::status "status" field in each packet + * to determine if errors occurred. */ + enum libusb_transfer_status status; + + /** Length of the data buffer */ + int length; + + /** Actual length of data that was transferred. Read-only, and only for + * use within transfer callback function. Not valid for isochronous + * endpoint transfers. */ + int actual_length; + + /** Callback function. This will be invoked when the transfer completes, + * fails, or is cancelled. */ + libusb_transfer_cb_fn callback; + + /** User context data to pass to the callback function. */ + void *user_data; + + /** Data buffer */ + unsigned char *buffer; + + /** Number of isochronous packets. Only used for I/O with isochronous + * endpoints. */ + int num_iso_packets; + + /** Isochronous packet descriptors, for isochronous transfers only. */ + struct libusb_iso_packet_descriptor iso_packet_desc +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif + ; +}; + +/** \ingroup misc + * Capabilities supported by an instance of libusb on the current running + * platform. Test if the loaded library supports a given capability by calling + * \ref libusb_has_capability(). + */ +enum libusb_capability { + /** The libusb_has_capability() API is available. */ + LIBUSB_CAP_HAS_CAPABILITY = 0x0000, + /** Hotplug support is available on this platform. */ + LIBUSB_CAP_HAS_HOTPLUG = 0x0001, + /** The library can access HID devices without requiring user intervention. + * Note that before being able to actually access an HID device, you may + * still have to call additional libusb functions such as + * \ref libusb_detach_kernel_driver(). */ + LIBUSB_CAP_HAS_HID_ACCESS = 0x0100, + /** The library supports detaching of the default USB driver, using + * \ref libusb_detach_kernel_driver(), if one is set by the OS kernel */ + LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER = 0x0101 +}; + +/** \ingroup lib + * Log message levels. + * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default) + * - LIBUSB_LOG_LEVEL_ERROR (1) : error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to stdout, warning + * and error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stdout, + * warnings and errors to stderr + */ +enum libusb_log_level { + LIBUSB_LOG_LEVEL_NONE = 0, + LIBUSB_LOG_LEVEL_ERROR, + LIBUSB_LOG_LEVEL_WARNING, + LIBUSB_LOG_LEVEL_INFO, + LIBUSB_LOG_LEVEL_DEBUG, +}; + +int LIBUSB_CALL libusb_init(libusb_context **ctx); +void LIBUSB_CALL libusb_exit(libusb_context *ctx); +void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level); +const struct libusb_version * LIBUSB_CALL libusb_get_version(void); +int LIBUSB_CALL libusb_has_capability(uint32_t capability); +const char * LIBUSB_CALL libusb_error_name(int errcode); +int LIBUSB_CALL libusb_setlocale(const char *locale); +const char * LIBUSB_CALL libusb_strerror(enum libusb_error errcode); + +ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx, + libusb_device ***list); +void LIBUSB_CALL libusb_free_device_list(libusb_device **list, + int unref_devices); +libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev); +void LIBUSB_CALL libusb_unref_device(libusb_device *dev); + +int LIBUSB_CALL libusb_get_configuration(libusb_device_handle *dev, + int *config); +int LIBUSB_CALL libusb_get_device_descriptor(libusb_device *dev, + struct libusb_device_descriptor *desc); +int LIBUSB_CALL libusb_get_active_config_descriptor(libusb_device *dev, + struct libusb_config_descriptor **config); +int LIBUSB_CALL libusb_get_config_descriptor(libusb_device *dev, + uint8_t config_index, struct libusb_config_descriptor **config); +int LIBUSB_CALL libusb_get_config_descriptor_by_value(libusb_device *dev, + uint8_t bConfigurationValue, struct libusb_config_descriptor **config); +void LIBUSB_CALL libusb_free_config_descriptor( + struct libusb_config_descriptor *config); +int LIBUSB_CALL libusb_get_ss_endpoint_companion_descriptor( + struct libusb_context *ctx, + const struct libusb_endpoint_descriptor *endpoint, + struct libusb_ss_endpoint_companion_descriptor **ep_comp); +void LIBUSB_CALL libusb_free_ss_endpoint_companion_descriptor( + struct libusb_ss_endpoint_companion_descriptor *ep_comp); +int LIBUSB_CALL libusb_get_bos_descriptor(libusb_device_handle *handle, + struct libusb_bos_descriptor **bos); +void LIBUSB_CALL libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos); +int LIBUSB_CALL libusb_get_usb_2_0_extension_descriptor( + struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension); +void LIBUSB_CALL libusb_free_usb_2_0_extension_descriptor( + struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension); +int LIBUSB_CALL libusb_get_ss_usb_device_capability_descriptor( + struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap); +void LIBUSB_CALL libusb_free_ss_usb_device_capability_descriptor( + struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap); +int LIBUSB_CALL libusb_get_container_id_descriptor(struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_container_id_descriptor **container_id); +void LIBUSB_CALL libusb_free_container_id_descriptor( + struct libusb_container_id_descriptor *container_id); +uint8_t LIBUSB_CALL libusb_get_bus_number(libusb_device *dev); +uint8_t LIBUSB_CALL libusb_get_port_number(libusb_device *dev); +int LIBUSB_CALL libusb_get_port_numbers(libusb_device *dev, uint8_t* port_numbers, int port_numbers_len); +LIBUSB_DEPRECATED_FOR(libusb_get_port_numbers) +int LIBUSB_CALL libusb_get_port_path(libusb_context *ctx, libusb_device *dev, uint8_t* path, uint8_t path_length); +libusb_device * LIBUSB_CALL libusb_get_parent(libusb_device *dev); +uint8_t LIBUSB_CALL libusb_get_device_address(libusb_device *dev); +int LIBUSB_CALL libusb_get_device_speed(libusb_device *dev); +int LIBUSB_CALL libusb_get_max_packet_size(libusb_device *dev, + unsigned char endpoint); +int LIBUSB_CALL libusb_get_max_iso_packet_size(libusb_device *dev, + unsigned char endpoint); + +int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **handle); +int LIBUSB_CALL libusb_open2(libusb_device *dev, libusb_device_handle **handle, int fd); +void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle); +libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle); +libusb_device * LIBUSB_CALL libusb_get_device2(libusb_context *ctx, const char *dev_node); + +int LIBUSB_CALL libusb_set_configuration(libusb_device_handle *dev, + int configuration); +int LIBUSB_CALL libusb_claim_interface(libusb_device_handle *dev, + int interface_number); +int LIBUSB_CALL libusb_release_interface(libusb_device_handle *dev, + int interface_number); + +libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid( + libusb_context *ctx, uint16_t vendor_id, uint16_t product_id); + +int LIBUSB_CALL libusb_set_interface_alt_setting(libusb_device_handle *dev, + int interface_number, int alternate_setting); +int LIBUSB_CALL libusb_clear_halt(libusb_device_handle *dev, + unsigned char endpoint); +int LIBUSB_CALL libusb_reset_device(libusb_device_handle *dev); + +int LIBUSB_CALL libusb_alloc_streams(libusb_device_handle *dev, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints); +int LIBUSB_CALL libusb_free_streams(libusb_device_handle *dev, + unsigned char *endpoints, int num_endpoints); + +int LIBUSB_CALL libusb_kernel_driver_active(libusb_device_handle *dev, + int interface_number); +int LIBUSB_CALL libusb_detach_kernel_driver(libusb_device_handle *dev, + int interface_number); +int LIBUSB_CALL libusb_attach_kernel_driver(libusb_device_handle *dev, + int interface_number); +int LIBUSB_CALL libusb_set_auto_detach_kernel_driver( + libusb_device_handle *dev, int enable); + +/* async I/O */ + +/** \ingroup asyncio + * Get the data section of a control transfer. This convenience function is here + * to remind you that the data does not start until 8 bytes into the actual + * buffer, as the setup packet comes first. + * + * Calling this function only makes sense from a transfer callback function, + * or situations where you have already allocated a suitably sized buffer at + * transfer->buffer. + * + * \param transfer a transfer + * \returns pointer to the first byte of the data section + */ +static inline unsigned char *libusb_control_transfer_get_data( + struct libusb_transfer *transfer) +{ + return transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; +} + +/** \ingroup asyncio + * Get the control setup packet of a control transfer. This convenience + * function is here to remind you that the control setup occupies the first + * 8 bytes of the transfer data buffer. + * + * Calling this function only makes sense from a transfer callback function, + * or situations where you have already allocated a suitably sized buffer at + * transfer->buffer. + * + * \param transfer a transfer + * \returns a casted pointer to the start of the transfer data buffer + */ +static inline struct libusb_control_setup *libusb_control_transfer_get_setup( + struct libusb_transfer *transfer) +{ + return (struct libusb_control_setup *)(void *) transfer->buffer; +} + +/** \ingroup asyncio + * Helper function to populate the setup packet (first 8 bytes of the data + * buffer) for a control transfer. The wIndex, wValue and wLength values should + * be given in host-endian byte order. + * + * \param buffer buffer to output the setup packet into + * This pointer must be aligned to at least 2 bytes boundary. + * \param bmRequestType see the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field of + * \ref libusb_control_setup + * \param bRequest see the + * \ref libusb_control_setup::bRequest "bRequest" field of + * \ref libusb_control_setup + * \param wValue see the + * \ref libusb_control_setup::wValue "wValue" field of + * \ref libusb_control_setup + * \param wIndex see the + * \ref libusb_control_setup::wIndex "wIndex" field of + * \ref libusb_control_setup + * \param wLength see the + * \ref libusb_control_setup::wLength "wLength" field of + * \ref libusb_control_setup + */ +static inline void libusb_fill_control_setup(unsigned char *buffer, + uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + uint16_t wLength) +{ + struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *) buffer; + setup->bmRequestType = bmRequestType; + setup->bRequest = bRequest; + setup->wValue = libusb_cpu_to_le16(wValue); + setup->wIndex = libusb_cpu_to_le16(wIndex); + setup->wLength = libusb_cpu_to_le16(wLength); +} + +struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(int iso_packets); +int LIBUSB_CALL libusb_submit_transfer(struct libusb_transfer *transfer); +int LIBUSB_CALL libusb_cancel_transfer(struct libusb_transfer *transfer); +void LIBUSB_CALL libusb_free_transfer(struct libusb_transfer *transfer); +void LIBUSB_CALL libusb_transfer_set_stream_id( + struct libusb_transfer *transfer, uint32_t stream_id); +uint32_t LIBUSB_CALL libusb_transfer_get_stream_id( + struct libusb_transfer *transfer); + +/** \ingroup asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for a control transfer. + * + * If you pass a transfer buffer to this function, the first 8 bytes will + * be interpreted as a control setup packet, and the wLength field will be + * used to automatically populate the \ref libusb_transfer::length "length" + * field of the transfer. Therefore the recommended approach is: + * -# Allocate a suitably sized data buffer (including space for control setup) + * -# Call libusb_fill_control_setup() + * -# If this is a host-to-device transfer with a data stage, put the data + * in place after the setup packet + * -# Call this function + * -# Call libusb_submit_transfer() + * + * It is also legal to pass a NULL buffer to this function, in which case this + * function will not attempt to populate the length field. Remember that you + * must then populate the buffer and length fields later. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param buffer data buffer. If provided, this function will interpret the + * first 8 bytes as a setup packet and infer the transfer length from that. + * This pointer must be aligned to at least 2 bytes boundary. + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_control_transfer( + struct libusb_transfer *transfer, libusb_device_handle *dev_handle, + unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data, + unsigned int timeout) +{ + struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *) buffer; + transfer->dev_handle = dev_handle; + transfer->endpoint = 0; + transfer->type = LIBUSB_TRANSFER_TYPE_CONTROL; + transfer->timeout = timeout; + transfer->buffer = buffer; + if (setup) + transfer->length = (int) (LIBUSB_CONTROL_SETUP_SIZE + + libusb_le16_to_cpu(setup->wLength)); + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for a bulk transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer, + libusb_device_handle *dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_BULK; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for a bulk transfer using bulk streams. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param stream_id bulk stream id for this transfer + * \param buffer data buffer + * \param length length of data buffer + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_bulk_stream_transfer( + struct libusb_transfer *transfer, libusb_device_handle *dev_handle, + unsigned char endpoint, uint32_t stream_id, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) +{ + libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, + length, callback, user_data, timeout); + transfer->type = LIBUSB_TRANSFER_TYPE_BULK_STREAM; + libusb_transfer_set_stream_id(transfer, stream_id); +} + +/** \ingroup asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for an interrupt transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_interrupt_transfer( + struct libusb_transfer *transfer, libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *buffer, int length, + libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for an isochronous transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param num_iso_packets the number of isochronous packets + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer, + libusb_device_handle *dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, int num_iso_packets, + libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->num_iso_packets = num_iso_packets; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup asyncio + * Convenience function to set the length of all packets in an isochronous + * transfer, based on the num_iso_packets field in the transfer structure. + * + * \param transfer a transfer + * \param length the length to set in each isochronous packet descriptor + * \see libusb_get_max_packet_size() + */ +static inline void libusb_set_iso_packet_lengths( + struct libusb_transfer *transfer, unsigned int length) +{ + int i; + for (i = 0; i < transfer->num_iso_packets; i++) + transfer->iso_packet_desc[i].length = length; +} + +/** \ingroup asyncio + * Convenience function to locate the position of an isochronous packet + * within the buffer of an isochronous transfer. + * + * This is a thorough function which loops through all preceding packets, + * accumulating their lengths to find the position of the specified packet. + * Typically you will assign equal lengths to each packet in the transfer, + * and hence the above method is sub-optimal. You may wish to use + * libusb_get_iso_packet_buffer_simple() instead. + * + * \param transfer a transfer + * \param packet the packet to return the address of + * \returns the base address of the packet buffer inside the transfer buffer, + * or NULL if the packet does not exist. + * \see libusb_get_iso_packet_buffer_simple() + */ +static inline unsigned char *libusb_get_iso_packet_buffer( + struct libusb_transfer *transfer, unsigned int packet) +{ + int i; + size_t offset = 0; + int _packet; + + /* oops..slight bug in the API. packet is an unsigned int, but we use + * signed integers almost everywhere else. range-check and convert to + * signed to avoid compiler warnings. FIXME for libusb-2. */ + if (packet > INT_MAX) + return NULL; + _packet = (int) packet; + + if (_packet >= transfer->num_iso_packets) + return NULL; + + for (i = 0; i < _packet; i++) + offset += transfer->iso_packet_desc[i].length; + + return transfer->buffer + offset; +} + +/** \ingroup asyncio + * Convenience function to locate the position of an isochronous packet + * within the buffer of an isochronous transfer, for transfers where each + * packet is of identical size. + * + * This function relies on the assumption that every packet within the transfer + * is of identical size to the first packet. Calculating the location of + * the packet buffer is then just a simple calculation: + * buffer + (packet_size * packet) + * + * Do not use this function on transfers other than those that have identical + * packet lengths for each packet. + * + * \param transfer a transfer + * \param packet the packet to return the address of + * \returns the base address of the packet buffer inside the transfer buffer, + * or NULL if the packet does not exist. + * \see libusb_get_iso_packet_buffer() + */ +static inline unsigned char *libusb_get_iso_packet_buffer_simple( + struct libusb_transfer *transfer, unsigned int packet) +{ + int _packet; + + /* oops..slight bug in the API. packet is an unsigned int, but we use + * signed integers almost everywhere else. range-check and convert to + * signed to avoid compiler warnings. FIXME for libusb-2. */ + if (packet > INT_MAX) + return NULL; + _packet = (int) packet; + + if (_packet >= transfer->num_iso_packets) + return NULL; + + return transfer->buffer + ((int) transfer->iso_packet_desc[0].length * _packet); +} + +/* sync I/O */ + +int LIBUSB_CALL libusb_control_transfer(libusb_device_handle *dev_handle, + uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + unsigned char *data, uint16_t wLength, unsigned int timeout); + +int LIBUSB_CALL libusb_bulk_transfer(libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *data, int length, + int *actual_length, unsigned int timeout); + +int LIBUSB_CALL libusb_interrupt_transfer(libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *data, int length, + int *actual_length, unsigned int timeout); + +/** \ingroup desc + * Retrieve a descriptor from the default control pipe. + * This is a convenience function which formulates the appropriate control + * message to retrieve the descriptor. + * + * \param dev a device handle + * \param desc_type the descriptor type, see \ref libusb_descriptor_type + * \param desc_index the index of the descriptor to retrieve + * \param data output buffer for descriptor + * \param length size of data buffer + * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure + */ +static inline int libusb_get_descriptor(libusb_device_handle *dev, + uint8_t desc_type, uint8_t desc_index, unsigned char *data, int length) +{ + return libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t) ((desc_type << 8) | desc_index), + 0, data, (uint16_t) length, 1000); +} + +/** \ingroup desc + * Retrieve a descriptor from a device. + * This is a convenience function which formulates the appropriate control + * message to retrieve the descriptor. The string returned is Unicode, as + * detailed in the USB specifications. + * + * \param dev a device handle + * \param desc_index the index of the descriptor to retrieve + * \param langid the language ID for the string descriptor + * \param data output buffer for descriptor + * \param length size of data buffer + * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure + * \see libusb_get_string_descriptor_ascii() + */ +static inline int libusb_get_string_descriptor(libusb_device_handle *dev, + uint8_t desc_index, uint16_t langid, unsigned char *data, int length) +{ + return libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t)((LIBUSB_DT_STRING << 8) | desc_index), + langid, data, (uint16_t) length, 1000); +} + +int LIBUSB_CALL libusb_get_string_descriptor_ascii(libusb_device_handle *dev, + uint8_t desc_index, unsigned char *data, int length); + +/* polling and timeouts */ + +int LIBUSB_CALL libusb_try_lock_events(libusb_context *ctx); +void LIBUSB_CALL libusb_lock_events(libusb_context *ctx); +void LIBUSB_CALL libusb_unlock_events(libusb_context *ctx); +int LIBUSB_CALL libusb_event_handling_ok(libusb_context *ctx); +int LIBUSB_CALL libusb_event_handler_active(libusb_context *ctx); +void LIBUSB_CALL libusb_lock_event_waiters(libusb_context *ctx); +void LIBUSB_CALL libusb_unlock_event_waiters(libusb_context *ctx); +int LIBUSB_CALL libusb_wait_for_event(libusb_context *ctx, struct timeval *tv); + +int LIBUSB_CALL libusb_handle_events_timeout(libusb_context *ctx, + struct timeval *tv); +int LIBUSB_CALL libusb_handle_events_timeout_completed(libusb_context *ctx, + struct timeval *tv, int *completed); +int LIBUSB_CALL libusb_handle_events(libusb_context *ctx); +int LIBUSB_CALL libusb_handle_events_completed(libusb_context *ctx, int *completed); +int LIBUSB_CALL libusb_handle_events_locked(libusb_context *ctx, + struct timeval *tv); +int LIBUSB_CALL libusb_pollfds_handle_timeouts(libusb_context *ctx); +int LIBUSB_CALL libusb_get_next_timeout(libusb_context *ctx, + struct timeval *tv); + +/** \ingroup poll + * File descriptor for polling + */ +struct libusb_pollfd { + /** Numeric file descriptor */ + int fd; + + /** Event flags to poll for from . POLLIN indicates that you + * should monitor this file descriptor for becoming ready to read from, + * and POLLOUT indicates that you should monitor this file descriptor for + * nonblocking write readiness. */ + short events; +}; + +/** \ingroup poll + * Callback function, invoked when a new file descriptor should be added + * to the set of file descriptors monitored for events. + * \param fd the new file descriptor + * \param events events to monitor for, see \ref libusb_pollfd for a + * description + * \param user_data User data pointer specified in + * libusb_set_pollfd_notifiers() call + * \see libusb_set_pollfd_notifiers() + */ +typedef void (LIBUSB_CALL *libusb_pollfd_added_cb)(int fd, short events, + void *user_data); + +/** \ingroup poll + * Callback function, invoked when a file descriptor should be removed from + * the set of file descriptors being monitored for events. After returning + * from this callback, do not use that file descriptor again. + * \param fd the file descriptor to stop monitoring + * \param user_data User data pointer specified in + * libusb_set_pollfd_notifiers() call + * \see libusb_set_pollfd_notifiers() + */ +typedef void (LIBUSB_CALL *libusb_pollfd_removed_cb)(int fd, void *user_data); + +const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds( + libusb_context *ctx); +void LIBUSB_CALL libusb_free_pollfds(const struct libusb_pollfd **pollfds); +void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx, + libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, + void *user_data); + +/** \ingroup hotplug + * Callback handle. + * + * Callbacks handles are generated by libusb_hotplug_register_callback() + * and can be used to deregister callbacks. Callback handles are unique + * per libusb_context and it is safe to call libusb_hotplug_deregister_callback() + * on an already deregisted callback. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * For more information, see \ref hotplug. + */ +typedef int libusb_hotplug_callback_handle; + +/** \ingroup hotplug + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * Flags for hotplug events */ +typedef enum { + /** Default value when not using any flags. */ + LIBUSB_HOTPLUG_NO_FLAGS = 0, + + /** Arm the callback and fire it for all matching currently attached devices. */ + LIBUSB_HOTPLUG_ENUMERATE = 1<<0, +} libusb_hotplug_flag; + +/** \ingroup hotplug + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * Hotplug events */ +typedef enum { + /** A device has been plugged in and is ready to use */ + LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED = 0x01, + + /** A device has left and is no longer available. + * It is the user's responsibility to call libusb_close on any handle associated with a disconnected device. + * It is safe to call libusb_get_device_descriptor on a device that has left */ + LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT = 0x02, +} libusb_hotplug_event; + +/** \ingroup hotplug + * Wildcard matching for hotplug events */ +#define LIBUSB_HOTPLUG_MATCH_ANY -1 + +/** \ingroup hotplug + * Hotplug callback function type. When requesting hotplug event notifications, + * you pass a pointer to a callback function of this type. + * + * This callback may be called by an internal event thread and as such it is + * recommended the callback do minimal processing before returning. + * + * libusb will call this function later, when a matching event had happened on + * a matching device. See \ref hotplug for more information. + * + * It is safe to call either libusb_hotplug_register_callback() or + * libusb_hotplug_deregister_callback() from within a callback function. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * \param ctx context of this notification + * \param device libusb_device this event occurred on + * \param event event that occurred + * \param user_data user data provided when this callback was registered + * \returns bool whether this callback is finished processing events. + * returning 1 will cause this callback to be deregistered + */ +typedef int (LIBUSB_CALL *libusb_hotplug_callback_fn)(libusb_context *ctx, + libusb_device *device, + libusb_hotplug_event event, + void *user_data); + +/** \ingroup hotplug + * Register a hotplug callback function + * + * Register a callback with the libusb_context. The callback will fire + * when a matching event occurs on a matching device. The callback is + * armed until either it is deregistered with libusb_hotplug_deregister_callback() + * or the supplied callback returns 1 to indicate it is finished processing events. + * + * If the \ref LIBUSB_HOTPLUG_ENUMERATE is passed the callback will be + * called with a \ref LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED for all devices + * already plugged into the machine. Note that libusb modifies its internal + * device list from a separate thread, while calling hotplug callbacks from + * libusb_handle_events(), so it is possible for a device to already be present + * on, or removed from, its internal device list, while the hotplug callbacks + * still need to be dispatched. This means that when using \ref + * LIBUSB_HOTPLUG_ENUMERATE, your callback may be called twice for the arrival + * of the same device, once from libusb_hotplug_register_callback() and once + * from libusb_handle_events(); and/or your callback may be called for the + * removal of a device for which an arrived call was never made. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * \param[in] ctx context to register this callback with + * \param[in] events bitwise or of events that will trigger this callback. See \ref + * libusb_hotplug_event + * \param[in] flags hotplug callback flags. See \ref libusb_hotplug_flag + * \param[in] vendor_id the vendor id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + * \param[in] product_id the product id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + * \param[in] dev_class the device class to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + * \param[in] cb_fn the function to be invoked on a matching event/device + * \param[in] user_data user data to pass to the callback function + * \param[out] handle pointer to store the handle of the allocated callback (can be NULL) + * \returns LIBUSB_SUCCESS on success LIBUSB_ERROR code on failure + */ +int LIBUSB_CALL libusb_hotplug_register_callback(libusb_context *ctx, + libusb_hotplug_event events, + libusb_hotplug_flag flags, + int vendor_id, int product_id, + int dev_class, + libusb_hotplug_callback_fn cb_fn, + void *user_data, + libusb_hotplug_callback_handle *handle); + +/** \ingroup hotplug + * Deregisters a hotplug callback. + * + * Deregister a callback from a libusb_context. This function is safe to call from within + * a hotplug callback. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * \param[in] ctx context this callback is registered with + * \param[in] handle the handle of the callback to deregister + */ +void LIBUSB_CALL libusb_hotplug_deregister_callback(libusb_context *ctx, + libusb_hotplug_callback_handle handle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/libusb.h.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/libusb.h.REMOVED.git-id deleted file mode 100644 index 12ee5e49..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/libusb.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6549d2eb4ca85f75d155f24946e9615663b90980 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/libusbi.h b/Desktop_Interface/build_android/libusb-martin-kuldeep/libusbi.h new file mode 100644 index 00000000..447ad045 --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/libusbi.h @@ -0,0 +1,1120 @@ +/* + * Internal header for libusb + * Copyright © 2007-2009 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * Copyright © 2013-2016 Martin Marinov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSBI_H +#define LIBUSBI_H + +#include + +#include + +#include +#include +#include +#include +#ifdef HAVE_POLL_H +#include +#endif +#ifdef HAVE_MISSING_H +#include +#endif + +#include "libusb.h" +#include "version.h" + +/* Inside the libusb code, mark all public functions as follows: + * return_type API_EXPORTED function_name(params) { ... } + * But if the function returns a pointer, mark it as follows: + * DEFAULT_VISIBILITY return_type * LIBUSB_CALL function_name(params) { ... } + * In the libusb public header, mark all declarations as: + * return_type LIBUSB_CALL function_name(params); + */ +#define API_EXPORTED LIBUSB_CALL DEFAULT_VISIBILITY + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEVICE_DESC_LENGTH 18 + +#define USB_MAXENDPOINTS 32 +#define USB_MAXINTERFACES 32 +#define USB_MAXCONFIG 8 + +/* Backend specific capabilities */ +#define USBI_CAP_HAS_HID_ACCESS 0x00010000 +#define USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER 0x00020000 + +/* Maximum number of bytes in a log line */ +#define USBI_MAX_LOG_LEN 1024 +/* Terminator for log lines */ +#define USBI_LOG_LINE_END "\n" + +/* The following is used to silence warnings for unused variables */ +#define UNUSED(var) do { (void)(var); } while(0) + +#if !defined(ARRAYSIZE) +#define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0])) +#endif + +struct list_head { + struct list_head *prev, *next; +}; + +/* Get an entry from the list + * ptr - the address of this list_head element in "type" + * type - the data type that contains "member" + * member - the list_head element in "type" + */ +#define list_entry(ptr, type, member) \ + ((type *)((uintptr_t)(ptr) - (uintptr_t)offsetof(type, member))) + +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +/* Get each entry from a list + * pos - A structure pointer has a "member" element + * head - list head + * member - the list_head element in "pos" + * type - the type of the first parameter + */ +#define list_for_each_entry(pos, head, member, type) \ + for (pos = list_entry((head)->next, type, member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, type, member)) + +#define list_for_each_entry_safe(pos, n, head, member, type) \ + for (pos = list_entry((head)->next, type, member), \ + n = list_entry(pos->member.next, type, member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, type, member)) + +#define list_empty(entry) ((entry)->next == (entry)) + +static inline void list_init(struct list_head *entry) +{ + entry->prev = entry->next = entry; +} + +static inline void list_add(struct list_head *entry, struct list_head *head) +{ + entry->next = head->next; + entry->prev = head; + + head->next->prev = entry; + head->next = entry; +} + +static inline void list_add_tail(struct list_head *entry, + struct list_head *head) +{ + entry->next = head; + entry->prev = head->prev; + + head->prev->next = entry; + head->prev = entry; +} + +static inline void list_del(struct list_head *entry) +{ + entry->next->prev = entry->prev; + entry->prev->next = entry->next; + entry->next = entry->prev = NULL; +} + +static inline void *usbi_reallocf(void *ptr, size_t size) +{ + void *ret = realloc(ptr, size); + if (!ret) + free(ptr); + return ret; +} + +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *mptr = (ptr); \ + (type *)( (char *)mptr - offsetof(type,member) );}) + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +#define TIMESPEC_IS_SET(ts) ((ts)->tv_sec != 0 || (ts)->tv_nsec != 0) + +/* Some platforms don't have this define */ +#ifndef TIMESPEC_TO_TIMEVAL +#define TIMESPEC_TO_TIMEVAL(tv, ts) \ + do { \ + (tv)->tv_sec = (ts)->tv_sec; \ + (tv)->tv_usec = (ts)->tv_nsec / 1000; \ + } while (0) +#endif + +void usbi_log(struct libusb_context *ctx, enum libusb_log_level level, + const char *function, const char *format, ...); + +void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level, + const char *function, const char *format, va_list args); + +#if !defined(_MSC_VER) || _MSC_VER >= 1400 + +#ifdef ENABLE_LOGGING +#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __FUNCTION__, __VA_ARGS__) +#define usbi_dbg(...) _usbi_log(NULL, LIBUSB_LOG_LEVEL_DEBUG, __VA_ARGS__) +#else +#define _usbi_log(ctx, level, ...) do { (void)(ctx); } while(0) +#define usbi_dbg(...) do {} while(0) +#endif + +#define usbi_info(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_INFO, __VA_ARGS__) +#define usbi_warn(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_WARNING, __VA_ARGS__) +#define usbi_err(ctx, ...) _usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__) + +#else /* !defined(_MSC_VER) || _MSC_VER >= 1400 */ + +#ifdef ENABLE_LOGGING +#define LOG_BODY(ctxt, level) \ +{ \ + va_list args; \ + va_start (args, format); \ + usbi_log_v(ctxt, level, "", format, args); \ + va_end(args); \ +} +#else +#define LOG_BODY(ctxt, level) do { (void)(ctxt); } while(0) +#endif + +static inline void usbi_info(struct libusb_context *ctx, const char *format, + ...) + LOG_BODY(ctx,LIBUSB_LOG_LEVEL_INFO) +static inline void usbi_warn(struct libusb_context *ctx, const char *format, + ...) + LOG_BODY(ctx,LIBUSB_LOG_LEVEL_WARNING) +static inline void usbi_err( struct libusb_context *ctx, const char *format, + ...) + LOG_BODY(ctx,LIBUSB_LOG_LEVEL_ERROR) + +static inline void usbi_dbg(const char *format, ...) + LOG_BODY(NULL,LIBUSB_LOG_LEVEL_DEBUG) + +#endif /* !defined(_MSC_VER) || _MSC_VER >= 1400 */ + +#define USBI_GET_CONTEXT(ctx) if (!(ctx)) (ctx) = usbi_default_context +#define DEVICE_CTX(dev) ((dev)->ctx) +#define HANDLE_CTX(handle) (DEVICE_CTX((handle)->dev)) +#define TRANSFER_CTX(transfer) (HANDLE_CTX((transfer)->dev_handle)) +#define ITRANSFER_CTX(transfer) \ + (TRANSFER_CTX(USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer))) + +#define IS_EPIN(ep) (0 != ((ep) & LIBUSB_ENDPOINT_IN)) +#define IS_EPOUT(ep) (!IS_EPIN(ep)) +#define IS_XFERIN(xfer) (0 != ((xfer)->endpoint & LIBUSB_ENDPOINT_IN)) +#define IS_XFEROUT(xfer) (!IS_XFERIN(xfer)) + +/* Internal abstraction for thread synchronization */ +#if defined(THREADS_POSIX) +#include "os/threads_posix.h" +#elif defined(OS_WINDOWS) || defined(OS_WINCE) +#include +#endif + +extern struct libusb_context *usbi_default_context; + +/* Forward declaration for use in context (fully defined inside poll abstraction) */ +struct pollfd; + +struct libusb_context { + int debug; + int debug_fixed; + + /* internal event pipe, used for signalling occurrence of an internal event. */ + int event_pipe[2]; + + struct list_head usb_devs; + usbi_mutex_t usb_devs_lock; + + /* A list of open handles. Backends are free to traverse this if required. + */ + struct list_head open_devs; + usbi_mutex_t open_devs_lock; + + /* A list of registered hotplug callbacks */ + struct list_head hotplug_cbs; + usbi_mutex_t hotplug_cbs_lock; + + /* this is a list of in-flight transfer handles, sorted by timeout + * expiration. URBs to timeout the soonest are placed at the beginning of + * the list, URBs that will time out later are placed after, and urbs with + * infinite timeout are always placed at the very end. */ + struct list_head flying_transfers; + usbi_mutex_t flying_transfers_lock; + + /* user callbacks for pollfd changes */ + libusb_pollfd_added_cb fd_added_cb; + libusb_pollfd_removed_cb fd_removed_cb; + void *fd_cb_user_data; + + /* ensures that only one thread is handling events at any one time */ + usbi_mutex_t events_lock; + + /* used to see if there is an active thread doing event handling */ + int event_handler_active; + + /* A thread-local storage key to track which thread is performing event + * handling */ + usbi_tls_key_t event_handling_key; + + /* used to wait for event completion in threads other than the one that is + * event handling */ + usbi_mutex_t event_waiters_lock; + usbi_cond_t event_waiters_cond; + + /* A lock to protect internal context event data. */ + usbi_mutex_t event_data_lock; + + /* A counter that is set when we want to interrupt and prevent event handling, + * in order to safely close a device. Protected by event_data_lock. */ + unsigned int device_close; + + /* list and count of poll fds and an array of poll fd structures that is + * (re)allocated as necessary prior to polling, and a flag to indicate + * when the list of poll fds has changed since the last poll. + * Protected by event_data_lock. */ + struct list_head ipollfds; + struct pollfd *pollfds; + POLL_NFDS_TYPE pollfds_cnt; + unsigned int pollfds_modified; + + /* A list of pending hotplug messages. Protected by event_data_lock. */ + struct list_head hotplug_msgs; + + /* A list of pending completed transfers. Protected by event_data_lock. */ + struct list_head completed_transfers; + +#ifdef USBI_TIMERFD_AVAILABLE + /* used for timeout handling, if supported by OS. + * this timerfd is maintained to trigger on the next pending timeout */ + int timerfd; +#endif + + struct list_head list; +}; + +/* Macros for managing event handling state */ +#define usbi_handling_events(ctx) \ + (usbi_tls_key_get((ctx)->event_handling_key) != NULL) + +#define usbi_start_event_handling(ctx) \ + usbi_tls_key_set((ctx)->event_handling_key, ctx) + +#define usbi_end_event_handling(ctx) \ + usbi_tls_key_set((ctx)->event_handling_key, NULL) + +/* Update the following macro if new event sources are added */ +#define usbi_pending_events(ctx) \ + ((ctx)->device_close || (ctx)->pollfds_modified \ + || !list_empty(&(ctx)->hotplug_msgs) || !list_empty(&(ctx)->completed_transfers)) + +#ifdef USBI_TIMERFD_AVAILABLE +#define usbi_using_timerfd(ctx) ((ctx)->timerfd >= 0) +#else +#define usbi_using_timerfd(ctx) (0) +#endif + +struct libusb_device { + /* lock protects refcnt, everything else is finalized at initialization + * time */ + usbi_mutex_t lock; + int refcnt; + + struct libusb_context *ctx; + + uint8_t bus_number; + uint8_t port_number; + struct libusb_device* parent_dev; + uint8_t device_address; + uint8_t num_configurations; + enum libusb_speed speed; + + struct list_head list; + unsigned long session_data; + + struct libusb_device_descriptor device_descriptor; + int attached; + + unsigned char os_priv +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif + ; +}; + +struct libusb_device_handle { + /* lock protects claimed_interfaces */ + usbi_mutex_t lock; + unsigned long claimed_interfaces; + + struct list_head list; + struct libusb_device *dev; + int auto_detach_kernel_driver; + unsigned char os_priv +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif + ; +}; + +enum { + USBI_CLOCK_MONOTONIC, + USBI_CLOCK_REALTIME +}; + +/* in-memory transfer layout: + * + * 1. struct usbi_transfer + * 2. struct libusb_transfer (which includes iso packets) [variable size] + * 3. os private data [variable size] + * + * from a libusb_transfer, you can get the usbi_transfer by rewinding the + * appropriate number of bytes. + * the usbi_transfer includes the number of allocated packets, so you can + * determine the size of the transfer and hence the start and length of the + * OS-private data. + */ + +struct usbi_transfer { + int num_iso_packets; + struct list_head list; + struct list_head completed_list; + struct timeval timeout; + int transferred; + uint32_t stream_id; + uint8_t flags; + + /* this lock is held during libusb_submit_transfer() and + * libusb_cancel_transfer() (allowing the OS backend to prevent duplicate + * cancellation, submission-during-cancellation, etc). the OS backend + * should also take this lock in the handle_events path, to prevent the user + * cancelling the transfer from another thread while you are processing + * its completion (presumably there would be races within your OS backend + * if this were possible). */ + usbi_mutex_t lock; + + /* this lock should be held whenever viewing or modifying flags + * relating to the transfer state */ + usbi_mutex_t flags_lock; +}; + +enum usbi_transfer_flags { + /* The transfer has timed out */ + USBI_TRANSFER_TIMED_OUT = 1 << 0, + + /* Set by backend submit_transfer() if the OS handles timeout */ + USBI_TRANSFER_OS_HANDLES_TIMEOUT = 1 << 1, + + /* Cancellation was requested via libusb_cancel_transfer() */ + USBI_TRANSFER_CANCELLING = 1 << 2, + + /* Operation on the transfer failed because the device disappeared */ + USBI_TRANSFER_DEVICE_DISAPPEARED = 1 << 3, + + /* Transfer is currently being submitted */ + USBI_TRANSFER_SUBMITTING = 1 << 4, + + /* Transfer successfully submitted by backend */ + USBI_TRANSFER_IN_FLIGHT = 1 << 5, + + /* Completion handler has run */ + USBI_TRANSFER_COMPLETED = 1 << 6, + + /* The transfer timeout has been handled */ + USBI_TRANSFER_TIMEOUT_HANDLED = 1 << 7, +}; + +#define USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \ + ((struct libusb_transfer *)(((unsigned char *)(transfer)) \ + + sizeof(struct usbi_transfer))) +#define LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer) \ + ((struct usbi_transfer *)(((unsigned char *)(transfer)) \ + - sizeof(struct usbi_transfer))) + +static inline void *usbi_transfer_get_os_priv(struct usbi_transfer *transfer) +{ + return ((unsigned char *)transfer) + sizeof(struct usbi_transfer) + + sizeof(struct libusb_transfer) + + (transfer->num_iso_packets + * sizeof(struct libusb_iso_packet_descriptor)); +} + +/* bus structures */ + +/* All standard descriptors have these 2 fields in common */ +struct usb_descriptor_header { + uint8_t bLength; + uint8_t bDescriptorType; +}; + +/* shared data and functions */ + +int usbi_io_init(struct libusb_context *ctx); +void usbi_io_exit(struct libusb_context *ctx); + +struct libusb_device *usbi_alloc_device(struct libusb_context *ctx, + unsigned long session_id); +struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx, + unsigned long session_id); +int usbi_sanitize_device(struct libusb_device *dev); +void usbi_handle_disconnect(struct libusb_device_handle *handle); + +int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, + enum libusb_transfer_status status); +int usbi_handle_transfer_cancellation(struct usbi_transfer *transfer); +void usbi_signal_transfer_completion(struct usbi_transfer *transfer); + +int usbi_parse_descriptor(const unsigned char *source, const char *descriptor, + void *dest, int host_endian); +int usbi_device_cache_descriptor(libusb_device *dev); +int usbi_get_config_index_by_value(struct libusb_device *dev, + uint8_t bConfigurationValue, int *idx); + +void usbi_connect_device (struct libusb_device *dev); +void usbi_disconnect_device (struct libusb_device *dev); + +int usbi_signal_event(struct libusb_context *ctx); +int usbi_clear_event(struct libusb_context *ctx); + +/* Internal abstraction for poll (needs struct usbi_transfer on Windows) */ +#if defined(OS_LINUX) || defined(OS_DARWIN) || defined(OS_OPENBSD) || defined(OS_NETBSD) || defined(OS_HAIKU) +#include +#include "os/poll_posix.h" +#elif defined(OS_WINDOWS) || defined(OS_WINCE) +#include "os/poll_windows.h" +#endif + +#if (defined(OS_WINDOWS) || defined(OS_WINCE)) && !defined(__GNUC__) +#define snprintf _snprintf +#define vsnprintf _vsnprintf +int usbi_gettimeofday(struct timeval *tp, void *tzp); +#define LIBUSB_GETTIMEOFDAY_WIN32 +#define HAVE_USBI_GETTIMEOFDAY +#else +#ifdef HAVE_GETTIMEOFDAY +#define usbi_gettimeofday(tv, tz) gettimeofday((tv), (tz)) +#define HAVE_USBI_GETTIMEOFDAY +#endif +#endif + +struct usbi_pollfd { + /* must come first */ + struct libusb_pollfd pollfd; + + struct list_head list; +}; + +int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events); +void usbi_remove_pollfd(struct libusb_context *ctx, int fd); + +/* device discovery */ + +/* we traverse usbfs without knowing how many devices we are going to find. + * so we create this discovered_devs model which is similar to a linked-list + * which grows when required. it can be freed once discovery has completed, + * eliminating the need for a list node in the libusb_device structure + * itself. */ +struct discovered_devs { + size_t len; + size_t capacity; + struct libusb_device *devices +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif + ; +}; + +struct discovered_devs *discovered_devs_append( + struct discovered_devs *discdevs, struct libusb_device *dev); + +/* OS abstraction */ + +/* This is the interface that OS backends need to implement. + * All fields are mandatory, except ones explicitly noted as optional. */ +struct usbi_os_backend { + /* A human-readable name for your backend, e.g. "Linux usbfs" */ + const char *name; + + /* Binary mask for backend specific capabilities */ + uint32_t caps; + + /* Perform initialization of your backend. You might use this function + * to determine specific capabilities of the system, allocate required + * data structures for later, etc. + * + * This function is called when a libusb user initializes the library + * prior to use. + * + * Return 0 on success, or a LIBUSB_ERROR code on failure. + */ + int (*init)(struct libusb_context *ctx); + + /* Deinitialization. Optional. This function should destroy anything + * that was set up by init. + * + * This function is called when the user deinitializes the library. + */ + void (*exit)(void); + + /* Enumerate all the USB devices on the system, returning them in a list + * of discovered devices. + * + * Your implementation should enumerate all devices on the system, + * regardless of whether they have been seen before or not. + * + * When you have found a device, compute a session ID for it. The session + * ID should uniquely represent that particular device for that particular + * connection session since boot (i.e. if you disconnect and reconnect a + * device immediately after, it should be assigned a different session ID). + * If your OS cannot provide a unique session ID as described above, + * presenting a session ID of (bus_number << 8 | device_address) should + * be sufficient. Bus numbers and device addresses wrap and get reused, + * but that is an unlikely case. + * + * After computing a session ID for a device, call + * usbi_get_device_by_session_id(). This function checks if libusb already + * knows about the device, and if so, it provides you with a reference + * to a libusb_device structure for it. + * + * If usbi_get_device_by_session_id() returns NULL, it is time to allocate + * a new device structure for the device. Call usbi_alloc_device() to + * obtain a new libusb_device structure with reference count 1. Populate + * the bus_number and device_address attributes of the new device, and + * perform any other internal backend initialization you need to do. At + * this point, you should be ready to provide device descriptors and so + * on through the get_*_descriptor functions. Finally, call + * usbi_sanitize_device() to perform some final sanity checks on the + * device. Assuming all of the above succeeded, we can now continue. + * If any of the above failed, remember to unreference the device that + * was returned by usbi_alloc_device(). + * + * At this stage we have a populated libusb_device structure (either one + * that was found earlier, or one that we have just allocated and + * populated). This can now be added to the discovered devices list + * using discovered_devs_append(). Note that discovered_devs_append() + * may reallocate the list, returning a new location for it, and also + * note that reallocation can fail. Your backend should handle these + * error conditions appropriately. + * + * This function should not generate any bus I/O and should not block. + * If I/O is required (e.g. reading the active configuration value), it is + * OK to ignore these suggestions :) + * + * This function is executed when the user wishes to retrieve a list + * of USB devices connected to the system. + * + * If the backend has hotplug support, this function is not used! + * + * Return 0 on success, or a LIBUSB_ERROR code on failure. + */ + int (*get_device_list)(struct libusb_context *ctx, + struct discovered_devs **discdevs); + + /* Apps which were written before hotplug support, may listen for + * hotplug events on their own and call libusb_get_device_list on + * device addition. In this case libusb_get_device_list will likely + * return a list without the new device in there, as the hotplug + * event thread will still be busy enumerating the device, which may + * take a while, or may not even have seen the event yet. + * + * To avoid this libusb_get_device_list will call this optional + * function for backends with hotplug support before copying + * ctx->usb_devs to the user. In this function the backend should + * ensure any pending hotplug events are fully processed before + * returning. + * + * Optional, should be implemented by backends with hotplug support. + */ + void (*hotplug_poll)(void); + + /* Open a device for I/O and other USB operations. The device handle + * is preallocated for you, you can retrieve the device in question + * through handle->dev. + * + * Your backend should allocate any internal resources required for I/O + * and other operations so that those operations can happen (hopefully) + * without hiccup. This is also a good place to inform libusb that it + * should monitor certain file descriptors related to this device - + * see the usbi_add_pollfd() function. + * + * This function should not generate any bus I/O and should not block. + * + * This function is called when the user attempts to obtain a device + * handle for a device. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_ACCESS if the user has insufficient permissions + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since + * discovery + * - another LIBUSB_ERROR code on other failure + * + * Do not worry about freeing the handle on failed open, the upper layers + * do this for you. + */ + int (*open)(struct libusb_device_handle *handle); + + int (*open2)(struct libusb_device_handle *handle, int fd); + struct libusb_device* (*device2)(struct libusb_context *ctx, const char *dev_node); + + /* Close a device such that the handle cannot be used again. Your backend + * should destroy any resources that were allocated in the open path. + * This may also be a good place to call usbi_remove_pollfd() to inform + * libusb of any file descriptors associated with this device that should + * no longer be monitored. + * + * This function is called when the user closes a device handle. + */ + void (*close)(struct libusb_device_handle *handle); + + /* Retrieve the device descriptor from a device. + * + * The descriptor should be retrieved from memory, NOT via bus I/O to the + * device. This means that you may have to cache it in a private structure + * during get_device_list enumeration. Alternatively, you may be able + * to retrieve it from a kernel interface (some Linux setups can do this) + * still without generating bus I/O. + * + * This function is expected to write DEVICE_DESC_LENGTH (18) bytes into + * buffer, which is guaranteed to be big enough. + * + * This function is called when sanity-checking a device before adding + * it to the list of discovered devices, and also when the user requests + * to read the device descriptor. + * + * This function is expected to return the descriptor in bus-endian format + * (LE). If it returns the multi-byte values in host-endian format, + * set the host_endian output parameter to "1". + * + * Return 0 on success or a LIBUSB_ERROR code on failure. + */ + int (*get_device_descriptor)(struct libusb_device *device, + unsigned char *buffer, int *host_endian); + + /* Get the ACTIVE configuration descriptor for a device. + * + * The descriptor should be retrieved from memory, NOT via bus I/O to the + * device. This means that you may have to cache it in a private structure + * during get_device_list enumeration. You may also have to keep track + * of which configuration is active when the user changes it. + * + * This function is expected to write len bytes of data into buffer, which + * is guaranteed to be big enough. If you can only do a partial write, + * return an error code. + * + * This function is expected to return the descriptor in bus-endian format + * (LE). If it returns the multi-byte values in host-endian format, + * set the host_endian output parameter to "1". + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the device is in unconfigured state + * - another LIBUSB_ERROR code on other failure + */ + int (*get_active_config_descriptor)(struct libusb_device *device, + unsigned char *buffer, size_t len, int *host_endian); + + /* Get a specific configuration descriptor for a device. + * + * The descriptor should be retrieved from memory, NOT via bus I/O to the + * device. This means that you may have to cache it in a private structure + * during get_device_list enumeration. + * + * The requested descriptor is expressed as a zero-based index (i.e. 0 + * indicates that we are requesting the first descriptor). The index does + * not (necessarily) equal the bConfigurationValue of the configuration + * being requested. + * + * This function is expected to write len bytes of data into buffer, which + * is guaranteed to be big enough. If you can only do a partial write, + * return an error code. + * + * This function is expected to return the descriptor in bus-endian format + * (LE). If it returns the multi-byte values in host-endian format, + * set the host_endian output parameter to "1". + * + * Return the length read on success or a LIBUSB_ERROR code on failure. + */ + int (*get_config_descriptor)(struct libusb_device *device, + uint8_t config_index, unsigned char *buffer, size_t len, + int *host_endian); + + /* Like get_config_descriptor but then by bConfigurationValue instead + * of by index. + * + * Optional, if not present the core will call get_config_descriptor + * for all configs until it finds the desired bConfigurationValue. + * + * Returns a pointer to the raw-descriptor in *buffer, this memory + * is valid as long as device is valid. + * + * Returns the length of the returned raw-descriptor on success, + * or a LIBUSB_ERROR code on failure. + */ + int (*get_config_descriptor_by_value)(struct libusb_device *device, + uint8_t bConfigurationValue, unsigned char **buffer, + int *host_endian); + + /* Get the bConfigurationValue for the active configuration for a device. + * Optional. This should only be implemented if you can retrieve it from + * cache (don't generate I/O). + * + * If you cannot retrieve this from cache, either do not implement this + * function, or return LIBUSB_ERROR_NOT_SUPPORTED. This will cause + * libusb to retrieve the information through a standard control transfer. + * + * This function must be non-blocking. + * Return: + * - 0 on success + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - LIBUSB_ERROR_NOT_SUPPORTED if the value cannot be retrieved without + * blocking + * - another LIBUSB_ERROR code on other failure. + */ + int (*get_configuration)(struct libusb_device_handle *handle, int *config); + + /* Set the active configuration for a device. + * + * A configuration value of -1 should put the device in unconfigured state. + * + * This function can block. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the configuration does not exist + * - LIBUSB_ERROR_BUSY if interfaces are currently claimed (and hence + * configuration cannot be changed) + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure. + */ + int (*set_configuration)(struct libusb_device_handle *handle, int config); + + /* Claim an interface. When claimed, the application can then perform + * I/O to an interface's endpoints. + * + * This function should not generate any bus I/O and should not block. + * Interface claiming is a logical operation that simply ensures that + * no other drivers/applications are using the interface, and after + * claiming, no other drivers/applications can use the interface because + * we now "own" it. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the interface does not exist + * - LIBUSB_ERROR_BUSY if the interface is in use by another driver/app + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*claim_interface)(struct libusb_device_handle *handle, int interface_number); + + /* Release a previously claimed interface. + * + * This function should also generate a SET_INTERFACE control request, + * resetting the alternate setting of that interface to 0. It's OK for + * this function to block as a result. + * + * You will only ever be asked to release an interface which was + * successfully claimed earlier. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*release_interface)(struct libusb_device_handle *handle, int interface_number); + + /* Set the alternate setting for an interface. + * + * You will only ever be asked to set the alternate setting for an + * interface which was successfully claimed earlier. + * + * It's OK for this function to block. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the alternate setting does not exist + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*set_interface_altsetting)(struct libusb_device_handle *handle, + int interface_number, int altsetting); + + /* Clear a halt/stall condition on an endpoint. + * + * It's OK for this function to block. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if the endpoint does not exist + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*clear_halt)(struct libusb_device_handle *handle, + unsigned char endpoint); + + /* Perform a USB port reset to reinitialize a device. + * + * If possible, the handle should still be usable after the reset + * completes, assuming that the device descriptors did not change during + * reset and all previous interface state can be restored. + * + * If something changes, or you cannot easily locate/verify the resetted + * device, return LIBUSB_ERROR_NOT_FOUND. This prompts the application + * to close the old handle and re-enumerate the device. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if re-enumeration is required, or if the device + * has been disconnected since it was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*reset_device)(struct libusb_device_handle *handle); + + /* Alloc num_streams usb3 bulk streams on the passed in endpoints */ + int (*alloc_streams)(struct libusb_device_handle *handle, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints); + + /* Free usb3 bulk streams allocated with alloc_streams */ + int (*free_streams)(struct libusb_device_handle *handle, + unsigned char *endpoints, int num_endpoints); + + /* Determine if a kernel driver is active on an interface. Optional. + * + * The presence of a kernel driver on an interface indicates that any + * calls to claim_interface would fail with the LIBUSB_ERROR_BUSY code. + * + * Return: + * - 0 if no driver is active + * - 1 if a driver is active + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*kernel_driver_active)(struct libusb_device_handle *handle, + int interface_number); + + /* Detach a kernel driver from an interface. Optional. + * + * After detaching a kernel driver, the interface should be available + * for claim. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if no kernel driver was active + * - LIBUSB_ERROR_INVALID_PARAM if the interface does not exist + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - another LIBUSB_ERROR code on other failure + */ + int (*detach_kernel_driver)(struct libusb_device_handle *handle, + int interface_number); + + /* Attach a kernel driver to an interface. Optional. + * + * Reattach a kernel driver to the device. + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NOT_FOUND if no kernel driver was active + * - LIBUSB_ERROR_INVALID_PARAM if the interface does not exist + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected since it + * was opened + * - LIBUSB_ERROR_BUSY if a program or driver has claimed the interface, + * preventing reattachment + * - another LIBUSB_ERROR code on other failure + */ + int (*attach_kernel_driver)(struct libusb_device_handle *handle, + int interface_number); + + /* Destroy a device. Optional. + * + * This function is called when the last reference to a device is + * destroyed. It should free any resources allocated in the get_device_list + * path. + */ + void (*destroy_device)(struct libusb_device *dev); + + /* Submit a transfer. Your implementation should take the transfer, + * morph it into whatever form your platform requires, and submit it + * asynchronously. + * + * This function must not block. + * + * This function gets called with the flying_transfers_lock locked! + * + * Return: + * - 0 on success + * - LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * - another LIBUSB_ERROR code on other failure + */ + int (*submit_transfer)(struct usbi_transfer *itransfer); + + /* Cancel a previously submitted transfer. + * + * This function must not block. The transfer cancellation must complete + * later, resulting in a call to usbi_handle_transfer_cancellation() + * from the context of handle_events. + */ + int (*cancel_transfer)(struct usbi_transfer *itransfer); + + /* Clear a transfer as if it has completed or cancelled, but do not + * report any completion/cancellation to the library. You should free + * all private data from the transfer as if you were just about to report + * completion or cancellation. + * + * This function might seem a bit out of place. It is used when libusb + * detects a disconnected device - it calls this function for all pending + * transfers before reporting completion (with the disconnect code) to + * the user. Maybe we can improve upon this internal interface in future. + */ + void (*clear_transfer_priv)(struct usbi_transfer *itransfer); + + /* Handle any pending events on file descriptors. Optional. + * + * Provide this function when file descriptors directly indicate device + * or transfer activity. If your backend does not have such file descriptors, + * implement the handle_transfer_completion function below. + * + * This involves monitoring any active transfers and processing their + * completion or cancellation. + * + * The function is passed an array of pollfd structures (size nfds) + * as a result of the poll() system call. The num_ready parameter + * indicates the number of file descriptors that have reported events + * (i.e. the poll() return value). This should be enough information + * for you to determine which actions need to be taken on the currently + * active transfers. + * + * For any cancelled transfers, call usbi_handle_transfer_cancellation(). + * For completed transfers, call usbi_handle_transfer_completion(). + * For control/bulk/interrupt transfers, populate the "transferred" + * element of the appropriate usbi_transfer structure before calling the + * above functions. For isochronous transfers, populate the status and + * transferred fields of the iso packet descriptors of the transfer. + * + * This function should also be able to detect disconnection of the + * device, reporting that situation with usbi_handle_disconnect(). + * + * When processing an event related to a transfer, you probably want to + * take usbi_transfer.lock to prevent races. See the documentation for + * the usbi_transfer structure. + * + * Return 0 on success, or a LIBUSB_ERROR code on failure. + */ + int (*handle_events)(struct libusb_context *ctx, + struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready); + + /* Handle transfer completion. Optional. + * + * Provide this function when there are no file descriptors available + * that directly indicate device or transfer activity. If your backend does + * have such file descriptors, implement the handle_events function above. + * + * Your backend must tell the library when a transfer has completed by + * calling usbi_signal_transfer_completion(). You should store any private + * information about the transfer and its completion status in the transfer's + * private backend data. + * + * During event handling, this function will be called on each transfer for + * which usbi_signal_transfer_completion() was called. + * + * For any cancelled transfers, call usbi_handle_transfer_cancellation(). + * For completed transfers, call usbi_handle_transfer_completion(). + * For control/bulk/interrupt transfers, populate the "transferred" + * element of the appropriate usbi_transfer structure before calling the + * above functions. For isochronous transfers, populate the status and + * transferred fields of the iso packet descriptors of the transfer. + * + * Return 0 on success, or a LIBUSB_ERROR code on failure. + */ + int (*handle_transfer_completion)(struct usbi_transfer *itransfer); + + /* Get time from specified clock. At least two clocks must be implemented + by the backend: USBI_CLOCK_REALTIME, and USBI_CLOCK_MONOTONIC. + + Description of clocks: + USBI_CLOCK_REALTIME : clock returns time since system epoch. + USBI_CLOCK_MONOTONIC: clock returns time since unspecified start + time (usually boot). + */ + int (*clock_gettime)(int clkid, struct timespec *tp); + +#ifdef USBI_TIMERFD_AVAILABLE + /* clock ID of the clock that should be used for timerfd */ + clockid_t (*get_timerfd_clockid)(void); +#endif + + /* Number of bytes to reserve for per-device private backend data. + * This private data area is accessible through the "os_priv" field of + * struct libusb_device. */ + size_t device_priv_size; + + /* Number of bytes to reserve for per-handle private backend data. + * This private data area is accessible through the "os_priv" field of + * struct libusb_device. */ + size_t device_handle_priv_size; + + /* Number of bytes to reserve for per-transfer private backend data. + * This private data area is accessible by calling + * usbi_transfer_get_os_priv() on the appropriate usbi_transfer instance. + */ + size_t transfer_priv_size; +}; + +extern const struct usbi_os_backend * const usbi_backend; + +extern const struct usbi_os_backend linux_usbfs_backend; +extern const struct usbi_os_backend darwin_backend; +extern const struct usbi_os_backend openbsd_backend; +extern const struct usbi_os_backend netbsd_backend; +extern const struct usbi_os_backend windows_backend; +extern const struct usbi_os_backend wince_backend; +extern const struct usbi_os_backend haiku_usb_raw_backend; + +extern struct list_head active_contexts_list; +extern usbi_mutex_static_t active_contexts_lock; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/libusbi.h.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/libusbi.h.REMOVED.git-id deleted file mode 100644 index 4e246480..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/libusbi.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -447ad045f8135dffc3b13c6393d3c0851594dceb \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_netlink.c b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_netlink.c new file mode 100644 index 00000000..96deeac7 --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_netlink.c @@ -0,0 +1,375 @@ +/* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */ +/* + * Linux usbfs backend for libusb + * Copyright (C) 2007-2009 Daniel Drake + * Copyright (c) 2001 Johannes Erdfelt + * Copyright (c) 2013 Nathan Hjelm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_ASM_TYPES_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#include + +#ifdef HAVE_LINUX_NETLINK_H +#include +#endif + +#ifdef HAVE_LINUX_FILTER_H +#include +#endif + +#include "libusbi.h" +#include "linux_usbfs.h" + +#define KERNEL 1 + +static int linux_netlink_socket = -1; +static int netlink_control_pipe[2] = { -1, -1 }; +static pthread_t libusb_linux_event_thread; + +static void *linux_netlink_event_thread_main(void *arg); + +static struct sockaddr_nl snl = { .nl_family=AF_NETLINK, .nl_groups=KERNEL }; + +static int set_fd_cloexec_nb(int fd) +{ + int flags; + +#if defined(FD_CLOEXEC) + flags = fcntl(fd, F_GETFD); + if (0 > flags) { + return -1; + } + + if (!(flags & FD_CLOEXEC)) { + fcntl(fd, F_SETFD, flags | FD_CLOEXEC); + } +#endif + + flags = fcntl(fd, F_GETFL); + if (0 > flags) { + return -1; + } + + if (!(flags & O_NONBLOCK)) { + fcntl(fd, F_SETFL, flags | O_NONBLOCK); + } + + return 0; +} + +int linux_netlink_start_event_monitor(void) +{ + int socktype = SOCK_RAW; + int ret; + + snl.nl_groups = KERNEL; + +#if defined(SOCK_CLOEXEC) + socktype |= SOCK_CLOEXEC; +#endif +#if defined(SOCK_NONBLOCK) + socktype |= SOCK_NONBLOCK; +#endif + + linux_netlink_socket = socket(PF_NETLINK, socktype, NETLINK_KOBJECT_UEVENT); + if (-1 == linux_netlink_socket && EINVAL == errno) { + linux_netlink_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT); + } + + if (-1 == linux_netlink_socket) { + return LIBUSB_ERROR_OTHER; + } + + ret = set_fd_cloexec_nb (linux_netlink_socket); + if (0 != ret) { + close (linux_netlink_socket); + linux_netlink_socket = -1; + return LIBUSB_ERROR_OTHER; + } + + ret = bind(linux_netlink_socket, (struct sockaddr *) &snl, sizeof(snl)); + if (0 != ret) { + close(linux_netlink_socket); + return LIBUSB_ERROR_OTHER; + } + + /* TODO -- add authentication */ + /* setsockopt(linux_netlink_socket, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); */ + + ret = usbi_pipe(netlink_control_pipe); + if (ret) { + usbi_err(NULL, "could not create netlink control pipe"); + close(linux_netlink_socket); + return LIBUSB_ERROR_OTHER; + } + + ret = pthread_create(&libusb_linux_event_thread, NULL, linux_netlink_event_thread_main, NULL); + if (0 != ret) { + close(netlink_control_pipe[0]); + close(netlink_control_pipe[1]); + close(linux_netlink_socket); + return LIBUSB_ERROR_OTHER; + } + + return LIBUSB_SUCCESS; +} + +int linux_netlink_stop_event_monitor(void) +{ + int r; + char dummy = 1; + + if (-1 == linux_netlink_socket) { + /* already closed. nothing to do */ + return LIBUSB_SUCCESS; + } + + /* Write some dummy data to the control pipe and + * wait for the thread to exit */ + r = usbi_write(netlink_control_pipe[1], &dummy, sizeof(dummy)); + if (r <= 0) { + usbi_warn(NULL, "netlink control pipe signal failed"); + } + pthread_join(libusb_linux_event_thread, NULL); + + close(linux_netlink_socket); + linux_netlink_socket = -1; + + /* close and reset control pipe */ + close(netlink_control_pipe[0]); + close(netlink_control_pipe[1]); + netlink_control_pipe[0] = -1; + netlink_control_pipe[1] = -1; + + return LIBUSB_SUCCESS; +} + +static const char *netlink_message_parse (const char *buffer, size_t len, const char *key) +{ + size_t keylen = strlen(key); + size_t offset; + + for (offset = 0 ; offset < len && '\0' != buffer[offset] ; offset += strlen(buffer + offset) + 1) { + if (0 == strncmp(buffer + offset, key, keylen) && + '=' == buffer[offset + keylen]) { + return buffer + offset + keylen + 1; + } + } + + return NULL; +} + +/* parse parts of netlink message common to both libudev and the kernel */ +static int linux_netlink_parse(char *buffer, size_t len, int *detached, const char **sys_name, + uint8_t *busnum, uint8_t *devaddr) { + const char *tmp; + int i; + + errno = 0; + + *sys_name = NULL; + *detached = 0; + *busnum = 0; + *devaddr = 0; + + tmp = netlink_message_parse((const char *) buffer, len, "ACTION"); + if (tmp == NULL) + return -1; + if (0 == strcmp(tmp, "remove")) { + *detached = 1; + } else if (0 != strcmp(tmp, "add")) { + usbi_dbg("unknown device action %s", tmp); + return -1; + } + + /* check that this is a usb message */ + tmp = netlink_message_parse(buffer, len, "SUBSYSTEM"); + if (NULL == tmp || 0 != strcmp(tmp, "usb")) { + /* not usb. ignore */ + return -1; + } + + /* check that this is an actual usb device */ + tmp = netlink_message_parse(buffer, len, "DEVTYPE"); + if (NULL == tmp || 0 != strcmp(tmp, "usb_device")) { + /* not usb. ignore */ + return -1; + } + + tmp = netlink_message_parse(buffer, len, "BUSNUM"); + if (NULL == tmp) { + /* no bus number. try "DEVICE" */ + tmp = netlink_message_parse(buffer, len, "DEVICE"); + if (NULL == tmp) { + /* not usb. ignore */ + return -1; + } + + /* Parse a device path such as /dev/bus/usb/003/004 */ + char *pLastSlash = (char*)strrchr(tmp,'/'); + if(NULL == pLastSlash) { + return -1; + } + + *devaddr = strtoul(pLastSlash + 1, NULL, 10); + if (errno) { + errno = 0; + return -1; + } + + *busnum = strtoul(pLastSlash - 3, NULL, 10); + if (errno) { + errno = 0; + return -1; + } + + return 0; + } + + *busnum = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff); + if (errno) { + errno = 0; + return -1; + } + + tmp = netlink_message_parse(buffer, len, "DEVNUM"); + if (NULL == tmp) { + return -1; + } + + *devaddr = (uint8_t)(strtoul(tmp, NULL, 10) & 0xff); + if (errno) { + errno = 0; + return -1; + } + + tmp = netlink_message_parse(buffer, len, "DEVPATH"); + if (NULL == tmp) { + return -1; + } + + for (i = strlen(tmp) - 1 ; i ; --i) { + if ('/' ==tmp[i]) { + *sys_name = tmp + i + 1; + break; + } + } + + /* found a usb device */ + return 0; +} + +static int linux_netlink_read_message(void) +{ + unsigned char buffer[1024]; + struct iovec iov = {.iov_base = buffer, .iov_len = sizeof(buffer)}; + struct msghdr meh = { .msg_iov=&iov, .msg_iovlen=1, + .msg_name=&snl, .msg_namelen=sizeof(snl) }; + const char *sys_name = NULL; + uint8_t busnum, devaddr; + int detached, r; + size_t len; + + /* read netlink message */ + memset(buffer, 0, sizeof(buffer)); + len = recvmsg(linux_netlink_socket, &meh, 0); + if (len < 32) { + if (errno != EAGAIN) + usbi_dbg("error recieving message from netlink"); + return -1; + } + + /* TODO -- authenticate this message is from the kernel or udevd */ + + r = linux_netlink_parse(buffer, len, &detached, &sys_name, + &busnum, &devaddr); + if (r) + return r; + + usbi_dbg("netlink hotplug found device busnum: %hhu, devaddr: %hhu, sys_name: %s, removed: %s", + busnum, devaddr, sys_name, detached ? "yes" : "no"); + + /* signal device is available (or not) to all contexts */ + if (detached) + linux_device_disconnected(busnum, devaddr); + else + linux_hotplug_enumerate(busnum, devaddr, sys_name); + + return 0; +} + +static void *linux_netlink_event_thread_main(void *arg) +{ + char dummy; + int r; + struct pollfd fds[] = { + { .fd = netlink_control_pipe[0], + .events = POLLIN }, + { .fd = linux_netlink_socket, + .events = POLLIN }, + }; + + UNUSED(arg); + + while (poll(fds, 2, -1) >= 0) { + if (fds[0].revents & POLLIN) { + /* activity on control pipe, read the byte and exit */ + r = usbi_read(netlink_control_pipe[0], &dummy, sizeof(dummy)); + if (r <= 0) { + usbi_warn(NULL, "netlink control pipe read failed"); + } + break; + } + if (fds[1].revents & POLLIN) { + usbi_mutex_static_lock(&linux_hotplug_lock); + linux_netlink_read_message(); + usbi_mutex_static_unlock(&linux_hotplug_lock); + } + } + + return NULL; +} + +void linux_netlink_hotplug_poll(void) +{ + int r; + + usbi_mutex_static_lock(&linux_hotplug_lock); + do { + r = linux_netlink_read_message(); + } while (r == 0); + usbi_mutex_static_unlock(&linux_hotplug_lock); +} diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_netlink.c.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_netlink.c.REMOVED.git-id deleted file mode 100644 index 465b38a5..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_netlink.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -96deeac762bf98ea7c35ffd6c1facd197142b0f2 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_usbfs.c b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_usbfs.c new file mode 100644 index 00000000..6b43770a --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_usbfs.c @@ -0,0 +1,2795 @@ +/* -*- Mode: C; c-basic-offset:8 ; indent-tabs-mode:t -*- */ +/* + * Linux usbfs backend for libusb + * Copyright © 2007-2009 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * Copyright © 2013 Nathan Hjelm + * Copyright © 2012-2013 Hans de Goede + * Copyright © 2013-2016 Martin Marinov + * Copyright © 2015 Kuldeep Singh Dhaka + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libusbi.h" +#include "linux_usbfs.h" + +/* sysfs vs usbfs: + * opening a usbfs node causes the device to be resumed, so we attempt to + * avoid this during enumeration. + * + * sysfs allows us to read the kernel's in-memory copies of device descriptors + * and so forth, avoiding the need to open the device: + * - The binary "descriptors" file contains all config descriptors since + * 2.6.26, commit 217a9081d8e69026186067711131b77f0ce219ed + * - The binary "descriptors" file was added in 2.6.23, commit + * 69d42a78f935d19384d1f6e4f94b65bb162b36df, but it only contains the + * active config descriptors + * - The "busnum" file was added in 2.6.22, commit + * 83f7d958eab2fbc6b159ee92bf1493924e1d0f72 + * - The "devnum" file has been present since pre-2.6.18 + * - the "bConfigurationValue" file has been present since pre-2.6.18 + * + * If we have bConfigurationValue, busnum, and devnum, then we can determine + * the active configuration without having to open the usbfs node in RDWR mode. + * The busnum file is important as that is the only way we can relate sysfs + * devices to usbfs nodes. + * + * If we also have all descriptors, we can obtain the device descriptor and + * configuration without touching usbfs at all. + */ + +/* endianness for multi-byte fields: + * + * Descriptors exposed by usbfs have the multi-byte fields in the device + * descriptor as host endian. Multi-byte fields in the other descriptors are + * bus-endian. The kernel documentation says otherwise, but it is wrong. + * + * In sysfs all descriptors are bus-endian. + */ + +static const char *usbfs_path = NULL; + +/* use usbdev*.* device names in /dev instead of the usbfs bus directories */ +static int usbdev_names = 0; + +/* Linux 2.6.32 adds support for a bulk continuation URB flag. this basically + * allows us to mark URBs as being part of a specific logical transfer when + * we submit them to the kernel. then, on any error except a cancellation, all + * URBs within that transfer will be cancelled and no more URBs will be + * accepted for the transfer, meaning that no more data can creep in. + * + * The BULK_CONTINUATION flag must be set on all URBs within a bulk transfer + * (in either direction) except the first. + * For IN transfers, we must also set SHORT_NOT_OK on all URBs except the + * last; it means that the kernel should treat a short reply as an error. + * For OUT transfers, SHORT_NOT_OK must not be set. it isn't needed (OUT + * transfers can't be short unless there's already some sort of error), and + * setting this flag is disallowed (a kernel with USB debugging enabled will + * reject such URBs). + */ +static int supports_flag_bulk_continuation = -1; + +/* Linux 2.6.31 fixes support for the zero length packet URB flag. This + * allows us to mark URBs that should be followed by a zero length data + * packet, which can be required by device- or class-specific protocols. + */ +static int supports_flag_zero_packet = -1; + +/* clock ID for monotonic clock, as not all clock sources are available on all + * systems. appropriate choice made at initialization time. */ +static clockid_t monotonic_clkid = -1; + +/* Linux 2.6.22 (commit 83f7d958eab2fbc6b159ee92bf1493924e1d0f72) adds a busnum + * to sysfs, so we can relate devices. This also implies that we can read + * the active configuration through bConfigurationValue */ +static int sysfs_can_relate_devices = -1; + +/* Linux 2.6.26 (commit 217a9081d8e69026186067711131b77f0ce219ed) adds all + * config descriptors (rather then just the active config) to the sysfs + * descriptors file, so from then on we can use them. */ +static int sysfs_has_descriptors = -1; + +/* how many times have we initted (and not exited) ? */ +static int init_count = 0; + +/* Serialize hotplug start/stop */ +static usbi_mutex_static_t linux_hotplug_startstop_lock = USBI_MUTEX_INITIALIZER; +/* Serialize scan-devices, event-thread, and poll */ +usbi_mutex_static_t linux_hotplug_lock = USBI_MUTEX_INITIALIZER; + +static int linux_start_event_monitor(void); +static int linux_stop_event_monitor(void); +static int linux_scan_devices(struct libusb_context *ctx); +static int linux_scan_devices2(struct libusb_context *ctx, int fd, const char * path); +static int sysfs_scan_device(struct libusb_context *ctx, const char *devname); +static int detach_kernel_driver_and_claim(struct libusb_device_handle *, int); + +#if !defined(USE_UDEV) +static int linux_default_scan_devices (struct libusb_context *ctx); +#endif + +struct linux_device_priv { + char *sysfs_dir; + unsigned char *descriptors; + int descriptors_len; + int active_config; /* cache val for !sysfs_can_relate_devices */ +}; + +struct linux_device_handle_priv { + int fd; + int fd_removed; + uint32_t caps; +}; + +enum reap_action { + NORMAL = 0, + /* submission failed after the first URB, so await cancellation/completion + * of all the others */ + SUBMIT_FAILED, + + /* cancelled by user or timeout */ + CANCELLED, + + /* completed multi-URB transfer in non-final URB */ + COMPLETED_EARLY, + + /* one or more urbs encountered a low-level error */ + ERROR, +}; + +struct linux_transfer_priv { + union { + struct usbfs_urb *urbs; + struct usbfs_urb **iso_urbs; + }; + + enum reap_action reap_action; + int num_urbs; + int num_retired; + enum libusb_transfer_status reap_status; + + /* next iso packet in user-supplied transfer to be populated */ + int iso_packet_offset; +}; + +static int _get_usbfs_fd(struct libusb_device *dev, mode_t mode, int silent) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + char path[PATH_MAX]; + int fd; + int delay = 10000; + + if (usbdev_names) + snprintf(path, PATH_MAX, "%s/usbdev%d.%d", + usbfs_path, dev->bus_number, dev->device_address); + else + snprintf(path, PATH_MAX, "%s/%03d/%03d", + usbfs_path, dev->bus_number, dev->device_address); + + fd = open(path, mode); + if (fd != -1) + return fd; /* Success */ + + if (errno == ENOENT) { + if (!silent) + usbi_err(ctx, "File doesn't exist, wait %d ms and try again", delay/1000); + + /* Wait 10ms for USB device path creation.*/ + usleep(delay); + + fd = open(path, mode); + if (fd != -1) + return fd; /* Success */ + } + + if (!silent) { + usbi_err(ctx, "libusb couldn't open USB device %s: %s", + path, strerror(errno)); + if (errno == EACCES && mode == O_RDWR) + usbi_err(ctx, "libusb requires write access to USB " + "device nodes."); + } + + if (errno == EACCES) + return LIBUSB_ERROR_ACCESS; + if (errno == ENOENT) + return LIBUSB_ERROR_NO_DEVICE; + return LIBUSB_ERROR_IO; +} + +static struct linux_device_priv *_device_priv(struct libusb_device *dev) +{ + return (struct linux_device_priv *) dev->os_priv; +} + +static struct linux_device_handle_priv *_device_handle_priv( + struct libusb_device_handle *handle) +{ + return (struct linux_device_handle_priv *) handle->os_priv; +} + +/* check dirent for a /dev/usbdev%d.%d name + * optionally return bus/device on success */ +static int _is_usbdev_entry(struct dirent *entry, int *bus_p, int *dev_p) +{ + int busnum, devnum; + + if (sscanf(entry->d_name, "usbdev%d.%d", &busnum, &devnum) != 2) + return 0; + + usbi_dbg("found: %s", entry->d_name); + if (bus_p != NULL) + *bus_p = busnum; + if (dev_p != NULL) + *dev_p = devnum; + return 1; +} + +static int check_usb_vfs(const char *dirname) +{ + DIR *dir; + struct dirent *entry; + int found = 0; + + dir = opendir(dirname); + if (!dir) + return 0; + + while ((entry = readdir(dir)) != NULL) { + if (entry->d_name[0] == '.') + continue; + + /* We assume if we find any files that it must be the right place */ + found = 1; + break; + } + + closedir(dir); + return found; +} + +static const char *find_usbfs_path(void) +{ + const char *path = "/dev/bus/usb"; + const char *ret = NULL; + + if (check_usb_vfs(path)) { + ret = path; + } else { + path = "/proc/bus/usb"; + if (check_usb_vfs(path)) + ret = path; + } + + /* look for /dev/usbdev*.* if the normal places fail */ + if (ret == NULL) { + struct dirent *entry; + DIR *dir; + + path = "/dev"; + dir = opendir(path); + if (dir != NULL) { + while ((entry = readdir(dir)) != NULL) { + if (_is_usbdev_entry(entry, NULL, NULL)) { + /* found one; that's enough */ + ret = path; + usbdev_names = 1; + break; + } + } + closedir(dir); + } + } + +/* On udev based systems without any usb-devices /dev/bus/usb will not + * exist. So if we've not found anything and we're using udev for hotplug + * simply assume /dev/bus/usb rather then making libusb_init fail. */ +#if defined(USE_UDEV) + if (ret == NULL) + ret = "/dev/bus/usb"; +#endif + + if (ret != NULL) + usbi_dbg("found usbfs at %s", ret); + + return ret; +} + +/* the monotonic clock is not usable on all systems (e.g. embedded ones often + * seem to lack it). fall back to REALTIME if we have to. */ +static clockid_t find_monotonic_clock(void) +{ +#ifdef CLOCK_MONOTONIC + struct timespec ts; + int r; + + /* Linux 2.6.28 adds CLOCK_MONOTONIC_RAW but we don't use it + * because it's not available through timerfd */ + r = clock_gettime(CLOCK_MONOTONIC, &ts); + if (r == 0) + return CLOCK_MONOTONIC; + usbi_dbg("monotonic clock doesn't work, errno %d", errno); +#endif + + return CLOCK_REALTIME; +} + +static int kernel_version_ge(int major, int minor, int sublevel) +{ + struct utsname uts; + int atoms, kmajor, kminor, ksublevel; + + if (uname(&uts) < 0) + return -1; + atoms = sscanf(uts.release, "%d.%d.%d", &kmajor, &kminor, &ksublevel); + if (atoms < 1) + return -1; + + if (kmajor > major) + return 1; + if (kmajor < major) + return 0; + + /* kmajor == major */ + if (atoms < 2) + return 0 == minor && 0 == sublevel; + if (kminor > minor) + return 1; + if (kminor < minor) + return 0; + + /* kminor == minor */ + if (atoms < 3) + return 0 == sublevel; + + return ksublevel >= sublevel; +} + +static char * find_usbfs_path_android(const char * path) { + static char USB_PATH_BUFFER[256]; + + int rem = 2; + char * pathcopy; + + memset(USB_PATH_BUFFER, 0, sizeof USB_PATH_BUFFER); + for (pathcopy = ((char *) path) + strlen(path); pathcopy >= path; pathcopy--) { + if (*pathcopy == '/' && --rem == 0) break; + } + + return strncpy(USB_PATH_BUFFER, path, pathcopy-path); +} + +static int op_init(struct libusb_context *ctx) +{ + struct stat statbuf; + int r; + + usbfs_path = find_usbfs_path(); + if (!usbfs_path) { + /* On Android Lollipop (Android 5), their is restriction due to SELinux. + * due to which, all filesystem related query ends up in failure. */ +#if defined(__ANDROID__) + usbi_warn(ctx, "could not find usbfs. Android 5+?"); +#else + usbi_err(ctx, "could not find usbfs"); + return LIBUSB_ERROR_OTHER; +#endif + } + + if (monotonic_clkid == -1) + monotonic_clkid = find_monotonic_clock(); + + if (supports_flag_bulk_continuation == -1) { + /* bulk continuation URB flag available from Linux 2.6.32 */ + supports_flag_bulk_continuation = kernel_version_ge(2,6,32); + if (supports_flag_bulk_continuation == -1) { + usbi_err(ctx, "error checking for bulk continuation support"); + return LIBUSB_ERROR_OTHER; + } + } + + if (supports_flag_bulk_continuation) + usbi_dbg("bulk continuation flag supported"); + + if (-1 == supports_flag_zero_packet) { + /* zero length packet URB flag fixed since Linux 2.6.31 */ + supports_flag_zero_packet = kernel_version_ge(2,6,31); + if (-1 == supports_flag_zero_packet) { + usbi_err(ctx, "error checking for zero length packet support"); + return LIBUSB_ERROR_OTHER; + } + } + + if (supports_flag_zero_packet) + usbi_dbg("zero length packet flag supported"); + + if (-1 == sysfs_has_descriptors) { + /* sysfs descriptors has all descriptors since Linux 2.6.26 */ + sysfs_has_descriptors = kernel_version_ge(2,6,26); + if (-1 == sysfs_has_descriptors) { + usbi_err(ctx, "error checking for sysfs descriptors"); + return LIBUSB_ERROR_OTHER; + } + } + + if (-1 == sysfs_can_relate_devices) { + /* sysfs has busnum since Linux 2.6.22 */ + sysfs_can_relate_devices = kernel_version_ge(2,6,22); + if (-1 == sysfs_can_relate_devices) { + usbi_err(ctx, "error checking for sysfs busnum"); + return LIBUSB_ERROR_OTHER; + } + } + + if (sysfs_can_relate_devices || sysfs_has_descriptors) { + r = stat(SYSFS_DEVICE_PATH, &statbuf); + if (r != 0 || !S_ISDIR(statbuf.st_mode)) { + usbi_warn(ctx, "sysfs not mounted"); + sysfs_can_relate_devices = 0; + sysfs_has_descriptors = 0; + } + } + + if (sysfs_can_relate_devices) + usbi_dbg("sysfs can relate devices"); + + if (sysfs_has_descriptors) + usbi_dbg("sysfs has complete descriptors"); + + usbi_mutex_static_lock(&linux_hotplug_startstop_lock); + r = LIBUSB_SUCCESS; + if (init_count == 0) { +#if defined(__ANDROID__) + if(linux_start_event_monitor() != LIBUSB_SUCCESS) { + usbi_warn(ctx, "unable to starting hotplug event monitor. Android 5+?"); + } +#else + /* start up hotplug event handler */ + r = linux_start_event_monitor(); +#endif + } + if (r == LIBUSB_SUCCESS) { +#if defined(__ANDROID__) + usbi_warn(ctx, "We don't enumerate devices on Android due to restriction issues in Android N"); +#else + r = linux_scan_devices(ctx); +#endif + if (r == LIBUSB_SUCCESS) + init_count++; + else if (init_count == 0) + linux_stop_event_monitor(); + } else { + usbi_err(ctx, "error starting hotplug event monitor"); + } + usbi_mutex_static_unlock(&linux_hotplug_startstop_lock); + + return r; +} + +static void op_exit(void) +{ + usbi_mutex_static_lock(&linux_hotplug_startstop_lock); + assert(init_count != 0); + if (!--init_count) { + /* tear down event handler */ + (void)linux_stop_event_monitor(); + } + usbi_mutex_static_unlock(&linux_hotplug_startstop_lock); +} + +static int linux_start_event_monitor(void) +{ +#if defined(USE_UDEV) + return linux_udev_start_event_monitor(); +#else + return linux_netlink_start_event_monitor(); +#endif +} + +static int linux_stop_event_monitor(void) +{ +#if defined(USE_UDEV) + return linux_udev_stop_event_monitor(); +#else + return linux_netlink_stop_event_monitor(); +#endif +} + +static int linux_scan_devices(struct libusb_context *ctx) +{ + int ret; + + usbi_mutex_static_lock(&linux_hotplug_lock); + +#if defined(USE_UDEV) + ret = linux_udev_scan_devices(ctx); +#else + ret = linux_default_scan_devices(ctx); +#endif + + usbi_mutex_static_unlock(&linux_hotplug_lock); + + return ret; +} + +static void op_hotplug_poll(void) +{ +#if defined(USE_UDEV) + linux_udev_hotplug_poll(); +#else + linux_netlink_hotplug_poll(); +#endif +} + +static int _open_sysfs_attr(struct libusb_device *dev, const char *attr) +{ + struct linux_device_priv *priv = _device_priv(dev); + char filename[PATH_MAX]; + int fd; + + snprintf(filename, PATH_MAX, "%s/%s/%s", + SYSFS_DEVICE_PATH, priv->sysfs_dir, attr); + fd = open(filename, O_RDONLY); + if (fd < 0) { + usbi_err(DEVICE_CTX(dev), + "open %s failed ret=%d errno=%d", filename, fd, errno); + return LIBUSB_ERROR_IO; + } + + return fd; +} + +/* Note only suitable for attributes which always read >= 0, < 0 is error */ +static int __read_sysfs_attr(struct libusb_context *ctx, + const char *devname, const char *attr) +{ + char filename[PATH_MAX]; + FILE *f; + int r, value; + + snprintf(filename, PATH_MAX, "%s/%s/%s", SYSFS_DEVICE_PATH, + devname, attr); + f = fopen(filename, "r"); + if (f == NULL) { + if (errno == ENOENT) { + /* File doesn't exist. Assume the device has been + disconnected (see trac ticket #70). */ + return LIBUSB_ERROR_NO_DEVICE; + } + usbi_err(ctx, "open %s failed errno=%d", filename, errno); + return LIBUSB_ERROR_IO; + } + + r = fscanf(f, "%d", &value); + fclose(f); + if (r != 1) { + usbi_err(ctx, "fscanf %s returned %d, errno=%d", attr, r, errno); + return LIBUSB_ERROR_NO_DEVICE; /* For unplug race (trac #70) */ + } + if (value < 0) { + usbi_err(ctx, "%s contains a negative value", filename); + return LIBUSB_ERROR_IO; + } + + return value; +} + +static int op_get_device_descriptor(struct libusb_device *dev, + unsigned char *buffer, int *host_endian) +{ + struct linux_device_priv *priv = _device_priv(dev); + + *host_endian = sysfs_has_descriptors ? 0 : 1; + memcpy(buffer, priv->descriptors, DEVICE_DESC_LENGTH); + + return 0; +} + +/* read the bConfigurationValue for a device */ +static int sysfs_get_active_config(struct libusb_device *dev, int *config) +{ + char *endptr; + char tmp[5] = {0, 0, 0, 0, 0}; + long num; + int fd; + ssize_t r; + + fd = _open_sysfs_attr(dev, "bConfigurationValue"); + if (fd < 0) + return fd; + + r = read(fd, tmp, sizeof(tmp)); + close(fd); + if (r < 0) { + usbi_err(DEVICE_CTX(dev), + "read bConfigurationValue failed ret=%d errno=%d", r, errno); + return LIBUSB_ERROR_IO; + } else if (r == 0) { + usbi_dbg("device unconfigured"); + *config = -1; + return 0; + } + + if (tmp[sizeof(tmp) - 1] != 0) { + usbi_err(DEVICE_CTX(dev), "not null-terminated?"); + return LIBUSB_ERROR_IO; + } else if (tmp[0] == 0) { + usbi_err(DEVICE_CTX(dev), "no configuration value?"); + return LIBUSB_ERROR_IO; + } + + num = strtol(tmp, &endptr, 10); + if (endptr == tmp) { + usbi_err(DEVICE_CTX(dev), "error converting '%s' to integer", tmp); + return LIBUSB_ERROR_IO; + } + + *config = (int) num; + return 0; +} + +int linux_get_device_address (struct libusb_context *ctx, int detached, + uint8_t *busnum, uint8_t *devaddr,const char *dev_node, + const char *sys_name) +{ + int sysfs_attr; + + usbi_dbg("getting address for device: %s detached: %d", sys_name, detached); + /* can't use sysfs to read the bus and device number if the + * device has been detached */ + if (!sysfs_can_relate_devices || detached || NULL == sys_name) { + if (NULL == dev_node) { + return LIBUSB_ERROR_OTHER; + } + + /* will this work with all supported kernel versions? */ + if (!strncmp(dev_node, "/dev/bus/usb", 12)) { + sscanf (dev_node, "/dev/bus/usb/%hhu/%hhu", busnum, devaddr); + } else if (!strncmp(dev_node, "/proc/bus/usb", 13)) { + sscanf (dev_node, "/proc/bus/usb/%hhu/%hhu", busnum, devaddr); + } + + return LIBUSB_SUCCESS; + } + + usbi_dbg("scan %s", sys_name); + + sysfs_attr = __read_sysfs_attr(ctx, sys_name, "busnum"); + if (0 > sysfs_attr) + return sysfs_attr; + if (sysfs_attr > 255) + return LIBUSB_ERROR_INVALID_PARAM; + *busnum = (uint8_t) sysfs_attr; + + sysfs_attr = __read_sysfs_attr(ctx, sys_name, "devnum"); + if (0 > sysfs_attr) + return sysfs_attr; + if (sysfs_attr > 255) + return LIBUSB_ERROR_INVALID_PARAM; + + *devaddr = (uint8_t) sysfs_attr; + + usbi_dbg("bus=%d dev=%d", *busnum, *devaddr); + + return LIBUSB_SUCCESS; +} + +/* Return offset of the next descriptor with the given type */ +static int seek_to_next_descriptor(struct libusb_context *ctx, + uint8_t descriptor_type, unsigned char *buffer, int size) +{ + struct usb_descriptor_header header; + int i; + + for (i = 0; size >= 0; i += header.bLength, size -= header.bLength) { + if (size == 0) + return LIBUSB_ERROR_NOT_FOUND; + + if (size < 2) { + usbi_err(ctx, "short descriptor read %d/2", size); + return LIBUSB_ERROR_IO; + } + usbi_parse_descriptor(buffer + i, "bb", &header, 0); + + if (i && header.bDescriptorType == descriptor_type) + return i; + } + usbi_err(ctx, "bLength overflow by %d bytes", -size); + return LIBUSB_ERROR_IO; +} + +/* Return offset to next config */ +static int seek_to_next_config(struct libusb_context *ctx, + unsigned char *buffer, int size) +{ + struct libusb_config_descriptor config; + + if (size == 0) + return LIBUSB_ERROR_NOT_FOUND; + + if (size < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(ctx, "short descriptor read %d/%d", + size, LIBUSB_DT_CONFIG_SIZE); + return LIBUSB_ERROR_IO; + } + + usbi_parse_descriptor(buffer, "bbwbbbbb", &config, 0); + if (config.bDescriptorType != LIBUSB_DT_CONFIG) { + usbi_err(ctx, "descriptor is not a config desc (type 0x%02x)", + config.bDescriptorType); + return LIBUSB_ERROR_IO; + } + + /* + * In usbfs the config descriptors are config.wTotalLength bytes apart, + * with any short reads from the device appearing as holes in the file. + * + * In sysfs wTotalLength is ignored, instead the kernel returns a + * config descriptor with verified bLength fields, with descriptors + * with an invalid bLength removed. + */ + if (sysfs_has_descriptors) { + int next = seek_to_next_descriptor(ctx, LIBUSB_DT_CONFIG, + buffer, size); + if (next == LIBUSB_ERROR_NOT_FOUND) + next = size; + if (next < 0) + return next; + + if (next != config.wTotalLength) + usbi_warn(ctx, "config length mismatch wTotalLength " + "%d real %d", config.wTotalLength, next); + return next; + } else { + if (config.wTotalLength < LIBUSB_DT_CONFIG_SIZE) { + usbi_err(ctx, "invalid wTotalLength %d", + config.wTotalLength); + return LIBUSB_ERROR_IO; + } else if (config.wTotalLength > size) { + usbi_warn(ctx, "short descriptor read %d/%d", + size, config.wTotalLength); + return size; + } else + return config.wTotalLength; + } +} + +static int op_get_config_descriptor_by_value(struct libusb_device *dev, + uint8_t value, unsigned char **buffer, int *host_endian) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + struct linux_device_priv *priv = _device_priv(dev); + unsigned char *descriptors = priv->descriptors; + int size = priv->descriptors_len; + struct libusb_config_descriptor *config; + + *buffer = NULL; + /* Unlike the device desc. config descs. are always in raw format */ + *host_endian = 0; + + /* Skip device header */ + descriptors += DEVICE_DESC_LENGTH; + size -= DEVICE_DESC_LENGTH; + + /* Seek till the config is found, or till "EOF" */ + while (1) { + int next = seek_to_next_config(ctx, descriptors, size); + if (next < 0) + return next; + config = (struct libusb_config_descriptor *)descriptors; + if (config->bConfigurationValue == value) { + *buffer = descriptors; + return next; + } + size -= next; + descriptors += next; + } +} + +static int op_get_active_config_descriptor(struct libusb_device *dev, + unsigned char *buffer, size_t len, int *host_endian) +{ + int r, config; + unsigned char *config_desc; + + if (sysfs_can_relate_devices) { + r = sysfs_get_active_config(dev, &config); + if (r < 0) + return r; + } else { + /* Use cached bConfigurationValue */ + struct linux_device_priv *priv = _device_priv(dev); + config = priv->active_config; + } + if (config == -1) + return LIBUSB_ERROR_NOT_FOUND; + + r = op_get_config_descriptor_by_value(dev, config, &config_desc, + host_endian); + if (r < 0) + return r; + + len = MIN(len, r); + memcpy(buffer, config_desc, len); + return len; +} + +static int op_get_config_descriptor(struct libusb_device *dev, + uint8_t config_index, unsigned char *buffer, size_t len, int *host_endian) +{ + struct linux_device_priv *priv = _device_priv(dev); + unsigned char *descriptors = priv->descriptors; + int i, r, size = priv->descriptors_len; + + /* Unlike the device desc. config descs. are always in raw format */ + *host_endian = 0; + + /* Skip device header */ + descriptors += DEVICE_DESC_LENGTH; + size -= DEVICE_DESC_LENGTH; + + /* Seek till the config is found, or till "EOF" */ + for (i = 0; ; i++) { + r = seek_to_next_config(DEVICE_CTX(dev), descriptors, size); + if (r < 0) + return r; + if (i == config_index) + break; + size -= r; + descriptors += r; + } + + len = MIN(len, r); + memcpy(buffer, descriptors, len); + return len; +} + +/* send a control message to retrieve active configuration */ +static int usbfs_get_active_config(struct libusb_device *dev, int fd) +{ + unsigned char active_config = 0; + int r; + + struct usbfs_ctrltransfer ctrl = { + .bmRequestType = LIBUSB_ENDPOINT_IN, + .bRequest = LIBUSB_REQUEST_GET_CONFIGURATION, + .wValue = 0, + .wIndex = 0, + .wLength = 1, + .timeout = 1000, + .data = &active_config + }; + + r = ioctl(fd, IOCTL_USBFS_CONTROL, &ctrl); + if (r < 0) { + if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + /* we hit this error path frequently with buggy devices :( */ + usbi_warn(DEVICE_CTX(dev), + "get_configuration failed ret=%d errno=%d", r, errno); + return LIBUSB_ERROR_IO; + } + + return active_config; +} + +static int initialize_device(struct libusb_device *dev, uint8_t busnum, + uint8_t devaddr, const char *sysfs_dir) +{ + struct linux_device_priv *priv = _device_priv(dev); + struct libusb_context *ctx = DEVICE_CTX(dev); + int descriptors_size = 512; /* Begin with a 1024 byte alloc */ + int fd, speed; + ssize_t r; + + dev->bus_number = busnum; + dev->device_address = devaddr; + + if (sysfs_dir) { + priv->sysfs_dir = strdup(sysfs_dir); + if (!priv->sysfs_dir) + return LIBUSB_ERROR_NO_MEM; + + /* Note speed can contain 1.5, in this case __read_sysfs_attr + will stop parsing at the '.' and return 1 */ + speed = __read_sysfs_attr(DEVICE_CTX(dev), sysfs_dir, "speed"); + if (speed >= 0) { + switch (speed) { + case 1: dev->speed = LIBUSB_SPEED_LOW; break; + case 12: dev->speed = LIBUSB_SPEED_FULL; break; + case 480: dev->speed = LIBUSB_SPEED_HIGH; break; + case 5000: dev->speed = LIBUSB_SPEED_SUPER; break; + default: + usbi_warn(DEVICE_CTX(dev), "Unknown device speed: %d Mbps", speed); + } + } + } + + /* cache descriptors in memory */ + if (sysfs_has_descriptors) + fd = _open_sysfs_attr(dev, "descriptors"); + else + fd = _get_usbfs_fd(dev, O_RDONLY, 0); + if (fd < 0) + return fd; + + do { + descriptors_size *= 2; + priv->descriptors = usbi_reallocf(priv->descriptors, + descriptors_size); + if (!priv->descriptors) { + close(fd); + return LIBUSB_ERROR_NO_MEM; + } + /* usbfs has holes in the file */ + if (!sysfs_has_descriptors) { + memset(priv->descriptors + priv->descriptors_len, + 0, descriptors_size - priv->descriptors_len); + } + r = read(fd, priv->descriptors + priv->descriptors_len, + descriptors_size - priv->descriptors_len); + if (r < 0) { + usbi_err(ctx, "read descriptor failed ret=%d errno=%d", + fd, errno); + close(fd); + return LIBUSB_ERROR_IO; + } + priv->descriptors_len += r; + } while (priv->descriptors_len == descriptors_size); + + close(fd); + + if (priv->descriptors_len < DEVICE_DESC_LENGTH) { + usbi_err(ctx, "short descriptor read (%d)", + priv->descriptors_len); + return LIBUSB_ERROR_IO; + } + + if (sysfs_can_relate_devices) + return LIBUSB_SUCCESS; + + /* cache active config */ + fd = _get_usbfs_fd(dev, O_RDWR, 1); + if (fd < 0) { + /* cannot send a control message to determine the active + * config. just assume the first one is active. */ + usbi_warn(ctx, "Missing rw usbfs access; cannot determine " + "active configuration descriptor"); + if (priv->descriptors_len >= + (DEVICE_DESC_LENGTH + LIBUSB_DT_CONFIG_SIZE)) { + struct libusb_config_descriptor config; + usbi_parse_descriptor( + priv->descriptors + DEVICE_DESC_LENGTH, + "bbwbbbbb", &config, 0); + priv->active_config = config.bConfigurationValue; + } else + priv->active_config = -1; /* No config dt */ + + return LIBUSB_SUCCESS; + } + + r = usbfs_get_active_config(dev, fd); + if (r > 0) { + priv->active_config = r; + r = LIBUSB_SUCCESS; + } else if (r == 0) { + /* some buggy devices have a configuration 0, but we're + * reaching into the corner of a corner case here, so let's + * not support buggy devices in these circumstances. + * stick to the specs: a configuration value of 0 means + * unconfigured. */ + usbi_dbg("active cfg 0? assuming unconfigured device"); + priv->active_config = -1; + r = LIBUSB_SUCCESS; + } else if (r == LIBUSB_ERROR_IO) { + /* buggy devices sometimes fail to report their active config. + * assume unconfigured and continue the probing */ + usbi_warn(ctx, "couldn't query active configuration, assuming" + " unconfigured"); + priv->active_config = -1; + r = LIBUSB_SUCCESS; + } /* else r < 0, just return the error code */ + + close(fd); + return r; +} + +static int linux_get_parent_info(struct libusb_device *dev, const char *sysfs_dir) +{ + struct libusb_context *ctx = DEVICE_CTX(dev); + struct libusb_device *it; + char *parent_sysfs_dir, *tmp; + int ret, add_parent = 1; + + /* XXX -- can we figure out the topology when using usbfs? */ + if (NULL == sysfs_dir || 0 == strncmp(sysfs_dir, "usb", 3)) { + /* either using usbfs or finding the parent of a root hub */ + return LIBUSB_SUCCESS; + } + + parent_sysfs_dir = strdup(sysfs_dir); + if (NULL == parent_sysfs_dir) { + return LIBUSB_ERROR_NO_MEM; + } + if (NULL != (tmp = strrchr(parent_sysfs_dir, '.')) || + NULL != (tmp = strrchr(parent_sysfs_dir, '-'))) { + dev->port_number = atoi(tmp + 1); + *tmp = '\0'; + } else { + usbi_warn(ctx, "Can not parse sysfs_dir: %s, no parent info", + parent_sysfs_dir); + free (parent_sysfs_dir); + return LIBUSB_SUCCESS; + } + + /* is the parent a root hub? */ + if (NULL == strchr(parent_sysfs_dir, '-')) { + tmp = parent_sysfs_dir; + ret = asprintf (&parent_sysfs_dir, "usb%s", tmp); + free (tmp); + if (0 > ret) { + return LIBUSB_ERROR_NO_MEM; + } + } + +retry: + /* find the parent in the context */ + usbi_mutex_lock(&ctx->usb_devs_lock); + list_for_each_entry(it, &ctx->usb_devs, list, struct libusb_device) { + struct linux_device_priv *priv = _device_priv(it); + if (0 == strcmp (priv->sysfs_dir, parent_sysfs_dir)) { + dev->parent_dev = libusb_ref_device(it); + break; + } + } + usbi_mutex_unlock(&ctx->usb_devs_lock); + + if (!dev->parent_dev && add_parent) { + usbi_dbg("parent_dev %s not enumerated yet, enumerating now", + parent_sysfs_dir); + sysfs_scan_device(ctx, parent_sysfs_dir); + add_parent = 0; + goto retry; + } + + usbi_dbg("Dev %p (%s) has parent %p (%s) port %d", dev, sysfs_dir, + dev->parent_dev, parent_sysfs_dir, dev->port_number); + + free (parent_sysfs_dir); + + return LIBUSB_SUCCESS; +} + +int linux_enumerate_device(struct libusb_context *ctx, + uint8_t busnum, uint8_t devaddr, const char *sysfs_dir) +{ + unsigned long session_id; + struct libusb_device *dev; + int r = 0; + + /* FIXME: session ID is not guaranteed unique as addresses can wrap and + * will be reused. instead we should add a simple sysfs attribute with + * a session ID. */ + session_id = busnum << 8 | devaddr; + usbi_dbg("busnum %d devaddr %d session_id %ld", busnum, devaddr, + session_id); + + dev = usbi_get_device_by_session_id(ctx, session_id); + if (dev) { + /* device already exists in the context */ + usbi_dbg("session_id %ld already exists", session_id); + libusb_unref_device(dev); + return LIBUSB_SUCCESS; + } + + usbi_dbg("allocating new device for %d/%d (session %ld)", + busnum, devaddr, session_id); + dev = usbi_alloc_device(ctx, session_id); + if (!dev) + return LIBUSB_ERROR_NO_MEM; + + r = initialize_device(dev, busnum, devaddr, sysfs_dir); + if (r < 0) + goto out; + r = usbi_sanitize_device(dev); + if (r < 0) + goto out; + + r = linux_get_parent_info(dev, sysfs_dir); + if (r < 0) + goto out; +out: + if (r < 0) + libusb_unref_device(dev); + else + usbi_connect_device(dev); + + return r; +} + +void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_name) +{ + struct libusb_context *ctx; + + usbi_mutex_static_lock(&active_contexts_lock); + list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { + linux_enumerate_device(ctx, busnum, devaddr, sys_name); + } + usbi_mutex_static_unlock(&active_contexts_lock); +} + +void linux_device_disconnected(uint8_t busnum, uint8_t devaddr) +{ + struct libusb_context *ctx; + struct libusb_device *dev; + unsigned long session_id = busnum << 8 | devaddr; + + usbi_mutex_static_lock(&active_contexts_lock); + list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) { + dev = usbi_get_device_by_session_id (ctx, session_id); + if (NULL != dev) { + usbi_disconnect_device (dev); + libusb_unref_device(dev); + } else { + usbi_dbg("device not found for session %x", session_id); + } + } + usbi_mutex_static_unlock(&active_contexts_lock); +} + +#if !defined(USE_UDEV) +/* open a bus directory and adds all discovered devices to the context */ +static int usbfs_scan_busdir(struct libusb_context *ctx, uint8_t busnum) +{ + DIR *dir; + char dirpath[PATH_MAX]; + struct dirent *entry; + int r = LIBUSB_ERROR_IO; + + snprintf(dirpath, PATH_MAX, "%s/%03d", usbfs_path, busnum); + usbi_dbg("%s", dirpath); + dir = opendir(dirpath); + if (!dir) { + usbi_err(ctx, "opendir '%s' failed, errno=%d", dirpath, errno); + /* FIXME: should handle valid race conditions like hub unplugged + * during directory iteration - this is not an error */ + return r; + } + + while ((entry = readdir(dir))) { + int devaddr; + + if (entry->d_name[0] == '.') + continue; + + devaddr = atoi(entry->d_name); + if (devaddr == 0) { + usbi_dbg("unknown dir entry %s", entry->d_name); + continue; + } + + if (linux_enumerate_device(ctx, busnum, (uint8_t) devaddr, NULL)) { + usbi_dbg("failed to enumerate dir entry %s", entry->d_name); + continue; + } + + r = 0; + } + + closedir(dir); + return r; +} + +static int usbfs_get_device_list(struct libusb_context *ctx) +{ + struct dirent *entry; + DIR *buses = opendir(usbfs_path); + int r = 0; + + if (!buses) { + usbi_err(ctx, "opendir buses failed errno=%d", errno); + return LIBUSB_ERROR_IO; + } + + while ((entry = readdir(buses))) { + int busnum; + + if (entry->d_name[0] == '.') + continue; + + if (usbdev_names) { + int devaddr; + if (!_is_usbdev_entry(entry, &busnum, &devaddr)) + continue; + + r = linux_enumerate_device(ctx, busnum, (uint8_t) devaddr, NULL); + if (r < 0) { + usbi_dbg("failed to enumerate dir entry %s", entry->d_name); + continue; + } + } else { + busnum = atoi(entry->d_name); + if (busnum == 0) { + usbi_dbg("unknown dir entry %s", entry->d_name); + continue; + } + + r = usbfs_scan_busdir(ctx, busnum); + if (r < 0) + break; + } + } + + closedir(buses); + return r; + +} +#endif + +static int sysfs_scan_device(struct libusb_context *ctx, const char *devname) +{ + uint8_t busnum, devaddr; + int ret; + + ret = linux_get_device_address (ctx, 0, &busnum, &devaddr, NULL, devname); + if (LIBUSB_SUCCESS != ret) { + return ret; + } + + return linux_enumerate_device(ctx, busnum & 0xff, devaddr & 0xff, + devname); +} + +#if !defined(USE_UDEV) +static int sysfs_get_device_list(struct libusb_context *ctx) +{ + DIR *devices = opendir(SYSFS_DEVICE_PATH); + struct dirent *entry; + int r = LIBUSB_ERROR_IO; + + if (!devices) { + usbi_err(ctx, "opendir devices failed errno=%d", errno); + return r; + } + + while ((entry = readdir(devices))) { + if ((!isdigit(entry->d_name[0]) && strncmp(entry->d_name, "usb", 3)) + || strchr(entry->d_name, ':')) + continue; + + if (sysfs_scan_device(ctx, entry->d_name)) { + usbi_dbg("failed to enumerate dir entry %s", entry->d_name); + continue; + } + + r = 0; + } + + closedir(devices); + return r; +} + +static int linux_default_scan_devices (struct libusb_context *ctx) +{ + /* we can retrieve device list and descriptors from sysfs or usbfs. + * sysfs is preferable, because if we use usbfs we end up resuming + * any autosuspended USB devices. however, sysfs is not available + * everywhere, so we need a usbfs fallback too. + * + * as described in the "sysfs vs usbfs" comment at the top of this + * file, sometimes we have sysfs but not enough information to + * relate sysfs devices to usbfs nodes. op_init() determines the + * adequacy of sysfs and sets sysfs_can_relate_devices. + */ + if (sysfs_can_relate_devices != 0) + return sysfs_get_device_list(ctx); + else + return usbfs_get_device_list(ctx); +} +#endif + +static int op_open(struct libusb_device_handle *handle) +{ + struct linux_device_handle_priv *hpriv = _device_handle_priv(handle); + int r; + + hpriv->fd = _get_usbfs_fd(handle->dev, O_RDWR, 0); + if (hpriv->fd < 0) { + if (hpriv->fd == LIBUSB_ERROR_NO_DEVICE) { + /* device will still be marked as attached if hotplug monitor thread + * hasn't processed remove event yet */ + usbi_mutex_static_lock(&linux_hotplug_lock); + if (handle->dev->attached) { + usbi_dbg("open failed with no device, but device still attached"); + linux_device_disconnected(handle->dev->bus_number, + handle->dev->device_address); + } + usbi_mutex_static_unlock(&linux_hotplug_lock); + } + return hpriv->fd; + } + + r = ioctl(hpriv->fd, IOCTL_USBFS_GET_CAPABILITIES, &hpriv->caps); + if (r < 0) { + if (errno == ENOTTY) + usbi_dbg("getcap not available"); + else + usbi_err(HANDLE_CTX(handle), "getcap failed (%d)", errno); + hpriv->caps = 0; + if (supports_flag_zero_packet) + hpriv->caps |= USBFS_CAP_ZERO_PACKET; + if (supports_flag_bulk_continuation) + hpriv->caps |= USBFS_CAP_BULK_CONTINUATION; + } + + r = usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT); + if (r < 0) + close(hpriv->fd); + + return r; +} + +static int op_open2(struct libusb_device_handle *handle, int fd) { + int r; + struct linux_device_handle_priv *hpriv = _device_handle_priv(handle); + + hpriv->fd = fd; + + r = ioctl(hpriv->fd, IOCTL_USBFS_GET_CAPABILITIES, &hpriv->caps); + if (r < 0) { + if (errno == ENOTTY) + usbi_dbg("getcap not available"); + else + usbi_err(HANDLE_CTX(handle), "getcap failed (%d)", errno); + hpriv->caps = 0; + if (supports_flag_zero_packet) + hpriv->caps |= USBFS_CAP_ZERO_PACKET; + if (supports_flag_bulk_continuation) + hpriv->caps |= USBFS_CAP_BULK_CONTINUATION; + } + + return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT); +} + +static libusb_device* op_device2(struct libusb_context *ctx, const char *dev_node) { + uint8_t busnum, devaddr; + unsigned int session_id; + if (linux_get_device_address(ctx, 0, &busnum, &devaddr, + dev_node, NULL) != LIBUSB_SUCCESS) { + usbi_dbg("failed to get device address (%s)", dev_node); + return NULL; + } + + /* make sure device is enumerated */ + struct libusb_device *dev; + + /* FIXME: session ID is not guaranteed unique as addresses can wrap and + * will be reused. instead we should add a simple sysfs attribute with + * a session ID. */ + session_id = busnum << 8 | devaddr; + usbi_dbg("busnum %d devaddr %d session_id %ld", busnum, devaddr, + session_id); + + usbi_dbg("allocating new device for %d/%d (session %ld)", + busnum, devaddr, session_id); + dev = usbi_alloc_device(ctx, session_id); + if (!dev) { + return NULL; + } + + usbi_connect_device(dev); + + return dev; +} + +static void op_close(struct libusb_device_handle *dev_handle) +{ + struct linux_device_handle_priv *hpriv = _device_handle_priv(dev_handle); + /* fd may have already been removed by POLLERR condition in op_handle_events() */ + if (!hpriv->fd_removed) + usbi_remove_pollfd(HANDLE_CTX(dev_handle), hpriv->fd); + close(hpriv->fd); +} + +static int op_get_configuration(struct libusb_device_handle *handle, + int *config) +{ + int r; + + if (sysfs_can_relate_devices) { + r = sysfs_get_active_config(handle->dev, config); + } else { + r = usbfs_get_active_config(handle->dev, + _device_handle_priv(handle)->fd); + } + if (r < 0) + return r; + + if (*config == -1) { + usbi_err(HANDLE_CTX(handle), "device unconfigured"); + *config = 0; + } + + return 0; +} + +static int op_set_configuration(struct libusb_device_handle *handle, int config) +{ + struct linux_device_priv *priv = _device_priv(handle->dev); + int fd = _device_handle_priv(handle)->fd; + int r = ioctl(fd, IOCTL_USBFS_SETCONFIG, &config); + if (r) { + if (errno == EINVAL) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == EBUSY) + return LIBUSB_ERROR_BUSY; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), "failed, error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + /* update our cached active config descriptor */ + priv->active_config = config; + + return LIBUSB_SUCCESS; +} + +static int claim_interface(struct libusb_device_handle *handle, int iface) +{ + int fd = _device_handle_priv(handle)->fd; + int r = ioctl(fd, IOCTL_USBFS_CLAIMINTF, &iface); + if (r) { + if (errno == ENOENT) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == EBUSY) + return LIBUSB_ERROR_BUSY; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "claim interface failed, error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + return 0; +} + +static int release_interface(struct libusb_device_handle *handle, int iface) +{ + int fd = _device_handle_priv(handle)->fd; + int r = ioctl(fd, IOCTL_USBFS_RELEASEINTF, &iface); + if (r) { + if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "release interface failed, error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + return 0; +} + +static int op_set_interface(struct libusb_device_handle *handle, int iface, + int altsetting) +{ + int fd = _device_handle_priv(handle)->fd; + struct usbfs_setinterface setintf; + int r; + + setintf.interface = iface; + setintf.altsetting = altsetting; + r = ioctl(fd, IOCTL_USBFS_SETINTF, &setintf); + if (r) { + if (errno == EINVAL) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "setintf failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + return 0; +} + +static int op_clear_halt(struct libusb_device_handle *handle, + unsigned char endpoint) +{ + int fd = _device_handle_priv(handle)->fd; + unsigned int _endpoint = endpoint; + int r = ioctl(fd, IOCTL_USBFS_CLEAR_HALT, &_endpoint); + if (r) { + if (errno == ENOENT) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "clear_halt failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + return 0; +} + +static int op_reset_device(struct libusb_device_handle *handle) +{ + int fd = _device_handle_priv(handle)->fd; + int i, r, ret = 0; + + /* Doing a device reset will cause the usbfs driver to get unbound + from any interfaces it is bound to. By voluntarily unbinding + the usbfs driver ourself, we stop the kernel from rebinding + the interface after reset (which would end up with the interface + getting bound to the in kernel driver if any). */ + for (i = 0; i < USB_MAXINTERFACES; i++) { + if (handle->claimed_interfaces & (1L << i)) { + release_interface(handle, i); + } + } + + usbi_mutex_lock(&handle->lock); + r = ioctl(fd, IOCTL_USBFS_RESET, NULL); + if (r) { + if (errno == ENODEV) { + ret = LIBUSB_ERROR_NOT_FOUND; + goto out; + } + + usbi_err(HANDLE_CTX(handle), + "reset failed error %d errno %d", r, errno); + ret = LIBUSB_ERROR_OTHER; + goto out; + } + + /* And re-claim any interfaces which were claimed before the reset */ + for (i = 0; i < USB_MAXINTERFACES; i++) { + if (handle->claimed_interfaces & (1L << i)) { + /* + * A driver may have completed modprobing during + * IOCTL_USBFS_RESET, and bound itself as soon as + * IOCTL_USBFS_RESET released the device lock + */ + r = detach_kernel_driver_and_claim(handle, i); + if (r) { + usbi_warn(HANDLE_CTX(handle), + "failed to re-claim interface %d after reset: %s", + i, libusb_error_name(r)); + handle->claimed_interfaces &= ~(1L << i); + ret = LIBUSB_ERROR_NOT_FOUND; + } + } + } +out: + usbi_mutex_unlock(&handle->lock); + return ret; +} + +static int do_streams_ioctl(struct libusb_device_handle *handle, long req, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints) +{ + int r, fd = _device_handle_priv(handle)->fd; + struct usbfs_streams *streams; + + if (num_endpoints > 30) /* Max 15 in + 15 out eps */ + return LIBUSB_ERROR_INVALID_PARAM; + + streams = malloc(sizeof(struct usbfs_streams) + num_endpoints); + if (!streams) + return LIBUSB_ERROR_NO_MEM; + + streams->num_streams = num_streams; + streams->num_eps = num_endpoints; + memcpy(streams->eps, endpoints, num_endpoints); + + r = ioctl(fd, req, streams); + + free(streams); + + if (r < 0) { + if (errno == ENOTTY) + return LIBUSB_ERROR_NOT_SUPPORTED; + else if (errno == EINVAL) + return LIBUSB_ERROR_INVALID_PARAM; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "streams-ioctl failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + return r; +} + +static int op_alloc_streams(struct libusb_device_handle *handle, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints) +{ + return do_streams_ioctl(handle, IOCTL_USBFS_ALLOC_STREAMS, + num_streams, endpoints, num_endpoints); +} + +static int op_free_streams(struct libusb_device_handle *handle, + unsigned char *endpoints, int num_endpoints) +{ + return do_streams_ioctl(handle, IOCTL_USBFS_FREE_STREAMS, 0, + endpoints, num_endpoints); +} + +static int op_kernel_driver_active(struct libusb_device_handle *handle, + int interface) +{ + int fd = _device_handle_priv(handle)->fd; + struct usbfs_getdriver getdrv; + int r; + + getdrv.interface = interface; + r = ioctl(fd, IOCTL_USBFS_GETDRIVER, &getdrv); + if (r) { + if (errno == ENODATA) + return 0; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "get driver failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + return (strcmp(getdrv.driver, "usbfs") == 0) ? 0 : 1; +} + +static int op_detach_kernel_driver(struct libusb_device_handle *handle, + int interface) +{ + int fd = _device_handle_priv(handle)->fd; + struct usbfs_ioctl command; + struct usbfs_getdriver getdrv; + int r; + + command.ifno = interface; + command.ioctl_code = IOCTL_USBFS_DISCONNECT; + command.data = NULL; + + getdrv.interface = interface; + r = ioctl(fd, IOCTL_USBFS_GETDRIVER, &getdrv); + if (r == 0 && strcmp(getdrv.driver, "usbfs") == 0) + return LIBUSB_ERROR_NOT_FOUND; + + r = ioctl(fd, IOCTL_USBFS_IOCTL, &command); + if (r) { + if (errno == ENODATA) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == EINVAL) + return LIBUSB_ERROR_INVALID_PARAM; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), + "detach failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } + + return 0; +} + +static int op_attach_kernel_driver(struct libusb_device_handle *handle, + int interface) +{ + int fd = _device_handle_priv(handle)->fd; + struct usbfs_ioctl command; + int r; + + command.ifno = interface; + command.ioctl_code = IOCTL_USBFS_CONNECT; + command.data = NULL; + + r = ioctl(fd, IOCTL_USBFS_IOCTL, &command); + if (r < 0) { + if (errno == ENODATA) + return LIBUSB_ERROR_NOT_FOUND; + else if (errno == EINVAL) + return LIBUSB_ERROR_INVALID_PARAM; + else if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + else if (errno == EBUSY) + return LIBUSB_ERROR_BUSY; + + usbi_err(HANDLE_CTX(handle), + "attach failed error %d errno %d", r, errno); + return LIBUSB_ERROR_OTHER; + } else if (r == 0) { + return LIBUSB_ERROR_NOT_FOUND; + } + + return 0; +} + +static int detach_kernel_driver_and_claim(struct libusb_device_handle *handle, + int interface) +{ + struct usbfs_disconnect_claim dc; + int r, fd = _device_handle_priv(handle)->fd; + + dc.interface = interface; + strcpy(dc.driver, "usbfs"); + dc.flags = USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER; + r = ioctl(fd, IOCTL_USBFS_DISCONNECT_CLAIM, &dc); + if (r == 0 || (r != 0 && errno != ENOTTY)) { + if (r == 0) + return 0; + + switch (errno) { + case EBUSY: + return LIBUSB_ERROR_BUSY; + case EINVAL: + return LIBUSB_ERROR_INVALID_PARAM; + case ENODEV: + return LIBUSB_ERROR_NO_DEVICE; + } + usbi_err(HANDLE_CTX(handle), + "disconnect-and-claim failed errno %d", errno); + return LIBUSB_ERROR_OTHER; + } + + /* Fallback code for kernels which don't support the + disconnect-and-claim ioctl */ + r = op_detach_kernel_driver(handle, interface); + if (r != 0 && r != LIBUSB_ERROR_NOT_FOUND) + return r; + + return claim_interface(handle, interface); +} + +static int op_claim_interface(struct libusb_device_handle *handle, int iface) +{ + if (handle->auto_detach_kernel_driver) + return detach_kernel_driver_and_claim(handle, iface); + else + return claim_interface(handle, iface); +} + +static int op_release_interface(struct libusb_device_handle *handle, int iface) +{ + int r; + + r = release_interface(handle, iface); + if (r) + return r; + + if (handle->auto_detach_kernel_driver) + op_attach_kernel_driver(handle, iface); + + return 0; +} + +static void op_destroy_device(struct libusb_device *dev) +{ + struct linux_device_priv *priv = _device_priv(dev); + if (priv->descriptors) + free(priv->descriptors); + if (priv->sysfs_dir) + free(priv->sysfs_dir); +} + +/* URBs are discarded in reverse order of submission to avoid races. */ +static int discard_urbs(struct usbi_transfer *itransfer, int first, int last_plus_one) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = + usbi_transfer_get_os_priv(itransfer); + struct linux_device_handle_priv *dpriv = + _device_handle_priv(transfer->dev_handle); + int i, ret = 0; + struct usbfs_urb *urb; + + for (i = last_plus_one - 1; i >= first; i--) { + if (LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type) + urb = tpriv->iso_urbs[i]; + else + urb = &tpriv->urbs[i]; + + if (0 == ioctl(dpriv->fd, IOCTL_USBFS_DISCARDURB, urb)) + continue; + + if (EINVAL == errno) { + usbi_dbg("URB not found --> assuming ready to be reaped"); + if (i == (last_plus_one - 1)) + ret = LIBUSB_ERROR_NOT_FOUND; + } else if (ENODEV == errno) { + usbi_dbg("Device not found for URB --> assuming ready to be reaped"); + ret = LIBUSB_ERROR_NO_DEVICE; + } else { + usbi_warn(TRANSFER_CTX(transfer), + "unrecognised discard errno %d", errno); + ret = LIBUSB_ERROR_OTHER; + } + } + return ret; +} + +static void free_iso_urbs(struct linux_transfer_priv *tpriv) +{ + int i; + for (i = 0; i < tpriv->num_urbs; i++) { + struct usbfs_urb *urb = tpriv->iso_urbs[i]; + if (!urb) + break; + free(urb); + } + + free(tpriv->iso_urbs); + tpriv->iso_urbs = NULL; +} + +static int submit_bulk_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct linux_device_handle_priv *dpriv = + _device_handle_priv(transfer->dev_handle); + struct usbfs_urb *urbs; + int is_out = (transfer->endpoint & LIBUSB_ENDPOINT_DIR_MASK) + == LIBUSB_ENDPOINT_OUT; + int bulk_buffer_len, use_bulk_continuation; + int r; + int i; + + if (is_out && (transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) && + !(dpriv->caps & USBFS_CAP_ZERO_PACKET)) + return LIBUSB_ERROR_NOT_SUPPORTED; + + /* + * Older versions of usbfs place a 16kb limit on bulk URBs. We work + * around this by splitting large transfers into 16k blocks, and then + * submit all urbs at once. it would be simpler to submit one urb at + * a time, but there is a big performance gain doing it this way. + * + * Newer versions lift the 16k limit (USBFS_CAP_NO_PACKET_SIZE_LIM), + * using arbritary large transfers can still be a bad idea though, as + * the kernel needs to allocate physical contiguous memory for this, + * which may fail for large buffers. + * + * The kernel solves this problem by splitting the transfer into + * blocks itself when the host-controller is scatter-gather capable + * (USBFS_CAP_BULK_SCATTER_GATHER), which most controllers are. + * + * Last, there is the issue of short-transfers when splitting, for + * short split-transfers to work reliable USBFS_CAP_BULK_CONTINUATION + * is needed, but this is not always available. + */ + if (dpriv->caps & USBFS_CAP_BULK_SCATTER_GATHER) { + /* Good! Just submit everything in one go */ + bulk_buffer_len = transfer->length ? transfer->length : 1; + use_bulk_continuation = 0; + } else if (dpriv->caps & USBFS_CAP_BULK_CONTINUATION) { + /* Split the transfers and use bulk-continuation to + avoid issues with short-transfers */ + bulk_buffer_len = MAX_BULK_BUFFER_LENGTH; + use_bulk_continuation = 1; + } else if (dpriv->caps & USBFS_CAP_NO_PACKET_SIZE_LIM) { + /* Don't split, assume the kernel can alloc the buffer + (otherwise the submit will fail with -ENOMEM) */ + bulk_buffer_len = transfer->length ? transfer->length : 1; + use_bulk_continuation = 0; + } else { + /* Bad, splitting without bulk-continuation, short transfers + which end before the last urb will not work reliable! */ + /* Note we don't warn here as this is "normal" on kernels < + 2.6.32 and not a problem for most applications */ + bulk_buffer_len = MAX_BULK_BUFFER_LENGTH; + use_bulk_continuation = 0; + } + + int num_urbs = transfer->length / bulk_buffer_len; + int last_urb_partial = 0; + + if (transfer->length == 0) { + num_urbs = 1; + } else if ((transfer->length % bulk_buffer_len) > 0) { + last_urb_partial = 1; + num_urbs++; + } + usbi_dbg("need %d urbs for new transfer with length %d", num_urbs, + transfer->length); + urbs = calloc(num_urbs, sizeof(struct usbfs_urb)); + if (!urbs) + return LIBUSB_ERROR_NO_MEM; + tpriv->urbs = urbs; + tpriv->num_urbs = num_urbs; + tpriv->num_retired = 0; + tpriv->reap_action = NORMAL; + tpriv->reap_status = LIBUSB_TRANSFER_COMPLETED; + + for (i = 0; i < num_urbs; i++) { + struct usbfs_urb *urb = &urbs[i]; + urb->usercontext = itransfer; + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_BULK: + urb->type = USBFS_URB_TYPE_BULK; + urb->stream_id = 0; + break; + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + urb->type = USBFS_URB_TYPE_BULK; + urb->stream_id = itransfer->stream_id; + break; + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + urb->type = USBFS_URB_TYPE_INTERRUPT; + break; + } + urb->endpoint = transfer->endpoint; + urb->buffer = transfer->buffer + (i * bulk_buffer_len); + /* don't set the short not ok flag for the last URB */ + if (use_bulk_continuation && !is_out && (i < num_urbs - 1)) + urb->flags = USBFS_URB_SHORT_NOT_OK; + if (i == num_urbs - 1 && last_urb_partial) + urb->buffer_length = transfer->length % bulk_buffer_len; + else if (transfer->length == 0) + urb->buffer_length = 0; + else + urb->buffer_length = bulk_buffer_len; + + if (i > 0 && use_bulk_continuation) + urb->flags |= USBFS_URB_BULK_CONTINUATION; + + /* we have already checked that the flag is supported */ + if (is_out && i == num_urbs - 1 && + transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) + urb->flags |= USBFS_URB_ZERO_PACKET; + + r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urb); + if (r < 0) { + if (errno == ENODEV) { + r = LIBUSB_ERROR_NO_DEVICE; + } else { + usbi_err(TRANSFER_CTX(transfer), + "submiturb failed error %d errno=%d", r, errno); + r = LIBUSB_ERROR_IO; + } + + /* if the first URB submission fails, we can simply free up and + * return failure immediately. */ + if (i == 0) { + usbi_dbg("first URB failed, easy peasy"); + free(urbs); + tpriv->urbs = NULL; + return r; + } + + /* if it's not the first URB that failed, the situation is a bit + * tricky. we may need to discard all previous URBs. there are + * complications: + * - discarding is asynchronous - discarded urbs will be reaped + * later. the user must not have freed the transfer when the + * discarded URBs are reaped, otherwise libusb will be using + * freed memory. + * - the earlier URBs may have completed successfully and we do + * not want to throw away any data. + * - this URB failing may be no error; EREMOTEIO means that + * this transfer simply didn't need all the URBs we submitted + * so, we report that the transfer was submitted successfully and + * in case of error we discard all previous URBs. later when + * the final reap completes we can report error to the user, + * or success if an earlier URB was completed successfully. + */ + tpriv->reap_action = EREMOTEIO == errno ? COMPLETED_EARLY : SUBMIT_FAILED; + + /* The URBs we haven't submitted yet we count as already + * retired. */ + tpriv->num_retired += num_urbs - i; + + /* If we completed short then don't try to discard. */ + if (COMPLETED_EARLY == tpriv->reap_action) + return 0; + + discard_urbs(itransfer, 0, i); + + usbi_dbg("reporting successful submission but waiting for %d " + "discards before reporting error", i); + return 0; + } + } + + return 0; +} + +static int submit_iso_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct linux_device_handle_priv *dpriv = + _device_handle_priv(transfer->dev_handle); + struct usbfs_urb **urbs; + size_t alloc_size; + int num_packets = transfer->num_iso_packets; + int i; + int this_urb_len = 0; + int num_urbs = 1; + int packet_offset = 0; + unsigned int packet_len; + unsigned char *urb_buffer = transfer->buffer; + + /* usbfs places arbitrary limits on iso URBs. this limit has changed + * at least three times, and it's difficult to accurately detect which + * limit this running kernel might impose. so we attempt to submit + * whatever the user has provided. if the kernel rejects the request + * due to its size, we return an error indicating such to the user. + */ + + /* calculate how many URBs we need */ + for (i = 0; i < num_packets; i++) { + unsigned int space_remaining = MAX_ISO_BUFFER_LENGTH - this_urb_len; + packet_len = transfer->iso_packet_desc[i].length; + + if (packet_len > space_remaining) { + num_urbs++; + this_urb_len = packet_len; + /* check that we can actually support this packet length */ + if (this_urb_len > MAX_ISO_BUFFER_LENGTH) + return LIBUSB_ERROR_INVALID_PARAM; + } else { + this_urb_len += packet_len; + } + } + usbi_dbg("need %d %dk URBs for transfer", num_urbs, MAX_ISO_BUFFER_LENGTH / 1024); + + urbs = calloc(num_urbs, sizeof(*urbs)); + if (!urbs) + return LIBUSB_ERROR_NO_MEM; + + tpriv->iso_urbs = urbs; + tpriv->num_urbs = num_urbs; + tpriv->num_retired = 0; + tpriv->reap_action = NORMAL; + tpriv->iso_packet_offset = 0; + + /* allocate + initialize each URB with the correct number of packets */ + for (i = 0; i < num_urbs; i++) { + struct usbfs_urb *urb; + unsigned int space_remaining_in_urb = MAX_ISO_BUFFER_LENGTH; + int urb_packet_offset = 0; + unsigned char *urb_buffer_orig = urb_buffer; + int j; + int k; + + /* swallow up all the packets we can fit into this URB */ + while (packet_offset < transfer->num_iso_packets) { + packet_len = transfer->iso_packet_desc[packet_offset].length; + if (packet_len <= space_remaining_in_urb) { + /* throw it in */ + urb_packet_offset++; + packet_offset++; + space_remaining_in_urb -= packet_len; + urb_buffer += packet_len; + } else { + /* it can't fit, save it for the next URB */ + break; + } + } + + alloc_size = sizeof(*urb) + + (urb_packet_offset * sizeof(struct usbfs_iso_packet_desc)); + urb = calloc(1, alloc_size); + if (!urb) { + free_iso_urbs(tpriv); + return LIBUSB_ERROR_NO_MEM; + } + urbs[i] = urb; + + /* populate packet lengths */ + for (j = 0, k = packet_offset - urb_packet_offset; + k < packet_offset; k++, j++) { + packet_len = transfer->iso_packet_desc[k].length; + urb->iso_frame_desc[j].length = packet_len; + } + + urb->usercontext = itransfer; + urb->type = USBFS_URB_TYPE_ISO; + /* FIXME: interface for non-ASAP data? */ + urb->flags = USBFS_URB_ISO_ASAP; + urb->endpoint = transfer->endpoint; + urb->number_of_packets = urb_packet_offset; + urb->buffer = urb_buffer_orig; + } + + /* submit URBs */ + for (i = 0; i < num_urbs; i++) { + int r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urbs[i]); + if (r < 0) { + if (errno == ENODEV) { + r = LIBUSB_ERROR_NO_DEVICE; + } else if (errno == EINVAL) { + usbi_warn(TRANSFER_CTX(transfer), + "submiturb failed, transfer too large"); + r = LIBUSB_ERROR_INVALID_PARAM; + } else { + usbi_err(TRANSFER_CTX(transfer), + "submiturb failed error %d errno=%d", r, errno); + r = LIBUSB_ERROR_IO; + } + + /* if the first URB submission fails, we can simply free up and + * return failure immediately. */ + if (i == 0) { + usbi_dbg("first URB failed, easy peasy"); + free_iso_urbs(tpriv); + return r; + } + + /* if it's not the first URB that failed, the situation is a bit + * tricky. we must discard all previous URBs. there are + * complications: + * - discarding is asynchronous - discarded urbs will be reaped + * later. the user must not have freed the transfer when the + * discarded URBs are reaped, otherwise libusb will be using + * freed memory. + * - the earlier URBs may have completed successfully and we do + * not want to throw away any data. + * so, in this case we discard all the previous URBs BUT we report + * that the transfer was submitted successfully. then later when + * the final discard completes we can report error to the user. + */ + tpriv->reap_action = SUBMIT_FAILED; + + /* The URBs we haven't submitted yet we count as already + * retired. */ + tpriv->num_retired = num_urbs - i; + discard_urbs(itransfer, 0, i); + + usbi_dbg("reporting successful submission but waiting for %d " + "discards before reporting error", i); + return 0; + } + } + + return 0; +} + +static int submit_control_transfer(struct usbi_transfer *itransfer) +{ + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_device_handle_priv *dpriv = + _device_handle_priv(transfer->dev_handle); + struct usbfs_urb *urb; + int r; + + if (transfer->length - LIBUSB_CONTROL_SETUP_SIZE > MAX_CTRL_BUFFER_LENGTH) + return LIBUSB_ERROR_INVALID_PARAM; + + urb = calloc(1, sizeof(struct usbfs_urb)); + if (!urb) + return LIBUSB_ERROR_NO_MEM; + tpriv->urbs = urb; + tpriv->num_urbs = 1; + tpriv->reap_action = NORMAL; + + urb->usercontext = itransfer; + urb->type = USBFS_URB_TYPE_CONTROL; + urb->endpoint = transfer->endpoint; + urb->buffer = transfer->buffer; + urb->buffer_length = transfer->length; + + r = ioctl(dpriv->fd, IOCTL_USBFS_SUBMITURB, urb); + if (r < 0) { + free(urb); + tpriv->urbs = NULL; + if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(TRANSFER_CTX(transfer), + "submiturb failed error %d errno=%d", r, errno); + return LIBUSB_ERROR_IO; + } + return 0; +} + +static int op_submit_transfer(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + return submit_control_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + return submit_bulk_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + return submit_bulk_transfer(itransfer); + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return submit_iso_transfer(itransfer); + default: + usbi_err(TRANSFER_CTX(transfer), + "unknown endpoint type %d", transfer->type); + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +static int op_cancel_transfer(struct usbi_transfer *itransfer) +{ + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + int r; + + if (!tpriv->urbs) + return LIBUSB_ERROR_NOT_FOUND; + + r = discard_urbs(itransfer, 0, tpriv->num_urbs); + if (r != 0) + return r; + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + if (tpriv->reap_action == ERROR) + break; + /* else, fall through */ + default: + tpriv->reap_action = CANCELLED; + } + + return 0; +} + +static void op_clear_transfer_priv(struct usbi_transfer *itransfer) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + + /* urbs can be freed also in submit_transfer so lock mutex first */ + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_CONTROL: + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + if (tpriv->urbs) { + free(tpriv->urbs); + tpriv->urbs = NULL; + } + break; + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + if (tpriv->iso_urbs) { + free_iso_urbs(tpriv); + tpriv->iso_urbs = NULL; + } + break; + default: + usbi_err(TRANSFER_CTX(transfer), + "unknown endpoint type %d", transfer->type); + } +} + +static int handle_bulk_completion(struct usbi_transfer *itransfer, + struct usbfs_urb *urb) +{ + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + int urb_idx = urb - tpriv->urbs; + + usbi_mutex_lock(&itransfer->lock); + usbi_dbg("handling completion status %d of bulk urb %d/%d", urb->status, + urb_idx + 1, tpriv->num_urbs); + + tpriv->num_retired++; + + if (tpriv->reap_action != NORMAL) { + /* cancelled, submit_fail, or completed early */ + usbi_dbg("abnormal reap: urb status %d", urb->status); + + /* even though we're in the process of cancelling, it's possible that + * we may receive some data in these URBs that we don't want to lose. + * examples: + * 1. while the kernel is cancelling all the packets that make up an + * URB, a few of them might complete. so we get back a successful + * cancellation *and* some data. + * 2. we receive a short URB which marks the early completion condition, + * so we start cancelling the remaining URBs. however, we're too + * slow and another URB completes (or at least completes partially). + * (this can't happen since we always use BULK_CONTINUATION.) + * + * When this happens, our objectives are not to lose any "surplus" data, + * and also to stick it at the end of the previously-received data + * (closing any holes), so that libusb reports the total amount of + * transferred data and presents it in a contiguous chunk. + */ + if (urb->actual_length > 0) { + unsigned char *target = transfer->buffer + itransfer->transferred; + usbi_dbg("received %d bytes of surplus data", urb->actual_length); + if (urb->buffer != target) { + usbi_dbg("moving surplus data from offset %d to offset %d", + (unsigned char *) urb->buffer - transfer->buffer, + target - transfer->buffer); + memmove(target, urb->buffer, urb->actual_length); + } + itransfer->transferred += urb->actual_length; + } + + if (tpriv->num_retired == tpriv->num_urbs) { + usbi_dbg("abnormal reap: last URB handled, reporting"); + if (tpriv->reap_action != COMPLETED_EARLY && + tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED) + tpriv->reap_status = LIBUSB_TRANSFER_ERROR; + goto completed; + } + goto out_unlock; + } + + itransfer->transferred += urb->actual_length; + + /* Many of these errors can occur on *any* urb of a multi-urb + * transfer. When they do, we tear down the rest of the transfer. + */ + switch (urb->status) { + case 0: + break; + case -EREMOTEIO: /* short transfer */ + break; + case -ENOENT: /* cancelled */ + case -ECONNRESET: + break; + case -ENODEV: + case -ESHUTDOWN: + usbi_dbg("device removed"); + tpriv->reap_status = LIBUSB_TRANSFER_NO_DEVICE; + goto cancel_remaining; + case -EPIPE: + usbi_dbg("detected endpoint stall"); + if (tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED) + tpriv->reap_status = LIBUSB_TRANSFER_STALL; + goto cancel_remaining; + case -EOVERFLOW: + /* overflow can only ever occur in the last urb */ + usbi_dbg("overflow, actual_length=%d", urb->actual_length); + if (tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED) + tpriv->reap_status = LIBUSB_TRANSFER_OVERFLOW; + goto completed; + case -ETIME: + case -EPROTO: + case -EILSEQ: + case -ECOMM: + case -ENOSR: + usbi_dbg("low level error %d", urb->status); + tpriv->reap_action = ERROR; + goto cancel_remaining; + default: + usbi_warn(ITRANSFER_CTX(itransfer), + "unrecognised urb status %d", urb->status); + tpriv->reap_action = ERROR; + goto cancel_remaining; + } + + /* if we're the last urb or we got less data than requested then we're + * done */ + if (urb_idx == tpriv->num_urbs - 1) { + usbi_dbg("last URB in transfer --> complete!"); + goto completed; + } else if (urb->actual_length < urb->buffer_length) { + usbi_dbg("short transfer %d/%d --> complete!", + urb->actual_length, urb->buffer_length); + if (tpriv->reap_action == NORMAL) + tpriv->reap_action = COMPLETED_EARLY; + } else + goto out_unlock; + +cancel_remaining: + if (ERROR == tpriv->reap_action && LIBUSB_TRANSFER_COMPLETED == tpriv->reap_status) + tpriv->reap_status = LIBUSB_TRANSFER_ERROR; + + if (tpriv->num_retired == tpriv->num_urbs) /* nothing to cancel */ + goto completed; + + /* cancel remaining urbs and wait for their completion before + * reporting results */ + discard_urbs(itransfer, urb_idx + 1, tpriv->num_urbs); + +out_unlock: + usbi_mutex_unlock(&itransfer->lock); + return 0; + +completed: + free(tpriv->urbs); + tpriv->urbs = NULL; + usbi_mutex_unlock(&itransfer->lock); + return CANCELLED == tpriv->reap_action ? + usbi_handle_transfer_cancellation(itransfer) : + usbi_handle_transfer_completion(itransfer, tpriv->reap_status); +} + +static int handle_iso_completion(struct usbi_transfer *itransfer, + struct usbfs_urb *urb) +{ + struct libusb_transfer *transfer = + USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + int num_urbs = tpriv->num_urbs; + int urb_idx = 0; + int i; + enum libusb_transfer_status status = LIBUSB_TRANSFER_COMPLETED; + + usbi_mutex_lock(&itransfer->lock); + for (i = 0; i < num_urbs; i++) { + if (urb == tpriv->iso_urbs[i]) { + urb_idx = i + 1; + break; + } + } + if (urb_idx == 0) { + usbi_err(TRANSFER_CTX(transfer), "could not locate urb!"); + usbi_mutex_unlock(&itransfer->lock); + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_dbg("handling completion status %d of iso urb %d/%d", urb->status, + urb_idx, num_urbs); + + /* copy isochronous results back in */ + + for (i = 0; i < urb->number_of_packets; i++) { + struct usbfs_iso_packet_desc *urb_desc = &urb->iso_frame_desc[i]; + struct libusb_iso_packet_descriptor *lib_desc = + &transfer->iso_packet_desc[tpriv->iso_packet_offset++]; + lib_desc->status = LIBUSB_TRANSFER_COMPLETED; + switch (urb_desc->status) { + case 0: + break; + case -ENOENT: /* cancelled */ + case -ECONNRESET: + break; + case -ENODEV: + case -ESHUTDOWN: + usbi_dbg("device removed"); + lib_desc->status = LIBUSB_TRANSFER_NO_DEVICE; + break; + case -EPIPE: + usbi_dbg("detected endpoint stall"); + lib_desc->status = LIBUSB_TRANSFER_STALL; + break; + case -EOVERFLOW: + usbi_dbg("overflow error"); + lib_desc->status = LIBUSB_TRANSFER_OVERFLOW; + break; + case -ETIME: + case -EPROTO: + case -EILSEQ: + case -ECOMM: + case -ENOSR: + case -EXDEV: + usbi_dbg("low-level USB error %d", urb_desc->status); + lib_desc->status = LIBUSB_TRANSFER_ERROR; + break; + default: + usbi_warn(TRANSFER_CTX(transfer), + "unrecognised urb status %d", urb_desc->status); + lib_desc->status = LIBUSB_TRANSFER_ERROR; + break; + } + lib_desc->actual_length = urb_desc->actual_length; + } + + tpriv->num_retired++; + + if (tpriv->reap_action != NORMAL) { /* cancelled or submit_fail */ + usbi_dbg("CANCEL: urb status %d", urb->status); + + if (tpriv->num_retired == num_urbs) { + usbi_dbg("CANCEL: last URB handled, reporting"); + free_iso_urbs(tpriv); + if (tpriv->reap_action == CANCELLED) { + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_cancellation(itransfer); + } else { + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_completion(itransfer, + LIBUSB_TRANSFER_ERROR); + } + } + goto out; + } + + switch (urb->status) { + case 0: + break; + case -ENOENT: /* cancelled */ + case -ECONNRESET: + break; + case -ESHUTDOWN: + usbi_dbg("device removed"); + status = LIBUSB_TRANSFER_NO_DEVICE; + break; + default: + usbi_warn(TRANSFER_CTX(transfer), + "unrecognised urb status %d", urb->status); + status = LIBUSB_TRANSFER_ERROR; + break; + } + + /* if we're the last urb then we're done */ + if (urb_idx == num_urbs) { + usbi_dbg("last URB in transfer --> complete!"); + free_iso_urbs(tpriv); + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_completion(itransfer, status); + } + +out: + usbi_mutex_unlock(&itransfer->lock); + return 0; +} + +static int handle_control_completion(struct usbi_transfer *itransfer, + struct usbfs_urb *urb) +{ + struct linux_transfer_priv *tpriv = usbi_transfer_get_os_priv(itransfer); + int status; + + usbi_mutex_lock(&itransfer->lock); + usbi_dbg("handling completion status %d", urb->status); + + itransfer->transferred += urb->actual_length; + + if (tpriv->reap_action == CANCELLED) { + if (urb->status != 0 && urb->status != -ENOENT) + usbi_warn(ITRANSFER_CTX(itransfer), + "cancel: unrecognised urb status %d", urb->status); + free(tpriv->urbs); + tpriv->urbs = NULL; + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_cancellation(itransfer); + } + + switch (urb->status) { + case 0: + status = LIBUSB_TRANSFER_COMPLETED; + break; + case -ENOENT: /* cancelled */ + status = LIBUSB_TRANSFER_CANCELLED; + break; + case -ENODEV: + case -ESHUTDOWN: + usbi_dbg("device removed"); + status = LIBUSB_TRANSFER_NO_DEVICE; + break; + case -EPIPE: + usbi_dbg("unsupported control request"); + status = LIBUSB_TRANSFER_STALL; + break; + case -EOVERFLOW: + usbi_dbg("control overflow error"); + status = LIBUSB_TRANSFER_OVERFLOW; + break; + case -ETIME: + case -EPROTO: + case -EILSEQ: + case -ECOMM: + case -ENOSR: + usbi_dbg("low-level bus error occurred"); + status = LIBUSB_TRANSFER_ERROR; + break; + default: + usbi_warn(ITRANSFER_CTX(itransfer), + "unrecognised urb status %d", urb->status); + status = LIBUSB_TRANSFER_ERROR; + break; + } + + free(tpriv->urbs); + tpriv->urbs = NULL; + usbi_mutex_unlock(&itransfer->lock); + return usbi_handle_transfer_completion(itransfer, status); +} + +static int reap_for_handle(struct libusb_device_handle *handle) +{ + struct linux_device_handle_priv *hpriv = _device_handle_priv(handle); + int r; + struct usbfs_urb *urb; + struct usbi_transfer *itransfer; + struct libusb_transfer *transfer; + + r = ioctl(hpriv->fd, IOCTL_USBFS_REAPURBNDELAY, &urb); + if (r == -1 && errno == EAGAIN) + return 1; + if (r < 0) { + if (errno == ENODEV) + return LIBUSB_ERROR_NO_DEVICE; + + usbi_err(HANDLE_CTX(handle), "reap failed error %d errno=%d", + r, errno); + return LIBUSB_ERROR_IO; + } + + itransfer = urb->usercontext; + transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); + + usbi_dbg("urb type=%d status=%d transferred=%d", urb->type, urb->status, + urb->actual_length); + + switch (transfer->type) { + case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: + return handle_iso_completion(itransfer, urb); + case LIBUSB_TRANSFER_TYPE_BULK: + case LIBUSB_TRANSFER_TYPE_BULK_STREAM: + case LIBUSB_TRANSFER_TYPE_INTERRUPT: + return handle_bulk_completion(itransfer, urb); + case LIBUSB_TRANSFER_TYPE_CONTROL: + return handle_control_completion(itransfer, urb); + default: + usbi_err(HANDLE_CTX(handle), "unrecognised endpoint type %x", + transfer->type); + return LIBUSB_ERROR_OTHER; + } +} + +static int op_handle_events(struct libusb_context *ctx, + struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready) +{ + int r; + unsigned int i = 0; + + usbi_mutex_lock(&ctx->open_devs_lock); + for (i = 0; i < nfds && num_ready > 0; i++) { + struct pollfd *pollfd = &fds[i]; + struct libusb_device_handle *handle; + struct linux_device_handle_priv *hpriv = NULL; + + if (!pollfd->revents) + continue; + + num_ready--; + list_for_each_entry(handle, &ctx->open_devs, list, struct libusb_device_handle) { + hpriv = _device_handle_priv(handle); + if (hpriv->fd == pollfd->fd) + break; + } + + if (!hpriv || hpriv->fd != pollfd->fd) { + usbi_err(ctx, "cannot find handle for fd %d", + pollfd->fd); + continue; + } + + if (pollfd->revents & POLLERR) { + /* remove the fd from the pollfd set so that it doesn't continuously + * trigger an event, and flag that it has been removed so op_close() + * doesn't try to remove it a second time */ + usbi_remove_pollfd(HANDLE_CTX(handle), hpriv->fd); + hpriv->fd_removed = 1; + + /* device will still be marked as attached if hotplug monitor thread + * hasn't processed remove event yet */ + usbi_mutex_static_lock(&linux_hotplug_lock); + if (handle->dev->attached) + linux_device_disconnected(handle->dev->bus_number, + handle->dev->device_address); + usbi_mutex_static_unlock(&linux_hotplug_lock); + + if (!(hpriv->caps & USBFS_CAP_REAP_AFTER_DISCONNECT)) { + usbi_handle_disconnect(handle); + continue; + } + } + + do { + r = reap_for_handle(handle); + } while (r == 0); + if (r == 1 || r == LIBUSB_ERROR_NO_DEVICE) + continue; + else if (r < 0) + goto out; + } + + r = 0; +out: + usbi_mutex_unlock(&ctx->open_devs_lock); + return r; +} + +static int op_clock_gettime(int clk_id, struct timespec *tp) +{ + switch (clk_id) { + case USBI_CLOCK_MONOTONIC: + return clock_gettime(monotonic_clkid, tp); + case USBI_CLOCK_REALTIME: + return clock_gettime(CLOCK_REALTIME, tp); + default: + return LIBUSB_ERROR_INVALID_PARAM; + } +} + +#ifdef USBI_TIMERFD_AVAILABLE +static clockid_t op_get_timerfd_clockid(void) +{ + return monotonic_clkid; + +} +#endif + +const struct usbi_os_backend linux_usbfs_backend = { + .name = "Linux usbfs", + .caps = USBI_CAP_HAS_HID_ACCESS|USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER, + .init = op_init, + .exit = op_exit, + .get_device_list = NULL, + .hotplug_poll = op_hotplug_poll, + .get_device_descriptor = op_get_device_descriptor, + .get_active_config_descriptor = op_get_active_config_descriptor, + .get_config_descriptor = op_get_config_descriptor, + .get_config_descriptor_by_value = op_get_config_descriptor_by_value, + + .open = op_open, + .open2 = op_open2, + .device2 = op_device2, + .close = op_close, + .get_configuration = op_get_configuration, + .set_configuration = op_set_configuration, + .claim_interface = op_claim_interface, + .release_interface = op_release_interface, + + .set_interface_altsetting = op_set_interface, + .clear_halt = op_clear_halt, + .reset_device = op_reset_device, + + .alloc_streams = op_alloc_streams, + .free_streams = op_free_streams, + + .kernel_driver_active = op_kernel_driver_active, + .detach_kernel_driver = op_detach_kernel_driver, + .attach_kernel_driver = op_attach_kernel_driver, + + .destroy_device = op_destroy_device, + + .submit_transfer = op_submit_transfer, + .cancel_transfer = op_cancel_transfer, + .clear_transfer_priv = op_clear_transfer_priv, + + .handle_events = op_handle_events, + + .clock_gettime = op_clock_gettime, + +#ifdef USBI_TIMERFD_AVAILABLE + .get_timerfd_clockid = op_get_timerfd_clockid, +#endif + + .device_priv_size = sizeof(struct linux_device_priv), + .device_handle_priv_size = sizeof(struct linux_device_handle_priv), + .transfer_priv_size = sizeof(struct linux_transfer_priv), +}; diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_usbfs.c.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_usbfs.c.REMOVED.git-id deleted file mode 100644 index 9c5dd970..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_usbfs.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6b43770a5685eb50317c5a9e7d82b6a59547747b \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_usbfs.h b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_usbfs.h new file mode 100644 index 00000000..8bd3ebcb --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_usbfs.h @@ -0,0 +1,193 @@ +/* + * usbfs header structures + * Copyright © 2007 Daniel Drake + * Copyright © 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_USBFS_H +#define LIBUSB_USBFS_H + +#include + +#define SYSFS_DEVICE_PATH "/sys/bus/usb/devices" + +struct usbfs_ctrltransfer { + /* keep in sync with usbdevice_fs.h:usbdevfs_ctrltransfer */ + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; + + uint32_t timeout; /* in milliseconds */ + + /* pointer to data */ + void *data; +}; + +struct usbfs_bulktransfer { + /* keep in sync with usbdevice_fs.h:usbdevfs_bulktransfer */ + unsigned int ep; + unsigned int len; + unsigned int timeout; /* in milliseconds */ + + /* pointer to data */ + void *data; +}; + +struct usbfs_setinterface { + /* keep in sync with usbdevice_fs.h:usbdevfs_setinterface */ + unsigned int interface; + unsigned int altsetting; +}; + +#define USBFS_MAXDRIVERNAME 255 + +struct usbfs_getdriver { + unsigned int interface; + char driver[USBFS_MAXDRIVERNAME + 1]; +}; + +#define USBFS_URB_SHORT_NOT_OK 0x01 +#define USBFS_URB_ISO_ASAP 0x02 +#define USBFS_URB_BULK_CONTINUATION 0x04 +#define USBFS_URB_QUEUE_BULK 0x10 +#define USBFS_URB_ZERO_PACKET 0x40 + +enum usbfs_urb_type { + USBFS_URB_TYPE_ISO = 0, + USBFS_URB_TYPE_INTERRUPT = 1, + USBFS_URB_TYPE_CONTROL = 2, + USBFS_URB_TYPE_BULK = 3, +}; + +struct usbfs_iso_packet_desc { + unsigned int length; + unsigned int actual_length; + unsigned int status; +}; + +#define MAX_ISO_BUFFER_LENGTH 49152 * 128 +#define MAX_BULK_BUFFER_LENGTH 16384 +#define MAX_CTRL_BUFFER_LENGTH 4096 + +struct usbfs_urb { + unsigned char type; + unsigned char endpoint; + int status; + unsigned int flags; + void *buffer; + int buffer_length; + int actual_length; + int start_frame; + union { + int number_of_packets; /* Only used for isoc urbs */ + unsigned int stream_id; /* Only used with bulk streams */ + }; + int error_count; + unsigned int signr; + void *usercontext; + struct usbfs_iso_packet_desc iso_frame_desc[0]; +}; + +struct usbfs_connectinfo { + unsigned int devnum; + unsigned char slow; +}; + +struct usbfs_ioctl { + int ifno; /* interface 0..N ; negative numbers reserved */ + int ioctl_code; /* MUST encode size + direction of data so the + * macros in give correct values */ + void *data; /* param buffer (in, or out) */ +}; + +struct usbfs_hub_portinfo { + unsigned char numports; + unsigned char port[127]; /* port to device num mapping */ +}; + +#define USBFS_CAP_ZERO_PACKET 0x01 +#define USBFS_CAP_BULK_CONTINUATION 0x02 +#define USBFS_CAP_NO_PACKET_SIZE_LIM 0x04 +#define USBFS_CAP_BULK_SCATTER_GATHER 0x08 +#define USBFS_CAP_REAP_AFTER_DISCONNECT 0x10 + +#define USBFS_DISCONNECT_CLAIM_IF_DRIVER 0x01 +#define USBFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02 + +struct usbfs_disconnect_claim { + unsigned int interface; + unsigned int flags; + char driver[USBFS_MAXDRIVERNAME + 1]; +}; + +struct usbfs_streams { + unsigned int num_streams; /* Not used by USBDEVFS_FREE_STREAMS */ + unsigned int num_eps; + unsigned char eps[0]; +}; + +#define IOCTL_USBFS_CONTROL _IOWR('U', 0, struct usbfs_ctrltransfer) +#define IOCTL_USBFS_BULK _IOWR('U', 2, struct usbfs_bulktransfer) +#define IOCTL_USBFS_RESETEP _IOR('U', 3, unsigned int) +#define IOCTL_USBFS_SETINTF _IOR('U', 4, struct usbfs_setinterface) +#define IOCTL_USBFS_SETCONFIG _IOR('U', 5, unsigned int) +#define IOCTL_USBFS_GETDRIVER _IOW('U', 8, struct usbfs_getdriver) +#define IOCTL_USBFS_SUBMITURB _IOR('U', 10, struct usbfs_urb) +#define IOCTL_USBFS_DISCARDURB _IO('U', 11) +#define IOCTL_USBFS_REAPURB _IOW('U', 12, void *) +#define IOCTL_USBFS_REAPURBNDELAY _IOW('U', 13, void *) +#define IOCTL_USBFS_CLAIMINTF _IOR('U', 15, unsigned int) +#define IOCTL_USBFS_RELEASEINTF _IOR('U', 16, unsigned int) +#define IOCTL_USBFS_CONNECTINFO _IOW('U', 17, struct usbfs_connectinfo) +#define IOCTL_USBFS_IOCTL _IOWR('U', 18, struct usbfs_ioctl) +#define IOCTL_USBFS_HUB_PORTINFO _IOR('U', 19, struct usbfs_hub_portinfo) +#define IOCTL_USBFS_RESET _IO('U', 20) +#define IOCTL_USBFS_CLEAR_HALT _IOR('U', 21, unsigned int) +#define IOCTL_USBFS_DISCONNECT _IO('U', 22) +#define IOCTL_USBFS_CONNECT _IO('U', 23) +#define IOCTL_USBFS_CLAIM_PORT _IOR('U', 24, unsigned int) +#define IOCTL_USBFS_RELEASE_PORT _IOR('U', 25, unsigned int) +#define IOCTL_USBFS_GET_CAPABILITIES _IOR('U', 26, __u32) +#define IOCTL_USBFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbfs_disconnect_claim) +#define IOCTL_USBFS_ALLOC_STREAMS _IOR('U', 28, struct usbfs_streams) +#define IOCTL_USBFS_FREE_STREAMS _IOR('U', 29, struct usbfs_streams) + +extern usbi_mutex_static_t linux_hotplug_lock; + +#if defined(HAVE_LIBUDEV) +int linux_udev_start_event_monitor(void); +int linux_udev_stop_event_monitor(void); +int linux_udev_scan_devices(struct libusb_context *ctx); +void linux_udev_hotplug_poll(void); +#else +int linux_netlink_start_event_monitor(void); +int linux_netlink_stop_event_monitor(void); +void linux_netlink_hotplug_poll(void); +#endif + +void linux_hotplug_enumerate(uint8_t busnum, uint8_t devaddr, const char *sys_name); +void linux_device_disconnected(uint8_t busnum, uint8_t devaddr); + +int linux_get_device_address (struct libusb_context *ctx, int detached, + uint8_t *busnum, uint8_t *devaddr, const char *dev_node, + const char *sys_name); +int linux_enumerate_device(struct libusb_context *ctx, + uint8_t busnum, uint8_t devaddr, const char *sysfs_dir); + +#endif diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_usbfs.h.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_usbfs.h.REMOVED.git-id deleted file mode 100644 index 386910a8..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/linux_usbfs.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8bd3ebcb163eb3b81446fd0d750693beaf361776 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/poll_posix.c b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/poll_posix.c new file mode 100644 index 00000000..e2f55a57 --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/poll_posix.c @@ -0,0 +1,53 @@ +/* + * poll_posix: poll compatibility wrapper for POSIX systems + * Copyright © 2013 RealVNC Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include +#include +#include +#include + +#include "libusbi.h" + +int usbi_pipe(int pipefd[2]) +{ + int ret = pipe(pipefd); + if (ret != 0) { + return ret; + } + ret = fcntl(pipefd[1], F_GETFL); + if (ret == -1) { + usbi_dbg("Failed to get pipe fd flags: %d", errno); + goto err_close_pipe; + } + ret = fcntl(pipefd[1], F_SETFL, ret | O_NONBLOCK); + if (ret != 0) { + usbi_dbg("Failed to set non-blocking on new pipe: %d", errno); + goto err_close_pipe; + } + + return 0; + +err_close_pipe: + usbi_close(pipefd[0]); + usbi_close(pipefd[1]); + return ret; +} diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/poll_posix.c.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/poll_posix.c.REMOVED.git-id deleted file mode 100644 index 6225b948..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/poll_posix.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e2f55a57a1400a1c0eb9b2ad3f24184272ed51bd \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/poll_posix.h b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/poll_posix.h new file mode 100644 index 00000000..5b4b2c90 --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/poll_posix.h @@ -0,0 +1,11 @@ +#ifndef LIBUSB_POLL_POSIX_H +#define LIBUSB_POLL_POSIX_H + +#define usbi_write write +#define usbi_read read +#define usbi_close close +#define usbi_poll poll + +int usbi_pipe(int pipefd[2]); + +#endif /* LIBUSB_POLL_POSIX_H */ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/poll_posix.h.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/poll_posix.h.REMOVED.git-id deleted file mode 100644 index dd0056a0..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/poll_posix.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5b4b2c905e7a3d929a2099b1b734bdb614794113 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/threads_posix.c b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/threads_posix.c new file mode 100644 index 00000000..e8e87bbb --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/threads_posix.c @@ -0,0 +1,82 @@ +/* + * libusb synchronization using POSIX Threads + * + * Copyright © 2011 Vitali Lovich + * Copyright © 2011 Peter Stuge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#if defined(__linux__) || defined(__OpenBSD__) +# if defined(__OpenBSD__) +# define _BSD_SOURCE +# endif +# include +# include +#elif defined(__APPLE__) +# include +#elif defined(__CYGWIN__) +# include +#endif + +#include "threads_posix.h" + +int usbi_mutex_init_recursive(pthread_mutex_t *mutex, pthread_mutexattr_t *attr) +{ + int err; + pthread_mutexattr_t stack_attr; + if (!attr) { + attr = &stack_attr; + err = pthread_mutexattr_init(&stack_attr); + if (err != 0) + return err; + } + + /* mutexattr_settype requires _GNU_SOURCE or _XOPEN_SOURCE >= 500 on Linux */ + err = pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE); + if (err != 0) + goto finish; + + err = pthread_mutex_init(mutex, attr); + +finish: + if (attr == &stack_attr) + pthread_mutexattr_destroy(&stack_attr); + + return err; +} + +int usbi_get_tid(void) +{ + int ret = -1; +#if defined(__ANDROID__) + ret = gettid(); +#elif defined(__linux__) + ret = syscall(SYS_gettid); +#elif defined(__OpenBSD__) + /* The following only works with OpenBSD > 5.1 as it requires + real thread support. For 5.1 and earlier, -1 is returned. */ + ret = syscall(SYS_getthrid); +#elif defined(__APPLE__) + ret = mach_thread_self(); + mach_port_deallocate(mach_task_self(), ret); +#elif defined(__CYGWIN__) + ret = GetCurrentThreadId(); +#endif +/* TODO: NetBSD thread ID support */ + return ret; +} diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/threads_posix.c.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/threads_posix.c.REMOVED.git-id deleted file mode 100644 index 815b92c4..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/threads_posix.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e8e87bbb4c7f1ba6bf89c4b8c2f11a1479584f15 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/threads_posix.h b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/threads_posix.h new file mode 100644 index 00000000..3caeca4c --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/threads_posix.h @@ -0,0 +1,56 @@ +/* + * libusb synchronization using POSIX Threads + * + * Copyright © 2010 Peter Stuge + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_THREADS_POSIX_H +#define LIBUSB_THREADS_POSIX_H + +#include + +#define usbi_mutex_static_t pthread_mutex_t +#define USBI_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#define usbi_mutex_static_lock pthread_mutex_lock +#define usbi_mutex_static_unlock pthread_mutex_unlock + +#define usbi_mutex_t pthread_mutex_t +#define usbi_mutex_init pthread_mutex_init +#define usbi_mutex_lock pthread_mutex_lock +#define usbi_mutex_unlock pthread_mutex_unlock +#define usbi_mutex_trylock pthread_mutex_trylock +#define usbi_mutex_destroy pthread_mutex_destroy + +#define usbi_cond_t pthread_cond_t +#define usbi_cond_init pthread_cond_init +#define usbi_cond_wait pthread_cond_wait +#define usbi_cond_timedwait pthread_cond_timedwait +#define usbi_cond_broadcast pthread_cond_broadcast +#define usbi_cond_destroy pthread_cond_destroy +#define usbi_cond_signal pthread_cond_signal + +#define usbi_tls_key_t pthread_key_t +#define usbi_tls_key_create pthread_key_create +#define usbi_tls_key_get pthread_getspecific +#define usbi_tls_key_set pthread_setspecific +#define usbi_tls_key_delete pthread_key_delete + +extern int usbi_mutex_init_recursive(pthread_mutex_t *mutex, pthread_mutexattr_t *attr); + +int usbi_get_tid(void); + +#endif /* LIBUSB_THREADS_POSIX_H */ diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/threads_posix.h.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/os/threads_posix.h.REMOVED.git-id deleted file mode 100644 index c816c3fe..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/os/threads_posix.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3caeca4c7d68bd0f4c53519a15ddb74691971a41 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/strerror.c b/Desktop_Interface/build_android/libusb-martin-kuldeep/strerror.c new file mode 100644 index 00000000..a534041a --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/strerror.c @@ -0,0 +1,202 @@ +/* + * libusb strerror code + * Copyright © 2013 Hans de Goede + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#if defined(HAVE_STRINGS_H) +#include +#endif + +#include "libusbi.h" + +#if defined(_MSC_VER) +#define strncasecmp _strnicmp +#endif + +static size_t usbi_locale = 0; + +/** \ingroup misc + * How to add a new \ref libusb_strerror() translation: + *
    + *
  1. Download the latest \c strerror.c from:
    + * https://raw.github.com/libusb/libusb/master/libusb/sterror.c
  2. + *
  3. Open the file in an UTF-8 capable editor
  4. + *
  5. Add the 2 letter ISO 639-1 + * code for your locale at the end of \c usbi_locale_supported[]
    + * Eg. for Chinese, you would add "zh" so that: + * \code... usbi_locale_supported[] = { "en", "nl", "fr" };\endcode + * becomes: + * \code... usbi_locale_supported[] = { "en", "nl", "fr", "zh" };\endcode
  6. + *
  7. Copy the { / * English (en) * / ... } section and add it at the end of \c usbi_localized_errors
    + * Eg. for Chinese, the last section of \c usbi_localized_errors could look like: + * \code + * }, { / * Chinese (zh) * / + * "Success", + * ... + * "Other error", + * } + * };\endcode
  8. + *
  9. Translate each of the English messages from the section you copied into your language
  10. + *
  11. Save the file (in UTF-8 format) and send it to \c libusb-devel\@lists.sourceforge.net
  12. + *
+ */ + +static const char* usbi_locale_supported[] = { "en", "nl", "fr", "ru" }; +static const char* usbi_localized_errors[ARRAYSIZE(usbi_locale_supported)][LIBUSB_ERROR_COUNT] = { + { /* English (en) */ + "Success", + "Input/Output Error", + "Invalid parameter", + "Access denied (insufficient permissions)", + "No such device (it may have been disconnected)", + "Entity not found", + "Resource busy", + "Operation timed out", + "Overflow", + "Pipe error", + "System call interrupted (perhaps due to signal)", + "Insufficient memory", + "Operation not supported or unimplemented on this platform", + "Other error", + }, { /* Dutch (nl) */ + "Gelukt", + "Invoer-/uitvoerfout", + "Ongeldig argument", + "Toegang geweigerd (onvoldoende toegangsrechten)", + "Apparaat bestaat niet (verbinding met apparaat verbroken?)", + "Niet gevonden", + "Apparaat of hulpbron is bezig", + "Bewerking verlopen", + "Waarde is te groot", + "Gebroken pijp", + "Onderbroken systeemaanroep", + "Onvoldoende geheugen beschikbaar", + "Bewerking wordt niet ondersteund", + "Andere fout", + }, { /* French (fr) */ + "Succès", + "Erreur d'entrée/sortie", + "Paramètre invalide", + "Accès refusé (permissions insuffisantes)", + "Périphérique introuvable (peut-être déconnecté)", + "Elément introuvable", + "Resource déjà occupée", + "Operation expirée", + "Débordement", + "Erreur de pipe", + "Appel système abandonné (peut-être à cause d’un signal)", + "Mémoire insuffisante", + "Opération non supportée or non implémentée sur cette plateforme", + "Autre erreur", + }, { /* Russian (ru) */ + "Успех", + "Ошибка ввода/вывода", + "Неверный параметр", + "Доступ запрещён (не хватает прав)", + "Устройство отсутствует (возможно, оно было отсоединено)", + "Элемент не найден", + "Ресурс занят", + "Истекло время ожидания операции", + "Переполнение", + "Ошибка канала", + "Системный вызов прерван (возможно, сигналом)", + "Память исчерпана", + "Операция не поддерживается данной платформой", + "Неизвестная ошибка" + } +}; + +/** \ingroup misc + * Set the language, and only the language, not the encoding! used for + * translatable libusb messages. + * + * This takes a locale string in the default setlocale format: lang[-region] + * or lang[_country_region][.codeset]. Only the lang part of the string is + * used, and only 2 letter ISO 639-1 codes are accepted for it, such as "de". + * The optional region, country_region or codeset parts are ignored. This + * means that functions which return translatable strings will NOT honor the + * specified encoding. + * All strings returned are encoded as UTF-8 strings. + * + * If libusb_setlocale() is not called, all messages will be in English. + * + * The following functions return translatable strings: libusb_strerror(). + * Note that the libusb log messages controlled through libusb_set_debug() + * are not translated, they are always in English. + * + * For POSIX UTF-8 environments if you want libusb to follow the standard + * locale settings, call libusb_setlocale(setlocale(LC_MESSAGES, NULL)), + * after your app has done its locale setup. + * + * \param locale locale-string in the form of lang[_country_region][.codeset] + * or lang[-region], where lang is a 2 letter ISO 639-1 code + * \returns LIBUSB_SUCCESS on success + * \returns LIBUSB_ERROR_INVALID_PARAM if the locale doesn't meet the requirements + * \returns LIBUSB_ERROR_NOT_FOUND if the requested language is not supported + * \returns a LIBUSB_ERROR code on other errors + */ + +int API_EXPORTED libusb_setlocale(const char *locale) +{ + size_t i; + + if ( (locale == NULL) || (strlen(locale) < 2) + || ((strlen(locale) > 2) && (locale[2] != '-') && (locale[2] != '_') && (locale[2] != '.')) ) + return LIBUSB_ERROR_INVALID_PARAM; + + for (i=0; i= ARRAYSIZE(usbi_locale_supported)) { + return LIBUSB_ERROR_NOT_FOUND; + } + + usbi_locale = i; + + return LIBUSB_SUCCESS; +} + +/** \ingroup misc + * Returns a constant string with a short description of the given error code, + * this description is intended for displaying to the end user and will be in + * the language set by libusb_setlocale(). + * + * The returned string is encoded in UTF-8. + * + * The messages always start with a capital letter and end without any dot. + * The caller must not free() the returned string. + * + * \param errcode the error code whose description is desired + * \returns a short description of the error code in UTF-8 encoding + */ +DEFAULT_VISIBILITY const char* LIBUSB_CALL libusb_strerror(enum libusb_error errcode) +{ + int errcode_index = -errcode; + + if ((errcode_index < 0) || (errcode_index >= LIBUSB_ERROR_COUNT)) { + /* "Other Error", which should always be our last message, is returned */ + errcode_index = LIBUSB_ERROR_COUNT - 1; + } + + return usbi_localized_errors[usbi_locale][errcode_index]; +} diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/strerror.c.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/strerror.c.REMOVED.git-id deleted file mode 100644 index ef9c49ed..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/strerror.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a534041a6a8cee01d43cf1dd910e74981178798a \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/sync.c b/Desktop_Interface/build_android/libusb-martin-kuldeep/sync.c new file mode 100644 index 00000000..0d1acd85 --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/sync.c @@ -0,0 +1,319 @@ +/* + * Synchronous I/O functions for libusb + * Copyright © 2007-2008 Daniel Drake + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include + +#include "libusbi.h" + +/** + * @defgroup syncio Synchronous device I/O + * + * This page documents libusb's synchronous (blocking) API for USB device I/O. + * This interface is easy to use but has some limitations. More advanced users + * may wish to consider using the \ref asyncio "asynchronous I/O API" instead. + */ + +static void LIBUSB_CALL sync_transfer_cb(struct libusb_transfer *transfer) +{ + int *completed = transfer->user_data; + *completed = 1; + usbi_dbg("actual_length=%d", transfer->actual_length); + /* caller interprets result and frees transfer */ +} + +static void sync_transfer_wait_for_completion(struct libusb_transfer *transfer) +{ + int r, *completed = transfer->user_data; + struct libusb_context *ctx = HANDLE_CTX(transfer->dev_handle); + + while (!*completed) { + r = libusb_handle_events_completed(ctx, completed); + if (r < 0) { + if (r == LIBUSB_ERROR_INTERRUPTED) + continue; + usbi_err(ctx, "libusb_handle_events failed: %s, cancelling transfer and retrying", + libusb_error_name(r)); + libusb_cancel_transfer(transfer); + continue; + } + } +} + +/** \ingroup syncio + * Perform a USB control transfer. + * + * The direction of the transfer is inferred from the bmRequestType field of + * the setup packet. + * + * The wValue, wIndex and wLength fields values should be given in host-endian + * byte order. + * + * \param dev_handle a handle for the device to communicate with + * \param bmRequestType the request type field for the setup packet + * \param bRequest the request field for the setup packet + * \param wValue the value field for the setup packet + * \param wIndex the index field for the setup packet + * \param data a suitably-sized data buffer for either input or output + * (depending on direction bits within bmRequestType) + * \param wLength the length field for the setup packet. The data buffer should + * be at least this size. + * \param timeout timeout (in millseconds) that this function should wait + * before giving up due to no response being received. For an unlimited + * timeout, use value 0. + * \returns on success, the number of bytes actually transferred + * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out + * \returns LIBUSB_ERROR_PIPE if the control request was not supported by the + * device + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_BUSY if called from event handling context + * \returns another LIBUSB_ERROR code on other failures + */ +int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle, + uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + unsigned char *data, uint16_t wLength, unsigned int timeout) +{ + struct libusb_transfer *transfer; + unsigned char *buffer; + int completed = 0; + int r; + + if (usbi_handling_events(HANDLE_CTX(dev_handle))) + return LIBUSB_ERROR_BUSY; + + transfer = libusb_alloc_transfer(0); + if (!transfer) + return LIBUSB_ERROR_NO_MEM; + + buffer = (unsigned char*) malloc(LIBUSB_CONTROL_SETUP_SIZE + wLength); + if (!buffer) { + libusb_free_transfer(transfer); + return LIBUSB_ERROR_NO_MEM; + } + + libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, + wLength); + if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) + memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength); + + libusb_fill_control_transfer(transfer, dev_handle, buffer, + sync_transfer_cb, &completed, timeout); + transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER; + r = libusb_submit_transfer(transfer); + if (r < 0) { + libusb_free_transfer(transfer); + return r; + } + + sync_transfer_wait_for_completion(transfer); + + if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) + memcpy(data, libusb_control_transfer_get_data(transfer), + transfer->actual_length); + + switch (transfer->status) { + case LIBUSB_TRANSFER_COMPLETED: + r = transfer->actual_length; + break; + case LIBUSB_TRANSFER_TIMED_OUT: + r = LIBUSB_ERROR_TIMEOUT; + break; + case LIBUSB_TRANSFER_STALL: + r = LIBUSB_ERROR_PIPE; + break; + case LIBUSB_TRANSFER_NO_DEVICE: + r = LIBUSB_ERROR_NO_DEVICE; + break; + case LIBUSB_TRANSFER_OVERFLOW: + r = LIBUSB_ERROR_OVERFLOW; + break; + case LIBUSB_TRANSFER_ERROR: + case LIBUSB_TRANSFER_CANCELLED: + r = LIBUSB_ERROR_IO; + break; + default: + usbi_warn(HANDLE_CTX(dev_handle), + "unrecognised status code %d", transfer->status); + r = LIBUSB_ERROR_OTHER; + } + + libusb_free_transfer(transfer); + return r; +} + +static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *buffer, int length, + int *transferred, unsigned int timeout, unsigned char type) +{ + struct libusb_transfer *transfer; + int completed = 0; + int r; + + if (usbi_handling_events(HANDLE_CTX(dev_handle))) + return LIBUSB_ERROR_BUSY; + + transfer = libusb_alloc_transfer(0); + if (!transfer) + return LIBUSB_ERROR_NO_MEM; + + libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length, + sync_transfer_cb, &completed, timeout); + transfer->type = type; + + r = libusb_submit_transfer(transfer); + if (r < 0) { + libusb_free_transfer(transfer); + return r; + } + + sync_transfer_wait_for_completion(transfer); + + *transferred = transfer->actual_length; + switch (transfer->status) { + case LIBUSB_TRANSFER_COMPLETED: + r = 0; + break; + case LIBUSB_TRANSFER_TIMED_OUT: + r = LIBUSB_ERROR_TIMEOUT; + break; + case LIBUSB_TRANSFER_STALL: + r = LIBUSB_ERROR_PIPE; + break; + case LIBUSB_TRANSFER_OVERFLOW: + r = LIBUSB_ERROR_OVERFLOW; + break; + case LIBUSB_TRANSFER_NO_DEVICE: + r = LIBUSB_ERROR_NO_DEVICE; + break; + case LIBUSB_TRANSFER_ERROR: + case LIBUSB_TRANSFER_CANCELLED: + r = LIBUSB_ERROR_IO; + break; + default: + usbi_warn(HANDLE_CTX(dev_handle), + "unrecognised status code %d", transfer->status); + r = LIBUSB_ERROR_OTHER; + } + + libusb_free_transfer(transfer); + return r; +} + +/** \ingroup syncio + * Perform a USB bulk transfer. The direction of the transfer is inferred from + * the direction bits of the endpoint address. + * + * For bulk reads, the length field indicates the maximum length of + * data you are expecting to receive. If less data arrives than expected, + * this function will return that data, so be sure to check the + * transferred output parameter. + * + * You should also check the transferred parameter for bulk writes. + * Not all of the data may have been written. + * + * Also check transferred when dealing with a timeout error code. + * libusb may have to split your transfer into a number of chunks to satisfy + * underlying O/S requirements, meaning that the timeout may expire after + * the first few chunks have completed. libusb is careful not to lose any data + * that may have been transferred; do not assume that timeout conditions + * indicate a complete lack of I/O. + * + * \param dev_handle a handle for the device to communicate with + * \param endpoint the address of a valid endpoint to communicate with + * \param data a suitably-sized data buffer for either input or output + * (depending on endpoint) + * \param length for bulk writes, the number of bytes from data to be sent. for + * bulk reads, the maximum number of bytes to receive into the data buffer. + * \param transferred output location for the number of bytes actually + * transferred. + * \param timeout timeout (in millseconds) that this function should wait + * before giving up due to no response being received. For an unlimited + * timeout, use value 0. + * + * \returns 0 on success (and populates transferred) + * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out (and populates + * transferred) + * \returns LIBUSB_ERROR_PIPE if the endpoint halted + * \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see + * \ref packetoverflow + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_BUSY if called from event handling context + * \returns another LIBUSB_ERROR code on other failures + */ +int API_EXPORTED libusb_bulk_transfer(struct libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *data, int length, int *transferred, + unsigned int timeout) +{ + return do_sync_bulk_transfer(dev_handle, endpoint, data, length, + transferred, timeout, LIBUSB_TRANSFER_TYPE_BULK); +} + +/** \ingroup syncio + * Perform a USB interrupt transfer. The direction of the transfer is inferred + * from the direction bits of the endpoint address. + * + * For interrupt reads, the length field indicates the maximum length + * of data you are expecting to receive. If less data arrives than expected, + * this function will return that data, so be sure to check the + * transferred output parameter. + * + * You should also check the transferred parameter for interrupt + * writes. Not all of the data may have been written. + * + * Also check transferred when dealing with a timeout error code. + * libusb may have to split your transfer into a number of chunks to satisfy + * underlying O/S requirements, meaning that the timeout may expire after + * the first few chunks have completed. libusb is careful not to lose any data + * that may have been transferred; do not assume that timeout conditions + * indicate a complete lack of I/O. + * + * The default endpoint bInterval value is used as the polling interval. + * + * \param dev_handle a handle for the device to communicate with + * \param endpoint the address of a valid endpoint to communicate with + * \param data a suitably-sized data buffer for either input or output + * (depending on endpoint) + * \param length for bulk writes, the number of bytes from data to be sent. for + * bulk reads, the maximum number of bytes to receive into the data buffer. + * \param transferred output location for the number of bytes actually + * transferred. + * \param timeout timeout (in millseconds) that this function should wait + * before giving up due to no response being received. For an unlimited + * timeout, use value 0. + * + * \returns 0 on success (and populates transferred) + * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out + * \returns LIBUSB_ERROR_PIPE if the endpoint halted + * \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see + * \ref packetoverflow + * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns LIBUSB_ERROR_BUSY if called from event handling context + * \returns another LIBUSB_ERROR code on other error + */ +int API_EXPORTED libusb_interrupt_transfer( + struct libusb_device_handle *dev_handle, unsigned char endpoint, + unsigned char *data, int length, int *transferred, unsigned int timeout) +{ + return do_sync_bulk_transfer(dev_handle, endpoint, data, length, + transferred, timeout, LIBUSB_TRANSFER_TYPE_INTERRUPT); +} diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/sync.c.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/sync.c.REMOVED.git-id deleted file mode 100644 index 91525864..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/sync.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0d1acd8507ee81caf39c81d515df6372b60092ef \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/version.h b/Desktop_Interface/build_android/libusb-martin-kuldeep/version.h new file mode 100644 index 00000000..0e3a3633 --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/version.h @@ -0,0 +1,18 @@ +/* This file is parsed by m4 and windres and RC.EXE so please keep it simple. */ +#include "version_nano.h" +#ifndef LIBUSB_MAJOR +#define LIBUSB_MAJOR 1 +#endif +#ifndef LIBUSB_MINOR +#define LIBUSB_MINOR 0 +#endif +#ifndef LIBUSB_MICRO +#define LIBUSB_MICRO 20 +#endif +#ifndef LIBUSB_NANO +#define LIBUSB_NANO 0 +#endif +/* LIBUSB_RC is the release candidate suffix. Should normally be empty. */ +#ifndef LIBUSB_RC +#define LIBUSB_RC "" +#endif diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/version.h.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/version.h.REMOVED.git-id deleted file mode 100644 index 9df2e90f..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/version.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0e3a3633d3ee792b5303d05f30993cbb853810d4 \ No newline at end of file diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/version_nano.h b/Desktop_Interface/build_android/libusb-martin-kuldeep/version_nano.h new file mode 100644 index 00000000..1cd51a47 --- /dev/null +++ b/Desktop_Interface/build_android/libusb-martin-kuldeep/version_nano.h @@ -0,0 +1 @@ +#define LIBUSB_NANO 11014 diff --git a/Desktop_Interface/build_android/libusb-martin-kuldeep/version_nano.h.REMOVED.git-id b/Desktop_Interface/build_android/libusb-martin-kuldeep/version_nano.h.REMOVED.git-id deleted file mode 100644 index c57a98f6..00000000 --- a/Desktop_Interface/build_android/libusb-martin-kuldeep/version_nano.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1cd51a4708bf9a78adb7f7716370c0528609dc88 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/AndroidManifest.xml b/Desktop_Interface/build_android/package_source/AndroidManifest.xml new file mode 100644 index 00000000..778be5eb --- /dev/null +++ b/Desktop_Interface/build_android/package_source/AndroidManifest.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Desktop_Interface/build_android/package_source/AndroidManifest.xml.REMOVED.git-id b/Desktop_Interface/build_android/package_source/AndroidManifest.xml.REMOVED.git-id deleted file mode 100644 index 9d610b79..00000000 --- a/Desktop_Interface/build_android/package_source/AndroidManifest.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -778be5ebea55e51b0cdd65420f001794548fa0a5 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/assets/firmware/labrafirm_0003_01.hex b/Desktop_Interface/build_android/package_source/assets/firmware/labrafirm_0003_01.hex new file mode 100644 index 00000000..f7946fd7 --- /dev/null +++ b/Desktop_Interface/build_android/package_source/assets/firmware/labrafirm_0003_01.hex @@ -0,0 +1,715 @@ +:1000000017C1000031C100002FC100002DC1000048 +:100010002BC1000029C100000C9414090C94230981 +:1000200023C1000021C100001FC100001DC100004C +:100030001BC1000019C1000017C1000015C100005C +:1000400013C1000011C100000FC100000DC100006C +:100050000BC1000009C1000007C1000005C100007C +:100060000C94FF090C940A0AFFC00000FDC00000B8 +:10007000FBC00000F9C00000F7C00000F5C00000A0 +:10008000F3C00000F1C00000EFC00000EDC00000B0 +:10009000EBC00000E9C00000E7C00000E5C00000C0 +:1000A000E3C00000E1C00000DFC00000DDC00000D0 +:1000B000DBC00000D9C00000D7C00000D5C00000E0 +:1000C000D3C00000D1C00000CFC00000CDC00000F0 +:1000D000CBC00000C9C00000C7C00000C5C0000000 +:1000E000C3C00000C1C00000BFC00000BDC0000010 +:1000F000BBC00000B9C00000B7C00000B5C0000020 +:10010000B3C00000B1C00000AFC00000ADC000002F +:10011000ABC00000A9C00000A7C00000A3C400003D +:10012000A3C00000A1C000009FC000009DC000004F +:100130009BC0000099C0000097C0000095C000005F +:1001400093C0000091C000008FC000000C9474099F +:100150008BC0000089C0000087C0000085C000007F +:1001600083C0000081C000007FC000007DC000008F +:100170007BC0000079C0000077C0000075C000009F +:1001800073C0000071C000006FC000006DC00000AF +:100190006BC0000069C0000067C0000065C00000BF +:1001A00063C0000061C000005FC000005DC00000CF +:1001B0005BC0000059C0000057C0000055C00000DF +:1001C00053C0000051C000004FC000004DC00000EF +:1001D0004BC0000049C0000047C0000045C00000FF +:1001E00043C0000041C000003FC000003DC000000F +:1001F0003BC000000C9420140C94D8140F0411047C +:1002000013041504170419041B041D04DB0B010C53 +:10021000280C510C5A0C5F0CA40CA90CC80CCF0C68 +:100220006B0C730C7B0C860C880C8A0C920C9A0C51 +:1002300011241FBECFEFCDBFDFE2DEBF10E2A0E092 +:10024000B0E2E2EDFBE202C005900D92AA3BB107DD +:10025000D9F72DE2AAEBB0E201C01D92AC3FB20784 +:10026000E1F794D20C94E715CBCE84E0809356004E +:100270008CE1C0D3809363008BEB8093660080E8B1 +:100280008093650081E08093600088ED84BF1092C8 +:10029000410083E080935000809151008330E1F76A +:1002A0008091500081608093500088E180935500D8 +:1002B0008091510080FFFCCF80915000806180933D +:1002C00050008091510084FFFCCF88ED84BF84E012 +:1002D000809340000895E0E7F0E085818E7F85837C +:1002E000E0E0FAE08FEB9DE586A397A380EE9EE227 +:1002F00080A391A382E0808308958091200A909149 +:10030000210A813E2EE2920718F020919E2306C01A +:10031000803E2EE2920721F020919B2320936A00D9 +:1003200020910520222321F080910520815033C0A7 +:10033000885F9A42813D974080F11092BA20809167 +:10034000BB209091BC20A091BD20B091BE20019611 +:10035000A11DB11D8093BB209093BC20A093BD2014 +:10036000B093BE208091BB209091BC20A091BD2075 +:10037000B091BE20892F9A2FAB2FBB278093BE232D +:100380008091BB209091BC20A091BD20B091BE2057 +:100390008093BD2386E08093052080910720909173 +:1003A00008200196B1F4809109208F3F91F080914F +:1003B0000620811106C0809106208150809306207E +:1003C00008958091140190911501809307209093D6 +:1003D00008200895009709F45EC00CF457C040E06F +:1003E00020916B0030E020939C2330939D2320913B +:1003F0009C2330919D233695322F222737952795C0 +:1004000020939C2330939D2350916A0020919C233C +:1004100030919D23250F311D20939C2330939D23E4 +:10042000000020919C2330919D232817390728F440 +:1004300010929C2310929D23089520919C2330912B +:100440009D23280F391F2115304238F08FEF9FE18F +:1004500080939C2390939D23089520919C23309119 +:100460009D23442329F0A901481B590BCA0102C04E +:10047000820F931F80939C2390939D2380919C23B4 +:1004800090919D238F7780936A000895919581952F +:10049000910941E0A5CF0895CF93DF93C091200A41 +:1004A000D091210A80910320909104209E01281B65 +:1004B000390B20939F233093A0238091BA20811180 +:1004C0004BC080919F239091A0238E3C9F4FD4F4EA +:1004D00080919F239091A0238B369F4F9CF0809119 +:1004E0000220882321F080910220815008C0809151 +:1004F0006A0080939E2381E08093BA208CE08093F1 +:1005000002202AC08CE08093022080919F2390914A +:10051000A0238A369F4F1CF08FEF9FEF02C081E02F +:1005200090E08093992390939A2380919F239091B8 +:10053000A0232091992330919A2360E370E00E94D8 +:10054000BE15261B370B2093992330939A23809155 +:10055000992390919A233EDF8091BA20813029F52A +:1005600080919F239091A023C39794F080910220C3 +:10057000882331F08091022081508093022015C0A1 +:1005800080916A0080939B2383E08093BA200DC002 +:1005900080919F239091A023873991051CF481E0DD +:1005A00090E002C08FEF9FEF15DFC0930320D09340 +:1005B0000420DF91CF9108958617970779F0681787 +:1005C000790728F49C01261B370BB90109C086174F +:1005D000970718F4681B790B03C0089560E070E07A +:1005E000CB010895CF93DF9380910020909101205B +:1005F000892B51F0809100209091012001978093E8 +:1006000000209093012043C080E490E0809300207C +:100610009093012080910720909108200196B9F1D4 +:10062000809114019091150120910920263018F431 +:1006300067E771E002C06EEE72E00E94AA15EC015D +:1006400080910720909108208C179D0758F46091A5 +:10065000072070910820CE01AFDF029718F080ECE0 +:100660009DE511C08091072090910820C817D907F7 +:1006700070F46091072070910820CE019DDF0297F1 +:1006800030F08FEB9DE58093360A9093370ADF9127 +:10069000CF910895AC01460F571F861B970B2091F1 +:1006A000200A3091210A24173507C8F72091200A23 +:1006B0003091210A8217930790F70895E0E8F6E059 +:1006C0008FE0808385E0848308951F93CF93DF9329 +:1006D000C0E4D0E0198180E4898340E250E064ED19 +:1006E0007DE280E290E00E94390F1983DF91CF9183 +:1006F0001F9108951F93CF93DF93C0E4D0E0198139 +:1007000080E4898387ED97E20E94810F81E00E9457 +:10071000930F1983DF91CF911F91089508950F933F +:100720001F93842F242F30E0215831099DE7929F99 +:10073000A001939F500D112490910920953048F409 +:10074000843810F049585E4F9091C42027E731E07B +:1007500004C09091C4202EEE32E0929FB001939F8E +:10076000700D11249A01260F371FA9014850584DCA +:100770000FE813E02DE730E060E00E944B131F917B +:100780000F9108951CBEEEEFF0E409949EDF809176 +:10079000D42D882369F080E2E4EDFDE2A7EDB7E215 +:1007A00001900D928A95E1F71092D727A3DFEADF37 +:1007B00087E08093A200789458DDB0DF86D765D1BA +:1007C00088D160E080E01FD10BD18CE0FFD04AD50A +:1007D000EED507D673DF60EA70E28AEA93E20E9400 +:1007E000E015000000000000000000000000000014 +:1007F00000000000000000000000000000008091E8 +:10080000BF20882371F3E091D6258E2F90E08830A9 +:100810009105A0F4FC01E250FF4F0C94D11585D155 +:100820000DC0F5D10BC07CD209C000D307C08CD35A +:1008300005C012D403C011D401C082D41092BF20CD +:10084000D0CF08950895809114018093B3238091AF +:1008500015018093B423809124018093B523809166 +:1008600025018093B6238091200A8093BF23809135 +:10087000210A8093C0238091140190911501863440 +:10088000914080F08091140190911501893A914036 +:1008900048F480911401909115018093F42D909368 +:1008A000F52D00008091C220882339F014DD1092CC +:1008B000C22081E08093C12008958091C1208823C7 +:1008C00041F08091BA20833019F417DD8BDE01C02E +:1008D000E3DD8091C020882351F080911401909134 +:1008E00015018093F42D9093F52D1092C0208091E6 +:1008F00009202091140130911501853028F481E000 +:100900002737314030F004C081E02E3E324008F0FD +:1009100080E08093C42008950F931F9381E080931B +:10092000C7208093C2200FE813E02DE730E048EFA6 +:1009300057E260E081E80E944B132DE730E045E785 +:1009400058E260E082E80E944B132DE730E042EF6E +:1009500058E260E083E80E944B132DE730E04FE659 +:1009600059E260E084E80E944B132DE730E04CEE42 +:1009700059E260E085E80E944B132DE730E049E63C +:100980005AE260E086E80E944B1381E01F910F91CC +:1009900008951092C720089581E0089581E0089598 +:1009A00010922002982F9C7193689093200287FFE9 +:1009B00003C090E182E002C090E080E0892B809348 +:1009C000210210922202109226020895E0E0F2E045 +:1009D00010AA836880AB80E181AB12AA16AA0895A1 +:1009E000E0E0F2E010A683E880A78FE281A712A6DC +:1009F00016A60895AAECB1E092E09C93E82FF0E0EF +:100A000084911C920895909171009D7F9093710044 +:100A100010920002623011F09CE101C09EE19093BF +:100A2000010290E490930202811102C080E401C0AF +:100A300080EC80930302613011F084E001C083E018 +:100A40008093040280E2D6DF80930C0281E2D2DF41 +:100A500080930D02109218021092190281E0809387 +:100A60000002BECF1F920F920FB60F9211248F93E8 +:100A7000000000000000000081E0809323028F91BD +:100A80000F900FBE0F901F901895CF93DF93E0E764 +:100A9000F0E082818B7F8283C0E2D3E08DE08883A7 +:100AA00080E4898389E08A8383E3A4DF888782E303 +:100AB000A1DF898787E39EDF8A8786E39BDF8B87B9 +:100AC000E0E2F6E08081836080831482DF91CF9141 +:100AD0000895E0E7F0E080818E7F808383E8809353 +:100AE00000010895E0E0F1E0108A80E4808B10A21C +:100AF00080A310AA80ABE0E4F1E010828083109222 +:100B0000C6201092C52081E08093C4201092A823B3 +:100B10001092A9231092A6231092A72308958093E0 +:100B2000D62581E08093BF200895CF93DF93109264 +:100B30000920D8DFC0E0D1E01EAA84E288AB19AA60 +:100B400049E54AAB32E03BAB60910B2070910C2041 +:100B50006CAB7DAB67ED75E268AF79AF1AAE9BE326 +:100B60009CAF93E090933D0110923E0128A920682C +:100B700028AB10924601E0E4F1E08083109241013D +:100B8000409342019093430140910D2050910E20DB +:100B9000409344015093450146EC53E24093480191 +:100BA0005093490110924A0129E320934C019093FC +:100BB0004D0110924E01908190689083188A90E4C4 +:100BC000988B888B198A95E99A8B90E19B8B4EEED6 +:100BD00052E04C8B5D8B888F398F1A8E88EF97E2AD +:100BE0008C8F9D8F1E8E68EC70E084EF91E052DD5B +:100BF00088EC90E0809307209093082081E0809318 +:100C0000062088898068888BDF91CF9108951F9393 +:100C1000CF93DF9311E01093092064DFC0E0D1E0AF +:100C200018AA80E488AB84E088AB19AA1AAA4BE41E +:100C30004BAB1CAA1DAA1EAA8AE090E288AF99AF0E +:100C40001AAE60EA6CAF38E030933D0110923E017D +:100C500088A9806A88ABE0EAF8E085E58083808334 +:100C600010924601E0E4F1E084E2808310924101B9 +:100C700099E59093420122E020934301A0910B203B +:100C8000B0910C20A0934401B0934501A7EDB5E2CB +:100C9000A0934801B093490110924A019BE39093BD +:100CA0004C0193E090934D0110924E019081906819 +:100CB000908388A319A295E99AA34BA34EEE52E024 +:100CC0004CA35DA368A739A71AA666EE7AE26CA7C3 +:100CD0007DA71EA6888B198A9A8B90E19B8B4C8BE3 +:100CE0005D8B888F298F1A8E88EF97E28C8F9D8F6E +:100CF0001E8E68EC70E084EF91E0CCDC88EC90E034 +:100D000080930720909308201093062088A1806884 +:100D100088A388898068888BDF91CF911F9108957F +:100D20001F93CF93DF9312E010930920DBDEC0E026 +:100D3000D1E01EAA84E288AB19AA39E53AAB1BAB15 +:100D400040910B2050910C204CAB5DAB47ED55E230 +:100D500048AF59AF1AAE9BE39CAF93E090933D012F +:100D600010923E0128A9206828AB10924601E0E4C9 +:100D7000F1E080831092410130934201909343014E +:100D800020910D2030910E20209344013093450195 +:100D900026EC33E2209348013093490110924A0136 +:100DA00029E320934C0190934D0110924E019081C4 +:100DB00090689083188A90E4988B888B198A45E90B +:100DC0004A8B90E19B8B2EEE32E02C8B3D8B888FF3 +:100DD000198F1A8E68EF77E26C8F7D8F1E8E88A335 +:100DE00019A24AA39BA32CA33DA384E388A719A718 +:100DF0001AA686EE9AE28CA79DA71EA668EC70E064 +:100E000084EF91E047DC88EC90E08093072090939A +:100E1000082081E08093062088898068888B88A1DB +:100E2000806888A3DF91CF911F9108951F93CF937E +:100E3000DF9313E01093092055DEC0E0D1E010925B +:100E40004601E0E4F1E084E280831092410129E56B +:100E50002093420192E09093430140910B205091E6 +:100E60000C20409344015093450147ED55E24093D7 +:100E700048015093490110924A019BE390934C0121 +:100E800010934D0110924E019081906890831EAA9C +:100E900088AB19AA2AAB1BAB20910D2030910E20F4 +:100EA0002CAB3DAB26EC33E228AF39AF1AAE99E359 +:100EB0009CAF10933D0110923E0198A9906898ABA9 +:100EC00018A250E458A394E098A319A21AA24BE4E4 +:100ED0004BA31CA21DA21EA22AE030E228A739A71C +:100EE0001AA630EA3CA728E02DA71EA698A1906A72 +:100EF00098A395E59093A008188A588B888B198A37 +:100F000085E98A8B4B8B8EEE92E08C8B9D8B388F94 +:100F1000298F1A8E88EF97E28C8F9D8F1E8E68EC3A +:100F200070E084EF91E0B6DB88EC90E080930720DE +:100F30009093082081E08093062088898068888BC0 +:100F4000DF91CF911F9108951F93CF93DF9314E00A +:100F500010930920C7DDC0E0D1E018AA80E488AB77 +:100F600018AB19AA1AAA3BE43BAB1CAA1DAA1EAADD +:100F70008AE090E288AF99AF1AAE50EA5CAF88E0A1 +:100F800080933D0110923E0198A9906A98AB95E537 +:100F90009093A00810924601E0E4F1E094E290837F +:100FA0001092410129E52093420122E02093430160 +:100FB00060910B2070910C20609344017093450167 +:100FC00067ED75E2609348017093490110924A0100 +:100FD0002BE320934C0123E020934D0110924E010E +:100FE000208120682083988B198A45E94A8B3B8BA6 +:100FF0002EEE32E02C8B3D8B588F898F1A8E68EF46 +:1010000077E26C8F7D8F1E8E98A319A24AA39AE473 +:101010009BA32CA33DA393EC98A789A71AA686EEC1 +:101020009AE28CA79DA71EA668EC70E084EF91E081 +:1010300031DB88EC90E0809307209093082081E0DA +:101040008093062088898068888B88A1806888A31F +:10105000DF91CF911F910895FFCFCF93DF9386E06B +:10106000809309203FDDC0E0D1E01EAA84E288AB76 +:1010700019AA39E53AAB93E09BAB40910D20509112 +:101080000E204CAB5DAB46EC53E248AF59AF1AAE05 +:1010900029E32CAF90933D0110923E0128A92068CE +:1010A00028AB10924601E0E4F1E080831092410108 +:1010B0003093420122E02093430140910B20509154 +:1010C0000C20409344015093450147ED55E2409375 +:1010D00048015093490110924A013BE330934C017F +:1010E00090934D0110924E01908190689083188AE0 +:1010F00090E4988B888B198A95E99A8B90E19B8B69 +:101100004CED55E04C8B5D8B888F298F1A8E88EFC4 +:1011100097E28C8F9D8F1E8E68EC70E084EF91E0DB +:10112000B9DA80E991E0809307209093082081E06C +:101130008093062088898068888BDF91CF910895FD +:10114000CF93DF9387E080930920CCDCC0E0D1E02F +:101150001EAA84E288AB19AA39E53AAB93E09BABAF +:1011600040910D2050910E204CAB5DAB46EC53E20C +:1011700048AF59AF1AAE29E32CAF90933D011092BE +:101180003E0128A9206828AB10924601E0E4F1E076 +:101190008083109241013093420122E02093430169 +:1011A00040910B2050910C204093440150934501F5 +:1011B00047ED55E2409348015093490110924A018E +:1011C0003BE330934C0190934D0110924E0190817E +:1011D00090689083188A90E4988B95E2988B198A8E +:1011E00095E99A8B90E19B8B4CED55E04C8B5D8B98 +:1011F000888F298F1A8E88EF97E28C8F9D8F1E8E95 +:1012000068EC70E084EF91E045DA80E991E080934A +:1012100007209093082081E08093062088898068C9 +:10122000888BDF91CF9108951F920F920FB60F9286 +:1012300011248F9381E0809303018F910F900FBE53 +:101240000F901F9018951F920F920FB60F921124B6 +:101250008F9382E0809303018F910F900FBE0F90C8 +:101260001F901895E0E7F0E083818C7F8383848171 +:101270008C7F848380818D7F8083E0E8F1E080EC47 +:101280008283128688EC81831186A0E0B8E034E086 +:101290003C9323E011962C93119714961C9214976B +:1012A00085ED91E096968D939C93979716961C9258 +:1012B0001697E0E4F8E030832183148286A397A395 +:1012C0001682E0E6F6E0808180618083E0E4F9E068 +:1012D00083E18183148282E08683A6A3B7A310A64C +:1012E00011A681E0808308951F920F920FB60F928E +:1012F00011242F933F934F935F938F939F93CF939B +:10130000DF931F92CDB7DEB78FEF80934C098091AA +:101310000920873031F480912C02898390912D022D +:1013200002C090912C028091C320891B20916809F2 +:101330003091690982308CF02A3F374070F4209157 +:1013400068093091690989301CF481E090E002C09D +:1013500086E090E0820F931F18C0209168093091B9 +:1013600069098F3FB4F42730310598F0209168095E +:1013700030916909883F1CF081E090E002C086E06E +:1013800090E0A901481B590BCA01809378099093FA +:1013900079090F90DF91CF919F918F915F914F913C +:1013A0003F912F910F900FBE0F901F901895E0E77F +:1013B000F0E083818F7E8383E0E4F6E080818A6AB7 +:1013C00080838FEF848388E5828BE0EAF8E080E316 +:1013D000838384EC858387E08683178288E1848316 +:1013E0000895E0E7F0E08381877F8383E0ECF8E015 +:1013F00080E48083118288E58093550608951F92CA +:101400000F920FB60F92112400000F900FBE0F9095 +:101410001F9018951F920F920FB60F9211248F9361 +:10142000EF93FF93E0EAF8E080818083FF91EF91F2 +:101430008F910F900FBE0F901F9018959FB7F89443 +:10144000A0E5B0E016968C911697897F16968C933E +:101450001697E0E6F0E080E885838BEB86831696AE +:101460008C911697846016968C938081816080831E +:101470009FBF08959FB7F894E82FF0E0E059FF4F21 +:1014800060958081682360839FBF0895CF938630E5 +:1014900011F0C0E001C0C8E18091510081FD0DC094 +:1014A0009FB7F894809150008260809350009FBF56 +:1014B0008091510081FFFCCFC1DF6C2F636084E419 +:1014C00090E0BCD460E480E0CF91D4CF8091C8207C +:1014D00008958091C820813009F45BCA0895F0D046 +:1014E000FC0183818093C820811101C015CA81E06D +:1014F00008959091C625892F807697FF07C0803484 +:1015000091F48091C72581110EC048CA803459F4E6 +:101510008091C725811107C08091CC259091CD2560 +:10152000892B09F039CA80E008958091C8258F770A +:101530000C94CD129091D020911102C080E00895BA +:10154000E091CD20F091CE200190F081E02D9481AA +:101550008917A0F7E093CB20F093CC202281338130 +:101560002E0F3F1FE217F30798F49181943061F436 +:101570009281891309C09381691306C0E093CB203F +:10158000F093CC2081E008959081E90FF11DEACF1E +:10159000E093CB20F093CC20D1CFE091CD20F091FF +:1015A000CE200190F081E02D228133812E0F3F1F4C +:1015B000FC014081E40FF11DE217F30748F481813B +:1015C000843031F0853039F08081E80FF11DF4CF9F +:1015D00080E090E00895CF0108951F93CF93DF93AB +:1015E000182FA8DF882339F1C091CB20D091CC20CF +:1015F000CE01D3DFEC01892B41F04C815D816B8101 +:101600008A81D8D78111F4CF16C0E091CD20F09116 +:10161000CE2092818381E92FF82FE10FF11DE10F98 +:10162000F11D0190F081E02D0190F081E02DDF911E +:10163000CF911F91099480E0DF91CF911F91089580 +:10164000EF92FF921F93CF93DF93C82F60E072DF7A +:10165000811102C010E02DC0E091CD20F091CE208C +:1016600092818381E92FF82FEC0FF11DEC0FF11D12 +:10167000E080F180D7011696ED91FC9117970995BE +:10168000682F8C2F57DF182F882321F3C091CB2090 +:10169000D091CC20CE0181DFEC01892B21F08A8111 +:1016A0000E940714F7CFD7011296ED91FC91139782 +:1016B0000995812FDF91CF911F91FF90EF900895B1 +:1016C0008091CB209091CC200895FBC6CF93809140 +:1016D000D020811108C01092D0201092D4201092F6 +:1016E000D520CF910895C0E0E091CD20F091CE209B +:1016F0000190F081E02D8481C81768F78C2FA0DF5E +:10170000CF5FF2CFCF938091D0208823F1F0C0E05B +:10171000E091CD20F091CE20A081B18114968C91E2 +:10172000C81798F492818381E92FF82FEC0FF11DEF +:10173000EC0FF11D0190F081E02D0084F185E02D8A +:10174000309709F00995CF5FE3CFCF910895EF92DD +:10175000FF920F931F93CF93DF931F92CDB7DEB706 +:101760001092D0251092D1251092D2251092D32517 +:101770001092D4251092D5258091C62587FF07C0E9 +:101780002091CC253091CD25232B09F44EC3982FE1 +:101790009076903409F00BC1E091C7258E2F90E030 +:1017A000FC01E05AF109EA30F10508F0CDC2EA5F28 +:1017B000FE4F0C94D11581E08093C02080910720CA +:1017C000909108208093B723809107209091082062 +:1017D0009093B82380919E238093B92380919B237B +:1017E0008093BA2380916A008093BB2380916B0021 +:1017F0008093BC236091CC257091CD258AEA93E239 +:10180000D4C0109200088091C8259091C92580937A +:101810003608909337088091CA258F70809300080E +:101820006091CC257091CD2586EC93E2BCD62091B9 +:101830000D2030910E208091CC259091CD25281738 +:10184000390709F4F0C280930D2090930E2026C032 +:10185000109240088091C8259091C9258093760800 +:10186000909377088091CA258F708093400860918B +:10187000CC257091CD2587ED95E295D620910B2052 +:1018800030910C208091CC259091CD2528173907D7 +:1018900009F4C9C280930B2090930C2080910920F9 +:1018A00051C010926809109269098091C8258093EF +:1018B000C320B9C28091C82580932406B4C2E091A8 +:1018C000C825F091C925E830F10508F03DC2E05F78 +:1018D000FE4F0C94D11560E080E095D88091CA2528 +:1018E0005FD880E02FC060E080E08DD88091CA256D +:1018F00057D881E027C061E081E085D88091CA2572 +:101900004FD88091CB2562D882E01CC083E01AC0FA +:1019100084E018C060E080E076D88091CA2540D885 +:1019200085E010C061E080E06ED88091CA2538D88B +:1019300086E008C062E080E066D88091CA258068B1 +:101940002FD887E0ECD86FC28091C8258093840699 +:101950006AC28091C8259091C925892B91F00E9477 +:10196000650380E2E4EDFDE2A7EDB7E201900D92A0 +:101970008A95E1F781E08093D7270E947A030E943D +:101980006503E9E7F0E091E088EDF89484BF908387 +:101990006091CC257091CD258AEA90E206C06091D5 +:1019A000CC257091CD2589EA90E2FDD53CC29111FC +:1019B000CBC187FFFCC02091CC253091CD252115CE +:1019C000310509F4C1C18F7109F09EC08091C7250E +:1019D000863071F0883009F48EC08111B5C1223093 +:1019E000310509F0B1C162E070E084ED90E2DDCF35 +:1019F0008091C8259091C925292F332722303105A0 +:101A0000A1F064F42130310509F09EC180911920C4 +:101A100090911A20DC016C9170E05BC0233031059D +:101A200089F12F30310509F18FC1E0911920F09132 +:101A30001A202189821708F087C19927880F991FDA +:101A4000880F991FE0911B20F0911C20E80FF91FCF +:101A500080819181FC0162817381A5D5E091CE25C1 +:101A6000F091CF2582E0818335C080911D20909137 +:101A70001E20009709F468C1DC0112966D917C91DB +:101A8000139727C099278130910569F038F00297A4 +:101A900009F05AC168E08AE890E208C064E070E0AA +:101AA0008CE990E216C067E083E990E2282FAAE76C +:101AB000B0E2FC01819190E08D939D938E2F821B6B +:101AC0008617C0F3660F6E5F6093782070E088E73A +:101AD00090E269D58091CC259091CD252091D0259B +:101AE0003091D1258217930708F09DC18093D025AE +:101AF0009093D12598C12130310509F025C161E0CD +:101B000070E080ED90E251CF8130C9F58091C7251A +:101B10008A3009F019C12130310509F015C18091D1 +:101B2000D020882309F410C1E090CA25F090CB257D +:101B30000091CD201091CE20D801ED91FC918481AF +:101B4000E81608F001C160E08E2DF4DC882309F46A +:101B5000FBC0FF24EE0CFF1CF801828193818E0DE7 +:101B60009F1DDC01ED91FC910680F781E02D099528 +:101B70008093D22061E070E082ED90E216CF823057 +:101B800009F0E2C08091C7258111DEC02230310505 +:101B900009F0DAC08091CA255ED590E08093C92013 +:101BA0009093CA2062E070E089EC90E2FECE8F71E3 +:101BB00009F07DC08091C725833009F4C5C018F4B1 +:101BC0008130A1F0C1C0853019F0893039F1BCC035 +:101BD0008091CC259091CD25892B09F0B5C085E960 +:101BE0009AE08093D2259093D3251DC18091CC2576 +:101BF0009091CD25892B09F0A7C08091C82590919F +:101C0000C925019709F0A0C08091D4209091D520DA +:101C10008D7F8093D4209093D52005C18091CC25D1 +:101C20009091CD25892B09F08FC0BAD4882309F46F +:101C30008BC02091C8253091C9253327E091192008 +:101C4000F0911A20818990E08217930708F47CC0F4 +:101C50003DDD8091C8259091C9258093D0208823AF +:101C600009F4E1C099278150904C880F991F880F83 +:101C7000991F20911B2030911C20820F931F80936D +:101C8000CD209093CE2010E0E091CD20F091CE2099 +:101C90000190F081E02D8481181708F0C4C060E045 +:101CA000812F9BDC882309F44FC01F5FEDCF81306B +:101CB000F1F48091C7258B3009F046C08091CC2586 +:101CC0009091CD25892B09F03FC08091D0208823A9 +:101CD00009F43AC01091CA256091C825812F698303 +:101CE000AFDC6981882381F1812F77DC2BC08230C2 +:101CF00059F58091C725813019F0833089F024C0CF +:101D00008091CC259091CD25892BF1F48091C82527 +:101D10009091C925892BC1F48091CA25A3D412C002 +:101D20008091CC259091CD25892B71F48091C82587 +:101D30009091C925892B41F48091CA2538D580918D +:101D4000CA256ED581116FC08091C6258F718130F3 +:101D5000B9F58091D020882399F1E090CA25F090C0 +:101D6000CB250091CD201091CE20D801ED91FC9192 +:101D70008481E81628F560E08E2DDCDB882301F1F4 +:101D8000F701FF27EE0FFF1FD80112968D919C914E +:101D90001397E80FF91F00811181D8011696ED9174 +:101DA000FC9117970995682F8E2DC4DB882341F08D +:101DB000D8011496ED91FC9115970995811133C0C6 +:101DC0008091C6258F71823081F58091D020882343 +:101DD00061F1F12CE091CD20F091CE20A081B18174 +:101DE00014968C91F81608F592818381E92FF82FCB +:101DF000EF0DF11DEF0DF11D00811181D801169637 +:101E0000ED91FC9117970995682F8F2D93DB88230F +:101E100061F0D8011496ED91FC9115970995811107 +:101E200002C0F394D7CF81E001C080E00F90DF9132 +:101E3000CF911F910F91FF90EF9008951BBEFC0171 +:101E400028ED24BF608308958091CF0187FDFCCFEA +:101E500008951F93CF93DF93C0ECD1E01A858A8752 +:101E600061E08BEC91E0EADF1A87DF91CF911F915F +:101E70000895CF92DF92EF92FF920F931F93CF932B +:101E8000DF9300D0CDB7DEB78C017B0149835A8345 +:101E9000DBDF8CECC82EDD24D394F60190819860B2 +:101EA0009083B801705F49815A81C70180D6F601DD +:101EB0008081877F80830F900F90DF91CF911F915A +:101EC0000F91FF90EF90DF90CF900895CF93DF9325 +:101ED00000D0CDB7DEB76A838983B6DFACECB1E062 +:101EE0009C9198609C938981E82FF0E0F05F6A8173 +:101EF00060838C91877F8C930F900F90DF91CF91AF +:101F000008950F931F93CF938C019EDFC0E0F801DB +:101F100061918F018C2FDADFCF5FC032C1F7CF9193 +:101F20001F910F910895CF93DF931F92CDB7DEB726 +:101F300089838ADF898120E2829FC0011124E0EC3D +:101F4000F1E012829183808385E30F90DF91CF913E +:101F500080CF4091CA01E62FF72F8093CA01849168 +:101F60004093CA010895E82FF0E0EA50F24D8081D5 +:101F70008F3F09F4FFCF9FB7F89480818F5F8083F4 +:101F80009FBF0895E82FF0E0EA50F24D8081811163 +:101F900001C0FFCF9FB7F8948081815080839FBF9D +:101FA0000895CF93C82F80919823C11105C088232D +:101FB00039F081E0E7DF04C0811102C081E0D3DFA6 +:101FC000C0939823CF910895282F2F70082E000CCE +:101FD000990B392F331F3327331F832F90E0820F44 +:101FE000911D820F911D23E0880F991F2A95E1F71B +:101FF0008C5D9C4D08950F93E8ECF4E080818F7D1B +:10200000808380818F7D8083ECE2F3E202E00593A0 +:1020100010922E2310922F2300E2069300E40693E1 +:10202000E4E2F3E200E2069300E40693E6ECF5E274 +:102030001486158616861786128613861092072335 +:102040000F9108950F9385E080930723EDE2F3E26B +:1020500004E00593E5E2F3E204E005930F910895AF +:102060000F9383E08093072310922E2310922F2347 +:10207000ECE2F3E202E006930F910895E091D2259D +:10208000F091D325309709F009940895282F2F70E7 +:10209000082E000C990B392F331F3327331F832F42 +:1020A00090E0820F911D820F911D029749E0489F99 +:1020B0009001499F300D1124C901895A9D4D089501 +:1020C0008F929F92AF92BF92DF92EF92FF920F9307 +:1020D0001F93CF93DF93D82ED9DFEC018D2D74DFC2 +:1020E0007C01DC011196EC91E770E150E73040F49F +:1020F000F0E0EE0FFF1FE455FF4D0081118102C09B +:1021000008E010E0ED81FE812B813C814881D70100 +:10211000D7FE48C016968D919C9117978E0F9F1FE2 +:102120008D839E838217930761F1281B390B21153C +:10213000B4E03B0738F02FEF33E0C901B8010AD50E +:10214000281B390B41FF0AC0C901B80103D5AC01F6 +:1021500091E0452B09F090E0892F01C080E0988143 +:1021600080FB91F99883F7011682178222833383CB +:1021700029813A818D819E81820F931F848395836B +:102180000EC041FF71C04D7F4883D70116961D9246 +:102190001C92179712961D921C921397F70102E05A +:1021A00006937BC01296AD90BC90139742FF10C06F +:1021B00089809A80C901B801CDD4B0E4DB9EB0011A +:1021C000112469567F4DAC01C4018E0F9F1FEFD4BF +:1021D0008D819E818A0D9B1D8D839E832B813C81E9 +:1021E0002817390710F42D833E83F70186819781E4 +:1021F000A816B906C9F58D819E8182179307A1F1B2 +:10220000281B390B2115F4E03F0710F02FEF33E0C6 +:10221000C901B8019FD4281B390BD70112961D9212 +:102220001C9213972017310778F488818460888383 +:10223000B0E4DB9EC001112489569F4DF7018483D1 +:10224000958306831783AACF49815A818D819E8108 +:10225000840F951FD70114968D939C93159716960E +:102260002D933C9317979ACF888180FF16C08E7F5D +:102270008883EF81F885309781F06D817E814D2DC7 +:1022800080E0DF91CF911F910F91FF90EF90DF9051 +:10229000BF90AF909F908F900994DF91CF911F9145 +:1022A0000F91FF90EF90DF90BF90AF909F908F9035 +:1022B00008950F93CF93DF9380910723833029F400 +:1022C000DDDEDF91CF910F9196CE209103233091E7 +:1022D0000423C091D025D091D125C21BD30B61F529 +:1022E0008091052390910623820F931F80930523ED +:1022F000909306232091CC253091CD2528173907BE +:1023000021F08091D620882331F084E08093072348 +:10231000E4E2F3E236C0E091D425F091D525309780 +:1023200099F00995882381F01092032310920423D9 +:10233000C091D025D091D125C034D10528F010927C +:10234000D620C0E4D0E003C081E08093D620C093C3 +:102350002E23D0932F238091032390910423209147 +:10236000CE253091CF25280F391F2093302330936D +:102370003123C80FD91FC0930323D0930423ECE269 +:10238000F3E202E00693DF91CF910F9108950F934E +:10239000CF93DF931F92CDB7DEB78091CC0480FF3F +:1023A00065C021E02093CC0484E293E2FC0100E8C4 +:1023B0000693ECE2F3E200E806932093CA04FC01E2 +:1023C00000E1069380910723882329F0835082300F +:1023D00008F454DE10DE809126239091272308977D +:1023E00009F046C088E0E3ECF2E2A6ECB5E2019029 +:1023F0000D928A95E1F78091C80480628093C804A9 +:102400008091C80480628093C804A1D9811102C060 +:1024100019DE2EC09091C62597FF0EC0109205239D +:1024200010920623109203231092042392E09093BB +:10243000072389833EDF08C02091CC253091CD252C +:10244000232B21F489830CDE898113C0109205238C +:1024500010920623109203231092042391E090938C +:102460000723E4E2F3E202E0069303C080E001C048 +:1024700081E00F90DF91CF910F910895CF93CFB767 +:10248000F89481E08EDDEAECF4E080E4808380E281 +:102490008083E1ECF4E0808181608083A9ECB4E08A +:1024A0008C9182608C93E8ECF4E08081806480837E +:1024B0008C9181608C93808180688083CFBFCF9125 +:1024C0000895CF931092600080E30E94460A8091A5 +:1024D000C00480648093C00481E080936000CFB723 +:1024E000F89480E090E0FC0123E0EE0FFF1F2A95B6 +:1024F000E1F7E85FFC4D158E01968E30910599F756 +:1025000080E090E039E0389FF001399FF00D112410 +:10251000E95AFD4D20812E7F208301968C30910554 +:1025200091F76AE170E082E014DD8F3F09F48FE1FA +:102530008093FA046BE170E082E00BDD8F3F09F4D9 +:102540008FE18093FB048091C00486608093C00477 +:102550008091C00480688093C0048091C004806131 +:102560008093C00484E293E28093C6049093C704EE +:102570008091C00480628093C0048FEF8093C50473 +:102580008091C80482608093C8041092982385E0EB +:10259000EADC74DFCFBFCF9108958093C304089520 +:1025A0008091C3040895E6ECF5E280879187628705 +:1025B000738708950F931F93CF93DF931F92CDB727 +:1025C000DEB78A01698300DDFC018181807C69813D +:1025D00081113AC06370613019F020F080E803C0C7 +:1025E00080EC01C080E400381105E9F058F40032B5 +:1025F0001105A9F000341105A1F000311105C9F44D +:1026000091E018C0011592E0190779F00F3F93E0AF +:10261000190769F00115114061F495E00BC092E0D3 +:1026200009C093E007C094E005C096E003C097E0BE +:1026300001C090E0118226E02083982B9183818154 +:102640008062818381E001C080E00F90DF91CF91B3 +:102650001F910F910895B8DCFC01818182FB8827CE +:1026600080F90895CF93C82FAFDCFC01818182FFF0 +:102670000FC091819B7F91838C2F08DDFC0190819D +:1026800090FF06C09E7F90830780F085E02D09951E +:1026900081E0CF9108958F929F92AF92BF92DF9287 +:1026A000EF92FF920F931F93CF93DF931F92CDB7BB +:1026B000DEB7D82E5A0179016983E8DC4C018D2DF3 +:1026C00083DC9C01DC0111968C911197807C6981DF +:1026D000882309F45EC011968C911197807C803C10 +:1026E00021F011968C9182FD54C09FB7F894F401AB +:1026F000808180FF02C09FBF4CC0816080839FBFEC +:10270000F401A182B282E382F482158216820783E9 +:10271000108791E0611104C0E114F10409F090E028 +:10272000D4018C9190FB81F98B7F8C93D7FE04C0F0 +:10273000F9011682178229C0D90111968C9111973F +:10274000807C803CC9F41196EC91E770E150E73051 +:1027500040F4F0E0EE0FFF1FE455FF4D6081718102 +:1027600002C068E070E0C701F5D1892B29F0F401BF +:1027700080818E7F80830DC0D90112961D921C929C +:10278000139716961D921C9217978D2D99DC81E058 +:1027900001C080E00F90DF91CF911F910F91FF90CA +:1027A000EF90DF90BF90AF909F908F900895EF9241 +:1027B000FF920F93CF93C82F07DC7C018C2F66DC30 +:1027C000DC01F70102E005939C9190FF1BC09E7F06 +:1027D0009C931796ED91FC911897309799F0D7013B +:1027E000C7FF05C016966D917C91179704C012968D +:1027F0006D917C9113974C2F81E0CF910F91FF90B9 +:10280000EF900994CF910F91FF90EF900895CF939F +:10281000C82FCDDF8C2FD8DBFC011182CF9108951A +:102820000F93CF93C82FD0DBFC01918194609183EB +:1028300001E006938C2FBBDF81E0CF910F910895CB +:102840001F920F920FB60F9211240F932F933F9365 +:102850004F935F936F937F938F939F93AF93BF93A8 +:10286000CF93EF93FF938091CB0487FF08C080E85C +:102870008093CA040E94820B0E94230486C0809128 +:10288000CB0482FF18C084E08093CA0480912C237B +:1028900086FF7BC08091CC0481FD77C078DD8111FB +:1028A00074C080910723813011F4DADB6EC084306C +:1028B00009F06BC021C08091CB0481FF26C082E06B +:1028C0008093CA048091242386FF5FC08091CC044A +:1028D00081FD5BC05CDD811158C08091072382308F +:1028E00041F484E080930723E4E2F3E202E00693FC +:1028F0004CC0833009F049C0EDE2F3E204E00593F7 +:10290000E5E2F3E204E0059340C08091CB0484FF4C +:1029100025C080E18093CA04C1E08C2F48DF8C2F52 +:10292000806845DFCF5FC630C1F70E94660B10920A +:10293000C30410922523C093242383E4809325238A +:1029400010922D23C0932C2380932D2383EC92E2AD +:1029500080932823909329234EDB17C08091CB04CA +:1029600086FF08C080E48093CA0480E01ADB0E94DE +:1029700021040BC08091CB0485FF07C080E28093C7 +:10298000CA0481E00EDB0E942204FF91EF91CF91F7 +:10299000BF91AF919F918F917F916F915F914F9177 +:1029A0003F912F910F910F900FBE0F901F90189590 +:1029B0001F920F920FB60F9211240F931F932F9314 +:1029C0003F934F935F936F937F938F939F93AF93B7 +:1029D000BF93CF93DF93EF93FF938091CC0481FF5C +:1029E0001AC082E08093CC048091C5048195880F41 +:1029F000E4E2F3E2E81BF109208131812452334201 +:102A000083E0369527958A95E1F7822F869520FDFC +:102A100006C0C0E005C0BBDC882319F386C0C0E84F +:102A2000C80F8C2FD1DAFC01208125FF7EC000E287 +:102A30000693C11174C080910723843019F41EDB02 +:102A4000DADA73C000912623109127238091D025D4 +:102A50009091D125C0910323D09104239E01200F92 +:102A6000311F8217930718F48C010C1B1D0B8091EA +:102A7000CE259091CF25A80163EC72E28C0F9D1FAB +:102A800096D0C00FD11FC0930323D09304230034EA +:102A9000110569F480910523909106238C0F9D1FE9 +:102AA0002091CC253091CD258217930788F0C093D3 +:102AB000D025D093D125E091D425F091D52530971C +:102AC00029F00995811102C0BDDA2FC0C9DA2DC0E5 +:102AD0008091D0259091D1258C179D07D9F4E09154 +:102AE000D425F091D525309779F30995882361F3A2 +:102AF0002091052330910623809103239091042394 +:102B0000820F931F80930523909306231092032333 +:102B100010920423E4E2F3E202E0069306C0C03818 +:102B200011F4C7DB02C08C2FCBDAFF91EF91DF915C +:102B3000CF91BF91AF919F918F917F916F915F9155 +:102B40004F913F912F911F910F910F900FBE0F90BA +:102B50001F901895AA1BBB1B51E107C0AA1FBB1FE2 +:102B6000A617B70710F0A61BB70B881F991F5A9519 +:102B7000A9F780959095BC01CD01089597FB072E8C +:102B800016F4009406D077FD08D0E4DF07FC05D0EA +:102B90003EF4909581959F4F0895709561957F4F74 +:102BA0000895EE0FFF1F0590F491E02D0994FB01AD +:102BB000DC0102C001900D9241505040D8F70895B9 +:102BC000FB01DC0101900D920020E1F70895F894DB +:022BD000FFCF35 +:102BD20040000CE02E0AFFFFFFFF55800080006FCF +:102BE2000A690A790A660A000064201F2000002888 +:102BF2002023200F2000000009023C000101008078 +:102C0200FA0904000006FFFFFF00070581018000AA +:102C12000107058201800001070583018000010789 +:102C220005840180000107058501800001070586F2 +:102C3200018000011201000200000040EB0394BA7F +:102C42000002010200010000000300000000000079 +:102C5200000000000000000000004C61627261642C +:102C62006F72004573706F54656B000004030904B2 +:102C72006465627567313233000103001000200081 +:0A2C82004000800000010002FF0383 +:00000001FF diff --git a/Desktop_Interface/build_android/package_source/assets/firmware/labrafirm_0003_01.hex.REMOVED.git-id b/Desktop_Interface/build_android/package_source/assets/firmware/labrafirm_0003_01.hex.REMOVED.git-id deleted file mode 100644 index b3667a22..00000000 --- a/Desktop_Interface/build_android/package_source/assets/firmware/labrafirm_0003_01.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f7946fd762c2bf7eaa4b76d5eb68948870244c19 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/assets/firmware/labrafirm_0003_02.hex b/Desktop_Interface/build_android/package_source/assets/firmware/labrafirm_0003_02.hex new file mode 100644 index 00000000..879125a9 --- /dev/null +++ b/Desktop_Interface/build_android/package_source/assets/firmware/labrafirm_0003_02.hex @@ -0,0 +1,714 @@ +:100000001FC1000039C1000037C1000035C1000028 +:1000100033C1000031C100000C94F3080C94230993 +:100020002BC1000029C1000027C1000025C100002C +:1000300023C1000021C100001FC100001DC100003C +:100040001BC1000019C1000017C1000015C100004C +:1000500013C1000011C100000FC100000DC100005C +:100060000C94200A0C942B0A07C1000005C1000063 +:1000700003C1000001C10000FFC00000FDC000007E +:10008000FBC00000F9C00000F7C00000F5C0000090 +:10009000F3C00000F1C00000EFC00000EDC00000A0 +:1000A000EBC00000E9C00000E7C00000E5C00000B0 +:1000B000E3C00000E1C00000DFC00000DDC00000C0 +:1000C000DBC00000D9C00000D7C00000D5C00000D0 +:1000D000D3C00000D1C00000CFC00000CDC00000E0 +:1000E000CBC00000C9C00000C7C00000C5C00000F0 +:1000F000C3C00000C1C00000BFC00000BDC0000000 +:10010000BBC00000B9C00000B7C00000B5C000000F +:10011000B3C00000B1C00000AFC0000074C4000054 +:10012000ABC00000A9C00000A7C00000A5C000002F +:10013000A3C00000A1C000009FC000009DC000003F +:100140009BC0000099C0000097C000000C94950966 +:1001500093C0000091C000008FC000008DC000005F +:100160008BC0000089C0000087C0000085C000006F +:1001700083C0000081C000007FC000007DC000007F +:100180007BC0000079C0000077C0000075C000008F +:1001900073C0000071C000006FC000006DC000009F +:1001A0006BC0000069C0000067C0000065C00000AF +:1001B00063C0000061C000005FC000005DC00000BF +:1001C0005BC0000059C0000057C0000055C00000CF +:1001D00053C0000051C000004FC000004DC00000DF +:1001E0004BC0000049C0000047C0000045C00000EF +:1001F00043C000000C9437140C94E514FC03FE0378 +:10020000000402040404060408040A041C041E0476 +:10021000200422042404290426042804FC0B220CB4 +:10022000490C720C7B0C800CC90CCE0CED0CF40C40 +:100230008C0C940C9C0CA80CAA0CAC0CB50CBE0C31 +:1002400011241FBECFEFCDBFDFE2DEBF10E2A0E082 +:10025000B0E2ECEEFBE202C005900D92AA39B107C4 +:10026000D9F72BE2AAE9B0E201C01D92A03EB20785 +:10027000E1F779D20C94F415C3CE84E08093560054 +:100280008CE189D3809363008BEB8093660080E8D8 +:100290008093650081E08093600088ED84BF1092B8 +:1002A000410083E080935000809151008330E1F75A +:1002B0008091500081608093500088E180935500C8 +:1002C0008091510080FFFCCF80915000806180932D +:1002D00050008091510084FFFCCF88ED84BF84E002 +:1002E000809340000895E0E7F0E085818E7F85836C +:1002F000E0E0FAE08FEB9DE586A397A380EE9EE217 +:1003000080A391A382E0808308958091200A909138 +:10031000210A813E2EE2920718F02091822106C028 +:10032000803E2EE2920721F020917F2120936A00E7 +:1003300020910520222321F080910520815033C097 +:10034000885F9A42813D974080F110929A20809177 +:100350009B2090919C20A0919D20B0919E20019681 +:10036000A11DB11D80939B2090939C20A0939D2064 +:10037000B0939E2080919B2090919C20A0919D20E5 +:10038000B0919E20892F9A2FAB2FBB278093A2215B +:1003900080919B2090919C20A0919D20B0919E20C7 +:1003A0008093A12186E08093052080910720909181 +:1003B00008200196B1F4809109208F3F91F080913F +:1003C0000620811106C0809106208150809306206E +:1003D00008958091140190911501809307209093C6 +:1003E00008200895009709F45EC00CF457C040E05F +:1003F00020916B0030E02093802130938121209167 +:100400008021309181213695322F222737952795EB +:10041000209380213093812150916A002091802186 +:1004200030918121250F311D20938021309381212E +:10043000000020918021309181212817390728F46C +:100440001092802110928121089520918021309175 +:100450008121280F391F2115304238F08FEF9FE19D +:100460008093802190938121089520918021309163 +:100470008121442329F0A901481B590BCA0102C05C +:10048000820F931F809380219093812180918021FE +:10049000909181218F7780936A000895919581953D +:1004A000910941E0A5CF0895CF93DF93C091200A31 +:1004B000D091210A80910320909104209E01281B55 +:1004C000390B209383213093842180919A208111CC +:1004D0004BC080918321909184218E3C9F4FD4F416 +:1004E00080918321909184218B369F4F9CF0809145 +:1004F0000220882321F080910220815008C0809141 +:100500006A008093822181E080939A208CE080931E +:1005100002202AC08CE08093022080918321909158 +:1005200084218A369F4F1CF08FEF9FEF02C081E03D +:1005300090E080937D2190937E2180918321909102 +:10054000842120917D2130917E2160E370E00E9422 +:10055000CB15261B370B20937D2130937E21809174 +:100560007D2190917E213EDF80919A20813029F576 +:100570008091832190918421C39794F080910220EF +:10058000882331F08091022081508093022015C091 +:1005900080916A0080937F2183E080939A200DC030 +:1005A0008091832190918421873991051CF481E009 +:1005B00090E002C08FEF9FEF15DFC0930320D09330 +:1005C0000420DF91CF9108958617970779F0681777 +:1005D000790728F49C01261B370BB90109C086173F +:1005E000970718F4681B790B03C0089560E070E06A +:1005F000CB010895CF93DF9380910020909101204B +:10060000892B51F0809100209091012001978093D7 +:1006100000209093012043C080E490E0809300206C +:100620009093012080910720909108200196B9F1C4 +:10063000809114019091150120910920263018F421 +:1006400067E771E002C06EEE72E00E94B715EC0140 +:1006500080910720909108208C179D0758F4609195 +:10066000072070910820CE01AFDF029718F080ECD0 +:100670009DE511C08091072090910820C817D907E7 +:1006800070F46091072070910820CE019DDF0297E1 +:1006900030F08FEB9DE58093360A9093370ADF9117 +:1006A000CF910895AC01460F571F861B970B2091E1 +:1006B000200A3091210A24173507C8F72091200A13 +:1006C0003091210A8217930790F70895E0E8F6E049 +:1006D0008FE0808385E0848308951F93CF93DF9319 +:1006E000C0E4D0E0198180E4898340E250E068EB07 +:1006F0007BE280E290E00E945E0F1983DF91CF9150 +:100700001F9108951F93CF93DF93C0E4D0E0198128 +:1007100080E489838BEB95E20E94A60F81E00E9422 +:10072000B80F1983DF91CF911F91089508950F930A +:100730001F932091A4208EEE92E0289FA001299F74 +:10074000500D112444525A4D07E913E02EEE32E0C9 +:1007500060E081E80E9462131F910F9108951CBE12 +:10076000EEEFF0E40994B9DF8091B82B882369F0AB +:1007700080E2E8EBFBE2ABEBB5E201900D928A95EB +:10078000E1F71092BB25BEDFEADF87E08093A2008D +:10079000789473DDCBDFBAD749D16CD160E080E0CB +:1007A00003D1EFD08CE0E3D07ED522D63BD68EDFCE +:1007B00060E870E28EE891E20E94ED150000000012 +:1007C0000000000000000000000000000000000029 +:1007D000000000000000000080919F20882371F33A +:1007E000E091BA238E2F90E088309105A0F4FC01AF +:1007F000E250FF4F0C94DE1568D10DC0DAD10BC06A +:1008000068D209C0EED207C07BD305C002D403C0B2 +:1008100001D401C073D410929F20D0CF08950895C1 +:10082000E09109208E2F90E08830910590F4FC0132 +:10083000EA5FFE4F0C94DE15BBD10BC049D209C054 +:10084000CFD207C05CD305C0E3D303C056D401C0E8 +:10085000C9D48091140180939721809115018093D0 +:100860009821809124018093992180912501809382 +:100870009A218091200A8093A3218091210A80935C +:10088000A42180911401909115018634914080F04B +:100890008091140190911501893A914048F480911A +:1008A0001401909115018093D82B9093D92B0000BF +:1008B0008091A220882339F016DD1092A22081E0D9 +:1008C0008093A12008958091A120882341F08091F8 +:1008D0009A20833019F419DD8DDE01C0E5DD8091A9 +:1008E000A020882351F080911401909115018093EC +:1008F000D82B9093D92B1092A0209091A42081E026 +:10090000911180E08093A42008950F931F9381E0BC +:100910008093A7208093A22007E913E02DE730E021 +:100920004CED55E260E081E80E94621381E01F9186 +:100930000F9108951092A720089581E0089581E015 +:10094000089510922002982F9C7193689093200232 +:1009500087FF03C090E182E002C090E080E0892B35 +:100960008093210210922202109226020895E0E064 +:10097000F2E010AA836880AB80E181AB12AA16AACC +:100980000895E0E0F2E010A683E880A78FE281A757 +:1009900012A616A60895AAECB1E092E09C93E82F67 +:1009A000F0E084911C920895909171009D7F909346 +:1009B000710010920002623011F09CE101C09EE1D2 +:1009C0009093010290E490930202811102C080E4AE +:1009D00001C080EC80930302613011F084E001C01B +:1009E00083E08093040280E2D6DF80930C0281E2F0 +:1009F000D2DF80930D02109218021092190281E04A +:100A000080930002BECF1F920F920FB60F92112457 +:100A10008F93000000000000000081E0809323021B +:100A20008F910F900FBE0F901F901895CF93DF936B +:100A3000E0E7F0E082818B7F8283C0E2D3E08DE04B +:100A4000888380E4898389E08A8383E3A4DF8887BD +:100A500082E3A1DF898787E39EDF8A8786E39BDFC6 +:100A60008B87E0E2F6E08081836080831482DF91EF +:100A7000CF910895E0E7F0E080818E7F808380E869 +:100A8000809300010895E0E0F1E0108A80E4808B1B +:100A900010A280A310AA80ABE0E4F1E01082808372 +:100AA0001092A6201092A5201092A42010928C21C2 +:100AB00010928D2110928A2110928B21089580939B +:100AC000BA2381E080939F200895CF93DF93109203 +:100AD0000920D9DFC0E0D1E01EAA94E298AB19AAA0 +:100AE00049E54AAB32E03BAB60910B2070910C20A2 +:100AF0006CAB7DAB6BEB73E268AF79AF1AAE8BE397 +:100B00008CAF83E080933D0110923E0128A92068BC +:100B100028AB10924601E0E4F1E09083109241018D +:100B2000409342018093430140910D2050910E204B +:100B300040934401509345014AEA51E240934801F1 +:100B40005093490110924A0129E320934C0180936C +:100B50004D0110924E01208120682083188A20E4E4 +:100B6000288B24E0288B898B85E98A8B80E18B8B0D +:100B700047E751E04C8B5D8B988F398F1A8E8CED47 +:100B800095E28C8F9D8F1E8E68EC70E084EF91E073 +:100B900089DD88EC90E0809307209093082081E025 +:100BA0008093062088898068888BDF91CF91089593 +:100BB0000895EF92FF921F93CF93DF9311E010936C +:100BC000092061DFC0E0D1E018AA80E488AB94E09E +:100BD00098AB19AA1AAA6BE46BAB1CAA1DAA1EAA91 +:100BE0002AE030E228AF39AF1AAEA0EAACAF58E045 +:100BF00050933D0110923E0188A9806A88ABE0EADB +:100C0000F8E085E58083808310924601E0E4F1E01E +:100C100044E240831092410189E58093420132E031 +:100C200030934301E0900B20F0900C20E0924401BF +:100C3000F09245018BEBE82E83E2F82EE09248011A +:100C4000F092490110924A018BE380934C0183E0BA +:100C500080934D0110924E0120812068208398A33B +:100C600089A325E92AA36BA367E771E06CA37DA3A1 +:100C7000A8A759A71AA6EAECF8E2ECA7FDA71EA6BA +:100C8000988B898B2A8B80E18B8B6C8B7D8B488F2B +:100C9000398F1A8E8CED95E28C8F9D8F1E8E68ECAD +:100CA00070E084EF91E0FEDC88EC90E08093072018 +:100CB000909308201093062088A1806888A38889D3 +:100CC0008068888BDF91CF911F91FF90EF900895FE +:100CD00008951F93CF93DF9312E010930920D3DE82 +:100CE000C0E0D1E01EAA94E298AB19AA39E53AAB6C +:100CF0001BAB40910B2050910C204CAB5DAB4BEBF0 +:100D000053E248AF59AF1AAE8BE38CAF83E08093C8 +:100D10003D0110923E0128A9206828AB109246019F +:100D2000E0E4F1E09083109241013093420180931E +:100D3000430120910D2030910E20209344013093E7 +:100D400045012AEA31E2209348013093490110928B +:100D50004A0129E320934C0180934D0110924E01EA +:100D6000208120682083188A20E4288B64E0688B27 +:100D7000898B55E95A8B40E14B8B27E731E02C8B6F +:100D80003D8B988F198F1A8EECEDF5E2EC8FFD8F6D +:100D90001E8E68A389A35AA34BA32CA33DA384E36F +:100DA00088A719A71AA68AEC98E28CA79DA71EA669 +:100DB00068EC70E084EF91E075DC88EC90E0809363 +:100DC00007209093082081E080930620888980681E +:100DD000888B88A1806888A3DF91CF911F910895A7 +:100DE00008951F93CF93DF9313E0109309204BDEF8 +:100DF000C0E0D1E010924601E0E4F1E024E220837B +:100E00001092410199E59093420182E08093430161 +:100E100040910B2050910C20409344015093450188 +:100E20004BEB53E2409348015093490110924A0121 +:100E30008BE380934C0110934D0110924E01808101 +:100E4000806880831EAA28AB19AA9AAB1BAB80913D +:100E50000D2090910E208CAB9DAB8AEA91E288AF79 +:100E600099AF1AAE89E38CAF10933D0110923E0109 +:100E700088A9806888AB18A250E458A344E048A32E +:100E800019A21AA23BE43BA31CA21DA21EA28AE047 +:100E900090E288A799A71AA620EA2CA798E09DA718 +:100EA0001EA688A1806A88A385E58093A008188A79 +:100EB000588B488B198B85E98A8B3B8B47E751E030 +:100EC0004C8B5D8B288F998F1A8E8CED95E28C8FD1 +:100ED0009D8F1E8E68EC70E084EF91E0E3DB88EC80 +:100EE00090E0809307209093082081E08093062073 +:100EF00088898068888BDF91CF911F91089508952C +:100F00001F93CF93DF9314E010930920BCDDC0E062 +:100F1000D1E018AA80E488AB18AB19AA1AAA3BE45E +:100F20003BAB1CAA1DAA1EAA8AE090E288AF99AF2B +:100F30001AAE50EA5CAF88E080933D0110923E010A +:100F400098A9906A98AB95E59093A00810924601F5 +:100F5000E0E4F1E094E290831092410199E59093EE +:100F6000420192E09093430160910B2070910C201C +:100F700060934401709345016BEB73E26093480109 +:100F80007093490110924A019BE390934C0193E0C6 +:100F900090934D0110924E01208120682083188B80 +:100FA000998B45E94A8B3B8B27E731E02C8B3D8BB6 +:100FB000588F898F1A8E6CED75E26C8F7D8F1E8E27 +:100FC00018A399A34AA39AE49BA32CA33DA393EC53 +:100FD00098A789A71AA68AEC98E28CA79DA71EA6B7 +:100FE00068EC70E084EF91E05DDB88EC90E080934A +:100FF00007209093082081E08093062088898068EC +:10100000888B88A1806888A3DF91CF911F91089574 +:101010000895FFCFCF93DF9386E08093092033DDDF +:10102000C0E0D1E01EAA84E288AB19AA39E53AAB48 +:1010300093E09BAB40910D2050910E204CAB5DABEB +:101040004AEA51E248AF59AF1AAE29E32CAF909368 +:101050003D0110923E0128A9206828AB109246015C +:10106000E0E4F1E08083109241013093420122E0FC +:101070002093430140910B2050910C204093440158 +:10108000509345014BEB53E2409348015093490183 +:1010900010924A013BE330934C0190934D01109222 +:1010A0004E01908190689083188A90E4988B888B89 +:1010B000198A95E99A8B90E19B8B4CED55E04C8B0E +:1010C0005D8B888F298F1A8E8CED95E28C8F9D8F8A +:1010D0001E8E68EC70E084EF91E0E4DA80E991E044 +:1010E000809307209093082081E0809306208889D0 +:1010F0008068888BDF91CF9108950895CF93DF9317 +:1011000087E080930920BFDCC0E0D1E01EAA84E222 +:1011100088AB19AA39E53AAB93E09BAB40910D201F +:1011200050910E204CAB5DAB4AEA51E248AF59AF4B +:101130001AAE29E32CAF90933D0110923E0128A9ED +:10114000206828AB10924601E0E4F1E08083109221 +:1011500041013093420122E02093430140910B2052 +:1011600050910C2040934401509345014BEB53E2C6 +:10117000409348015093490110924A013BE3309358 +:101180004C0190934D0110924E0190819068908394 +:10119000188A90E4988B95E2988B198A95E99A8B36 +:1011A00090E19B8B4CED55E04C8B5D8B888F298FAC +:1011B0001A8E8CED95E28C8F9D8F1E8E68EC70E000 +:1011C00084EF91E06FDA80E991E0809307209093BB +:1011D000082081E08093062088898068888BDF91D1 +:1011E000CF91089508951F920F920FB60F92112478 +:1011F0008F939F9381E0809303011092100184E00C +:101200008093100187E791E080931401909315017A +:101210008091A420811103C08EEE92E002C080E094 +:1012200090E084529A4D80931C0190931D0180910F +:1012300010018068809310019F918F910F900FBED5 +:101240000F901F9018951F920F920FB60F921124B6 +:101250008F939F9382E0809303011092200184E09A +:101260008093200187E791E08093240190932501EA +:101270008091A420811103C085E694E002C087E735 +:1012800091E084529A4D80932C0190932D0180918E +:1012900020018068809320019F918F910F900FBE55 +:1012A0000F901F901895E0E7F0E083818C7F838397 +:1012B00084818C7F848380818D7F8083E0E8F1E06E +:1012C00080EC8283128688EC81831186A0E0B8E0EE +:1012D00034E03C9323E011962C93119714961C92C2 +:1012E000149785ED91E096968D939C93979716961B +:1012F0001C921697E0E4F8E030832183148286A3E1 +:1013000097A31682E0E6F6E0808180618083E0E4C6 +:10131000F9E083E18183148282E08683A6A3B7A3E8 +:1013200010A611A681E0808308951F920F920FB638 +:101330000F9211242F933F934F935F938F939F931B +:10134000CF93DF931F92CDB7DEB78FEF80934C0919 +:1013500080910920873031F480912C02898390910B +:101360002D0202C090912C028091A320891B209114 +:1013700068093091690982308CF02A3F374070F457 +:10138000209168093091690989301CF481E090E06E +:1013900002C086E090E0820F931F18C02091680978 +:1013A000309169098F3FB4F42730310598F02091CE +:1013B000680930916909883F1CF081E090E002C023 +:1013C00086E090E0A901481B590BCA018093780977 +:1013D000909379090F90DF91CF919F918F915F91B9 +:1013E0004F913F912F910F900FBE0F901F90189526 +:1013F000E0E7F0E083818F7E8383E0E4F6E08081A4 +:101400008A6A80838FEF848388E5828BE0EAF8E044 +:1014100080E3838384EC858387E08683178288E179 +:1014200084830895E0E7F0E08381877F8383E0ECA5 +:10143000F8E080E48083118288E580935506089562 +:101440001F920F920FB60F92112400000F900FBE43 +:101450000F901F9018951F920F920FB60F921124A4 +:101460008F93EF93FF93E0EAF8E080818083FF9110 +:10147000EF918F910F900FBE0F901F9018959FB70F +:10148000F894A0E5B0E016968C911697897F169691 +:101490008C931697E0E6F0E080E885838BEB8683FB +:1014A00016968C911697846016968C938081816035 +:1014B00080839FBF08959FB7F894E82FF0E0E0592C +:1014C000FF4F60958081682360839FBF0895CF930D +:1014D000863011F0C0E001C0C8E18091510081FD6B +:1014E0000DC09FB7F89480915000826080935000A7 +:1014F0009FBF8091510081FFFCCFC1DF6C2F6360E3 +:1015000084E490E0C0D460E480E0CF91D4CF8091B7 +:10151000A82008958091A820813009F40BCA08956D +:10152000F0D0FC0183818093A820811101C0EDC916 +:1015300081E008959091AA23892F807697FF07C0B4 +:10154000803491F48091AB2381110EC0F8C98034AE +:1015500059F48091AB23811107C08091B023909101 +:10156000B123892B09F0E9C980E008958091AC236B +:101570008F770C94E4129091B020911102C080E01A +:101580000895E091AD20F091AE200190F081E02D22 +:1015900094818917A0F7E093AB20F093AC202281CF +:1015A00033812E0F3F1FE217F30798F49181943097 +:1015B00061F49281891309C09381691306C0E09395 +:1015C000AB20F093AC2081E008959081E90FF11DEC +:1015D000EACFE093AB20F093AC20D1CFE091AD20E7 +:1015E000F091AE200190F081E02D228133812E0F09 +:1015F0003F1FFC014081E40FF11DE217F30748F49F +:101600008181843031F0853039F08081E80FF11D1F +:10161000F4CF80E090E00895CF0108951F93CF9319 +:10162000DF93182FA8DF882339F1C091AB20D09128 +:10163000AC20CE01D3DFEC01892B41F04C815D81E0 +:101640006B818A81CED78111F4CF16C0E091AD2095 +:10165000F091AE2092818381E92FF82FE10FF11DE7 +:10166000E10FF11D0190F081E02D0190F081E02D5E +:10167000DF91CF911F91099480E0DF91CF911F916D +:101680000895EF92FF921F93CF93DF93C82F60E0EE +:1016900072DF811102C010E02DC0E091AD20F09109 +:1016A000AE2092818381E92FF82FEC0FF11DEC0F12 +:1016B000F11DE080F180D7011696ED91FC9117970E +:1016C0000995682F8C2F57DF182F882321F3C0919D +:1016D000AB20D091AC20CE0181DFEC01892B21F031 +:1016E0008A810E941E14F7CFD7011296ED91FC91CA +:1016F00013970995812FDF91CF911F91FF90EF9064 +:1017000008958091AB209091AC200895FFC6CF93AF +:101710008091B020811108C01092B0201092B420A6 +:101720001092B520CF910895C0E0E091AD20F091E6 +:10173000AE200190F081E02D8481C81768F78C2FCE +:10174000A0DFCF5FF2CFCF938091B0208823F1F05C +:10175000C0E0E091AD20F091AE20A081B18114965F +:101760008C91C81798F492818381E92FF82FEC0FA0 +:10177000F11DEC0FF11D0190F081E02D0084F18549 +:10178000E02D309709F00995CF5FE3CFCF91089511 +:10179000EF92FF920F931F93CF93DF931F92CDB7DA +:1017A000DEB71092B4231092B5231092B623109294 +:1017B000B7231092B8231092B9238091AA2387FFF0 +:1017C00007C02091B0233091B123232B09F452C3D9 +:1017D000982F9076903409F00FC1E091AB238E2FB3 +:1017E00090E0FC01E05AF109EA30F10508F0D1C2BD +:1017F000E25FFE4F0C94DE1581E08093A020809183 +:1018000007209091082080939B2180910720909140 +:10181000082090939C218091822180939D2180912A +:101820007F2180939E2180916A0080939F218091E7 +:101830006B008093A0216091B0237091B1238EE85A +:1018400091E2D8C0109200088091AC239091AD2312 +:1018500080933608909337088091AE238F708093E1 +:1018600000086091B0237091B1238AEA91E2B2D668 +:1018700020910D2030910E208091B0239091B123C2 +:101880002817390709F4F4C280930D2090930E2095 +:1018900026C0109240088091AC239091AD23809394 +:1018A0007608909377088091AE238F7080934008DC +:1018B0006091B0237091B1238BEB93E28BD6209192 +:1018C0000B2030910C208091B0239091B1232817E8 +:1018D000390709F4CDC280930B2090930C2080919E +:1018E000092055C010926809109269098091AC23B3 +:1018F0008093A320BDC28091AC2380932406B8C2FC +:10190000E091AC23F091AD23E830F10508F041C23D +:10191000E85EFE4F0C94DE1560E080E045D88091D3 +:10192000AE230FD880E033C060E080E03DD88091E6 +:10193000AE2307D881E02BC061E081E035D88091EB +:10194000AE230E94A1048091AF2311D882E01FC072 +:1019500083E01DC084E01BC060E080E025D880915A +:10196000AE230E94A10485E012C061E080E01CD893 +:101970008091AE230E94A10486E009C062E080E06D +:1019800013D88091AE2380680E94A10487E097D885 +:101990006FC28091AC23809384066AC28091AC238D +:1019A0009091AD23892B91F00E946D0380E2E8EBCA +:1019B000FBE2ABEBB5E201900D928A95E1F781E095 +:1019C0008093BB250E9482030E946D03E9E7F0E04B +:1019D00091E088EDF89484BF90836091B02370917A +:1019E000B1238AE890E206C06091B0237091B123E0 +:1019F00089E890E2EFD53CC29111CBC187FFFCC0D2 +:101A00002091B0233091B1232115310509F4C1C1D2 +:101A10008F7109F09EC08091AB23863071F08830C1 +:101A200009F48EC08111B5C12230310509F0B1C170 +:101A300062E070E084EB90E2DDCF8091AC23909186 +:101A4000AD23292F332722303105A1F064F4213052 +:101A5000310509F09EC18091192090911A20DC0176 +:101A60006C9170E05BC02330310589F12F30310576 +:101A700009F18FC1E0911920F0911A202189821774 +:101A800008F087C19927880F991F880F991FE09147 +:101A90001B20F0911C20E80FF91F80819181FC012F +:101AA0006281738197D5E091B223F091B32382E0F4 +:101AB000818335C080911D2090911E20009709F4EC +:101AC00068C1DC0112966D917C91139727C099270C +:101AD0008130910569F038F0029709F05AC168E049 +:101AE0008AE690E208C064E070E08CE790E216C0FD +:101AF00067E083E790E2282FAAE5B0E2FC0181913C +:101B000090E08D939D938E2F821B8617C0F3660FF6 +:101B10006E5F6093582070E088E590E25BD580911D +:101B2000B0239091B1232091B4233091B523821733 +:101B3000930708F09DC18093B4239093B52398C177 +:101B40002130310509F025C161E070E080EB90E2C1 +:101B500051CF8130C9F58091AB238A3009F019C18A +:101B60002130310509F015C18091B020882309F496 +:101B700010C1E090AE23F090AF230091AD20109102 +:101B8000AE20D801ED91FC918481E81608F001C1E6 +:101B900060E08E2DF0DC882309F4FBC0FF24EE0CFE +:101BA000FF1CF801828193818E0D9F1DDC01ED9158 +:101BB000FC910680F781E02D09958093B22061E0C9 +:101BC00070E082EB90E216CF823009F0E2C08091A3 +:101BD000AB238111DEC02230310509F0DAC08091DB +:101BE000AE2350D590E08093A9209093AA2062E084 +:101BF00070E089EA90E2FECE8F7109F07DC080919D +:101C0000AB23833009F4C5C018F48130A1F0C1C002 +:101C1000853019F0893039F1BCC08091B0239091A2 +:101C2000B123892B09F0B5C086EB9AE08093B623E7 +:101C30009093B7231DC18091B0239091B123892B3C +:101C400009F0A7C08091AC239091AD23019709F0D2 +:101C5000A0C08091B4209091B5208D7F8093B42056 +:101C60009093B52005C18091B0239091B123892B29 +:101C700009F08FC0ACD4882309F48BC02091AC2329 +:101C80003091AD233327E0911920F0911A208189FA +:101C900090E08217930708F47CC039DD8091AC2373 +:101CA0009091AD238093B020882309F4E1C0992757 +:101CB0008150904C880F991F880F991F20911B20ED +:101CC00030911C20820F931F8093AD209093AE2003 +:101CD00010E0E091AD20F091AE200190F081E02D78 +:101CE0008481181708F0C4C060E0812F97DC882336 +:101CF00009F44FC01F5FEDCF8130F1F48091AB2329 +:101D00008B3009F046C08091B0239091B123892B8C +:101D100009F03FC08091B020882309F43AC01091A7 +:101D2000AE236091AC23812F6983ABDC698188236A +:101D300081F1812F73DC2BC0823059F58091AB2368 +:101D4000813019F0833089F024C08091B0239091C4 +:101D5000B123892BF1F48091AC239091AD23892B91 +:101D6000C1F48091AE2395D412C08091B02390919C +:101D7000B123892B71F48091AC239091AD23892BF1 +:101D800041F48091AE232AD58091AE2360D5811194 +:101D90006FC08091AA238F718130B9F58091B020F6 +:101DA000882399F1E090AE23F090AF230091AD200D +:101DB0001091AE20D801ED91FC918481E81628F5B0 +:101DC00060E08E2DD8DB882301F1F701FF27EE0FAD +:101DD000FF1FD80112968D919C911397E80FF91F60 +:101DE00000811181D8011696ED91FC911797099504 +:101DF000682F8E2DC0DB882341F0D8011496ED9119 +:101E0000FC9115970995811133C08091AA238F7198 +:101E1000823081F58091B020882361F1F12CE0912E +:101E2000AD20F091AE20A081B18114968C91F8166E +:101E300008F592818381E92FF82FEF0DF11DEF0D49 +:101E4000F11D00811181D8011696ED91FC91179733 +:101E50000995682F8F2D8FDB882361F0D8011496A8 +:101E6000ED91FC9115970995811102C0F394D7CF9C +:101E700081E001C080E00F90DF91CF911F910F9121 +:101E8000FF90EF9008951BBEFC0128ED24BF6083F6 +:101E900008958091CF0187FDFCCF08951F93CF93C4 +:101EA000DF93C0ECD1E01A858A8761E08BEC91E08A +:101EB000EADF1A87DF91CF911F910895CF92DF92C9 +:101EC000EF92FF920F931F93CF93DF9300D0CDB784 +:101ED000DEB78C017B0149835A83DBDF8CECC82E93 +:101EE000DD24D394F601908198609083B801705FEF +:101EF00049815A81C70168D6F6018081877F808336 +:101F00000F900F90DF91CF911F910F91FF90EF9065 +:101F1000DF90CF900895CF93DF9300D0CDB7DEB799 +:101F20006A838983B6DFACECB1E09C9198609C93A6 +:101F30008981E82FF0E0F05F6A8160838C91877F70 +:101F40008C930F900F90DF91CF9108950F931F9373 +:101F5000CF938C019EDFC0E0F80161918F018C2F3F +:101F6000DADFCF5FC032C1F7CF911F910F91089593 +:101F7000CF93DF931F92CDB7DEB789838ADF898144 +:101F800020E2829FC0011124E0ECF1E012829183F3 +:101F9000808385E30F90DF91CF9180CF4091CA017C +:101FA000E62FF72F8093CA0184914093CA010895C8 +:101FB000E82FF0E0E652F44D80818F3F09F4FFCF27 +:101FC0009FB7F89480818F5F80839FBF0895E82F2B +:101FD000F0E0E652F44D8081811101C0FFCF9FB740 +:101FE000F8948081815080839FBF0895CF93C82F3C +:101FF00080917C21C11105C0882339F081E0E7DFA1 +:1020000004C0811102C081E0D3DFC0937C21CF9155 +:102010000895282F2F70082E000C990B392F331F8D +:102020003327331F832F90E0820F911D820F911D64 +:1020300023E0880F991F2A95E1F7885A9E4D08954D +:102040000F93E8ECF4E080818F7D808380818F7D29 +:102050008083E0E6F1E202E00593109262211092A3 +:10206000632100E2069300E40693E8E5F1E200E272 +:10207000069300E40693EAEAF3E2148615861686D0 +:1020800017861286138610924D210F9108950F9393 +:1020900085E080934D21E1E6F1E204E00593E9E576 +:1020A000F1E204E005930F9108950F9383E080938C +:1020B0004D211092622110926321E0E6F1E202E0EC +:1020C00006930F910895E091B623F091B7233097CE +:1020D00009F009940895282F2F70082E000C990BF1 +:1020E000392F331F3327331F832F90E0820F911D29 +:1020F000820F911D029749E0489F9001499F300D42 +:102100001124C90189509F4D08958F929F92AF92DB +:10211000BF92DF92EF92FF920F931F93CF93DF93C3 +:10212000D82ED9DFEC018D2D74DF7C01DC011196F6 +:10213000EC91E770E150E73040F4F0E0EE0FFF1F64 +:10214000E457FF4D0081118102C008E010E0ED81ED +:10215000FE812B813C814881D701D7FE48C016966D +:102160008D919C9117978E0F9F1F8D839E83821751 +:10217000930761F1281B390B2115B4E03B0738F0B8 +:102180002FEF33E0C901B801F2D4281B390B41FF0E +:102190000AC0C901B801EBD4AC0191E0452B09F0AC +:1021A00090E0892F01C080E0988180FB91F99883AD +:1021B000F701168217822283338329813A818D8128 +:1021C0009E81820F931F848395830EC041FF71C04F +:1021D0004D7F4883D70116961D921C921797129631 +:1021E0001D921C921397F70102E006937BC0129692 +:1021F000AD90BC90139742FF10C089809A80C901AE +:10220000B801B5D4B0E4DB9EB001112469587F4D0C +:10221000AC01C4018E0F9F1FD7D48D819E818A0D82 +:102220009B1D8D839E832B813C812817390710F4D9 +:102230002D833E83F70186819781A816B906C9F5DB +:102240008D819E8182179307A1F1281B390B2115DF +:10225000F4E03F0710F02FEF33E0C901B80187D455 +:10226000281B390BD70112961D921C921397201729 +:10227000310778F4888184608883B0E4DB9EC001F4 +:10228000112489589F4DF701848395830683178312 +:10229000AACF49815A818D819E81840F951FD701D4 +:1022A00014968D939C93159716962D933C931797A0 +:1022B0009ACF888180FF16C08E7F8883EF81F88552 +:1022C000309781F06D817E814D2D80E0DF91CF913F +:1022D0001F910F91FF90EF90DF90BF90AF909F9074 +:1022E0008F900994DF91CF911F910F91FF90EF9004 +:1022F000DF90BF90AF909F908F9008950F93CF93F2 +:10230000DF9380914D21833029F4DDDEDF91CF9181 +:102310000F9196CE2091492130914A21C091B4234A +:10232000D091B523C21BD30B61F580914B219091C5 +:102330004C21820F931F80934B2190934C2120912D +:10234000B0233091B1232817390721F08091B620AE +:10235000882331F084E080934D21E8E5F1E236C036 +:10236000E091B823F091B923309799F0099588232B +:1023700081F01092492110924A21C091B423D0914A +:10238000B523C034D10528F01092B620C0E4D0E0C7 +:1023900003C081E08093B620C0936221D093632173 +:1023A0008091492190914A212091B2233091B32309 +:1023B000280F391F2093642130936521C80FD91F3E +:1023C000C0934921D0934A21E0E6F1E202E006936E +:1023D000DF91CF910F9108950F93CF93DF931F92C9 +:1023E000CDB7DEB78091CC0480FF65C021E020939B +:1023F000CC0488E591E2FC0100E80693E0E6F1E216 +:1024000000E806932093CA04FC0100E10693809142 +:102410004D21882329F08350823008F454DE10DEE9 +:1024200080915A2190915B21089709F046C088E07D +:10243000E9E0F1E2AAEAB3E201900D928A95E1F7B0 +:102440008091C80480628093C8048091C80480622F +:102450008093C8049DD9811102C019DE2EC09091CD +:10246000AA2397FF0EC010924B2110924C2110927C +:10247000492110924A2192E090934D2189833EDFB9 +:1024800008C02091B0233091B123232B21F48983FC +:102490000CDE898113C010924B2110924C211092B6 +:1024A000492110924A2191E090934D21E8E5F1E213 +:1024B00002E0069303C080E001C081E00F90DF914D +:1024C000CF910F910895CF93CFB7F89481E08EDD2F +:1024D000EAECF4E080E4808380E28083E1ECF4E0E5 +:1024E000808181608083A9ECB4E08C9182608C93C0 +:1024F000E8ECF4E08081806480838C9181608C932F +:10250000808180688083CFBFCF910895CF93109250 +:10251000600080E30E94670A8091C0048064809319 +:10252000C00481E080936000CFB7F89410925921E5 +:102530001092612110926921109271218091F720EF +:102540008E7F8093F720809100218E7F80930021E1 +:102550006AE170E082E022DD8F3F09F48FE1809331 +:10256000FA046BE170E082E019DD8F3F09F48FE13E +:102570008093FB048091C00481608093C0048091AB +:10258000C00480688093C0048091C00480618093FF +:10259000C00488E591E28093C6049093C7048091BB +:1025A000C00480628093C0048FEF8093C504809143 +:1025B000C80482608093C80410927C2185E0F8DC16 +:1025C00082DFCFBFCF9108958093C3040895809197 +:1025D000C3040895EAEAF3E28087918762877387EC +:1025E00008950F931F93CF93DF931F92CDB7DEB75C +:1025F0008A0169830EDDFC018181807C6981811102 +:102600003AC06370613019F020F080E803C080ECBC +:1026100001C080E400381105E9F058F400321105DA +:10262000A9F000341105A1F000311105C9F491E0C1 +:1026300018C0011592E0190779F00F3F93E01907D0 +:1026400069F00115114061F495E00BC092E009C0FA +:1026500093E007C094E005C096E003C097E001C096 +:1026600090E0118226E02083982B91838181806203 +:10267000818381E001C080E00F90DF91CF911F91B5 +:102680000F910895C6DCFC01818182FB882780F9C7 +:102690000895CF93C82FBDDCFC01818182FF0FC05C +:1026A00091819B7F91838C2F16DDFC01908190FF9F +:1026B00006C09E7F90830780F085E02D099581E01C +:1026C000CF9108958F929F92AF92BF92DF92EF9237 +:1026D000FF920F931F93CF93DF931F92CDB7DEB777 +:1026E000D82E5A0179016983F6DC4C018D2D91DCDD +:1026F0009C01DC0111968C911197807C6981882363 +:1027000009F45EC011968C911197807C803C21F079 +:1027100011968C9182FD54C09FB7F894F40180818A +:1027200080FF02C09FBF4CC0816080839FBFF401C7 +:10273000A182B282E382F482158216820783108717 +:1027400091E0611104C0E114F10409F090E0D401BA +:102750008C9190FB81F98B7F8C93D7FE04C0F9019B +:102760001682178229C0D90111968C911197807C0D +:10277000803CC9F41196EC91E770E150E73040F4E9 +:10278000F0E0EE0FFF1FE457FF4D6081718102C042 +:1027900068E070E0C701EBD1892B29F0F40180815A +:1027A0008E7F80830DC0D90112961D921C921397C3 +:1027B00016961D921C9217978D2DA7DC81E001C003 +:1027C00080E00F90DF91CF911F910F91FF90EF90DC +:1027D000DF90BF90AF909F908F900895EF92FF92FF +:1027E0000F93CF93C82F15DC7C018C2F74DCDC0198 +:1027F000F70102E005939C9190FF1BC09E7F9C9384 +:102800001796ED91FC911897309799F0D701C7FF73 +:1028100005C016966D917C91179704C012966D9124 +:102820007C9113974C2F81E0CF910F91FF90EF9007 +:102830000994CF910F91FF90EF900895CF93C82FF7 +:10284000CDDF8C2FE6DBFC011182CF9108950F9331 +:10285000CF93C82FDEDBFC0191819460918301E06E +:1028600006938C2FBBDF81E0CF910F9108951F92CB +:102870000F920FB60F9211240F932F933F934F9304 +:102880005F936F937F938F939F93AF93BF93EF93D8 +:10289000FF938091CB0487FF08C080E88093CA042F +:1028A0000E94A30B0E9410047EC08091CB0482FF83 +:1028B00018C084E08093CA048091602186FF73C0B1 +:1028C0008091CC0481FD6FC087DD81116CC0809147 +:1028D0004D21813011F4E9DB66C0843009F063C01A +:1028E00021C08091CB0481FF26C082E08093CA047E +:1028F0008091582186FF57C08091CC0481FD53C040 +:102900006BDD811150C080914D21823041F484E013 +:1029100080934D21E8E5F1E202E0069344C0833064 +:1029200009F041C0E1E6F1E204E00593E9E5F1E2F6 +:1029300004E0059338C08091CB0484FF1DC080E182 +:102940008093CA040E94870B1092C30410925921ED +:1029500096E09093582183E480935921109261214D +:10296000909360218093612189E091E280935C21C2 +:1029700090935D2165DB17C08091CB0486FF08C072 +:1029800080E48093CA0480E031DB0E940E040BC017 +:102990008091CB0485FF07C080E28093CA0481E068 +:1029A00025DB0E940F04FF91EF91BF91AF919F91A2 +:1029B0008F917F916F915F914F913F912F910F91E7 +:1029C0000F900FBE0F901F9018951F920F920FB689 +:1029D0000F9211240F931F932F933F934F935F9365 +:1029E0006F937F938F939F93AF93BF93CF93DF9317 +:1029F000EF93FF938091CC0481FF1AC082E0809313 +:102A0000CC048091C5048195880FE8E5F1E2E81BCC +:102A1000F109208131812855314283E0369527958F +:102A20008A95E1F7822F869520FD06C0C0E005C09B +:102A3000D3DC882319F386C0C0E8C80F8C2FE9DAED +:102A4000FC01208125FF7EC000E20693C11174C005 +:102A500080914D21843019F436DBF2DA73C0009195 +:102A60005A2110915B218091B4239091B523C0919C +:102A70004921D0914A219E01200F311F82179307CF +:102A800018F48C010C1B1D0B8091B2239091B32381 +:102A9000A80169E071E28C0F9D1F96D0C00FD11F75 +:102AA000C0934921D0934A210034110569F48091E3 +:102AB0004B2190914C218C0F9D1F2091B023309180 +:102AC000B1238217930788F0C093B423D093B52322 +:102AD000E091B823F091B923309729F0099581113D +:102AE00002C0D5DA2FC0E1DA2DC08091B4239091D5 +:102AF000B5238C179D07D9F4E091B823F091B92341 +:102B0000309779F30995882361F320914B21309117 +:102B10004C218091492190914A21820F931F8093EB +:102B20004B2190934C211092492110924A21E8E5C3 +:102B3000F1E202E0069306C0C03811F4DFDB02C008 +:102B40008C2FE3DAFF91EF91DF91CF91BF91AF919D +:102B50009F918F917F916F915F914F913F912F91B5 +:102B60001F910F910F900FBE0F901F901895AA1BE9 +:102B7000BB1B51E107C0AA1FBB1FA617B70710F068 +:102B8000A61BB70B881F991F5A95A9F7809590959A +:102B9000BC01CD01089597FB072E16F4009406D0D2 +:102BA00077FD08D0E4DF07FC05D03EF490958195D1 +:102BB0009F4F0895709561957F4F0895EE0FFF1F09 +:102BC0000590F491E02D0994FB01DC0102C0019015 +:102BD0000D9241505040D8F70895FB01DC0101905F +:0C2BE0000D920020E1F70895F894FFCF5B +:102BEC0040000CE02E0AFFFFFFFF55800080009094 +:102BFC000A8A0A9A0A870A000044201F200000282B +:102C0C002023200F20000000090219000101008080 +:102C1C00FA0904000001FFFFFF0007058101FF0313 +:102C2C00010000001201000200000040EB0394BA06 +:102C3C00000201020001000000030000000000007F +:102C4C00000000000000000000004C616272616432 +:102C5C006F72004573706F54656B000004030904B8 +:102C6C006465627567313233000203001000200086 +:0A2C7C004000800000010002FF0389 +:00000001FF diff --git a/Desktop_Interface/build_android/package_source/assets/firmware/labrafirm_0003_02.hex.REMOVED.git-id b/Desktop_Interface/build_android/package_source/assets/firmware/labrafirm_0003_02.hex.REMOVED.git-id deleted file mode 100644 index 42c42b45..00000000 --- a/Desktop_Interface/build_android/package_source/assets/firmware/labrafirm_0003_02.hex.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -879125a9685d89a7f05bd38994079919338f49b6 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/assets/waveforms/DC.tlw b/Desktop_Interface/build_android/package_source/assets/waveforms/DC.tlw new file mode 100644 index 00000000..69f322d2 --- /dev/null +++ b/Desktop_Interface/build_android/package_source/assets/waveforms/DC.tlw @@ -0,0 +1,3 @@ +1 +1 +255 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/assets/waveforms/DC.tlw.REMOVED.git-id b/Desktop_Interface/build_android/package_source/assets/waveforms/DC.tlw.REMOVED.git-id deleted file mode 100644 index e3326948..00000000 --- a/Desktop_Interface/build_android/package_source/assets/waveforms/DC.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -69f322d2c3c6452561c8232b20784828fc438399 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/assets/waveforms/Sawtooth.tlw b/Desktop_Interface/build_android/package_source/assets/waveforms/Sawtooth.tlw new file mode 100644 index 00000000..e989a81b --- /dev/null +++ b/Desktop_Interface/build_android/package_source/assets/waveforms/Sawtooth.tlw @@ -0,0 +1,3 @@ +128 +3 +0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100 102 104 106 108 110 112 114 116 118 120 122 124 126 129 131 133 135 137 139 141 143 145 147 149 151 153 155 157 159 161 163 165 167 169 171 173 175 177 179 181 183 185 187 189 191 193 195 197 199 201 203 205 207 209 211 213 215 217 219 221 223 225 227 229 231 233 235 237 239 241 243 245 247 249 251 253 255 diff --git a/Desktop_Interface/build_android/package_source/assets/waveforms/Sawtooth.tlw.REMOVED.git-id b/Desktop_Interface/build_android/package_source/assets/waveforms/Sawtooth.tlw.REMOVED.git-id deleted file mode 100644 index 87e86502..00000000 --- a/Desktop_Interface/build_android/package_source/assets/waveforms/Sawtooth.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e989a81be4fb7a2d79495ce7e96db776b0366a94 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/assets/waveforms/Sin.tlw b/Desktop_Interface/build_android/package_source/assets/waveforms/Sin.tlw new file mode 100644 index 00000000..e376c353 --- /dev/null +++ b/Desktop_Interface/build_android/package_source/assets/waveforms/Sin.tlw @@ -0,0 +1,3 @@ +128 +4 +128 134 140 146 153 159 165 171 177 182 188 194 199 204 209 214 218 223 227 230 234 237 240 243 246 248 250 251 253 254 255 255 255 255 254 253 252 251 249 247 245 242 239 236 232 229 225 220 216 211 206 201 196 191 185 180 174 168 162 156 149 143 137 131 124 118 112 106 99 93 87 81 75 70 64 59 54 49 44 39 35 30 26 23 19 16 13 10 8 6 4 3 2 1 0 0 0 0 1 2 4 5 7 9 12 15 18 21 25 28 32 37 41 46 51 56 61 67 73 78 84 90 96 102 109 115 121 127 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/assets/waveforms/Sin.tlw.REMOVED.git-id b/Desktop_Interface/build_android/package_source/assets/waveforms/Sin.tlw.REMOVED.git-id deleted file mode 100644 index ceeb1ad1..00000000 --- a/Desktop_Interface/build_android/package_source/assets/waveforms/Sin.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e376c35388394ccfa4a86cb5bc6f9961e00fef20 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/assets/waveforms/Square.tlw b/Desktop_Interface/build_android/package_source/assets/waveforms/Square.tlw new file mode 100644 index 00000000..7bdd30be --- /dev/null +++ b/Desktop_Interface/build_android/package_source/assets/waveforms/Square.tlw @@ -0,0 +1,3 @@ +128 +5 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 diff --git a/Desktop_Interface/build_android/package_source/assets/waveforms/Square.tlw.REMOVED.git-id b/Desktop_Interface/build_android/package_source/assets/waveforms/Square.tlw.REMOVED.git-id deleted file mode 100644 index 25d85bc6..00000000 --- a/Desktop_Interface/build_android/package_source/assets/waveforms/Square.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7bdd30bee84b15cc3fe88dd02751316a2016060c \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/assets/waveforms/Triangle.tlw b/Desktop_Interface/build_android/package_source/assets/waveforms/Triangle.tlw new file mode 100644 index 00000000..420ac92c --- /dev/null +++ b/Desktop_Interface/build_android/package_source/assets/waveforms/Triangle.tlw @@ -0,0 +1,3 @@ +128 +4 +0 4 8 12 16 20 24 28 32 36 40 45 49 53 57 61 65 69 73 77 81 85 89 93 97 101 105 109 113 117 121 125 130 134 138 142 146 150 154 158 162 166 170 174 178 182 186 190 194 198 202 206 210 215 219 223 227 231 235 239 243 247 251 255 255 251 247 243 239 235 231 227 223 219 215 210 206 202 198 194 190 186 182 178 174 170 166 162 158 154 150 146 142 138 134 130 125 121 117 113 109 105 101 97 93 89 85 81 77 73 69 65 61 57 53 49 45 40 36 32 28 24 20 16 12 8 4 0 diff --git a/Desktop_Interface/build_android/package_source/assets/waveforms/Triangle.tlw.REMOVED.git-id b/Desktop_Interface/build_android/package_source/assets/waveforms/Triangle.tlw.REMOVED.git-id deleted file mode 100644 index 768d2ac7..00000000 --- a/Desktop_Interface/build_android/package_source/assets/waveforms/Triangle.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -420ac92c2c292688434b3987874cc98a9180e336 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/assets/waveforms/_list.wfl b/Desktop_Interface/build_android/package_source/assets/waveforms/_list.wfl new file mode 100644 index 00000000..d9c5ca2b --- /dev/null +++ b/Desktop_Interface/build_android/package_source/assets/waveforms/_list.wfl @@ -0,0 +1,5 @@ +Sin +Square +Triangle +Sawtooth +DC \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/assets/waveforms/_list.wfl.REMOVED.git-id b/Desktop_Interface/build_android/package_source/assets/waveforms/_list.wfl.REMOVED.git-id deleted file mode 100644 index 2b3bbd46..00000000 --- a/Desktop_Interface/build_android/package_source/assets/waveforms/_list.wfl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d9c5ca2b7e1352538debad0a17885fc4355864fc \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/build.gradle b/Desktop_Interface/build_android/package_source/build.gradle new file mode 100644 index 00000000..ef416b0b --- /dev/null +++ b/Desktop_Interface/build_android/package_source/build.gradle @@ -0,0 +1,57 @@ +buildscript { + repositories { + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:1.1.0' + } +} + +allprojects { + repositories { + jcenter() + } +} + +apply plugin: 'com.android.application' + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) +} + +android { + /******************************************************* + * The following variables: + * - androidBuildToolsVersion, + * - androidCompileSdkVersion + * - qt5AndroidDir - holds the path to qt android files + * needed to build any Qt application + * on Android. + * + * are defined in gradle.properties file. This file is + * updated by QtCreator and androiddeployqt tools. + * Changing them manually might break the compilation! + *******************************************************/ + + compileSdkVersion androidCompileSdkVersion.toInteger() + + buildToolsVersion androidBuildToolsVersion + + sourceSets { + main { + manifest.srcFile 'AndroidManifest.xml' + java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java'] + aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl'] + res.srcDirs = [qt5AndroidDir + '/res', 'res'] + resources.srcDirs = ['src'] + renderscript.srcDirs = ['src'] + assets.srcDirs = ['assets'] + jniLibs.srcDirs = ['libs'] + } + } + + lintOptions { + abortOnError false + } +} diff --git a/Desktop_Interface/build_android/package_source/build.gradle.REMOVED.git-id b/Desktop_Interface/build_android/package_source/build.gradle.REMOVED.git-id deleted file mode 100644 index 6af3117a..00000000 --- a/Desktop_Interface/build_android/package_source/build.gradle.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ef416b0b88c1420d7bed0975240c678198aa73c2 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/gradle.properties b/Desktop_Interface/build_android/package_source/gradle.properties new file mode 100644 index 00000000..90794630 --- /dev/null +++ b/Desktop_Interface/build_android/package_source/gradle.properties @@ -0,0 +1,9 @@ +## This file is automatically generated by QtCreator. +# +# This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. + +androidBuildToolsVersion=25.0.2 +androidCompileSdkVersion=25 +buildDir=.build +qt5AndroidDir=C:/Qt/5.7/android_armv7/src/android/java diff --git a/Desktop_Interface/build_android/package_source/gradle.properties.REMOVED.git-id b/Desktop_Interface/build_android/package_source/gradle.properties.REMOVED.git-id deleted file mode 100644 index 9341d3fd..00000000 --- a/Desktop_Interface/build_android/package_source/gradle.properties.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9079463055754018dedc3bb1863c806547f78eac \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/gradle.properties~ b/Desktop_Interface/build_android/package_source/gradle.properties~ new file mode 100644 index 00000000..25d553c6 --- /dev/null +++ b/Desktop_Interface/build_android/package_source/gradle.properties~ @@ -0,0 +1,9 @@ +## This file is automatically generated by QtCreator. +# +# This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. + +androidBuildToolsVersion=25.0.2 +androidCompileSdkVersion=25 +buildDir=.build +qt5AndroidDir=C:/Qt/5.7/android_armv7/src/android/java diff --git a/Desktop_Interface/build_android/package_source/gradle.properties~.REMOVED.git-id b/Desktop_Interface/build_android/package_source/gradle.properties~.REMOVED.git-id deleted file mode 100644 index 361411c7..00000000 --- a/Desktop_Interface/build_android/package_source/gradle.properties~.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -25d553c6940dc201ee2ccf19bb861622dcc0c1c0 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.jar b/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..8c0fb64a Binary files /dev/null and b/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.jar differ diff --git a/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.jar.REMOVED.git-id b/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.jar.REMOVED.git-id deleted file mode 100644 index 382c51d0..00000000 --- a/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.jar.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8c0fb64a8698b08ecc4158d828ca593c4928e9dd \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.properties b/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..0c71e760 --- /dev/null +++ b/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Apr 10 15:27:10 PDT 2013 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.properties.REMOVED.git-id b/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.properties.REMOVED.git-id deleted file mode 100644 index 6ea1c853..00000000 --- a/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.properties.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0c71e760dc93830dd3411fe50d6f5c86bf0a8f4d \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.properties~ b/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.properties~ new file mode 100644 index 00000000..1e61d1fd --- /dev/null +++ b/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.properties~ @@ -0,0 +1,6 @@ +#Wed Apr 10 15:27:10 PDT 2013 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip diff --git a/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.properties~.REMOVED.git-id b/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.properties~.REMOVED.git-id deleted file mode 100644 index ba902396..00000000 --- a/Desktop_Interface/build_android/package_source/gradle/wrapper/gradle-wrapper.properties~.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1e61d1fd3a9bc5be8381127e4d6457cf08e7c473 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/gradlew b/Desktop_Interface/build_android/package_source/gradlew new file mode 100644 index 00000000..91a7e269 --- /dev/null +++ b/Desktop_Interface/build_android/package_source/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/Desktop_Interface/build_android/package_source/gradlew.REMOVED.git-id b/Desktop_Interface/build_android/package_source/gradlew.REMOVED.git-id deleted file mode 100644 index 48aa526b..00000000 --- a/Desktop_Interface/build_android/package_source/gradlew.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -91a7e269e19dfc62e27137a0b57ef3e430cee4fd \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/gradlew.bat b/Desktop_Interface/build_android/package_source/gradlew.bat new file mode 100644 index 00000000..8a0b282a --- /dev/null +++ b/Desktop_Interface/build_android/package_source/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/Desktop_Interface/build_android/package_source/gradlew.bat.REMOVED.git-id b/Desktop_Interface/build_android/package_source/gradlew.bat.REMOVED.git-id deleted file mode 100644 index c1b45adf..00000000 --- a/Desktop_Interface/build_android/package_source/gradlew.bat.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8a0b282aa6885fb573c106b3551f7275c5f17e8e \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/local.properties b/Desktop_Interface/build_android/package_source/local.properties new file mode 100644 index 00000000..342f07a9 --- /dev/null +++ b/Desktop_Interface/build_android/package_source/local.properties @@ -0,0 +1,6 @@ +## This file is automatically generated by QtCreator. +# +# This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. + +sdk.dir=I:/AndroidSDK/Android/sdk diff --git a/Desktop_Interface/build_android/package_source/local.properties.REMOVED.git-id b/Desktop_Interface/build_android/package_source/local.properties.REMOVED.git-id deleted file mode 100644 index 22db0449..00000000 --- a/Desktop_Interface/build_android/package_source/local.properties.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -342f07a9359a44af35a48bdb989ab7d640378c5e \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/local.properties~ b/Desktop_Interface/build_android/package_source/local.properties~ new file mode 100644 index 00000000..e2f2992a --- /dev/null +++ b/Desktop_Interface/build_android/package_source/local.properties~ @@ -0,0 +1,6 @@ +## This file is automatically generated by QtCreator. +# +# This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. + +sdk.dir=I:/AndroidSDK/Android/sdk diff --git a/Desktop_Interface/build_android/package_source/local.properties~.REMOVED.git-id b/Desktop_Interface/build_android/package_source/local.properties~.REMOVED.git-id deleted file mode 100644 index 319d6adb..00000000 --- a/Desktop_Interface/build_android/package_source/local.properties~.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e2f2992a9f349a07b1107859dfd3da90fcb2006e \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/res/Thumbs.db b/Desktop_Interface/build_android/package_source/res/Thumbs.db new file mode 100644 index 00000000..728c7c09 Binary files /dev/null and b/Desktop_Interface/build_android/package_source/res/Thumbs.db differ diff --git a/Desktop_Interface/build_android/package_source/res/Thumbs.db.REMOVED.git-id b/Desktop_Interface/build_android/package_source/res/Thumbs.db.REMOVED.git-id deleted file mode 100644 index cc424b7a..00000000 --- a/Desktop_Interface/build_android/package_source/res/Thumbs.db.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -728c7c09f66a1c1c54ac921895b5bda14a21d55b \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/res/mipmap-hdpi/ic_launcher.png b/Desktop_Interface/build_android/package_source/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..b77d2db1 Binary files /dev/null and b/Desktop_Interface/build_android/package_source/res/mipmap-hdpi/ic_launcher.png differ diff --git a/Desktop_Interface/build_android/package_source/res/mipmap-hdpi/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/build_android/package_source/res/mipmap-hdpi/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 7b387687..00000000 --- a/Desktop_Interface/build_android/package_source/res/mipmap-hdpi/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b77d2db15ac66d272f411892fef5dc78f1a334ec \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/res/mipmap-mdpi/Thumbs.db b/Desktop_Interface/build_android/package_source/res/mipmap-mdpi/Thumbs.db new file mode 100644 index 00000000..9ce77f46 Binary files /dev/null and b/Desktop_Interface/build_android/package_source/res/mipmap-mdpi/Thumbs.db differ diff --git a/Desktop_Interface/build_android/package_source/res/mipmap-mdpi/Thumbs.db.REMOVED.git-id b/Desktop_Interface/build_android/package_source/res/mipmap-mdpi/Thumbs.db.REMOVED.git-id deleted file mode 100644 index 770c6a93..00000000 --- a/Desktop_Interface/build_android/package_source/res/mipmap-mdpi/Thumbs.db.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9ce77f46f29740353189bbb1961626c4a537455a \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/res/mipmap-mdpi/ic_launcher.png b/Desktop_Interface/build_android/package_source/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..85c704a8 Binary files /dev/null and b/Desktop_Interface/build_android/package_source/res/mipmap-mdpi/ic_launcher.png differ diff --git a/Desktop_Interface/build_android/package_source/res/mipmap-mdpi/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/build_android/package_source/res/mipmap-mdpi/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 45e1c039..00000000 --- a/Desktop_Interface/build_android/package_source/res/mipmap-mdpi/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -85c704a8fa459a34d512155668563e8eb7986ea8 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/res/mipmap-xhdpi/ic_launcher.png b/Desktop_Interface/build_android/package_source/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..872eabdb Binary files /dev/null and b/Desktop_Interface/build_android/package_source/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/Desktop_Interface/build_android/package_source/res/mipmap-xhdpi/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/build_android/package_source/res/mipmap-xhdpi/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 8673d8db..00000000 --- a/Desktop_Interface/build_android/package_source/res/mipmap-xhdpi/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -872eabdbf53fbc6155a1f08711874f0a4e343b16 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/res/mipmap-xxhdpi/ic_launcher.png b/Desktop_Interface/build_android/package_source/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..e6058385 Binary files /dev/null and b/Desktop_Interface/build_android/package_source/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/Desktop_Interface/build_android/package_source/res/mipmap-xxhdpi/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/build_android/package_source/res/mipmap-xxhdpi/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index c5041fc2..00000000 --- a/Desktop_Interface/build_android/package_source/res/mipmap-xxhdpi/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e6058385db5d994fcc73681590faa55bcce4119e \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/res/mipmap-xxxhdpi/Thumbs.db b/Desktop_Interface/build_android/package_source/res/mipmap-xxxhdpi/Thumbs.db new file mode 100644 index 00000000..6678b8f4 Binary files /dev/null and b/Desktop_Interface/build_android/package_source/res/mipmap-xxxhdpi/Thumbs.db differ diff --git a/Desktop_Interface/build_android/package_source/res/mipmap-xxxhdpi/Thumbs.db.REMOVED.git-id b/Desktop_Interface/build_android/package_source/res/mipmap-xxxhdpi/Thumbs.db.REMOVED.git-id deleted file mode 100644 index 5e30c8cf..00000000 --- a/Desktop_Interface/build_android/package_source/res/mipmap-xxxhdpi/Thumbs.db.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6678b8f4b15e3a0c94fa71d1445d9a6641827f95 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/res/mipmap-xxxhdpi/ic_launcher.png b/Desktop_Interface/build_android/package_source/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..2b287a91 Binary files /dev/null and b/Desktop_Interface/build_android/package_source/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/Desktop_Interface/build_android/package_source/res/mipmap-xxxhdpi/ic_launcher.png.REMOVED.git-id b/Desktop_Interface/build_android/package_source/res/mipmap-xxxhdpi/ic_launcher.png.REMOVED.git-id deleted file mode 100644 index 50284b7d..00000000 --- a/Desktop_Interface/build_android/package_source/res/mipmap-xxxhdpi/ic_launcher.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2b287a9164a0e2f7e7914bf9abbdbcd17f217513 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/res/values/libs.xml b/Desktop_Interface/build_android/package_source/res/values/libs.xml new file mode 100644 index 00000000..43296f2e --- /dev/null +++ b/Desktop_Interface/build_android/package_source/res/values/libs.xml @@ -0,0 +1,25 @@ + + + + https://download.qt.io/ministro/android/qt5/qt-5.7 + + + + + + + + + + + + + + + + + + + + diff --git a/Desktop_Interface/build_android/package_source/res/values/libs.xml.REMOVED.git-id b/Desktop_Interface/build_android/package_source/res/values/libs.xml.REMOVED.git-id deleted file mode 100644 index 98808207..00000000 --- a/Desktop_Interface/build_android/package_source/res/values/libs.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -43296f2e7a24d7bdfafcfcbb0e872dc9eb3f3958 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/res/web_hi_res_512.png b/Desktop_Interface/build_android/package_source/res/web_hi_res_512.png new file mode 100644 index 00000000..893eebc7 Binary files /dev/null and b/Desktop_Interface/build_android/package_source/res/web_hi_res_512.png differ diff --git a/Desktop_Interface/build_android/package_source/res/web_hi_res_512.png.REMOVED.git-id b/Desktop_Interface/build_android/package_source/res/web_hi_res_512.png.REMOVED.git-id deleted file mode 100644 index 0abefa4f..00000000 --- a/Desktop_Interface/build_android/package_source/res/web_hi_res_512.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -893eebc776c2d6f520d41af0b4d8075a9c99716d \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/res/xml/device_filter.xml b/Desktop_Interface/build_android/package_source/res/xml/device_filter.xml new file mode 100644 index 00000000..5d9a8059 --- /dev/null +++ b/Desktop_Interface/build_android/package_source/res/xml/device_filter.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/Desktop_Interface/build_android/package_source/res/xml/device_filter.xml.REMOVED.git-id b/Desktop_Interface/build_android/package_source/res/xml/device_filter.xml.REMOVED.git-id deleted file mode 100644 index 436375a5..00000000 --- a/Desktop_Interface/build_android/package_source/res/xml/device_filter.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5d9a80593045cdda9d8316eba096bb3c5823100a \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/src/androidInterface.java b/Desktop_Interface/build_android/package_source/src/androidInterface.java new file mode 100644 index 00000000..7caea66a --- /dev/null +++ b/Desktop_Interface/build_android/package_source/src/androidInterface.java @@ -0,0 +1,136 @@ +package com.EspoTek.Labrador.Java; + +import org.qtproject.qt5.android.bindings.QtApplication; +import org.qtproject.qt5.android.bindings.QtActivity; + +import android.util.Log; +import java.io.IOException; + +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbManager; +import android.hardware.usb.UsbDeviceConnection; +import android.content.Context; +import android.app.Activity; +import android.app.PendingIntent; +import android.content.Intent; +import java.util.HashMap; +import java.util.Iterator; +import java.lang.String; +import android.os.Bundle; + +public class androidInterface extends QtActivity +{ + private static final String ACTION_USB_PERMISSION = "org.qtproject.example.androidLibusb.USB_PERMISSION"; + + public String usbfs_path; + public int file_descriptor; + private UsbDeviceConnection connection; + + public androidInterface() + { + file_descriptor = -69; + Log.d(QtApplication.QtTAG, "An androidInterface has been constructed!"); + } + + public static void staticTest() + { + Log.d(QtApplication.QtTAG, "staticTest"); + } + + public void nonStaticTest() + { + Log.d(QtApplication.QtTAG, "nonStaticTest"); + } + + public void findDevice() + { + Log.d(QtApplication.QtTAG, "findDevice"); + PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); //??? + UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); //Handle to system USB service? + HashMap deviceList = manager.getDeviceList(); + Iterator deviceIterator = deviceList.values().iterator(); + if(!deviceIterator.hasNext()){ + Log.d(QtApplication.QtTAG, "NO DEVICE FOUND"); + } + + while(deviceIterator.hasNext()){ + Log.d(QtApplication.QtTAG, "DEVICE FOUND"); + UsbDevice device = deviceIterator.next(); + + manager.requestPermission(device, mPermissionIntent); + //Wait until it gets the permission + while(!manager.hasPermission(device)){ + ; + } + + String Model = device.getDeviceName(); + + int DeviceID = device.getDeviceId(); + int VID = device.getVendorId(); + int PID = device.getProductId(); + Log.d(QtApplication.QtTAG, String.format("Device ID = %d\nVID=0x%04x\nPID=0x%04x\n", DeviceID, VID, PID)); + if((VID==0x03eb) && (PID==0xba94)){ + if(!manager.hasPermission(device)){ + Log.d(QtApplication.QtTAG, "permission was not granted to the USB device!!!"); + return; + } + Log.d(QtApplication.QtTAG, "MATCH FOUND!"); + usbfs_path = device.getDeviceName(); + Log.d(QtApplication.QtTAG, "usbfs_path = " + usbfs_path); + connection = manager.openDevice(device); + file_descriptor = connection.getFileDescriptor(); + Log.d(QtApplication.QtTAG, "fd = " + file_descriptor); + Log.d(QtApplication.QtTAG, "Returning..."); + return; + } + } + } + public void findDevice_bootloader() + { + Log.d(QtApplication.QtTAG, "findDevice_bootloader"); + PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); //??? + UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); //Handle to system USB service? + HashMap deviceList = manager.getDeviceList(); + Iterator deviceIterator = deviceList.values().iterator(); + if(!deviceIterator.hasNext()){ + Log.d(QtApplication.QtTAG, "NO DEVICE FOUND"); + } + + while(deviceIterator.hasNext()){ + Log.d(QtApplication.QtTAG, "DEVICE FOUND"); + UsbDevice device = deviceIterator.next(); + + manager.requestPermission(device, mPermissionIntent); + //Wait until it gets the permission + while(!manager.hasPermission(device)){ + ; + } + + String Model = device.getDeviceName(); + + int DeviceID = device.getDeviceId(); + int VID = device.getVendorId(); + int PID = device.getProductId(); + Log.d(QtApplication.QtTAG, String.format("Device ID = %d\nVID=0x%04x\nPID=0x%04x\n", DeviceID, VID, PID)); + if((VID==0x03eb) && (PID==0x2fe4)){ + if(!manager.hasPermission(device)){ + Log.d(QtApplication.QtTAG, "permission was not granted to the USB device!!!"); + return; + } + Log.d(QtApplication.QtTAG, "MATCH FOUND!"); + usbfs_path = device.getDeviceName(); + Log.d(QtApplication.QtTAG, "usbfs_path = " + usbfs_path); + connection = manager.openDevice(device); + file_descriptor = connection.getFileDescriptor(); + Log.d(QtApplication.QtTAG, "fd = " + file_descriptor); + Log.d(QtApplication.QtTAG, "Returning..."); + return; + } + } + } + public void closeDevice() + { + file_descriptor = -69; + Log.d(QtApplication.QtTAG, "androidInterface has been closed!"); + } +} diff --git a/Desktop_Interface/build_android/package_source/src/androidInterface.java.REMOVED.git-id b/Desktop_Interface/build_android/package_source/src/androidInterface.java.REMOVED.git-id deleted file mode 100644 index 86600d3e..00000000 --- a/Desktop_Interface/build_android/package_source/src/androidInterface.java.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7caea66ab4cc45a43869b1c24c948cc768c57811 \ No newline at end of file diff --git a/Desktop_Interface/build_android/package_source/src/androidInterface.java.bak b/Desktop_Interface/build_android/package_source/src/androidInterface.java.bak new file mode 100644 index 00000000..d480bb2d --- /dev/null +++ b/Desktop_Interface/build_android/package_source/src/androidInterface.java.bak @@ -0,0 +1,72 @@ +package com.EspoTek.Labrador.Java; + +import org.qtproject.qt5.android.bindings.QtApplication; +import org.qtproject.qt5.android.bindings.QtActivity; + +import android.util.Log; +import java.io.IOException; + +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbManager; +import android.content.Context; +import android.app.Activity; +import android.app.PendingIntent; +import android.content.Intent; +import java.util.HashMap; +import java.util.Iterator; +import java.lang.String; +import android.os.Bundle; + +public class androidInterface extends QtActivity +{ + private static final String ACTION_USB_PERMISSION = "org.qtproject.example.androidLibusb.USB_PERMISSION"; + + //This function doesn't work. I'm not sure there is a way to get it to work... + public static void requestRoot() + { + Log.d("androidInterface::requestRoot", "Entering"); + Log.d("androidInterface", "Attempting to gain root access"); + try { + Runtime.getRuntime().exec("su"); + Log.d("androidInterface", "Gained root successfully!"); + + } catch (IOException e) { + Log.d("androidInterface", "Root unsuccessful!"); + } + } + + public static void bababooey() + { + Log.d("androidInterface::bababooey", "Entering"); + Log.d("Howard Stern's Penis", "Bababooey"); + } + + public void nonStaticTest() + { + Log.d("androidInterface::nonStaticTest", "Entering"); + Log.d("Howard Stern's Penis", "Bababooey (Non Static)"); + } + + + public void findDevice() + { + Log.d("androidInterface::findDevice", "Entering"); + PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); //??? + UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); //Handle to system USB service? + Log.d("usbActivity", String.format("manager=%d", manager)); + + HashMap deviceList = manager.getDeviceList(); + Iterator deviceIterator = deviceList.values().iterator(); + while(deviceIterator.hasNext()){ + UsbDevice device = deviceIterator.next(); + + manager.requestPermission(device, mPermissionIntent); + String Model = device.getDeviceName(); + + int DeviceID = device.getDeviceId(); + int Vendor = device.getVendorId(); + int Product= device.getProductId(); + Log.d("usbActivity", String.format("Device ID = %d\nVID=%d\nPID=%d\n", DeviceID, Vendor, Product)); + } + } +} diff --git a/Desktop_Interface/build_android/package_source/src/androidInterface.java.bak.REMOVED.git-id b/Desktop_Interface/build_android/package_source/src/androidInterface.java.bak.REMOVED.git-id deleted file mode 100644 index eef66601..00000000 --- a/Desktop_Interface/build_android/package_source/src/androidInterface.java.bak.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d480bb2df3c38016e18106ba7afcf4d4bfb6c05c \ No newline at end of file diff --git a/Desktop_Interface/build_android/platformspecific.h b/Desktop_Interface/build_android/platformspecific.h new file mode 100644 index 00000000..c4b90fa1 --- /dev/null +++ b/Desktop_Interface/build_android/platformspecific.h @@ -0,0 +1,9 @@ +#ifndef PLATFORMSPECIFIC_H +#define PLATFORMSPECIFIC_H + +#include "androidusbdriver.h" +#define PLATFORM_ANDROID +#define _PLATFORM_DEPENDENT_USB_OBJECT androidUsbDriver +#define _PLATFORM_DEPENDENT_FOLDER_ACTION + +#endif // PLATFORMSPECIFIC_H diff --git a/Desktop_Interface/build_android/platformspecific.h.REMOVED.git-id b/Desktop_Interface/build_android/platformspecific.h.REMOVED.git-id deleted file mode 100644 index b561154c..00000000 --- a/Desktop_Interface/build_android/platformspecific.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c4b90fa15e8336c7b6140eafee35748d32fad249 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libdfuprog/include/libdfuprog.h b/Desktop_Interface/build_linux/libdfuprog/include/libdfuprog.h new file mode 100644 index 00000000..a93da6a3 --- /dev/null +++ b/Desktop_Interface/build_linux/libdfuprog/include/libdfuprog.h @@ -0,0 +1,6 @@ +#ifndef LIBDFUPROG_H +#define LIBDFUPROG_H + +int dfuprog_virtual_cmd(char* commandLine); + +#endif diff --git a/Desktop_Interface/build_linux/libdfuprog/include/libdfuprog.h.REMOVED.git-id b/Desktop_Interface/build_linux/libdfuprog/include/libdfuprog.h.REMOVED.git-id deleted file mode 100644 index 6ad77c07..00000000 --- a/Desktop_Interface/build_linux/libdfuprog/include/libdfuprog.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a93da6a335dcd982c2d16a2a8ffe31086bab90c1 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libdfuprog/lib/arm/libdfuprog-0.9.so b/Desktop_Interface/build_linux/libdfuprog/lib/arm/libdfuprog-0.9.so new file mode 100644 index 00000000..604aba1b Binary files /dev/null and b/Desktop_Interface/build_linux/libdfuprog/lib/arm/libdfuprog-0.9.so differ diff --git a/Desktop_Interface/build_linux/libdfuprog/lib/arm/libdfuprog-0.9.so.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/build_linux/libdfuprog/lib/arm/libdfuprog-0.9.so.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index f1ae5942..00000000 --- a/Desktop_Interface/build_linux/libdfuprog/lib/arm/libdfuprog-0.9.so.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2f86926facec11998ed268298507e49cd380a706 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libdfuprog/lib/libdfuprog-0.9.so.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/build_linux/libdfuprog/lib/libdfuprog-0.9.so.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index a64e9bc5..00000000 --- a/Desktop_Interface/build_linux/libdfuprog/lib/libdfuprog-0.9.so.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b04c433b2f0fd776705e1d368c199f5c7b24583c \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libdfuprog/lib/x64/libdfuprog-0.9.so b/Desktop_Interface/build_linux/libdfuprog/lib/x64/libdfuprog-0.9.so new file mode 100644 index 00000000..eb35890d Binary files /dev/null and b/Desktop_Interface/build_linux/libdfuprog/lib/x64/libdfuprog-0.9.so differ diff --git a/Desktop_Interface/build_linux/libdfuprog/lib/x64/libdfuprog-0.9.so.REMOVED.git-id b/Desktop_Interface/build_linux/libdfuprog/lib/x64/libdfuprog-0.9.so.REMOVED.git-id deleted file mode 100644 index b04c433b..00000000 --- a/Desktop_Interface/build_linux/libdfuprog/lib/x64/libdfuprog-0.9.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -eb35890d8f3a778fd224b6b162b36f53e63eb451 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libdfuprog/lib/x86/libdfuprog-0.9.so b/Desktop_Interface/build_linux/libdfuprog/lib/x86/libdfuprog-0.9.so new file mode 100644 index 00000000..0b7c782e Binary files /dev/null and b/Desktop_Interface/build_linux/libdfuprog/lib/x86/libdfuprog-0.9.so differ diff --git a/Desktop_Interface/build_linux/libdfuprog/lib/x86/libdfuprog-0.9.so.REMOVED.git-id b/Desktop_Interface/build_linux/libdfuprog/lib/x86/libdfuprog-0.9.so.REMOVED.git-id deleted file mode 100644 index 62b7edc2..00000000 --- a/Desktop_Interface/build_linux/libdfuprog/lib/x86/libdfuprog-0.9.so.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0b7c782eb0ca970970e44208f12ffbbb22daebca \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libdfuprog/libz.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/build_linux/libdfuprog/libz.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index a64e9bc5..00000000 --- a/Desktop_Interface/build_linux/libdfuprog/libz.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b04c433b2f0fd776705e1d368c199f5c7b24583c \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-core.Plo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-core.Plo.REMOVED.git-id deleted file mode 100644 index f6bd52cd..00000000 --- a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-core.Plo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -380faa1e6f58bbda4aaa5a04319d7401302f93bb \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-darwin_usb.Plo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-darwin_usb.Plo.REMOVED.git-id deleted file mode 100644 index 23f0919e..00000000 --- a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-darwin_usb.Plo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9ce06a81ea45b2883a6faf07a0d2136bb2a4e647 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-descriptor.Plo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-descriptor.Plo.REMOVED.git-id deleted file mode 100644 index 4649ba06..00000000 --- a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-descriptor.Plo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2a94c0c7b51306d4220a084f9630f1717637fc83 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-io.Plo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-io.Plo.REMOVED.git-id deleted file mode 100644 index 2e52e490..00000000 --- a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-io.Plo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -609f72ce09eef3a060abd59c88c273350aa6fc51 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-linux_usbfs.Plo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-linux_usbfs.Plo.REMOVED.git-id deleted file mode 100644 index 44b0e099..00000000 --- a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-linux_usbfs.Plo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -af8b02c9c8bfdd945bd3d1f83162cc02b844632f \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-openbsd_usb.Plo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-openbsd_usb.Plo.REMOVED.git-id deleted file mode 100644 index 23f0919e..00000000 --- a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-openbsd_usb.Plo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9ce06a81ea45b2883a6faf07a0d2136bb2a4e647 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-poll_windows.Plo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-poll_windows.Plo.REMOVED.git-id deleted file mode 100644 index 23f0919e..00000000 --- a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-poll_windows.Plo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9ce06a81ea45b2883a6faf07a0d2136bb2a4e647 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-sync.Plo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-sync.Plo.REMOVED.git-id deleted file mode 100644 index 06158f80..00000000 --- a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-sync.Plo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6d021155d6f957fe3e42b7ea0f5cbfae4c2ad5d5 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-threads_posix.Plo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-threads_posix.Plo.REMOVED.git-id deleted file mode 100644 index 497731fd..00000000 --- a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-threads_posix.Plo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7b84732297a15f00f6105a7158e66df59aceb89c \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-threads_windows.Plo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-threads_windows.Plo.REMOVED.git-id deleted file mode 100644 index 23f0919e..00000000 --- a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-threads_windows.Plo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9ce06a81ea45b2883a6faf07a0d2136bb2a4e647 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-windows_usb.Plo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-windows_usb.Plo.REMOVED.git-id deleted file mode 100644 index 23f0919e..00000000 --- a/Desktop_Interface/build_linux/libusb/.deps/libusb_1_0_la-windows_usb.Plo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9ce06a81ea45b2883a6faf07a0d2136bb2a4e647 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/Makefile.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/Makefile.REMOVED.git-id deleted file mode 100644 index a1b2bf92..00000000 --- a/Desktop_Interface/build_linux/libusb/Makefile.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fece81fa30059e618fd5e36a8813c78df1b2d0ef \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/Makefile.am.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/Makefile.am.REMOVED.git-id deleted file mode 100644 index 7a14aa0a..00000000 --- a/Desktop_Interface/build_linux/libusb/Makefile.am.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3316ebcbb817906f7da89d28e4f3e0258e847d19 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/Makefile.in.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/Makefile.in.REMOVED.git-id deleted file mode 100644 index 823c1b69..00000000 --- a/Desktop_Interface/build_linux/libusb/Makefile.in.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -193adaed9a54d3e5c7dc9548717f2d6db1e7d69c \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/core.c.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/core.c.REMOVED.git-id deleted file mode 100644 index 0e310e5c..00000000 --- a/Desktop_Interface/build_linux/libusb/core.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -767dcbfabf160c48c0851d61cab7ca7d8483a92a \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/descriptor.c.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/descriptor.c.REMOVED.git-id deleted file mode 100644 index 40e145ff..00000000 --- a/Desktop_Interface/build_linux/libusb/descriptor.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e358e9e5925469fc3fe1ddd880e3d49f90bcdd14 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/io.c.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/io.c.REMOVED.git-id deleted file mode 100644 index 57054ea0..00000000 --- a/Desktop_Interface/build_linux/libusb/io.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e9bd312c8cc2d624b7c8826461bb1338162fd4b7 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb-1.0.def.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb-1.0.def.REMOVED.git-id deleted file mode 100644 index 67b704ad..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb-1.0.def.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1d6a5d2113ecb267676e35c1ef25e00a72b7614a \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb-1.0.la.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb-1.0.la.REMOVED.git-id deleted file mode 100644 index 4ba474eb..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb-1.0.la.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -384d0b2fc1be036b62efe29d57637f262f461f5d \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb-1.0.rc.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb-1.0.rc.REMOVED.git-id deleted file mode 100644 index 278684fc..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb-1.0.rc.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a59a4307dc5054bfbba313b7230dcf602229dd1a \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb.h b/Desktop_Interface/build_linux/libusb/libusb.h new file mode 100644 index 00000000..58b406f2 --- /dev/null +++ b/Desktop_Interface/build_linux/libusb/libusb.h @@ -0,0 +1,1443 @@ +/* + * Public libusb header file + * Copyright (C) 2007-2008 Daniel Drake + * Copyright (c) 2001 Johannes Erdfelt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_H +#define LIBUSB_H + +#ifdef _MSC_VER +/* on MS environments, the inline keyword is available in C++ only */ +#define inline __inline +/* ssize_t is also not available (copy/paste from MinGW) */ +#ifndef _SSIZE_T_DEFINED +#define _SSIZE_T_DEFINED +#undef ssize_t +#ifdef _WIN64 + typedef __int64 ssize_t; +#else + typedef int ssize_t; +#endif /* _WIN64 */ +#endif /* _SSIZE_T_DEFINED */ +#endif /* _MSC_VER */ + +/* stdint.h is also not usually available on MS */ +#if defined(_MSC_VER) && (_MSC_VER < 1600) && (!defined(_STDINT)) && (!defined(_STDINT_H)) +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +#else +#include +#endif + +#include +#include +#include + +#if defined(__linux) || defined(__APPLE__) || defined(__CYGWIN__) +#include +#endif + +/* 'interface' might be defined as a macro on Windows, so we need to + * undefine it so as not to break the current libusb API, because + * libusb_config_descriptor has an 'interface' member + * As this can be problematic if you include windows.h after libusb.h + * in your sources, we force windows.h to be included first. */ +#if defined(_WIN32) || defined(__CYGWIN__) +#include +#if defined(interface) +#undef interface +#endif +#endif + +/** \def LIBUSB_CALL + * \ingroup misc + * libusb's Windows calling convention. + * + * Under Windows, the selection of available compilers and configurations + * means that, unlike other platforms, there is not one true calling + * convention (calling convention: the manner in which parameters are + * passed to funcions in the generated assembly code). + * + * Matching the Windows API itself, libusb uses the WINAPI convention (which + * translates to the stdcall convention) and guarantees that the + * library is compiled in this way. The public header file also includes + * appropriate annotations so that your own software will use the right + * convention, even if another convention is being used by default within + * your codebase. + * + * The one consideration that you must apply in your software is to mark + * all functions which you use as libusb callbacks with this LIBUSB_CALL + * annotation, so that they too get compiled for the correct calling + * convention. + * + * On non-Windows operating systems, this macro is defined as nothing. This + * means that you can apply it to your code without worrying about + * cross-platform compatibility. + */ +/* LIBUSB_CALL must be defined on both definition and declaration of libusb + * functions. You'd think that declaration would be enough, but cygwin will + * complain about conflicting types unless both are marked this way. + * The placement of this macro is important too; it must appear after the + * return type, before the function name. See internal documentation for + * API_EXPORTED. + */ +#if defined(_WIN32) || defined(__CYGWIN__) +#define LIBUSB_CALL WINAPI +#else +#define LIBUSB_CALL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** \def libusb_cpu_to_le16 + * \ingroup misc + * Convert a 16-bit value from host-endian to little-endian format. On + * little endian systems, this function does nothing. On big endian systems, + * the bytes are swapped. + * \param x the host-endian value to convert + * \returns the value in little-endian byte order + */ +static inline uint16_t libusb_cpu_to_le16(const uint16_t x) +{ + union { + uint8_t b8[2]; + uint16_t b16; + } _tmp; + _tmp.b8[1] = x >> 8; + _tmp.b8[0] = x & 0xff; + return _tmp.b16; +} + +/** \def libusb_le16_to_cpu + * \ingroup misc + * Convert a 16-bit value from little-endian to host-endian format. On + * little endian systems, this function does nothing. On big endian systems, + * the bytes are swapped. + * \param x the little-endian value to convert + * \returns the value in host-endian byte order + */ +#define libusb_le16_to_cpu libusb_cpu_to_le16 + +/* standard USB stuff */ + +/** \ingroup desc + * Device and/or Interface Class codes */ +enum libusb_class_code { + /** In the context of a \ref libusb_device_descriptor "device descriptor", + * this bDeviceClass value indicates that each interface specifies its + * own class information and all interfaces operate independently. + */ + LIBUSB_CLASS_PER_INTERFACE = 0, + + /** Audio class */ + LIBUSB_CLASS_AUDIO = 1, + + /** Communications class */ + LIBUSB_CLASS_COMM = 2, + + /** Human Interface Device class */ + LIBUSB_CLASS_HID = 3, + + /** Physical */ + LIBUSB_CLASS_PHYSICAL = 5, + + /** Printer class */ + LIBUSB_CLASS_PRINTER = 7, + + /** Image class */ + LIBUSB_CLASS_PTP = 6, /* legacy name from libusb-0.1 usb.h */ + LIBUSB_CLASS_IMAGE = 6, + + /** Mass storage class */ + LIBUSB_CLASS_MASS_STORAGE = 8, + + /** Hub class */ + LIBUSB_CLASS_HUB = 9, + + /** Data class */ + LIBUSB_CLASS_DATA = 10, + + /** Smart Card */ + LIBUSB_CLASS_SMART_CARD = 0x0b, + + /** Content Security */ + LIBUSB_CLASS_CONTENT_SECURITY = 0x0d, + + /** Video */ + LIBUSB_CLASS_VIDEO = 0x0e, + + /** Personal Healthcare */ + LIBUSB_CLASS_PERSONAL_HEALTHCARE = 0x0f, + + /** Diagnostic Device */ + LIBUSB_CLASS_DIAGNOSTIC_DEVICE = 0xdc, + + /** Wireless class */ + LIBUSB_CLASS_WIRELESS = 0xe0, + + /** Application class */ + LIBUSB_CLASS_APPLICATION = 0xfe, + + /** Class is vendor-specific */ + LIBUSB_CLASS_VENDOR_SPEC = 0xff +}; + +/** \ingroup desc + * Descriptor types as defined by the USB specification. */ +enum libusb_descriptor_type { + /** Device descriptor. See libusb_device_descriptor. */ + LIBUSB_DT_DEVICE = 0x01, + + /** Configuration descriptor. See libusb_config_descriptor. */ + LIBUSB_DT_CONFIG = 0x02, + + /** String descriptor */ + LIBUSB_DT_STRING = 0x03, + + /** Interface descriptor. See libusb_interface_descriptor. */ + LIBUSB_DT_INTERFACE = 0x04, + + /** Endpoint descriptor. See libusb_endpoint_descriptor. */ + LIBUSB_DT_ENDPOINT = 0x05, + + /** HID descriptor */ + LIBUSB_DT_HID = 0x21, + + /** HID report descriptor */ + LIBUSB_DT_REPORT = 0x22, + + /** Physical descriptor */ + LIBUSB_DT_PHYSICAL = 0x23, + + /** Hub descriptor */ + LIBUSB_DT_HUB = 0x29, +}; + +/* Descriptor sizes per descriptor type */ +#define LIBUSB_DT_DEVICE_SIZE 18 +#define LIBUSB_DT_CONFIG_SIZE 9 +#define LIBUSB_DT_INTERFACE_SIZE 9 +#define LIBUSB_DT_ENDPOINT_SIZE 7 +#define LIBUSB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ +#define LIBUSB_DT_HUB_NONVAR_SIZE 7 + +#define LIBUSB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ +#define LIBUSB_ENDPOINT_DIR_MASK 0x80 + +/** \ingroup desc + * Endpoint direction. Values for bit 7 of the + * \ref libusb_endpoint_descriptor::bEndpointAddress "endpoint address" scheme. + */ +enum libusb_endpoint_direction { + /** In: device-to-host */ + LIBUSB_ENDPOINT_IN = 0x80, + + /** Out: host-to-device */ + LIBUSB_ENDPOINT_OUT = 0x00 +}; + +#define LIBUSB_TRANSFER_TYPE_MASK 0x03 /* in bmAttributes */ + +/** \ingroup desc + * Endpoint transfer type. Values for bits 0:1 of the + * \ref libusb_endpoint_descriptor::bmAttributes "endpoint attributes" field. + */ +enum libusb_transfer_type { + /** Control endpoint */ + LIBUSB_TRANSFER_TYPE_CONTROL = 0, + + /** Isochronous endpoint */ + LIBUSB_TRANSFER_TYPE_ISOCHRONOUS = 1, + + /** Bulk endpoint */ + LIBUSB_TRANSFER_TYPE_BULK = 2, + + /** Interrupt endpoint */ + LIBUSB_TRANSFER_TYPE_INTERRUPT = 3 +}; + +/** \ingroup misc + * Standard requests, as defined in table 9-3 of the USB2 specifications */ +enum libusb_standard_request { + /** Request status of the specific recipient */ + LIBUSB_REQUEST_GET_STATUS = 0x00, + + /** Clear or disable a specific feature */ + LIBUSB_REQUEST_CLEAR_FEATURE = 0x01, + + /* 0x02 is reserved */ + + /** Set or enable a specific feature */ + LIBUSB_REQUEST_SET_FEATURE = 0x03, + + /* 0x04 is reserved */ + + /** Set device address for all future accesses */ + LIBUSB_REQUEST_SET_ADDRESS = 0x05, + + /** Get the specified descriptor */ + LIBUSB_REQUEST_GET_DESCRIPTOR = 0x06, + + /** Used to update existing descriptors or add new descriptors */ + LIBUSB_REQUEST_SET_DESCRIPTOR = 0x07, + + /** Get the current device configuration value */ + LIBUSB_REQUEST_GET_CONFIGURATION = 0x08, + + /** Set device configuration */ + LIBUSB_REQUEST_SET_CONFIGURATION = 0x09, + + /** Return the selected alternate setting for the specified interface */ + LIBUSB_REQUEST_GET_INTERFACE = 0x0A, + + /** Select an alternate interface for the specified interface */ + LIBUSB_REQUEST_SET_INTERFACE = 0x0B, + + /** Set then report an endpoint's synchronization frame */ + LIBUSB_REQUEST_SYNCH_FRAME = 0x0C, +}; + +/** \ingroup misc + * Request type bits of the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field in control + * transfers. */ +enum libusb_request_type { + /** Standard */ + LIBUSB_REQUEST_TYPE_STANDARD = (0x00 << 5), + + /** Class */ + LIBUSB_REQUEST_TYPE_CLASS = (0x01 << 5), + + /** Vendor */ + LIBUSB_REQUEST_TYPE_VENDOR = (0x02 << 5), + + /** Reserved */ + LIBUSB_REQUEST_TYPE_RESERVED = (0x03 << 5) +}; + +/** \ingroup misc + * Recipient bits of the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field in control + * transfers. Values 4 through 31 are reserved. */ +enum libusb_request_recipient { + /** Device */ + LIBUSB_RECIPIENT_DEVICE = 0x00, + + /** Interface */ + LIBUSB_RECIPIENT_INTERFACE = 0x01, + + /** Endpoint */ + LIBUSB_RECIPIENT_ENDPOINT = 0x02, + + /** Other */ + LIBUSB_RECIPIENT_OTHER = 0x03, +}; + +#define LIBUSB_ISO_SYNC_TYPE_MASK 0x0C + +/** \ingroup desc + * Synchronization type for isochronous endpoints. Values for bits 2:3 of the + * \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in + * libusb_endpoint_descriptor. + */ +enum libusb_iso_sync_type { + /** No synchronization */ + LIBUSB_ISO_SYNC_TYPE_NONE = 0, + + /** Asynchronous */ + LIBUSB_ISO_SYNC_TYPE_ASYNC = 1, + + /** Adaptive */ + LIBUSB_ISO_SYNC_TYPE_ADAPTIVE = 2, + + /** Synchronous */ + LIBUSB_ISO_SYNC_TYPE_SYNC = 3 +}; + +#define LIBUSB_ISO_USAGE_TYPE_MASK 0x30 + +/** \ingroup desc + * Usage type for isochronous endpoints. Values for bits 4:5 of the + * \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in + * libusb_endpoint_descriptor. + */ +enum libusb_iso_usage_type { + /** Data endpoint */ + LIBUSB_ISO_USAGE_TYPE_DATA = 0, + + /** Feedback endpoint */ + LIBUSB_ISO_USAGE_TYPE_FEEDBACK = 1, + + /** Implicit feedback Data endpoint */ + LIBUSB_ISO_USAGE_TYPE_IMPLICIT = 2, +}; + +/** \ingroup desc + * A structure representing the standard USB device descriptor. This + * descriptor is documented in section 9.6.1 of the USB 2.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_device_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE LIBUSB_DT_DEVICE in this + * context. */ + uint8_t bDescriptorType; + + /** USB specification release number in binary-coded decimal. A value of + * 0x0200 indicates USB 2.0, 0x0110 indicates USB 1.1, etc. */ + uint16_t bcdUSB; + + /** USB-IF class code for the device. See \ref libusb_class_code. */ + uint8_t bDeviceClass; + + /** USB-IF subclass code for the device, qualified by the bDeviceClass + * value */ + uint8_t bDeviceSubClass; + + /** USB-IF protocol code for the device, qualified by the bDeviceClass and + * bDeviceSubClass values */ + uint8_t bDeviceProtocol; + + /** Maximum packet size for endpoint 0 */ + uint8_t bMaxPacketSize0; + + /** USB-IF vendor ID */ + uint16_t idVendor; + + /** USB-IF product ID */ + uint16_t idProduct; + + /** Device release number in binary-coded decimal */ + uint16_t bcdDevice; + + /** Index of string descriptor describing manufacturer */ + uint8_t iManufacturer; + + /** Index of string descriptor describing product */ + uint8_t iProduct; + + /** Index of string descriptor containing device serial number */ + uint8_t iSerialNumber; + + /** Number of possible configurations */ + uint8_t bNumConfigurations; +}; + +/** \ingroup desc + * A structure representing the standard USB endpoint descriptor. This + * descriptor is documented in section 9.6.3 of the USB 2.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_endpoint_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_ENDPOINT LIBUSB_DT_ENDPOINT in + * this context. */ + uint8_t bDescriptorType; + + /** The address of the endpoint described by this descriptor. Bits 0:3 are + * the endpoint number. Bits 4:6 are reserved. Bit 7 indicates direction, + * see \ref libusb_endpoint_direction. + */ + uint8_t bEndpointAddress; + + /** Attributes which apply to the endpoint when it is configured using + * the bConfigurationValue. Bits 0:1 determine the transfer type and + * correspond to \ref libusb_transfer_type. Bits 2:3 are only used for + * isochronous endpoints and correspond to \ref libusb_iso_sync_type. + * Bits 4:5 are also only used for isochronous endpoints and correspond to + * \ref libusb_iso_usage_type. Bits 6:7 are reserved. + */ + uint8_t bmAttributes; + + /** Maximum packet size this endpoint is capable of sending/receiving. */ + uint16_t wMaxPacketSize; + + /** Interval for polling endpoint for data transfers. */ + uint8_t bInterval; + + /** For audio devices only: the rate at which synchronization feedback + * is provided. */ + uint8_t bRefresh; + + /** For audio devices only: the address if the synch endpoint */ + uint8_t bSynchAddress; + + /** Extra descriptors. If libusb encounters unknown endpoint descriptors, + * it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup desc + * A structure representing the standard USB interface descriptor. This + * descriptor is documented in section 9.6.5 of the USB 2.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_interface_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_INTERFACE LIBUSB_DT_INTERFACE + * in this context. */ + uint8_t bDescriptorType; + + /** Number of this interface */ + uint8_t bInterfaceNumber; + + /** Value used to select this alternate setting for this interface */ + uint8_t bAlternateSetting; + + /** Number of endpoints used by this interface (excluding the control + * endpoint). */ + uint8_t bNumEndpoints; + + /** USB-IF class code for this interface. See \ref libusb_class_code. */ + uint8_t bInterfaceClass; + + /** USB-IF subclass code for this interface, qualified by the + * bInterfaceClass value */ + uint8_t bInterfaceSubClass; + + /** USB-IF protocol code for this interface, qualified by the + * bInterfaceClass and bInterfaceSubClass values */ + uint8_t bInterfaceProtocol; + + /** Index of string descriptor describing this interface */ + uint8_t iInterface; + + /** Array of endpoint descriptors. This length of this array is determined + * by the bNumEndpoints field. */ + const struct libusb_endpoint_descriptor *endpoint; + + /** Extra descriptors. If libusb encounters unknown interface descriptors, + * it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup desc + * A collection of alternate settings for a particular USB interface. + */ +struct libusb_interface { + /** Array of interface descriptors. The length of this array is determined + * by the num_altsetting field. */ + const struct libusb_interface_descriptor *altsetting; + + /** The number of alternate settings that belong to this interface */ + int num_altsetting; +}; + +/** \ingroup desc + * A structure representing the standard USB configuration descriptor. This + * descriptor is documented in section 9.6.3 of the USB 2.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_config_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_CONFIG LIBUSB_DT_CONFIG + * in this context. */ + uint8_t bDescriptorType; + + /** Total length of data returned for this configuration */ + uint16_t wTotalLength; + + /** Number of interfaces supported by this configuration */ + uint8_t bNumInterfaces; + + /** Identifier value for this configuration */ + uint8_t bConfigurationValue; + + /** Index of string descriptor describing this configuration */ + uint8_t iConfiguration; + + /** Configuration characteristics */ + uint8_t bmAttributes; + + /** Maximum power consumption of the USB device from this bus in this + * configuration when the device is fully opreation. Expressed in units + * of 2 mA. */ + uint8_t MaxPower; + + /** Array of interfaces supported by this configuration. The length of + * this array is determined by the bNumInterfaces field. */ + const struct libusb_interface *interface; + + /** Extra descriptors. If libusb encounters unknown configuration + * descriptors, it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup asyncio + * Setup packet for control transfers. */ +struct libusb_control_setup { + /** Request type. Bits 0:4 determine recipient, see + * \ref libusb_request_recipient. Bits 5:6 determine type, see + * \ref libusb_request_type. Bit 7 determines data transfer direction, see + * \ref libusb_endpoint_direction. + */ + uint8_t bmRequestType; + + /** Request. If the type bits of bmRequestType are equal to + * \ref libusb_request_type::LIBUSB_REQUEST_TYPE_STANDARD + * "LIBUSB_REQUEST_TYPE_STANDARD" then this field refers to + * \ref libusb_standard_request. For other cases, use of this field is + * application-specific. */ + uint8_t bRequest; + + /** Value. Varies according to request */ + uint16_t wValue; + + /** Index. Varies according to request, typically used to pass an index + * or offset */ + uint16_t wIndex; + + /** Number of bytes to transfer */ + uint16_t wLength; +}; + +#define LIBUSB_CONTROL_SETUP_SIZE (sizeof(struct libusb_control_setup)) + +/* libusb */ + +struct libusb_context; +struct libusb_device; +struct libusb_device_handle; + +/** \ingroup lib + * Structure representing the libusb version. + */ +struct libusb_version { + /** Library major version. */ + const uint16_t major; + + /** Library minor version. */ + const uint16_t minor; + + /** Library micro version. */ + const uint16_t micro; + + /** Library nano version. This field is only nonzero on Windows. */ + const uint16_t nano; + + /** Library release candidate suffix string, e.g. "-rc4". */ + const char *rc; + + /** Output of `git describe --tags` at library build time. */ + const char *describe; +}; + +/** \ingroup lib + * Structure representing a libusb session. The concept of individual libusb + * sessions allows for your program to use two libraries (or dynamically + * load two modules) which both independently use libusb. This will prevent + * interference between the individual libusb users - for example + * libusb_set_debug() will not affect the other user of the library, and + * libusb_exit() will not destroy resources that the other user is still + * using. + * + * Sessions are created by libusb_init() and destroyed through libusb_exit(). + * If your application is guaranteed to only ever include a single libusb + * user (i.e. you), you do not have to worry about contexts: pass NULL in + * every function call where a context is required. The default context + * will be used. + * + * For more information, see \ref contexts. + */ +typedef struct libusb_context libusb_context; + +/** \ingroup dev + * Structure representing a USB device detected on the system. This is an + * opaque type for which you are only ever provided with a pointer, usually + * originating from libusb_get_device_list(). + * + * Certain operations can be performed on a device, but in order to do any + * I/O you will have to first obtain a device handle using libusb_open(). + * + * Devices are reference counted with libusb_device_ref() and + * libusb_device_unref(), and are freed when the reference count reaches 0. + * New devices presented by libusb_get_device_list() have a reference count of + * 1, and libusb_free_device_list() can optionally decrease the reference count + * on all devices in the list. libusb_open() adds another reference which is + * later destroyed by libusb_close(). + */ +typedef struct libusb_device libusb_device; + + +/** \ingroup dev + * Structure representing a handle on a USB device. This is an opaque type for + * which you are only ever provided with a pointer, usually originating from + * libusb_open(). + * + * A device handle is used to perform I/O and other operations. When finished + * with a device handle, you should call libusb_close(). + */ +typedef struct libusb_device_handle libusb_device_handle; + +/** \ingroup dev + * Speed codes. Indicates the speed at which the device is operating. + */ +enum libusb_speed { + /** The OS doesn't report or know the device speed. */ + LIBUSB_SPEED_UNKNOWN = 0, + + /** The device is operating at low speed (1.5MBit/s). */ + LIBUSB_SPEED_LOW = 1, + + /** The device is operating at full speed (12MBit/s). */ + LIBUSB_SPEED_FULL = 2, + + /** The device is operating at high speed (480MBit/s). */ + LIBUSB_SPEED_HIGH = 3, + + /** The device is operating at super speed (5000MBit/s). */ + LIBUSB_SPEED_SUPER = 4, +}; + +/** \ingroup misc + * Error codes. Most libusb functions return 0 on success or one of these + * codes on failure. + * You can call \ref libusb_error_name() to retrieve a string representation + * of an error code. + */ +enum libusb_error { + /** Success (no error) */ + LIBUSB_SUCCESS = 0, + + /** Input/output error */ + LIBUSB_ERROR_IO = -1, + + /** Invalid parameter */ + LIBUSB_ERROR_INVALID_PARAM = -2, + + /** Access denied (insufficient permissions) */ + LIBUSB_ERROR_ACCESS = -3, + + /** No such device (it may have been disconnected) */ + LIBUSB_ERROR_NO_DEVICE = -4, + + /** Entity not found */ + LIBUSB_ERROR_NOT_FOUND = -5, + + /** Resource busy */ + LIBUSB_ERROR_BUSY = -6, + + /** Operation timed out */ + LIBUSB_ERROR_TIMEOUT = -7, + + /** Overflow */ + LIBUSB_ERROR_OVERFLOW = -8, + + /** Pipe error */ + LIBUSB_ERROR_PIPE = -9, + + /** System call interrupted (perhaps due to signal) */ + LIBUSB_ERROR_INTERRUPTED = -10, + + /** Insufficient memory */ + LIBUSB_ERROR_NO_MEM = -11, + + /** Operation not supported or unimplemented on this platform */ + LIBUSB_ERROR_NOT_SUPPORTED = -12, + + /* NB! Remember to update libusb_error_name() + when adding new error codes here. */ + + /** Other error */ + LIBUSB_ERROR_OTHER = -99, +}; + +/** \ingroup asyncio + * Transfer status codes */ +enum libusb_transfer_status { + /** Transfer completed without error. Note that this does not indicate + * that the entire amount of requested data was transferred. */ + LIBUSB_TRANSFER_COMPLETED, + + /** Transfer failed */ + LIBUSB_TRANSFER_ERROR, + + /** Transfer timed out */ + LIBUSB_TRANSFER_TIMED_OUT, + + /** Transfer was cancelled */ + LIBUSB_TRANSFER_CANCELLED, + + /** For bulk/interrupt endpoints: halt condition detected (endpoint + * stalled). For control endpoints: control request not supported. */ + LIBUSB_TRANSFER_STALL, + + /** Device was disconnected */ + LIBUSB_TRANSFER_NO_DEVICE, + + /** Device sent more data than requested */ + LIBUSB_TRANSFER_OVERFLOW, +}; + +/** \ingroup asyncio + * libusb_transfer.flags values */ +enum libusb_transfer_flags { + /** Report short frames as errors */ + LIBUSB_TRANSFER_SHORT_NOT_OK = 1<<0, + + /** Automatically free() transfer buffer during libusb_free_transfer() */ + LIBUSB_TRANSFER_FREE_BUFFER = 1<<1, + + /** Automatically call libusb_free_transfer() after callback returns. + * If this flag is set, it is illegal to call libusb_free_transfer() + * from your transfer callback, as this will result in a double-free + * when this flag is acted upon. */ + LIBUSB_TRANSFER_FREE_TRANSFER = 1<<2, + + /** Terminate transfers that are a multiple of the endpoint's + * wMaxPacketSize with an extra zero length packet. This is useful + * when a device protocol mandates that each logical request is + * terminated by an incomplete packet (i.e. the logical requests are + * not separated by other means). + * + * This flag only affects host-to-device transfers to bulk and interrupt + * endpoints. In other situations, it is ignored. + * + * This flag only affects transfers with a length that is a multiple of + * the endpoint's wMaxPacketSize. On transfers of other lengths, this + * flag has no effect. Therefore, if you are working with a device that + * needs a ZLP whenever the end of the logical request falls on a packet + * boundary, then it is sensible to set this flag on every + * transfer (you do not have to worry about only setting it on transfers + * that end on the boundary). + * + * This flag is currently only supported on Linux. + * On other systems, libusb_submit_transfer() will return + * LIBUSB_ERROR_NOT_SUPPORTED for every transfer where this flag is set. + * + * Available since libusb-1.0.9. + */ + LIBUSB_TRANSFER_ADD_ZERO_PACKET = 1 << 3, +}; + +/** \ingroup asyncio + * Isochronous packet descriptor. */ +struct libusb_iso_packet_descriptor { + /** Length of data to request in this packet */ + unsigned int length; + + /** Amount of data that was actually transferred */ + unsigned int actual_length; + + /** Status code for this packet */ + enum libusb_transfer_status status; +}; + +struct libusb_transfer; + +/** \ingroup asyncio + * Asynchronous transfer callback function type. When submitting asynchronous + * transfers, you pass a pointer to a callback function of this type via the + * \ref libusb_transfer::callback "callback" member of the libusb_transfer + * structure. libusb will call this function later, when the transfer has + * completed or failed. See \ref asyncio for more information. + * \param transfer The libusb_transfer struct the callback function is being + * notified about. + */ +typedef void (LIBUSB_CALL *libusb_transfer_cb_fn)(struct libusb_transfer *transfer); + +/** \ingroup asyncio + * The generic USB transfer structure. The user populates this structure and + * then submits it in order to request a transfer. After the transfer has + * completed, the library populates the transfer with the results and passes + * it back to the user. + */ +struct libusb_transfer { + /** Handle of the device that this transfer will be submitted to */ + libusb_device_handle *dev_handle; + + /** A bitwise OR combination of \ref libusb_transfer_flags. */ + uint8_t flags; + + /** Address of the endpoint where this transfer will be sent. */ + unsigned char endpoint; + + /** Type of the endpoint from \ref libusb_transfer_type */ + unsigned char type; + + /** Timeout for this transfer in millseconds. A value of 0 indicates no + * timeout. */ + unsigned int timeout; + + /** The status of the transfer. Read-only, and only for use within + * transfer callback function. + * + * If this is an isochronous transfer, this field may read COMPLETED even + * if there were errors in the frames. Use the + * \ref libusb_iso_packet_descriptor::status "status" field in each packet + * to determine if errors occurred. */ + enum libusb_transfer_status status; + + /** Length of the data buffer */ + int length; + + /** Actual length of data that was transferred. Read-only, and only for + * use within transfer callback function. Not valid for isochronous + * endpoint transfers. */ + int actual_length; + + /** Callback function. This will be invoked when the transfer completes, + * fails, or is cancelled. */ + libusb_transfer_cb_fn callback; + + /** User context data to pass to the callback function. */ + void *user_data; + + /** Data buffer */ + unsigned char *buffer; + + /** Number of isochronous packets. Only used for I/O with isochronous + * endpoints. */ + int num_iso_packets; + + /** Isochronous packet descriptors, for isochronous transfers only. */ + struct libusb_iso_packet_descriptor iso_packet_desc +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif + ; +}; + +/** \ingroup misc + * Capabilities supported by this instance of libusb. Test if the loaded + * library supports a given capability by calling + * \ref libusb_has_capability(). + */ +enum libusb_capability { + /** The libusb_has_capability() API is available. */ + LIBUSB_CAP_HAS_CAPABILITY = 0, +}; + +int LIBUSB_CALL libusb_init(libusb_context **ctx); +void LIBUSB_CALL libusb_exit(libusb_context *ctx); +void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level); +const struct libusb_version * LIBUSB_CALL libusb_get_version(void); +int LIBUSB_CALL libusb_has_capability(uint32_t capability); +const char * LIBUSB_CALL libusb_error_name(int errcode); + +ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx, + libusb_device ***list); +void LIBUSB_CALL libusb_free_device_list(libusb_device **list, + int unref_devices); +libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev); +void LIBUSB_CALL libusb_unref_device(libusb_device *dev); + +int LIBUSB_CALL libusb_get_configuration(libusb_device_handle *dev, + int *config); +int LIBUSB_CALL libusb_get_device_descriptor(libusb_device *dev, + struct libusb_device_descriptor *desc); +int LIBUSB_CALL libusb_get_active_config_descriptor(libusb_device *dev, + struct libusb_config_descriptor **config); +int LIBUSB_CALL libusb_get_config_descriptor(libusb_device *dev, + uint8_t config_index, struct libusb_config_descriptor **config); +int LIBUSB_CALL libusb_get_config_descriptor_by_value(libusb_device *dev, + uint8_t bConfigurationValue, struct libusb_config_descriptor **config); +void LIBUSB_CALL libusb_free_config_descriptor( + struct libusb_config_descriptor *config); +uint8_t LIBUSB_CALL libusb_get_bus_number(libusb_device *dev); +uint8_t LIBUSB_CALL libusb_get_device_address(libusb_device *dev); +int LIBUSB_CALL libusb_get_device_speed(libusb_device *dev); +int LIBUSB_CALL libusb_get_max_packet_size(libusb_device *dev, + unsigned char endpoint); +int LIBUSB_CALL libusb_get_max_iso_packet_size(libusb_device *dev, + unsigned char endpoint); + +int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **handle); +void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle); +libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle); + +int LIBUSB_CALL libusb_set_configuration(libusb_device_handle *dev, + int configuration); +int LIBUSB_CALL libusb_claim_interface(libusb_device_handle *dev, + int interface_number); +int LIBUSB_CALL libusb_release_interface(libusb_device_handle *dev, + int interface_number); + +libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid( + libusb_context *ctx, uint16_t vendor_id, uint16_t product_id); + +int LIBUSB_CALL libusb_set_interface_alt_setting(libusb_device_handle *dev, + int interface_number, int alternate_setting); +int LIBUSB_CALL libusb_clear_halt(libusb_device_handle *dev, + unsigned char endpoint); +int LIBUSB_CALL libusb_reset_device(libusb_device_handle *dev); + +int LIBUSB_CALL libusb_kernel_driver_active(libusb_device_handle *dev, + int interface_number); +int LIBUSB_CALL libusb_detach_kernel_driver(libusb_device_handle *dev, + int interface_number); +int LIBUSB_CALL libusb_attach_kernel_driver(libusb_device_handle *dev, + int interface_number); + +/* async I/O */ + +/** \ingroup asyncio + * Get the data section of a control transfer. This convenience function is here + * to remind you that the data does not start until 8 bytes into the actual + * buffer, as the setup packet comes first. + * + * Calling this function only makes sense from a transfer callback function, + * or situations where you have already allocated a suitably sized buffer at + * transfer->buffer. + * + * \param transfer a transfer + * \returns pointer to the first byte of the data section + */ +static inline unsigned char *libusb_control_transfer_get_data( + struct libusb_transfer *transfer) +{ + return transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; +} + +/** \ingroup asyncio + * Get the control setup packet of a control transfer. This convenience + * function is here to remind you that the control setup occupies the first + * 8 bytes of the transfer data buffer. + * + * Calling this function only makes sense from a transfer callback function, + * or situations where you have already allocated a suitably sized buffer at + * transfer->buffer. + * + * \param transfer a transfer + * \returns a casted pointer to the start of the transfer data buffer + */ +static inline struct libusb_control_setup *libusb_control_transfer_get_setup( + struct libusb_transfer *transfer) +{ + return (struct libusb_control_setup *) transfer->buffer; +} + +/** \ingroup asyncio + * Helper function to populate the setup packet (first 8 bytes of the data + * buffer) for a control transfer. The wIndex, wValue and wLength values should + * be given in host-endian byte order. + * + * \param buffer buffer to output the setup packet into + * \param bmRequestType see the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field of + * \ref libusb_control_setup + * \param bRequest see the + * \ref libusb_control_setup::bRequest "bRequest" field of + * \ref libusb_control_setup + * \param wValue see the + * \ref libusb_control_setup::wValue "wValue" field of + * \ref libusb_control_setup + * \param wIndex see the + * \ref libusb_control_setup::wIndex "wIndex" field of + * \ref libusb_control_setup + * \param wLength see the + * \ref libusb_control_setup::wLength "wLength" field of + * \ref libusb_control_setup + */ +static inline void libusb_fill_control_setup(unsigned char *buffer, + uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + uint16_t wLength) +{ + struct libusb_control_setup *setup = (struct libusb_control_setup *) buffer; + setup->bmRequestType = bmRequestType; + setup->bRequest = bRequest; + setup->wValue = libusb_cpu_to_le16(wValue); + setup->wIndex = libusb_cpu_to_le16(wIndex); + setup->wLength = libusb_cpu_to_le16(wLength); +} + +struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(int iso_packets); +int LIBUSB_CALL libusb_submit_transfer(struct libusb_transfer *transfer); +int LIBUSB_CALL libusb_cancel_transfer(struct libusb_transfer *transfer); +void LIBUSB_CALL libusb_free_transfer(struct libusb_transfer *transfer); + +/** \ingroup asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for a control transfer. + * + * If you pass a transfer buffer to this function, the first 8 bytes will + * be interpreted as a control setup packet, and the wLength field will be + * used to automatically populate the \ref libusb_transfer::length "length" + * field of the transfer. Therefore the recommended approach is: + * -# Allocate a suitably sized data buffer (including space for control setup) + * -# Call libusb_fill_control_setup() + * -# If this is a host-to-device transfer with a data stage, put the data + * in place after the setup packet + * -# Call this function + * -# Call libusb_submit_transfer() + * + * It is also legal to pass a NULL buffer to this function, in which case this + * function will not attempt to populate the length field. Remember that you + * must then populate the buffer and length fields later. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param buffer data buffer. If provided, this function will interpret the + * first 8 bytes as a setup packet and infer the transfer length from that. + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_control_transfer( + struct libusb_transfer *transfer, libusb_device_handle *dev_handle, + unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data, + unsigned int timeout) +{ + struct libusb_control_setup *setup = (struct libusb_control_setup *) buffer; + transfer->dev_handle = dev_handle; + transfer->endpoint = 0; + transfer->type = LIBUSB_TRANSFER_TYPE_CONTROL; + transfer->timeout = timeout; + transfer->buffer = buffer; + if (setup) + transfer->length = LIBUSB_CONTROL_SETUP_SIZE + + libusb_le16_to_cpu(setup->wLength); + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for a bulk transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer, + libusb_device_handle *dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_BULK; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for an interrupt transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_interrupt_transfer( + struct libusb_transfer *transfer, libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *buffer, int length, + libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for an isochronous transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param num_iso_packets the number of isochronous packets + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer, + libusb_device_handle *dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, int num_iso_packets, + libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->num_iso_packets = num_iso_packets; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup asyncio + * Convenience function to set the length of all packets in an isochronous + * transfer, based on the num_iso_packets field in the transfer structure. + * + * \param transfer a transfer + * \param length the length to set in each isochronous packet descriptor + * \see libusb_get_max_packet_size() + */ +static inline void libusb_set_iso_packet_lengths( + struct libusb_transfer *transfer, unsigned int length) +{ + int i; + for (i = 0; i < transfer->num_iso_packets; i++) + transfer->iso_packet_desc[i].length = length; +} + +/** \ingroup asyncio + * Convenience function to locate the position of an isochronous packet + * within the buffer of an isochronous transfer. + * + * This is a thorough function which loops through all preceding packets, + * accumulating their lengths to find the position of the specified packet. + * Typically you will assign equal lengths to each packet in the transfer, + * and hence the above method is sub-optimal. You may wish to use + * libusb_get_iso_packet_buffer_simple() instead. + * + * \param transfer a transfer + * \param packet the packet to return the address of + * \returns the base address of the packet buffer inside the transfer buffer, + * or NULL if the packet does not exist. + * \see libusb_get_iso_packet_buffer_simple() + */ +static inline unsigned char *libusb_get_iso_packet_buffer( + struct libusb_transfer *transfer, unsigned int packet) +{ + int i; + size_t offset = 0; + int _packet; + + /* oops..slight bug in the API. packet is an unsigned int, but we use + * signed integers almost everywhere else. range-check and convert to + * signed to avoid compiler warnings. FIXME for libusb-2. */ + if (packet > INT_MAX) + return NULL; + _packet = packet; + + if (_packet >= transfer->num_iso_packets) + return NULL; + + for (i = 0; i < _packet; i++) + offset += transfer->iso_packet_desc[i].length; + + return transfer->buffer + offset; +} + +/** \ingroup asyncio + * Convenience function to locate the position of an isochronous packet + * within the buffer of an isochronous transfer, for transfers where each + * packet is of identical size. + * + * This function relies on the assumption that every packet within the transfer + * is of identical size to the first packet. Calculating the location of + * the packet buffer is then just a simple calculation: + * buffer + (packet_size * packet) + * + * Do not use this function on transfers other than those that have identical + * packet lengths for each packet. + * + * \param transfer a transfer + * \param packet the packet to return the address of + * \returns the base address of the packet buffer inside the transfer buffer, + * or NULL if the packet does not exist. + * \see libusb_get_iso_packet_buffer() + */ +static inline unsigned char *libusb_get_iso_packet_buffer_simple( + struct libusb_transfer *transfer, unsigned int packet) +{ + int _packet; + + /* oops..slight bug in the API. packet is an unsigned int, but we use + * signed integers almost everywhere else. range-check and convert to + * signed to avoid compiler warnings. FIXME for libusb-2. */ + if (packet > INT_MAX) + return NULL; + _packet = packet; + + if (_packet >= transfer->num_iso_packets) + return NULL; + + return transfer->buffer + (transfer->iso_packet_desc[0].length * _packet); +} + +/* sync I/O */ + +int LIBUSB_CALL libusb_control_transfer(libusb_device_handle *dev_handle, + uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + unsigned char *data, uint16_t wLength, unsigned int timeout); + +int LIBUSB_CALL libusb_bulk_transfer(libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *data, int length, + int *actual_length, unsigned int timeout); + +int LIBUSB_CALL libusb_interrupt_transfer(libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *data, int length, + int *actual_length, unsigned int timeout); + +/** \ingroup desc + * Retrieve a descriptor from the default control pipe. + * This is a convenience function which formulates the appropriate control + * message to retrieve the descriptor. + * + * \param dev a device handle + * \param desc_type the descriptor type, see \ref libusb_descriptor_type + * \param desc_index the index of the descriptor to retrieve + * \param data output buffer for descriptor + * \param length size of data buffer + * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure + */ +static inline int libusb_get_descriptor(libusb_device_handle *dev, + uint8_t desc_type, uint8_t desc_index, unsigned char *data, int length) +{ + return libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, (desc_type << 8) | desc_index, 0, data, + (uint16_t) length, 1000); +} + +/** \ingroup desc + * Retrieve a descriptor from a device. + * This is a convenience function which formulates the appropriate control + * message to retrieve the descriptor. The string returned is Unicode, as + * detailed in the USB specifications. + * + * \param dev a device handle + * \param desc_index the index of the descriptor to retrieve + * \param langid the language ID for the string descriptor + * \param data output buffer for descriptor + * \param length size of data buffer + * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure + * \see libusb_get_string_descriptor_ascii() + */ +static inline int libusb_get_string_descriptor(libusb_device_handle *dev, + uint8_t desc_index, uint16_t langid, unsigned char *data, int length) +{ + return libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t)((LIBUSB_DT_STRING << 8) | desc_index), + langid, data, (uint16_t) length, 1000); +} + +int LIBUSB_CALL libusb_get_string_descriptor_ascii(libusb_device_handle *dev, + uint8_t desc_index, unsigned char *data, int length); + +/* polling and timeouts */ + +int LIBUSB_CALL libusb_try_lock_events(libusb_context *ctx); +void LIBUSB_CALL libusb_lock_events(libusb_context *ctx); +void LIBUSB_CALL libusb_unlock_events(libusb_context *ctx); +int LIBUSB_CALL libusb_event_handling_ok(libusb_context *ctx); +int LIBUSB_CALL libusb_event_handler_active(libusb_context *ctx); +void LIBUSB_CALL libusb_lock_event_waiters(libusb_context *ctx); +void LIBUSB_CALL libusb_unlock_event_waiters(libusb_context *ctx); +int LIBUSB_CALL libusb_wait_for_event(libusb_context *ctx, struct timeval *tv); + +int LIBUSB_CALL libusb_handle_events_timeout(libusb_context *ctx, + struct timeval *tv); +int LIBUSB_CALL libusb_handle_events_timeout_completed(libusb_context *ctx, + struct timeval *tv, int *completed); +int LIBUSB_CALL libusb_handle_events(libusb_context *ctx); +int LIBUSB_CALL libusb_handle_events_completed(libusb_context *ctx, int *completed); +int LIBUSB_CALL libusb_handle_events_locked(libusb_context *ctx, + struct timeval *tv); +int LIBUSB_CALL libusb_pollfds_handle_timeouts(libusb_context *ctx); +int LIBUSB_CALL libusb_get_next_timeout(libusb_context *ctx, + struct timeval *tv); + +/** \ingroup poll + * File descriptor for polling + */ +struct libusb_pollfd { + /** Numeric file descriptor */ + int fd; + + /** Event flags to poll for from . POLLIN indicates that you + * should monitor this file descriptor for becoming ready to read from, + * and POLLOUT indicates that you should monitor this file descriptor for + * nonblocking write readiness. */ + short events; +}; + +/** \ingroup poll + * Callback function, invoked when a new file descriptor should be added + * to the set of file descriptors monitored for events. + * \param fd the new file descriptor + * \param events events to monitor for, see \ref libusb_pollfd for a + * description + * \param user_data User data pointer specified in + * libusb_set_pollfd_notifiers() call + * \see libusb_set_pollfd_notifiers() + */ +typedef void (LIBUSB_CALL *libusb_pollfd_added_cb)(int fd, short events, + void *user_data); + +/** \ingroup poll + * Callback function, invoked when a file descriptor should be removed from + * the set of file descriptors being monitored for events. After returning + * from this callback, do not use that file descriptor again. + * \param fd the file descriptor to stop monitoring + * \param user_data User data pointer specified in + * libusb_set_pollfd_notifiers() call + * \see libusb_set_pollfd_notifiers() + */ +typedef void (LIBUSB_CALL *libusb_pollfd_removed_cb)(int fd, void *user_data); + +const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds( + libusb_context *ctx); +void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx, + libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, + void *user_data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Desktop_Interface/build_linux/libusb/libusb.h.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb.h.REMOVED.git-id deleted file mode 100644 index 547a024d..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -58b406f247fe3db891496f8b1ab8227f387e545e \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-core.lo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb_1_0_la-core.lo.REMOVED.git-id deleted file mode 100644 index 208cc0cc..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-core.lo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -30e5bee43039b6eadee6d209fb76f629d017802b \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-core.o.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb_1_0_la-core.o.REMOVED.git-id deleted file mode 100644 index b0ca5ae7..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-core.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -19e308387dc1230624f93ead6c5cf9cfe3b0d36b \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-descriptor.lo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb_1_0_la-descriptor.lo.REMOVED.git-id deleted file mode 100644 index 379f5c38..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-descriptor.lo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f1cc6dc9004226e74b9d2c09c50fa1f7fcb446d0 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-descriptor.o.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb_1_0_la-descriptor.o.REMOVED.git-id deleted file mode 100644 index 60dc0fa6..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-descriptor.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1e8439a484e516163a1fd16b6000d53d0d0aa700 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-io.lo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb_1_0_la-io.lo.REMOVED.git-id deleted file mode 100644 index 44e2df1f..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-io.lo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -dd09400664a0612dd822c00ca98424a2744c7e80 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-io.o.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb_1_0_la-io.o.REMOVED.git-id deleted file mode 100644 index 65be629a..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-io.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -01f698c6bf227ef3ef0bd00385dcd18213588745 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-linux_usbfs.lo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb_1_0_la-linux_usbfs.lo.REMOVED.git-id deleted file mode 100644 index ae36cebb..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-linux_usbfs.lo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -382263035b19f0b9298337497d016e26fbb09290 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-linux_usbfs.o.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb_1_0_la-linux_usbfs.o.REMOVED.git-id deleted file mode 100644 index 7432b4c9..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-linux_usbfs.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -396f330a239ab09c4a34322dd89046ae922142e8 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-sync.lo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb_1_0_la-sync.lo.REMOVED.git-id deleted file mode 100644 index 3d0ab670..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-sync.lo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -84dbf59dcac0ba5d9894256df2a309db042aeb4d \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-sync.o.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb_1_0_la-sync.o.REMOVED.git-id deleted file mode 100644 index ae68500d..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-sync.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aa7878919f97e51b54f9823177c3da057e5d836f \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-threads_posix.lo.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb_1_0_la-threads_posix.lo.REMOVED.git-id deleted file mode 100644 index 2dba13db..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-threads_posix.lo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -06e649cfd5f4624b1433c4c97709ac9433f72c2c \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-threads_posix.o.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusb_1_0_la-threads_posix.o.REMOVED.git-id deleted file mode 100644 index 44bcfbe2..00000000 --- a/Desktop_Interface/build_linux/libusb/libusb_1_0_la-threads_posix.o.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2aa87d195a17d088af8cb60a80b56be336ca77df \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/libusbi.h.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/libusbi.h.REMOVED.git-id deleted file mode 100644 index 9ea8d6a6..00000000 --- a/Desktop_Interface/build_linux/libusb/libusbi.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -976be0d13b6bf41a4685664563bebe5f1f7e8477 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/os/darwin_usb.c.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/os/darwin_usb.c.REMOVED.git-id deleted file mode 100644 index 3c7d0cf7..00000000 --- a/Desktop_Interface/build_linux/libusb/os/darwin_usb.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8834d0f958b3693c94a62a9724f76dd1a2447b1b \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/os/darwin_usb.h.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/os/darwin_usb.h.REMOVED.git-id deleted file mode 100644 index 1474ac47..00000000 --- a/Desktop_Interface/build_linux/libusb/os/darwin_usb.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -59d0a694cedea8f1d3141261312734ca2d6d9872 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/os/linux_usbfs.c.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/os/linux_usbfs.c.REMOVED.git-id deleted file mode 100644 index 966d59a3..00000000 --- a/Desktop_Interface/build_linux/libusb/os/linux_usbfs.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -02d182d65aa751ee55d9886a77c0f177a2e94709 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/os/linux_usbfs.h.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/os/linux_usbfs.h.REMOVED.git-id deleted file mode 100644 index 2bd49429..00000000 --- a/Desktop_Interface/build_linux/libusb/os/linux_usbfs.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -487acb5ac2576495930c9f8c7abb463f3d67639f \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/os/openbsd_usb.c.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/os/openbsd_usb.c.REMOVED.git-id deleted file mode 100644 index 22ab5102..00000000 --- a/Desktop_Interface/build_linux/libusb/os/openbsd_usb.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e31941bfecb5c9275525baea566258968d84c817 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/os/poll_posix.h.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/os/poll_posix.h.REMOVED.git-id deleted file mode 100644 index 0c26fba9..00000000 --- a/Desktop_Interface/build_linux/libusb/os/poll_posix.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0e5e7f5b720b112441663ee3bf9c6483689693ed \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/os/poll_windows.c.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/os/poll_windows.c.REMOVED.git-id deleted file mode 100644 index d5c908f1..00000000 --- a/Desktop_Interface/build_linux/libusb/os/poll_windows.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7f4d9c4e7e94def7a91a16624d16582a9f539a94 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/os/poll_windows.h.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/os/poll_windows.h.REMOVED.git-id deleted file mode 100644 index 1a02f45b..00000000 --- a/Desktop_Interface/build_linux/libusb/os/poll_windows.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6e5bf2bcef40da7bb1b27bcb367436378a0f802b \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/os/threads_posix.c.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/os/threads_posix.c.REMOVED.git-id deleted file mode 100644 index e536db6a..00000000 --- a/Desktop_Interface/build_linux/libusb/os/threads_posix.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -60c57cf81e63e92d1f5c252bdb18040d4e08140b \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/os/threads_posix.h.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/os/threads_posix.h.REMOVED.git-id deleted file mode 100644 index 67d9cc6c..00000000 --- a/Desktop_Interface/build_linux/libusb/os/threads_posix.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -97522089369ba69a922e6520fc5af9b697916a43 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/os/threads_windows.c.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/os/threads_windows.c.REMOVED.git-id deleted file mode 100644 index 56f66e95..00000000 --- a/Desktop_Interface/build_linux/libusb/os/threads_windows.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1394bb0f80174b4b41874060190dd27a3cf8e3d2 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/os/threads_windows.h.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/os/threads_windows.h.REMOVED.git-id deleted file mode 100644 index 61f7e89f..00000000 --- a/Desktop_Interface/build_linux/libusb/os/threads_windows.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7bb144af584c2a66e660bf37eb0f23978086e770 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/os/windows_usb.c.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/os/windows_usb.c.REMOVED.git-id deleted file mode 100644 index 93bdb5d0..00000000 --- a/Desktop_Interface/build_linux/libusb/os/windows_usb.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0739c1924265e0a17ef49ec1bcc48946cf935e97 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/os/windows_usb.h.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/os/windows_usb.h.REMOVED.git-id deleted file mode 100644 index 802b4933..00000000 --- a/Desktop_Interface/build_linux/libusb/os/windows_usb.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ddbd68075b97871ee0e1973d84f3a310acf54cd7 \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/sync.c.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/sync.c.REMOVED.git-id deleted file mode 100644 index baf477d7..00000000 --- a/Desktop_Interface/build_linux/libusb/sync.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8eed47b68a8737ba3ffd8d8c881468521525c68d \ No newline at end of file diff --git a/Desktop_Interface/build_linux/libusb/version.h.REMOVED.git-id b/Desktop_Interface/build_linux/libusb/version.h.REMOVED.git-id deleted file mode 100644 index 7312a661..00000000 --- a/Desktop_Interface/build_linux/libusb/version.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -62446da871174fe85551c9d2b315a6910262c1be \ No newline at end of file diff --git a/Desktop_Interface/build_linux/platformspecific.h b/Desktop_Interface/build_linux/platformspecific.h new file mode 100644 index 00000000..7373f179 --- /dev/null +++ b/Desktop_Interface/build_linux/platformspecific.h @@ -0,0 +1,9 @@ +#ifndef PLATFORMSPECIFIC_H +#define PLATFORMSPECIFIC_H + +#include "unixusbdriver.h" +#define PLATFORM_LINUX +#define _PLATFORM_DEPENDENT_USB_OBJECT unixUsbDriver +#define _PLATFORM_DEPENDENT_FOLDER_ACTION + +#endif // PLATFORMSPECIFIC_H diff --git a/Desktop_Interface/build_linux/platformspecific.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/build_linux/platformspecific.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 80cdca3d..00000000 --- a/Desktop_Interface/build_linux/platformspecific.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2b2a1db81679331316ecfb7f2eec549e6d052e75 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libdfuprog/include/libdfuprog.h b/Desktop_Interface/build_mac/libdfuprog/include/libdfuprog.h new file mode 100644 index 00000000..a93da6a3 --- /dev/null +++ b/Desktop_Interface/build_mac/libdfuprog/include/libdfuprog.h @@ -0,0 +1,6 @@ +#ifndef LIBDFUPROG_H +#define LIBDFUPROG_H + +int dfuprog_virtual_cmd(char* commandLine); + +#endif diff --git a/Desktop_Interface/build_mac/libdfuprog/include/libdfuprog.h.REMOVED.git-id b/Desktop_Interface/build_mac/libdfuprog/include/libdfuprog.h.REMOVED.git-id deleted file mode 100644 index 6ad77c07..00000000 --- a/Desktop_Interface/build_mac/libdfuprog/include/libdfuprog.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a93da6a335dcd982c2d16a2a8ffe31086bab90c1 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libdfuprog/lib/libdfuprog-0.9.dylib b/Desktop_Interface/build_mac/libdfuprog/lib/libdfuprog-0.9.dylib new file mode 100644 index 00000000..7441cdb8 Binary files /dev/null and b/Desktop_Interface/build_mac/libdfuprog/lib/libdfuprog-0.9.dylib differ diff --git a/Desktop_Interface/build_mac/libdfuprog/lib/libdfuprog-0.9.dylib.REMOVED.git-id b/Desktop_Interface/build_mac/libdfuprog/lib/libdfuprog-0.9.dylib.REMOVED.git-id deleted file mode 100644 index 77c2ff37..00000000 --- a/Desktop_Interface/build_mac/libdfuprog/lib/libdfuprog-0.9.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7441cdb891d71caf3dcf7323879bdf88eebaa904 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/AUTHORS.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/AUTHORS.REMOVED.git-id deleted file mode 100644 index 9b407b69..00000000 --- a/Desktop_Interface/build_mac/libusb/AUTHORS.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b7d7ac9b4f07124a418f693d78762367563e2aa1 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/COPYING.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/COPYING.REMOVED.git-id deleted file mode 100644 index 20d78510..00000000 --- a/Desktop_Interface/build_mac/libusb/COPYING.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5ab7695ab8cabe0c5c8a814bb0ab1e8066578fbb \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/ChangeLog.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/ChangeLog.REMOVED.git-id deleted file mode 100644 index 796fe18d..00000000 --- a/Desktop_Interface/build_mac/libusb/ChangeLog.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fc5fc2ad5f517d4174da8c6fae443dc8b28bc552 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/INSTALL_RECEIPT.json.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/INSTALL_RECEIPT.json.REMOVED.git-id deleted file mode 100644 index e9281aa0..00000000 --- a/Desktop_Interface/build_mac/libusb/INSTALL_RECEIPT.json.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f03988be9c9794db4658bf6b4d683ba0f24db27a \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/NEWS.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/NEWS.REMOVED.git-id deleted file mode 100644 index 1da3da4a..00000000 --- a/Desktop_Interface/build_mac/libusb/NEWS.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4fc85af1e92f815f1e93fa18306a8732d153fcad \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/README.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/README.REMOVED.git-id deleted file mode 100644 index 6757ff84..00000000 --- a/Desktop_Interface/build_mac/libusb/README.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9d434f97278377c05fddca4842eda27ebb6a0417 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/TODO.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/TODO.REMOVED.git-id deleted file mode 100644 index 9614cddf..00000000 --- a/Desktop_Interface/build_mac/libusb/TODO.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -19dd1d0e6f2e985354c7331e5b4dec26514fa60d \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/include/libusb-1.0/libusb.h b/Desktop_Interface/build_mac/libusb/include/libusb-1.0/libusb.h new file mode 100644 index 00000000..513945f0 --- /dev/null +++ b/Desktop_Interface/build_mac/libusb/include/libusb-1.0/libusb.h @@ -0,0 +1,1999 @@ +/* + * Public libusb header file + * Copyright © 2001 Johannes Erdfelt + * Copyright © 2007-2008 Daniel Drake + * Copyright © 2012 Pete Batard + * Copyright © 2012 Nathan Hjelm + * For more information, please visit: http://libusb.info + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LIBUSB_H +#define LIBUSB_H + +#ifdef _MSC_VER +/* on MS environments, the inline keyword is available in C++ only */ +#if !defined(__cplusplus) +#define inline __inline +#endif +/* ssize_t is also not available (copy/paste from MinGW) */ +#ifndef _SSIZE_T_DEFINED +#define _SSIZE_T_DEFINED +#undef ssize_t +#ifdef _WIN64 + typedef __int64 ssize_t; +#else + typedef int ssize_t; +#endif /* _WIN64 */ +#endif /* _SSIZE_T_DEFINED */ +#endif /* _MSC_VER */ + +/* stdint.h is not available on older MSVC */ +#if defined(_MSC_VER) && (_MSC_VER < 1600) && (!defined(_STDINT)) && (!defined(_STDINT_H)) +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +#else +#include +#endif + +#if !defined(_WIN32_WCE) +#include +#endif + +#if defined(__linux) || defined(__APPLE__) || defined(__CYGWIN__) || defined(__HAIKU__) +#include +#endif + +#include +#include + +/* 'interface' might be defined as a macro on Windows, so we need to + * undefine it so as not to break the current libusb API, because + * libusb_config_descriptor has an 'interface' member + * As this can be problematic if you include windows.h after libusb.h + * in your sources, we force windows.h to be included first. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +#include +#if defined(interface) +#undef interface +#endif +#if !defined(__CYGWIN__) +#include +#endif +#endif + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#define LIBUSB_DEPRECATED_FOR(f) \ + __attribute__((deprecated("Use " #f " instead"))) +#else +#define LIBUSB_DEPRECATED_FOR(f) +#endif /* __GNUC__ */ + +/** \def LIBUSB_CALL + * \ingroup misc + * libusb's Windows calling convention. + * + * Under Windows, the selection of available compilers and configurations + * means that, unlike other platforms, there is not one true calling + * convention (calling convention: the manner in which parameters are + * passed to functions in the generated assembly code). + * + * Matching the Windows API itself, libusb uses the WINAPI convention (which + * translates to the stdcall convention) and guarantees that the + * library is compiled in this way. The public header file also includes + * appropriate annotations so that your own software will use the right + * convention, even if another convention is being used by default within + * your codebase. + * + * The one consideration that you must apply in your software is to mark + * all functions which you use as libusb callbacks with this LIBUSB_CALL + * annotation, so that they too get compiled for the correct calling + * convention. + * + * On non-Windows operating systems, this macro is defined as nothing. This + * means that you can apply it to your code without worrying about + * cross-platform compatibility. + */ +/* LIBUSB_CALL must be defined on both definition and declaration of libusb + * functions. You'd think that declaration would be enough, but cygwin will + * complain about conflicting types unless both are marked this way. + * The placement of this macro is important too; it must appear after the + * return type, before the function name. See internal documentation for + * API_EXPORTED. + */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +#define LIBUSB_CALL WINAPI +#else +#define LIBUSB_CALL +#endif + +/** \def LIBUSB_API_VERSION + * \ingroup misc + * libusb's API version. + * + * Since version 1.0.13, to help with feature detection, libusb defines + * a LIBUSB_API_VERSION macro that gets increased every time there is a + * significant change to the API, such as the introduction of a new call, + * the definition of a new macro/enum member, or any other element that + * libusb applications may want to detect at compilation time. + * + * The macro is typically used in an application as follows: + * \code + * #if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01001234) + * // Use one of the newer features from the libusb API + * #endif + * \endcode + * + * Internally, LIBUSB_API_VERSION is defined as follows: + * (libusb major << 24) | (libusb minor << 16) | (16 bit incremental) + */ +#define LIBUSB_API_VERSION 0x01000104 + +/* The following is kept for compatibility, but will be deprecated in the future */ +#define LIBUSBX_API_VERSION LIBUSB_API_VERSION + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup misc + * Convert a 16-bit value from host-endian to little-endian format. On + * little endian systems, this function does nothing. On big endian systems, + * the bytes are swapped. + * \param x the host-endian value to convert + * \returns the value in little-endian byte order + */ +static inline uint16_t libusb_cpu_to_le16(const uint16_t x) +{ + union { + uint8_t b8[2]; + uint16_t b16; + } _tmp; + _tmp.b8[1] = (uint8_t) (x >> 8); + _tmp.b8[0] = (uint8_t) (x & 0xff); + return _tmp.b16; +} + +/** \def libusb_le16_to_cpu + * \ingroup misc + * Convert a 16-bit value from little-endian to host-endian format. On + * little endian systems, this function does nothing. On big endian systems, + * the bytes are swapped. + * \param x the little-endian value to convert + * \returns the value in host-endian byte order + */ +#define libusb_le16_to_cpu libusb_cpu_to_le16 + +/* standard USB stuff */ + +/** \ingroup desc + * Device and/or Interface Class codes */ +enum libusb_class_code { + /** In the context of a \ref libusb_device_descriptor "device descriptor", + * this bDeviceClass value indicates that each interface specifies its + * own class information and all interfaces operate independently. + */ + LIBUSB_CLASS_PER_INTERFACE = 0, + + /** Audio class */ + LIBUSB_CLASS_AUDIO = 1, + + /** Communications class */ + LIBUSB_CLASS_COMM = 2, + + /** Human Interface Device class */ + LIBUSB_CLASS_HID = 3, + + /** Physical */ + LIBUSB_CLASS_PHYSICAL = 5, + + /** Printer class */ + LIBUSB_CLASS_PRINTER = 7, + + /** Image class */ + LIBUSB_CLASS_PTP = 6, /* legacy name from libusb-0.1 usb.h */ + LIBUSB_CLASS_IMAGE = 6, + + /** Mass storage class */ + LIBUSB_CLASS_MASS_STORAGE = 8, + + /** Hub class */ + LIBUSB_CLASS_HUB = 9, + + /** Data class */ + LIBUSB_CLASS_DATA = 10, + + /** Smart Card */ + LIBUSB_CLASS_SMART_CARD = 0x0b, + + /** Content Security */ + LIBUSB_CLASS_CONTENT_SECURITY = 0x0d, + + /** Video */ + LIBUSB_CLASS_VIDEO = 0x0e, + + /** Personal Healthcare */ + LIBUSB_CLASS_PERSONAL_HEALTHCARE = 0x0f, + + /** Diagnostic Device */ + LIBUSB_CLASS_DIAGNOSTIC_DEVICE = 0xdc, + + /** Wireless class */ + LIBUSB_CLASS_WIRELESS = 0xe0, + + /** Application class */ + LIBUSB_CLASS_APPLICATION = 0xfe, + + /** Class is vendor-specific */ + LIBUSB_CLASS_VENDOR_SPEC = 0xff +}; + +/** \ingroup desc + * Descriptor types as defined by the USB specification. */ +enum libusb_descriptor_type { + /** Device descriptor. See libusb_device_descriptor. */ + LIBUSB_DT_DEVICE = 0x01, + + /** Configuration descriptor. See libusb_config_descriptor. */ + LIBUSB_DT_CONFIG = 0x02, + + /** String descriptor */ + LIBUSB_DT_STRING = 0x03, + + /** Interface descriptor. See libusb_interface_descriptor. */ + LIBUSB_DT_INTERFACE = 0x04, + + /** Endpoint descriptor. See libusb_endpoint_descriptor. */ + LIBUSB_DT_ENDPOINT = 0x05, + + /** BOS descriptor */ + LIBUSB_DT_BOS = 0x0f, + + /** Device Capability descriptor */ + LIBUSB_DT_DEVICE_CAPABILITY = 0x10, + + /** HID descriptor */ + LIBUSB_DT_HID = 0x21, + + /** HID report descriptor */ + LIBUSB_DT_REPORT = 0x22, + + /** Physical descriptor */ + LIBUSB_DT_PHYSICAL = 0x23, + + /** Hub descriptor */ + LIBUSB_DT_HUB = 0x29, + + /** SuperSpeed Hub descriptor */ + LIBUSB_DT_SUPERSPEED_HUB = 0x2a, + + /** SuperSpeed Endpoint Companion descriptor */ + LIBUSB_DT_SS_ENDPOINT_COMPANION = 0x30 +}; + +/* Descriptor sizes per descriptor type */ +#define LIBUSB_DT_DEVICE_SIZE 18 +#define LIBUSB_DT_CONFIG_SIZE 9 +#define LIBUSB_DT_INTERFACE_SIZE 9 +#define LIBUSB_DT_ENDPOINT_SIZE 7 +#define LIBUSB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ +#define LIBUSB_DT_HUB_NONVAR_SIZE 7 +#define LIBUSB_DT_SS_ENDPOINT_COMPANION_SIZE 6 +#define LIBUSB_DT_BOS_SIZE 5 +#define LIBUSB_DT_DEVICE_CAPABILITY_SIZE 3 + +/* BOS descriptor sizes */ +#define LIBUSB_BT_USB_2_0_EXTENSION_SIZE 7 +#define LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE 10 +#define LIBUSB_BT_CONTAINER_ID_SIZE 20 + +/* We unwrap the BOS => define its max size */ +#define LIBUSB_DT_BOS_MAX_SIZE ((LIBUSB_DT_BOS_SIZE) +\ + (LIBUSB_BT_USB_2_0_EXTENSION_SIZE) +\ + (LIBUSB_BT_SS_USB_DEVICE_CAPABILITY_SIZE) +\ + (LIBUSB_BT_CONTAINER_ID_SIZE)) + +#define LIBUSB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */ +#define LIBUSB_ENDPOINT_DIR_MASK 0x80 + +/** \ingroup desc + * Endpoint direction. Values for bit 7 of the + * \ref libusb_endpoint_descriptor::bEndpointAddress "endpoint address" scheme. + */ +enum libusb_endpoint_direction { + /** In: device-to-host */ + LIBUSB_ENDPOINT_IN = 0x80, + + /** Out: host-to-device */ + LIBUSB_ENDPOINT_OUT = 0x00 +}; + +#define LIBUSB_TRANSFER_TYPE_MASK 0x03 /* in bmAttributes */ + +/** \ingroup desc + * Endpoint transfer type. Values for bits 0:1 of the + * \ref libusb_endpoint_descriptor::bmAttributes "endpoint attributes" field. + */ +enum libusb_transfer_type { + /** Control endpoint */ + LIBUSB_TRANSFER_TYPE_CONTROL = 0, + + /** Isochronous endpoint */ + LIBUSB_TRANSFER_TYPE_ISOCHRONOUS = 1, + + /** Bulk endpoint */ + LIBUSB_TRANSFER_TYPE_BULK = 2, + + /** Interrupt endpoint */ + LIBUSB_TRANSFER_TYPE_INTERRUPT = 3, + + /** Stream endpoint */ + LIBUSB_TRANSFER_TYPE_BULK_STREAM = 4, +}; + +/** \ingroup misc + * Standard requests, as defined in table 9-5 of the USB 3.0 specifications */ +enum libusb_standard_request { + /** Request status of the specific recipient */ + LIBUSB_REQUEST_GET_STATUS = 0x00, + + /** Clear or disable a specific feature */ + LIBUSB_REQUEST_CLEAR_FEATURE = 0x01, + + /* 0x02 is reserved */ + + /** Set or enable a specific feature */ + LIBUSB_REQUEST_SET_FEATURE = 0x03, + + /* 0x04 is reserved */ + + /** Set device address for all future accesses */ + LIBUSB_REQUEST_SET_ADDRESS = 0x05, + + /** Get the specified descriptor */ + LIBUSB_REQUEST_GET_DESCRIPTOR = 0x06, + + /** Used to update existing descriptors or add new descriptors */ + LIBUSB_REQUEST_SET_DESCRIPTOR = 0x07, + + /** Get the current device configuration value */ + LIBUSB_REQUEST_GET_CONFIGURATION = 0x08, + + /** Set device configuration */ + LIBUSB_REQUEST_SET_CONFIGURATION = 0x09, + + /** Return the selected alternate setting for the specified interface */ + LIBUSB_REQUEST_GET_INTERFACE = 0x0A, + + /** Select an alternate interface for the specified interface */ + LIBUSB_REQUEST_SET_INTERFACE = 0x0B, + + /** Set then report an endpoint's synchronization frame */ + LIBUSB_REQUEST_SYNCH_FRAME = 0x0C, + + /** Sets both the U1 and U2 Exit Latency */ + LIBUSB_REQUEST_SET_SEL = 0x30, + + /** Delay from the time a host transmits a packet to the time it is + * received by the device. */ + LIBUSB_SET_ISOCH_DELAY = 0x31, +}; + +/** \ingroup misc + * Request type bits of the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field in control + * transfers. */ +enum libusb_request_type { + /** Standard */ + LIBUSB_REQUEST_TYPE_STANDARD = (0x00 << 5), + + /** Class */ + LIBUSB_REQUEST_TYPE_CLASS = (0x01 << 5), + + /** Vendor */ + LIBUSB_REQUEST_TYPE_VENDOR = (0x02 << 5), + + /** Reserved */ + LIBUSB_REQUEST_TYPE_RESERVED = (0x03 << 5) +}; + +/** \ingroup misc + * Recipient bits of the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field in control + * transfers. Values 4 through 31 are reserved. */ +enum libusb_request_recipient { + /** Device */ + LIBUSB_RECIPIENT_DEVICE = 0x00, + + /** Interface */ + LIBUSB_RECIPIENT_INTERFACE = 0x01, + + /** Endpoint */ + LIBUSB_RECIPIENT_ENDPOINT = 0x02, + + /** Other */ + LIBUSB_RECIPIENT_OTHER = 0x03, +}; + +#define LIBUSB_ISO_SYNC_TYPE_MASK 0x0C + +/** \ingroup desc + * Synchronization type for isochronous endpoints. Values for bits 2:3 of the + * \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in + * libusb_endpoint_descriptor. + */ +enum libusb_iso_sync_type { + /** No synchronization */ + LIBUSB_ISO_SYNC_TYPE_NONE = 0, + + /** Asynchronous */ + LIBUSB_ISO_SYNC_TYPE_ASYNC = 1, + + /** Adaptive */ + LIBUSB_ISO_SYNC_TYPE_ADAPTIVE = 2, + + /** Synchronous */ + LIBUSB_ISO_SYNC_TYPE_SYNC = 3 +}; + +#define LIBUSB_ISO_USAGE_TYPE_MASK 0x30 + +/** \ingroup desc + * Usage type for isochronous endpoints. Values for bits 4:5 of the + * \ref libusb_endpoint_descriptor::bmAttributes "bmAttributes" field in + * libusb_endpoint_descriptor. + */ +enum libusb_iso_usage_type { + /** Data endpoint */ + LIBUSB_ISO_USAGE_TYPE_DATA = 0, + + /** Feedback endpoint */ + LIBUSB_ISO_USAGE_TYPE_FEEDBACK = 1, + + /** Implicit feedback Data endpoint */ + LIBUSB_ISO_USAGE_TYPE_IMPLICIT = 2, +}; + +/** \ingroup desc + * A structure representing the standard USB device descriptor. This + * descriptor is documented in section 9.6.1 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_device_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE LIBUSB_DT_DEVICE in this + * context. */ + uint8_t bDescriptorType; + + /** USB specification release number in binary-coded decimal. A value of + * 0x0200 indicates USB 2.0, 0x0110 indicates USB 1.1, etc. */ + uint16_t bcdUSB; + + /** USB-IF class code for the device. See \ref libusb_class_code. */ + uint8_t bDeviceClass; + + /** USB-IF subclass code for the device, qualified by the bDeviceClass + * value */ + uint8_t bDeviceSubClass; + + /** USB-IF protocol code for the device, qualified by the bDeviceClass and + * bDeviceSubClass values */ + uint8_t bDeviceProtocol; + + /** Maximum packet size for endpoint 0 */ + uint8_t bMaxPacketSize0; + + /** USB-IF vendor ID */ + uint16_t idVendor; + + /** USB-IF product ID */ + uint16_t idProduct; + + /** Device release number in binary-coded decimal */ + uint16_t bcdDevice; + + /** Index of string descriptor describing manufacturer */ + uint8_t iManufacturer; + + /** Index of string descriptor describing product */ + uint8_t iProduct; + + /** Index of string descriptor containing device serial number */ + uint8_t iSerialNumber; + + /** Number of possible configurations */ + uint8_t bNumConfigurations; +}; + +/** \ingroup desc + * A structure representing the standard USB endpoint descriptor. This + * descriptor is documented in section 9.6.6 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_endpoint_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_ENDPOINT LIBUSB_DT_ENDPOINT in + * this context. */ + uint8_t bDescriptorType; + + /** The address of the endpoint described by this descriptor. Bits 0:3 are + * the endpoint number. Bits 4:6 are reserved. Bit 7 indicates direction, + * see \ref libusb_endpoint_direction. + */ + uint8_t bEndpointAddress; + + /** Attributes which apply to the endpoint when it is configured using + * the bConfigurationValue. Bits 0:1 determine the transfer type and + * correspond to \ref libusb_transfer_type. Bits 2:3 are only used for + * isochronous endpoints and correspond to \ref libusb_iso_sync_type. + * Bits 4:5 are also only used for isochronous endpoints and correspond to + * \ref libusb_iso_usage_type. Bits 6:7 are reserved. + */ + uint8_t bmAttributes; + + /** Maximum packet size this endpoint is capable of sending/receiving. */ + uint16_t wMaxPacketSize; + + /** Interval for polling endpoint for data transfers. */ + uint8_t bInterval; + + /** For audio devices only: the rate at which synchronization feedback + * is provided. */ + uint8_t bRefresh; + + /** For audio devices only: the address if the synch endpoint */ + uint8_t bSynchAddress; + + /** Extra descriptors. If libusb encounters unknown endpoint descriptors, + * it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup desc + * A structure representing the standard USB interface descriptor. This + * descriptor is documented in section 9.6.5 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_interface_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_INTERFACE LIBUSB_DT_INTERFACE + * in this context. */ + uint8_t bDescriptorType; + + /** Number of this interface */ + uint8_t bInterfaceNumber; + + /** Value used to select this alternate setting for this interface */ + uint8_t bAlternateSetting; + + /** Number of endpoints used by this interface (excluding the control + * endpoint). */ + uint8_t bNumEndpoints; + + /** USB-IF class code for this interface. See \ref libusb_class_code. */ + uint8_t bInterfaceClass; + + /** USB-IF subclass code for this interface, qualified by the + * bInterfaceClass value */ + uint8_t bInterfaceSubClass; + + /** USB-IF protocol code for this interface, qualified by the + * bInterfaceClass and bInterfaceSubClass values */ + uint8_t bInterfaceProtocol; + + /** Index of string descriptor describing this interface */ + uint8_t iInterface; + + /** Array of endpoint descriptors. This length of this array is determined + * by the bNumEndpoints field. */ + const struct libusb_endpoint_descriptor *endpoint; + + /** Extra descriptors. If libusb encounters unknown interface descriptors, + * it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup desc + * A collection of alternate settings for a particular USB interface. + */ +struct libusb_interface { + /** Array of interface descriptors. The length of this array is determined + * by the num_altsetting field. */ + const struct libusb_interface_descriptor *altsetting; + + /** The number of alternate settings that belong to this interface */ + int num_altsetting; +}; + +/** \ingroup desc + * A structure representing the standard USB configuration descriptor. This + * descriptor is documented in section 9.6.3 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_config_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_CONFIG LIBUSB_DT_CONFIG + * in this context. */ + uint8_t bDescriptorType; + + /** Total length of data returned for this configuration */ + uint16_t wTotalLength; + + /** Number of interfaces supported by this configuration */ + uint8_t bNumInterfaces; + + /** Identifier value for this configuration */ + uint8_t bConfigurationValue; + + /** Index of string descriptor describing this configuration */ + uint8_t iConfiguration; + + /** Configuration characteristics */ + uint8_t bmAttributes; + + /** Maximum power consumption of the USB device from this bus in this + * configuration when the device is fully operation. Expressed in units + * of 2 mA when the device is operating in high-speed mode and in units + * of 8 mA when the device is operating in super-speed mode. */ + uint8_t MaxPower; + + /** Array of interfaces supported by this configuration. The length of + * this array is determined by the bNumInterfaces field. */ + const struct libusb_interface *interface; + + /** Extra descriptors. If libusb encounters unknown configuration + * descriptors, it will store them here, should you wish to parse them. */ + const unsigned char *extra; + + /** Length of the extra descriptors, in bytes. */ + int extra_length; +}; + +/** \ingroup desc + * A structure representing the superspeed endpoint companion + * descriptor. This descriptor is documented in section 9.6.7 of + * the USB 3.0 specification. All multiple-byte fields are represented in + * host-endian format. + */ +struct libusb_ss_endpoint_companion_descriptor { + + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_SS_ENDPOINT_COMPANION in + * this context. */ + uint8_t bDescriptorType; + + + /** The maximum number of packets the endpoint can send or + * recieve as part of a burst. */ + uint8_t bMaxBurst; + + /** In bulk EP: bits 4:0 represents the maximum number of + * streams the EP supports. In isochronous EP: bits 1:0 + * represents the Mult - a zero based value that determines + * the maximum number of packets within a service interval */ + uint8_t bmAttributes; + + /** The total number of bytes this EP will transfer every + * service interval. valid only for periodic EPs. */ + uint16_t wBytesPerInterval; +}; + +/** \ingroup desc + * A generic representation of a BOS Device Capability descriptor. It is + * advised to check bDevCapabilityType and call the matching + * libusb_get_*_descriptor function to get a structure fully matching the type. + */ +struct libusb_bos_dev_capability_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + /** Device Capability type */ + uint8_t bDevCapabilityType; + /** Device Capability data (bLength - 3 bytes) */ + uint8_t dev_capability_data +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif + ; +}; + +/** \ingroup desc + * A structure representing the Binary Device Object Store (BOS) descriptor. + * This descriptor is documented in section 9.6.2 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_bos_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_BOS LIBUSB_DT_BOS + * in this context. */ + uint8_t bDescriptorType; + + /** Length of this descriptor and all of its sub descriptors */ + uint16_t wTotalLength; + + /** The number of separate device capability descriptors in + * the BOS */ + uint8_t bNumDeviceCaps; + + /** bNumDeviceCap Device Capability Descriptors */ + struct libusb_bos_dev_capability_descriptor *dev_capability +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif + ; +}; + +/** \ingroup desc + * A structure representing the USB 2.0 Extension descriptor + * This descriptor is documented in section 9.6.2.1 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_usb_2_0_extension_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + + /** Capability type. Will have value + * \ref libusb_capability_type::LIBUSB_BT_USB_2_0_EXTENSION + * LIBUSB_BT_USB_2_0_EXTENSION in this context. */ + uint8_t bDevCapabilityType; + + /** Bitmap encoding of supported device level features. + * A value of one in a bit location indicates a feature is + * supported; a value of zero indicates it is not supported. + * See \ref libusb_usb_2_0_extension_attributes. */ + uint32_t bmAttributes; +}; + +/** \ingroup desc + * A structure representing the SuperSpeed USB Device Capability descriptor + * This descriptor is documented in section 9.6.2.2 of the USB 3.0 specification. + * All multiple-byte fields are represented in host-endian format. + */ +struct libusb_ss_usb_device_capability_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + + /** Capability type. Will have value + * \ref libusb_capability_type::LIBUSB_BT_SS_USB_DEVICE_CAPABILITY + * LIBUSB_BT_SS_USB_DEVICE_CAPABILITY in this context. */ + uint8_t bDevCapabilityType; + + /** Bitmap encoding of supported device level features. + * A value of one in a bit location indicates a feature is + * supported; a value of zero indicates it is not supported. + * See \ref libusb_ss_usb_device_capability_attributes. */ + uint8_t bmAttributes; + + /** Bitmap encoding of the speed supported by this device when + * operating in SuperSpeed mode. See \ref libusb_supported_speed. */ + uint16_t wSpeedSupported; + + /** The lowest speed at which all the functionality supported + * by the device is available to the user. For example if the + * device supports all its functionality when connected at + * full speed and above then it sets this value to 1. */ + uint8_t bFunctionalitySupport; + + /** U1 Device Exit Latency. */ + uint8_t bU1DevExitLat; + + /** U2 Device Exit Latency. */ + uint16_t bU2DevExitLat; +}; + +/** \ingroup desc + * A structure representing the Container ID descriptor. + * This descriptor is documented in section 9.6.2.3 of the USB 3.0 specification. + * All multiple-byte fields, except UUIDs, are represented in host-endian format. + */ +struct libusb_container_id_descriptor { + /** Size of this descriptor (in bytes) */ + uint8_t bLength; + + /** Descriptor type. Will have value + * \ref libusb_descriptor_type::LIBUSB_DT_DEVICE_CAPABILITY + * LIBUSB_DT_DEVICE_CAPABILITY in this context. */ + uint8_t bDescriptorType; + + /** Capability type. Will have value + * \ref libusb_capability_type::LIBUSB_BT_CONTAINER_ID + * LIBUSB_BT_CONTAINER_ID in this context. */ + uint8_t bDevCapabilityType; + + /** Reserved field */ + uint8_t bReserved; + + /** 128 bit UUID */ + uint8_t ContainerID[16]; +}; + +/** \ingroup asyncio + * Setup packet for control transfers. */ +struct libusb_control_setup { + /** Request type. Bits 0:4 determine recipient, see + * \ref libusb_request_recipient. Bits 5:6 determine type, see + * \ref libusb_request_type. Bit 7 determines data transfer direction, see + * \ref libusb_endpoint_direction. + */ + uint8_t bmRequestType; + + /** Request. If the type bits of bmRequestType are equal to + * \ref libusb_request_type::LIBUSB_REQUEST_TYPE_STANDARD + * "LIBUSB_REQUEST_TYPE_STANDARD" then this field refers to + * \ref libusb_standard_request. For other cases, use of this field is + * application-specific. */ + uint8_t bRequest; + + /** Value. Varies according to request */ + uint16_t wValue; + + /** Index. Varies according to request, typically used to pass an index + * or offset */ + uint16_t wIndex; + + /** Number of bytes to transfer */ + uint16_t wLength; +}; + +#define LIBUSB_CONTROL_SETUP_SIZE (sizeof(struct libusb_control_setup)) + +/* libusb */ + +struct libusb_context; +struct libusb_device; +struct libusb_device_handle; + +/** \ingroup lib + * Structure providing the version of the libusb runtime + */ +struct libusb_version { + /** Library major version. */ + const uint16_t major; + + /** Library minor version. */ + const uint16_t minor; + + /** Library micro version. */ + const uint16_t micro; + + /** Library nano version. */ + const uint16_t nano; + + /** Library release candidate suffix string, e.g. "-rc4". */ + const char *rc; + + /** For ABI compatibility only. */ + const char* describe; +}; + +/** \ingroup lib + * Structure representing a libusb session. The concept of individual libusb + * sessions allows for your program to use two libraries (or dynamically + * load two modules) which both independently use libusb. This will prevent + * interference between the individual libusb users - for example + * libusb_set_debug() will not affect the other user of the library, and + * libusb_exit() will not destroy resources that the other user is still + * using. + * + * Sessions are created by libusb_init() and destroyed through libusb_exit(). + * If your application is guaranteed to only ever include a single libusb + * user (i.e. you), you do not have to worry about contexts: pass NULL in + * every function call where a context is required. The default context + * will be used. + * + * For more information, see \ref contexts. + */ +typedef struct libusb_context libusb_context; + +/** \ingroup dev + * Structure representing a USB device detected on the system. This is an + * opaque type for which you are only ever provided with a pointer, usually + * originating from libusb_get_device_list(). + * + * Certain operations can be performed on a device, but in order to do any + * I/O you will have to first obtain a device handle using libusb_open(). + * + * Devices are reference counted with libusb_ref_device() and + * libusb_unref_device(), and are freed when the reference count reaches 0. + * New devices presented by libusb_get_device_list() have a reference count of + * 1, and libusb_free_device_list() can optionally decrease the reference count + * on all devices in the list. libusb_open() adds another reference which is + * later destroyed by libusb_close(). + */ +typedef struct libusb_device libusb_device; + + +/** \ingroup dev + * Structure representing a handle on a USB device. This is an opaque type for + * which you are only ever provided with a pointer, usually originating from + * libusb_open(). + * + * A device handle is used to perform I/O and other operations. When finished + * with a device handle, you should call libusb_close(). + */ +typedef struct libusb_device_handle libusb_device_handle; + +/** \ingroup dev + * Speed codes. Indicates the speed at which the device is operating. + */ +enum libusb_speed { + /** The OS doesn't report or know the device speed. */ + LIBUSB_SPEED_UNKNOWN = 0, + + /** The device is operating at low speed (1.5MBit/s). */ + LIBUSB_SPEED_LOW = 1, + + /** The device is operating at full speed (12MBit/s). */ + LIBUSB_SPEED_FULL = 2, + + /** The device is operating at high speed (480MBit/s). */ + LIBUSB_SPEED_HIGH = 3, + + /** The device is operating at super speed (5000MBit/s). */ + LIBUSB_SPEED_SUPER = 4, +}; + +/** \ingroup dev + * Supported speeds (wSpeedSupported) bitfield. Indicates what + * speeds the device supports. + */ +enum libusb_supported_speed { + /** Low speed operation supported (1.5MBit/s). */ + LIBUSB_LOW_SPEED_OPERATION = 1, + + /** Full speed operation supported (12MBit/s). */ + LIBUSB_FULL_SPEED_OPERATION = 2, + + /** High speed operation supported (480MBit/s). */ + LIBUSB_HIGH_SPEED_OPERATION = 4, + + /** Superspeed operation supported (5000MBit/s). */ + LIBUSB_SUPER_SPEED_OPERATION = 8, +}; + +/** \ingroup dev + * Masks for the bits of the + * \ref libusb_usb_2_0_extension_descriptor::bmAttributes "bmAttributes" field + * of the USB 2.0 Extension descriptor. + */ +enum libusb_usb_2_0_extension_attributes { + /** Supports Link Power Management (LPM) */ + LIBUSB_BM_LPM_SUPPORT = 2, +}; + +/** \ingroup dev + * Masks for the bits of the + * \ref libusb_ss_usb_device_capability_descriptor::bmAttributes "bmAttributes" field + * field of the SuperSpeed USB Device Capability descriptor. + */ +enum libusb_ss_usb_device_capability_attributes { + /** Supports Latency Tolerance Messages (LTM) */ + LIBUSB_BM_LTM_SUPPORT = 2, +}; + +/** \ingroup dev + * USB capability types + */ +enum libusb_bos_type { + /** Wireless USB device capability */ + LIBUSB_BT_WIRELESS_USB_DEVICE_CAPABILITY = 1, + + /** USB 2.0 extensions */ + LIBUSB_BT_USB_2_0_EXTENSION = 2, + + /** SuperSpeed USB device capability */ + LIBUSB_BT_SS_USB_DEVICE_CAPABILITY = 3, + + /** Container ID type */ + LIBUSB_BT_CONTAINER_ID = 4, +}; + +/** \ingroup misc + * Error codes. Most libusb functions return 0 on success or one of these + * codes on failure. + * You can call libusb_error_name() to retrieve a string representation of an + * error code or libusb_strerror() to get an end-user suitable description of + * an error code. + */ +enum libusb_error { + /** Success (no error) */ + LIBUSB_SUCCESS = 0, + + /** Input/output error */ + LIBUSB_ERROR_IO = -1, + + /** Invalid parameter */ + LIBUSB_ERROR_INVALID_PARAM = -2, + + /** Access denied (insufficient permissions) */ + LIBUSB_ERROR_ACCESS = -3, + + /** No such device (it may have been disconnected) */ + LIBUSB_ERROR_NO_DEVICE = -4, + + /** Entity not found */ + LIBUSB_ERROR_NOT_FOUND = -5, + + /** Resource busy */ + LIBUSB_ERROR_BUSY = -6, + + /** Operation timed out */ + LIBUSB_ERROR_TIMEOUT = -7, + + /** Overflow */ + LIBUSB_ERROR_OVERFLOW = -8, + + /** Pipe error */ + LIBUSB_ERROR_PIPE = -9, + + /** System call interrupted (perhaps due to signal) */ + LIBUSB_ERROR_INTERRUPTED = -10, + + /** Insufficient memory */ + LIBUSB_ERROR_NO_MEM = -11, + + /** Operation not supported or unimplemented on this platform */ + LIBUSB_ERROR_NOT_SUPPORTED = -12, + + /* NB: Remember to update LIBUSB_ERROR_COUNT below as well as the + message strings in strerror.c when adding new error codes here. */ + + /** Other error */ + LIBUSB_ERROR_OTHER = -99, +}; + +/* Total number of error codes in enum libusb_error */ +#define LIBUSB_ERROR_COUNT 14 + +/** \ingroup asyncio + * Transfer status codes */ +enum libusb_transfer_status { + /** Transfer completed without error. Note that this does not indicate + * that the entire amount of requested data was transferred. */ + LIBUSB_TRANSFER_COMPLETED, + + /** Transfer failed */ + LIBUSB_TRANSFER_ERROR, + + /** Transfer timed out */ + LIBUSB_TRANSFER_TIMED_OUT, + + /** Transfer was cancelled */ + LIBUSB_TRANSFER_CANCELLED, + + /** For bulk/interrupt endpoints: halt condition detected (endpoint + * stalled). For control endpoints: control request not supported. */ + LIBUSB_TRANSFER_STALL, + + /** Device was disconnected */ + LIBUSB_TRANSFER_NO_DEVICE, + + /** Device sent more data than requested */ + LIBUSB_TRANSFER_OVERFLOW, + + /* NB! Remember to update libusb_error_name() + when adding new status codes here. */ +}; + +/** \ingroup asyncio + * libusb_transfer.flags values */ +enum libusb_transfer_flags { + /** Report short frames as errors */ + LIBUSB_TRANSFER_SHORT_NOT_OK = 1<<0, + + /** Automatically free() transfer buffer during libusb_free_transfer() */ + LIBUSB_TRANSFER_FREE_BUFFER = 1<<1, + + /** Automatically call libusb_free_transfer() after callback returns. + * If this flag is set, it is illegal to call libusb_free_transfer() + * from your transfer callback, as this will result in a double-free + * when this flag is acted upon. */ + LIBUSB_TRANSFER_FREE_TRANSFER = 1<<2, + + /** Terminate transfers that are a multiple of the endpoint's + * wMaxPacketSize with an extra zero length packet. This is useful + * when a device protocol mandates that each logical request is + * terminated by an incomplete packet (i.e. the logical requests are + * not separated by other means). + * + * This flag only affects host-to-device transfers to bulk and interrupt + * endpoints. In other situations, it is ignored. + * + * This flag only affects transfers with a length that is a multiple of + * the endpoint's wMaxPacketSize. On transfers of other lengths, this + * flag has no effect. Therefore, if you are working with a device that + * needs a ZLP whenever the end of the logical request falls on a packet + * boundary, then it is sensible to set this flag on every + * transfer (you do not have to worry about only setting it on transfers + * that end on the boundary). + * + * This flag is currently only supported on Linux. + * On other systems, libusb_submit_transfer() will return + * LIBUSB_ERROR_NOT_SUPPORTED for every transfer where this flag is set. + * + * Available since libusb-1.0.9. + */ + LIBUSB_TRANSFER_ADD_ZERO_PACKET = 1 << 3, +}; + +/** \ingroup asyncio + * Isochronous packet descriptor. */ +struct libusb_iso_packet_descriptor { + /** Length of data to request in this packet */ + unsigned int length; + + /** Amount of data that was actually transferred */ + unsigned int actual_length; + + /** Status code for this packet */ + enum libusb_transfer_status status; +}; + +struct libusb_transfer; + +/** \ingroup asyncio + * Asynchronous transfer callback function type. When submitting asynchronous + * transfers, you pass a pointer to a callback function of this type via the + * \ref libusb_transfer::callback "callback" member of the libusb_transfer + * structure. libusb will call this function later, when the transfer has + * completed or failed. See \ref asyncio for more information. + * \param transfer The libusb_transfer struct the callback function is being + * notified about. + */ +typedef void (LIBUSB_CALL *libusb_transfer_cb_fn)(struct libusb_transfer *transfer); + +/** \ingroup asyncio + * The generic USB transfer structure. The user populates this structure and + * then submits it in order to request a transfer. After the transfer has + * completed, the library populates the transfer with the results and passes + * it back to the user. + */ +struct libusb_transfer { + /** Handle of the device that this transfer will be submitted to */ + libusb_device_handle *dev_handle; + + /** A bitwise OR combination of \ref libusb_transfer_flags. */ + uint8_t flags; + + /** Address of the endpoint where this transfer will be sent. */ + unsigned char endpoint; + + /** Type of the endpoint from \ref libusb_transfer_type */ + unsigned char type; + + /** Timeout for this transfer in millseconds. A value of 0 indicates no + * timeout. */ + unsigned int timeout; + + /** The status of the transfer. Read-only, and only for use within + * transfer callback function. + * + * If this is an isochronous transfer, this field may read COMPLETED even + * if there were errors in the frames. Use the + * \ref libusb_iso_packet_descriptor::status "status" field in each packet + * to determine if errors occurred. */ + enum libusb_transfer_status status; + + /** Length of the data buffer */ + int length; + + /** Actual length of data that was transferred. Read-only, and only for + * use within transfer callback function. Not valid for isochronous + * endpoint transfers. */ + int actual_length; + + /** Callback function. This will be invoked when the transfer completes, + * fails, or is cancelled. */ + libusb_transfer_cb_fn callback; + + /** User context data to pass to the callback function. */ + void *user_data; + + /** Data buffer */ + unsigned char *buffer; + + /** Number of isochronous packets. Only used for I/O with isochronous + * endpoints. */ + int num_iso_packets; + + /** Isochronous packet descriptors, for isochronous transfers only. */ + struct libusb_iso_packet_descriptor iso_packet_desc +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + [] /* valid C99 code */ +#else + [0] /* non-standard, but usually working code */ +#endif + ; +}; + +/** \ingroup misc + * Capabilities supported by an instance of libusb on the current running + * platform. Test if the loaded library supports a given capability by calling + * \ref libusb_has_capability(). + */ +enum libusb_capability { + /** The libusb_has_capability() API is available. */ + LIBUSB_CAP_HAS_CAPABILITY = 0x0000, + /** Hotplug support is available on this platform. */ + LIBUSB_CAP_HAS_HOTPLUG = 0x0001, + /** The library can access HID devices without requiring user intervention. + * Note that before being able to actually access an HID device, you may + * still have to call additional libusb functions such as + * \ref libusb_detach_kernel_driver(). */ + LIBUSB_CAP_HAS_HID_ACCESS = 0x0100, + /** The library supports detaching of the default USB driver, using + * \ref libusb_detach_kernel_driver(), if one is set by the OS kernel */ + LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER = 0x0101 +}; + +/** \ingroup lib + * Log message levels. + * - LIBUSB_LOG_LEVEL_NONE (0) : no messages ever printed by the library (default) + * - LIBUSB_LOG_LEVEL_ERROR (1) : error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_WARNING (2) : warning and error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_INFO (3) : informational messages are printed to stdout, warning + * and error messages are printed to stderr + * - LIBUSB_LOG_LEVEL_DEBUG (4) : debug and informational messages are printed to stdout, + * warnings and errors to stderr + */ +enum libusb_log_level { + LIBUSB_LOG_LEVEL_NONE = 0, + LIBUSB_LOG_LEVEL_ERROR, + LIBUSB_LOG_LEVEL_WARNING, + LIBUSB_LOG_LEVEL_INFO, + LIBUSB_LOG_LEVEL_DEBUG, +}; + +int LIBUSB_CALL libusb_init(libusb_context **ctx); +void LIBUSB_CALL libusb_exit(libusb_context *ctx); +void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level); +const struct libusb_version * LIBUSB_CALL libusb_get_version(void); +int LIBUSB_CALL libusb_has_capability(uint32_t capability); +const char * LIBUSB_CALL libusb_error_name(int errcode); +int LIBUSB_CALL libusb_setlocale(const char *locale); +const char * LIBUSB_CALL libusb_strerror(enum libusb_error errcode); + +ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx, + libusb_device ***list); +void LIBUSB_CALL libusb_free_device_list(libusb_device **list, + int unref_devices); +libusb_device * LIBUSB_CALL libusb_ref_device(libusb_device *dev); +void LIBUSB_CALL libusb_unref_device(libusb_device *dev); + +int LIBUSB_CALL libusb_get_configuration(libusb_device_handle *dev, + int *config); +int LIBUSB_CALL libusb_get_device_descriptor(libusb_device *dev, + struct libusb_device_descriptor *desc); +int LIBUSB_CALL libusb_get_active_config_descriptor(libusb_device *dev, + struct libusb_config_descriptor **config); +int LIBUSB_CALL libusb_get_config_descriptor(libusb_device *dev, + uint8_t config_index, struct libusb_config_descriptor **config); +int LIBUSB_CALL libusb_get_config_descriptor_by_value(libusb_device *dev, + uint8_t bConfigurationValue, struct libusb_config_descriptor **config); +void LIBUSB_CALL libusb_free_config_descriptor( + struct libusb_config_descriptor *config); +int LIBUSB_CALL libusb_get_ss_endpoint_companion_descriptor( + struct libusb_context *ctx, + const struct libusb_endpoint_descriptor *endpoint, + struct libusb_ss_endpoint_companion_descriptor **ep_comp); +void LIBUSB_CALL libusb_free_ss_endpoint_companion_descriptor( + struct libusb_ss_endpoint_companion_descriptor *ep_comp); +int LIBUSB_CALL libusb_get_bos_descriptor(libusb_device_handle *handle, + struct libusb_bos_descriptor **bos); +void LIBUSB_CALL libusb_free_bos_descriptor(struct libusb_bos_descriptor *bos); +int LIBUSB_CALL libusb_get_usb_2_0_extension_descriptor( + struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension); +void LIBUSB_CALL libusb_free_usb_2_0_extension_descriptor( + struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension); +int LIBUSB_CALL libusb_get_ss_usb_device_capability_descriptor( + struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap); +void LIBUSB_CALL libusb_free_ss_usb_device_capability_descriptor( + struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap); +int LIBUSB_CALL libusb_get_container_id_descriptor(struct libusb_context *ctx, + struct libusb_bos_dev_capability_descriptor *dev_cap, + struct libusb_container_id_descriptor **container_id); +void LIBUSB_CALL libusb_free_container_id_descriptor( + struct libusb_container_id_descriptor *container_id); +uint8_t LIBUSB_CALL libusb_get_bus_number(libusb_device *dev); +uint8_t LIBUSB_CALL libusb_get_port_number(libusb_device *dev); +int LIBUSB_CALL libusb_get_port_numbers(libusb_device *dev, uint8_t* port_numbers, int port_numbers_len); +LIBUSB_DEPRECATED_FOR(libusb_get_port_numbers) +int LIBUSB_CALL libusb_get_port_path(libusb_context *ctx, libusb_device *dev, uint8_t* path, uint8_t path_length); +libusb_device * LIBUSB_CALL libusb_get_parent(libusb_device *dev); +uint8_t LIBUSB_CALL libusb_get_device_address(libusb_device *dev); +int LIBUSB_CALL libusb_get_device_speed(libusb_device *dev); +int LIBUSB_CALL libusb_get_max_packet_size(libusb_device *dev, + unsigned char endpoint); +int LIBUSB_CALL libusb_get_max_iso_packet_size(libusb_device *dev, + unsigned char endpoint); + +int LIBUSB_CALL libusb_open(libusb_device *dev, libusb_device_handle **handle); +void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle); +libusb_device * LIBUSB_CALL libusb_get_device(libusb_device_handle *dev_handle); + +int LIBUSB_CALL libusb_set_configuration(libusb_device_handle *dev, + int configuration); +int LIBUSB_CALL libusb_claim_interface(libusb_device_handle *dev, + int interface_number); +int LIBUSB_CALL libusb_release_interface(libusb_device_handle *dev, + int interface_number); + +libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid( + libusb_context *ctx, uint16_t vendor_id, uint16_t product_id); + +int LIBUSB_CALL libusb_set_interface_alt_setting(libusb_device_handle *dev, + int interface_number, int alternate_setting); +int LIBUSB_CALL libusb_clear_halt(libusb_device_handle *dev, + unsigned char endpoint); +int LIBUSB_CALL libusb_reset_device(libusb_device_handle *dev); + +int LIBUSB_CALL libusb_alloc_streams(libusb_device_handle *dev, + uint32_t num_streams, unsigned char *endpoints, int num_endpoints); +int LIBUSB_CALL libusb_free_streams(libusb_device_handle *dev, + unsigned char *endpoints, int num_endpoints); + +int LIBUSB_CALL libusb_kernel_driver_active(libusb_device_handle *dev, + int interface_number); +int LIBUSB_CALL libusb_detach_kernel_driver(libusb_device_handle *dev, + int interface_number); +int LIBUSB_CALL libusb_attach_kernel_driver(libusb_device_handle *dev, + int interface_number); +int LIBUSB_CALL libusb_set_auto_detach_kernel_driver( + libusb_device_handle *dev, int enable); + +/* async I/O */ + +/** \ingroup asyncio + * Get the data section of a control transfer. This convenience function is here + * to remind you that the data does not start until 8 bytes into the actual + * buffer, as the setup packet comes first. + * + * Calling this function only makes sense from a transfer callback function, + * or situations where you have already allocated a suitably sized buffer at + * transfer->buffer. + * + * \param transfer a transfer + * \returns pointer to the first byte of the data section + */ +static inline unsigned char *libusb_control_transfer_get_data( + struct libusb_transfer *transfer) +{ + return transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE; +} + +/** \ingroup asyncio + * Get the control setup packet of a control transfer. This convenience + * function is here to remind you that the control setup occupies the first + * 8 bytes of the transfer data buffer. + * + * Calling this function only makes sense from a transfer callback function, + * or situations where you have already allocated a suitably sized buffer at + * transfer->buffer. + * + * \param transfer a transfer + * \returns a casted pointer to the start of the transfer data buffer + */ +static inline struct libusb_control_setup *libusb_control_transfer_get_setup( + struct libusb_transfer *transfer) +{ + return (struct libusb_control_setup *)(void *) transfer->buffer; +} + +/** \ingroup asyncio + * Helper function to populate the setup packet (first 8 bytes of the data + * buffer) for a control transfer. The wIndex, wValue and wLength values should + * be given in host-endian byte order. + * + * \param buffer buffer to output the setup packet into + * This pointer must be aligned to at least 2 bytes boundary. + * \param bmRequestType see the + * \ref libusb_control_setup::bmRequestType "bmRequestType" field of + * \ref libusb_control_setup + * \param bRequest see the + * \ref libusb_control_setup::bRequest "bRequest" field of + * \ref libusb_control_setup + * \param wValue see the + * \ref libusb_control_setup::wValue "wValue" field of + * \ref libusb_control_setup + * \param wIndex see the + * \ref libusb_control_setup::wIndex "wIndex" field of + * \ref libusb_control_setup + * \param wLength see the + * \ref libusb_control_setup::wLength "wLength" field of + * \ref libusb_control_setup + */ +static inline void libusb_fill_control_setup(unsigned char *buffer, + uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + uint16_t wLength) +{ + struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *) buffer; + setup->bmRequestType = bmRequestType; + setup->bRequest = bRequest; + setup->wValue = libusb_cpu_to_le16(wValue); + setup->wIndex = libusb_cpu_to_le16(wIndex); + setup->wLength = libusb_cpu_to_le16(wLength); +} + +struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(int iso_packets); +int LIBUSB_CALL libusb_submit_transfer(struct libusb_transfer *transfer); +int LIBUSB_CALL libusb_cancel_transfer(struct libusb_transfer *transfer); +void LIBUSB_CALL libusb_free_transfer(struct libusb_transfer *transfer); +void LIBUSB_CALL libusb_transfer_set_stream_id( + struct libusb_transfer *transfer, uint32_t stream_id); +uint32_t LIBUSB_CALL libusb_transfer_get_stream_id( + struct libusb_transfer *transfer); + +/** \ingroup asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for a control transfer. + * + * If you pass a transfer buffer to this function, the first 8 bytes will + * be interpreted as a control setup packet, and the wLength field will be + * used to automatically populate the \ref libusb_transfer::length "length" + * field of the transfer. Therefore the recommended approach is: + * -# Allocate a suitably sized data buffer (including space for control setup) + * -# Call libusb_fill_control_setup() + * -# If this is a host-to-device transfer with a data stage, put the data + * in place after the setup packet + * -# Call this function + * -# Call libusb_submit_transfer() + * + * It is also legal to pass a NULL buffer to this function, in which case this + * function will not attempt to populate the length field. Remember that you + * must then populate the buffer and length fields later. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param buffer data buffer. If provided, this function will interpret the + * first 8 bytes as a setup packet and infer the transfer length from that. + * This pointer must be aligned to at least 2 bytes boundary. + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_control_transfer( + struct libusb_transfer *transfer, libusb_device_handle *dev_handle, + unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data, + unsigned int timeout) +{ + struct libusb_control_setup *setup = (struct libusb_control_setup *)(void *) buffer; + transfer->dev_handle = dev_handle; + transfer->endpoint = 0; + transfer->type = LIBUSB_TRANSFER_TYPE_CONTROL; + transfer->timeout = timeout; + transfer->buffer = buffer; + if (setup) + transfer->length = (int) (LIBUSB_CONTROL_SETUP_SIZE + + libusb_le16_to_cpu(setup->wLength)); + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for a bulk transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer, + libusb_device_handle *dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_BULK; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for a bulk transfer using bulk streams. + * + * Since version 1.0.19, \ref LIBUSB_API_VERSION >= 0x01000103 + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param stream_id bulk stream id for this transfer + * \param buffer data buffer + * \param length length of data buffer + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_bulk_stream_transfer( + struct libusb_transfer *transfer, libusb_device_handle *dev_handle, + unsigned char endpoint, uint32_t stream_id, + unsigned char *buffer, int length, libusb_transfer_cb_fn callback, + void *user_data, unsigned int timeout) +{ + libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, + length, callback, user_data, timeout); + transfer->type = LIBUSB_TRANSFER_TYPE_BULK_STREAM; + libusb_transfer_set_stream_id(transfer, stream_id); +} + +/** \ingroup asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for an interrupt transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_interrupt_transfer( + struct libusb_transfer *transfer, libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *buffer, int length, + libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_INTERRUPT; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup asyncio + * Helper function to populate the required \ref libusb_transfer fields + * for an isochronous transfer. + * + * \param transfer the transfer to populate + * \param dev_handle handle of the device that will handle the transfer + * \param endpoint address of the endpoint where this transfer will be sent + * \param buffer data buffer + * \param length length of data buffer + * \param num_iso_packets the number of isochronous packets + * \param callback callback function to be invoked on transfer completion + * \param user_data user data to pass to callback function + * \param timeout timeout for the transfer in milliseconds + */ +static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer, + libusb_device_handle *dev_handle, unsigned char endpoint, + unsigned char *buffer, int length, int num_iso_packets, + libusb_transfer_cb_fn callback, void *user_data, unsigned int timeout) +{ + transfer->dev_handle = dev_handle; + transfer->endpoint = endpoint; + transfer->type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS; + transfer->timeout = timeout; + transfer->buffer = buffer; + transfer->length = length; + transfer->num_iso_packets = num_iso_packets; + transfer->user_data = user_data; + transfer->callback = callback; +} + +/** \ingroup asyncio + * Convenience function to set the length of all packets in an isochronous + * transfer, based on the num_iso_packets field in the transfer structure. + * + * \param transfer a transfer + * \param length the length to set in each isochronous packet descriptor + * \see libusb_get_max_packet_size() + */ +static inline void libusb_set_iso_packet_lengths( + struct libusb_transfer *transfer, unsigned int length) +{ + int i; + for (i = 0; i < transfer->num_iso_packets; i++) + transfer->iso_packet_desc[i].length = length; +} + +/** \ingroup asyncio + * Convenience function to locate the position of an isochronous packet + * within the buffer of an isochronous transfer. + * + * This is a thorough function which loops through all preceding packets, + * accumulating their lengths to find the position of the specified packet. + * Typically you will assign equal lengths to each packet in the transfer, + * and hence the above method is sub-optimal. You may wish to use + * libusb_get_iso_packet_buffer_simple() instead. + * + * \param transfer a transfer + * \param packet the packet to return the address of + * \returns the base address of the packet buffer inside the transfer buffer, + * or NULL if the packet does not exist. + * \see libusb_get_iso_packet_buffer_simple() + */ +static inline unsigned char *libusb_get_iso_packet_buffer( + struct libusb_transfer *transfer, unsigned int packet) +{ + int i; + size_t offset = 0; + int _packet; + + /* oops..slight bug in the API. packet is an unsigned int, but we use + * signed integers almost everywhere else. range-check and convert to + * signed to avoid compiler warnings. FIXME for libusb-2. */ + if (packet > INT_MAX) + return NULL; + _packet = (int) packet; + + if (_packet >= transfer->num_iso_packets) + return NULL; + + for (i = 0; i < _packet; i++) + offset += transfer->iso_packet_desc[i].length; + + return transfer->buffer + offset; +} + +/** \ingroup asyncio + * Convenience function to locate the position of an isochronous packet + * within the buffer of an isochronous transfer, for transfers where each + * packet is of identical size. + * + * This function relies on the assumption that every packet within the transfer + * is of identical size to the first packet. Calculating the location of + * the packet buffer is then just a simple calculation: + * buffer + (packet_size * packet) + * + * Do not use this function on transfers other than those that have identical + * packet lengths for each packet. + * + * \param transfer a transfer + * \param packet the packet to return the address of + * \returns the base address of the packet buffer inside the transfer buffer, + * or NULL if the packet does not exist. + * \see libusb_get_iso_packet_buffer() + */ +static inline unsigned char *libusb_get_iso_packet_buffer_simple( + struct libusb_transfer *transfer, unsigned int packet) +{ + int _packet; + + /* oops..slight bug in the API. packet is an unsigned int, but we use + * signed integers almost everywhere else. range-check and convert to + * signed to avoid compiler warnings. FIXME for libusb-2. */ + if (packet > INT_MAX) + return NULL; + _packet = (int) packet; + + if (_packet >= transfer->num_iso_packets) + return NULL; + + return transfer->buffer + ((int) transfer->iso_packet_desc[0].length * _packet); +} + +/* sync I/O */ + +int LIBUSB_CALL libusb_control_transfer(libusb_device_handle *dev_handle, + uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, + unsigned char *data, uint16_t wLength, unsigned int timeout); + +int LIBUSB_CALL libusb_bulk_transfer(libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *data, int length, + int *actual_length, unsigned int timeout); + +int LIBUSB_CALL libusb_interrupt_transfer(libusb_device_handle *dev_handle, + unsigned char endpoint, unsigned char *data, int length, + int *actual_length, unsigned int timeout); + +/** \ingroup desc + * Retrieve a descriptor from the default control pipe. + * This is a convenience function which formulates the appropriate control + * message to retrieve the descriptor. + * + * \param dev a device handle + * \param desc_type the descriptor type, see \ref libusb_descriptor_type + * \param desc_index the index of the descriptor to retrieve + * \param data output buffer for descriptor + * \param length size of data buffer + * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure + */ +static inline int libusb_get_descriptor(libusb_device_handle *dev, + uint8_t desc_type, uint8_t desc_index, unsigned char *data, int length) +{ + return libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t) ((desc_type << 8) | desc_index), + 0, data, (uint16_t) length, 1000); +} + +/** \ingroup desc + * Retrieve a descriptor from a device. + * This is a convenience function which formulates the appropriate control + * message to retrieve the descriptor. The string returned is Unicode, as + * detailed in the USB specifications. + * + * \param dev a device handle + * \param desc_index the index of the descriptor to retrieve + * \param langid the language ID for the string descriptor + * \param data output buffer for descriptor + * \param length size of data buffer + * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure + * \see libusb_get_string_descriptor_ascii() + */ +static inline int libusb_get_string_descriptor(libusb_device_handle *dev, + uint8_t desc_index, uint16_t langid, unsigned char *data, int length) +{ + return libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, (uint16_t)((LIBUSB_DT_STRING << 8) | desc_index), + langid, data, (uint16_t) length, 1000); +} + +int LIBUSB_CALL libusb_get_string_descriptor_ascii(libusb_device_handle *dev, + uint8_t desc_index, unsigned char *data, int length); + +/* polling and timeouts */ + +int LIBUSB_CALL libusb_try_lock_events(libusb_context *ctx); +void LIBUSB_CALL libusb_lock_events(libusb_context *ctx); +void LIBUSB_CALL libusb_unlock_events(libusb_context *ctx); +int LIBUSB_CALL libusb_event_handling_ok(libusb_context *ctx); +int LIBUSB_CALL libusb_event_handler_active(libusb_context *ctx); +void LIBUSB_CALL libusb_lock_event_waiters(libusb_context *ctx); +void LIBUSB_CALL libusb_unlock_event_waiters(libusb_context *ctx); +int LIBUSB_CALL libusb_wait_for_event(libusb_context *ctx, struct timeval *tv); + +int LIBUSB_CALL libusb_handle_events_timeout(libusb_context *ctx, + struct timeval *tv); +int LIBUSB_CALL libusb_handle_events_timeout_completed(libusb_context *ctx, + struct timeval *tv, int *completed); +int LIBUSB_CALL libusb_handle_events(libusb_context *ctx); +int LIBUSB_CALL libusb_handle_events_completed(libusb_context *ctx, int *completed); +int LIBUSB_CALL libusb_handle_events_locked(libusb_context *ctx, + struct timeval *tv); +int LIBUSB_CALL libusb_pollfds_handle_timeouts(libusb_context *ctx); +int LIBUSB_CALL libusb_get_next_timeout(libusb_context *ctx, + struct timeval *tv); + +/** \ingroup poll + * File descriptor for polling + */ +struct libusb_pollfd { + /** Numeric file descriptor */ + int fd; + + /** Event flags to poll for from . POLLIN indicates that you + * should monitor this file descriptor for becoming ready to read from, + * and POLLOUT indicates that you should monitor this file descriptor for + * nonblocking write readiness. */ + short events; +}; + +/** \ingroup poll + * Callback function, invoked when a new file descriptor should be added + * to the set of file descriptors monitored for events. + * \param fd the new file descriptor + * \param events events to monitor for, see \ref libusb_pollfd for a + * description + * \param user_data User data pointer specified in + * libusb_set_pollfd_notifiers() call + * \see libusb_set_pollfd_notifiers() + */ +typedef void (LIBUSB_CALL *libusb_pollfd_added_cb)(int fd, short events, + void *user_data); + +/** \ingroup poll + * Callback function, invoked when a file descriptor should be removed from + * the set of file descriptors being monitored for events. After returning + * from this callback, do not use that file descriptor again. + * \param fd the file descriptor to stop monitoring + * \param user_data User data pointer specified in + * libusb_set_pollfd_notifiers() call + * \see libusb_set_pollfd_notifiers() + */ +typedef void (LIBUSB_CALL *libusb_pollfd_removed_cb)(int fd, void *user_data); + +const struct libusb_pollfd ** LIBUSB_CALL libusb_get_pollfds( + libusb_context *ctx); +void LIBUSB_CALL libusb_free_pollfds(const struct libusb_pollfd **pollfds); +void LIBUSB_CALL libusb_set_pollfd_notifiers(libusb_context *ctx, + libusb_pollfd_added_cb added_cb, libusb_pollfd_removed_cb removed_cb, + void *user_data); + +/** \ingroup hotplug + * Callback handle. + * + * Callbacks handles are generated by libusb_hotplug_register_callback() + * and can be used to deregister callbacks. Callback handles are unique + * per libusb_context and it is safe to call libusb_hotplug_deregister_callback() + * on an already deregisted callback. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * For more information, see \ref hotplug. + */ +typedef int libusb_hotplug_callback_handle; + +/** \ingroup hotplug + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * Flags for hotplug events */ +typedef enum { + /** Default value when not using any flags. */ + LIBUSB_HOTPLUG_NO_FLAGS = 0, + + /** Arm the callback and fire it for all matching currently attached devices. */ + LIBUSB_HOTPLUG_ENUMERATE = 1<<0, +} libusb_hotplug_flag; + +/** \ingroup hotplug + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * Hotplug events */ +typedef enum { + /** A device has been plugged in and is ready to use */ + LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED = 0x01, + + /** A device has left and is no longer available. + * It is the user's responsibility to call libusb_close on any handle associated with a disconnected device. + * It is safe to call libusb_get_device_descriptor on a device that has left */ + LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT = 0x02, +} libusb_hotplug_event; + +/** \ingroup hotplug + * Wildcard matching for hotplug events */ +#define LIBUSB_HOTPLUG_MATCH_ANY -1 + +/** \ingroup hotplug + * Hotplug callback function type. When requesting hotplug event notifications, + * you pass a pointer to a callback function of this type. + * + * This callback may be called by an internal event thread and as such it is + * recommended the callback do minimal processing before returning. + * + * libusb will call this function later, when a matching event had happened on + * a matching device. See \ref hotplug for more information. + * + * It is safe to call either libusb_hotplug_register_callback() or + * libusb_hotplug_deregister_callback() from within a callback function. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * \param ctx context of this notification + * \param device libusb_device this event occurred on + * \param event event that occurred + * \param user_data user data provided when this callback was registered + * \returns bool whether this callback is finished processing events. + * returning 1 will cause this callback to be deregistered + */ +typedef int (LIBUSB_CALL *libusb_hotplug_callback_fn)(libusb_context *ctx, + libusb_device *device, + libusb_hotplug_event event, + void *user_data); + +/** \ingroup hotplug + * Register a hotplug callback function + * + * Register a callback with the libusb_context. The callback will fire + * when a matching event occurs on a matching device. The callback is + * armed until either it is deregistered with libusb_hotplug_deregister_callback() + * or the supplied callback returns 1 to indicate it is finished processing events. + * + * If the \ref LIBUSB_HOTPLUG_ENUMERATE is passed the callback will be + * called with a \ref LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED for all devices + * already plugged into the machine. Note that libusb modifies its internal + * device list from a separate thread, while calling hotplug callbacks from + * libusb_handle_events(), so it is possible for a device to already be present + * on, or removed from, its internal device list, while the hotplug callbacks + * still need to be dispatched. This means that when using \ref + * LIBUSB_HOTPLUG_ENUMERATE, your callback may be called twice for the arrival + * of the same device, once from libusb_hotplug_register_callback() and once + * from libusb_handle_events(); and/or your callback may be called for the + * removal of a device for which an arrived call was never made. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * \param[in] ctx context to register this callback with + * \param[in] events bitwise or of events that will trigger this callback. See \ref + * libusb_hotplug_event + * \param[in] flags hotplug callback flags. See \ref libusb_hotplug_flag + * \param[in] vendor_id the vendor id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + * \param[in] product_id the product id to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + * \param[in] dev_class the device class to match or \ref LIBUSB_HOTPLUG_MATCH_ANY + * \param[in] cb_fn the function to be invoked on a matching event/device + * \param[in] user_data user data to pass to the callback function + * \param[out] handle pointer to store the handle of the allocated callback (can be NULL) + * \returns LIBUSB_SUCCESS on success LIBUSB_ERROR code on failure + */ +int LIBUSB_CALL libusb_hotplug_register_callback(libusb_context *ctx, + libusb_hotplug_event events, + libusb_hotplug_flag flags, + int vendor_id, int product_id, + int dev_class, + libusb_hotplug_callback_fn cb_fn, + void *user_data, + libusb_hotplug_callback_handle *handle); + +/** \ingroup hotplug + * Deregisters a hotplug callback. + * + * Deregister a callback from a libusb_context. This function is safe to call from within + * a hotplug callback. + * + * Since version 1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102 + * + * \param[in] ctx context this callback is registered with + * \param[in] handle the handle of the callback to deregister + */ +void LIBUSB_CALL libusb_hotplug_deregister_callback(libusb_context *ctx, + libusb_hotplug_callback_handle handle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Desktop_Interface/build_mac/libusb/include/libusb-1.0/libusb.h.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/include/libusb-1.0/libusb.h.REMOVED.git-id deleted file mode 100644 index a5125d2a..00000000 --- a/Desktop_Interface/build_mac/libusb/include/libusb-1.0/libusb.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -513945f054f4866409ebdd4e969227ec625a1069 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/lib/libusb-1.0.a.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/lib/libusb-1.0.a.REMOVED.git-id deleted file mode 100644 index 06cb7d66..00000000 --- a/Desktop_Interface/build_mac/libusb/lib/libusb-1.0.a.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b2d260323ade351e45400db1efa8263540f364b9 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/lib/libusb-1.0.dylib b/Desktop_Interface/build_mac/libusb/lib/libusb-1.0.dylib new file mode 100644 index 00000000..80ef0159 Binary files /dev/null and b/Desktop_Interface/build_mac/libusb/lib/libusb-1.0.dylib differ diff --git a/Desktop_Interface/build_mac/libusb/lib/libusb-1.0.dylib.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/lib/libusb-1.0.dylib.REMOVED.git-id deleted file mode 100644 index 75114fed..00000000 --- a/Desktop_Interface/build_mac/libusb/lib/libusb-1.0.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -80ef01596ce0aec937da3e02f91bf6c85b128237 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/lib/libusb-1.0.dylib.bak.dylib.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/lib/libusb-1.0.dylib.bak.dylib.REMOVED.git-id deleted file mode 100644 index 776ea12e..00000000 --- a/Desktop_Interface/build_mac/libusb/lib/libusb-1.0.dylib.bak.dylib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a84467019f521835e35c3b5e0bc6bf282a9d14f1 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/lib/pkgconfig/libusb-1.0.pc.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/lib/pkgconfig/libusb-1.0.pc.REMOVED.git-id deleted file mode 100644 index 69eefddf..00000000 --- a/Desktop_Interface/build_mac/libusb/lib/pkgconfig/libusb-1.0.pc.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2f809ca26e760eaba73c66fd4a9796a0cd7c0319 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/Makefile.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/Makefile.REMOVED.git-id deleted file mode 100644 index 84b8f734..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/Makefile.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -434cb740bf0081741f1000fb1eb52b045796ff4d \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/Makefile.am.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/Makefile.am.REMOVED.git-id deleted file mode 100644 index 3f2761b7..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/Makefile.am.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8081927417fb69e07058050ef3fccde21954b99c \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/Makefile.in.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/Makefile.in.REMOVED.git-id deleted file mode 100644 index 81918796..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/Makefile.in.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -465452d1df3a3a2fd024798412e0149e91efae08 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/dpfp.c.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/dpfp.c.REMOVED.git-id deleted file mode 100644 index 1e00329e..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/dpfp.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ed682671ab80451c8bef226c2797c8bf9f782309 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/dpfp_threaded.c.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/dpfp_threaded.c.REMOVED.git-id deleted file mode 100644 index b5f37998..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/dpfp_threaded.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a7502a40ef8718722756306c16c24cc23be87da6 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/ezusb.c.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/ezusb.c.REMOVED.git-id deleted file mode 100644 index 72e49144..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/ezusb.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f369e5094aa4a026473175326f33023060acd174 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/ezusb.h.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/ezusb.h.REMOVED.git-id deleted file mode 100644 index cdce96cc..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/ezusb.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cd0776de7bf9f56d631e91e1191fdb85e10b1c8d \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/fxload.c.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/fxload.c.REMOVED.git-id deleted file mode 100644 index 5811f620..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/fxload.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5dff736db40b871bc4cd148038c1fd7eeea95dbd \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/getopt/getopt.c.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/getopt/getopt.c.REMOVED.git-id deleted file mode 100644 index b4e477d3..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/getopt/getopt.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b7f26eb4b63429b478924c5d6f4388dbb1db2044 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/getopt/getopt.h.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/getopt/getopt.h.REMOVED.git-id deleted file mode 100644 index 5343f81c..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/getopt/getopt.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a1b8dd6658f25a4f42eeab7ef1735b41bdafc037 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/getopt/getopt1.c.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/getopt/getopt1.c.REMOVED.git-id deleted file mode 100644 index 98879026..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/getopt/getopt1.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -22a7efbdd19a941b450b285d2d87a1b83bbc1f6b \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/hotplugtest.c.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/hotplugtest.c.REMOVED.git-id deleted file mode 100644 index 5cec60eb..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/hotplugtest.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -851915e1c0c8f099da70eae321d76538cba31520 \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/listdevs.c.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/listdevs.c.REMOVED.git-id deleted file mode 100644 index 764d13cf..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/listdevs.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -332891066c560cc0434244be06f7609029f2caaa \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/sam3u_benchmark.c.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/sam3u_benchmark.c.REMOVED.git-id deleted file mode 100644 index bea6d3ff..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/sam3u_benchmark.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -99d6b0f1becf7b88479a8f8786e3836f91afbadd \ No newline at end of file diff --git a/Desktop_Interface/build_mac/libusb/share/libusb/examples/xusb.c.REMOVED.git-id b/Desktop_Interface/build_mac/libusb/share/libusb/examples/xusb.c.REMOVED.git-id deleted file mode 100644 index 7b2b1f94..00000000 --- a/Desktop_Interface/build_mac/libusb/share/libusb/examples/xusb.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0fdb19d446ae62d4ec5882d98315b62611b02d1f \ No newline at end of file diff --git a/Desktop_Interface/build_mac/platformspecific.h b/Desktop_Interface/build_mac/platformspecific.h new file mode 100644 index 00000000..ed82b121 --- /dev/null +++ b/Desktop_Interface/build_mac/platformspecific.h @@ -0,0 +1,9 @@ +#ifndef PLATFORMSPECIFIC_H +#define PLATFORMSPECIFIC_H + +#include "unixusbdriver.h" +#define PLATFORM_MAC +#define _PLATFORM_DEPENDENT_USB_OBJECT unixUsbDriver +#define _PLATFORM_DEPENDENT_FOLDER_ACTION + +#endif // PLATFORMSPECIFIC_H diff --git a/Desktop_Interface/build_mac/platformspecific.h.REMOVED.git-id b/Desktop_Interface/build_mac/platformspecific.h.REMOVED.git-id deleted file mode 100644 index 495455af..00000000 --- a/Desktop_Interface/build_mac/platformspecific.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ed82b1210305064b9aa785b3b4a2830728ff1ade \ No newline at end of file diff --git a/Desktop_Interface/build_win/libusbk/bin/dll/amd64/libusbK.dll b/Desktop_Interface/build_win/libusbk/bin/dll/amd64/libusbK.dll new file mode 100644 index 00000000..d8112b9e Binary files /dev/null and b/Desktop_Interface/build_win/libusbk/bin/dll/amd64/libusbK.dll differ diff --git a/Desktop_Interface/build_win/libusbk/bin/dll/amd64/libusbK.dll.REMOVED.git-id b/Desktop_Interface/build_win/libusbk/bin/dll/amd64/libusbK.dll.REMOVED.git-id deleted file mode 100644 index 6bfd6c15..00000000 --- a/Desktop_Interface/build_win/libusbk/bin/dll/amd64/libusbK.dll.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d8112b9e825d4ea9ab0ee96685aa18b02ab58e4f \ No newline at end of file diff --git a/Desktop_Interface/build_win/libusbk/bin/dll/ia64/libusbK.dll.REMOVED.git-id b/Desktop_Interface/build_win/libusbk/bin/dll/ia64/libusbK.dll.REMOVED.git-id deleted file mode 100644 index 43c32a95..00000000 --- a/Desktop_Interface/build_win/libusbk/bin/dll/ia64/libusbK.dll.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -717244d59d3388a7d0c61611fe09dfcbc16506b8 \ No newline at end of file diff --git a/Desktop_Interface/build_win/libusbk/bin/dll/x86/libusbK.dll b/Desktop_Interface/build_win/libusbk/bin/dll/x86/libusbK.dll new file mode 100644 index 00000000..0d410629 Binary files /dev/null and b/Desktop_Interface/build_win/libusbk/bin/dll/x86/libusbK.dll differ diff --git a/Desktop_Interface/build_win/libusbk/bin/dll/x86/libusbK.dll.REMOVED.git-id b/Desktop_Interface/build_win/libusbk/bin/dll/x86/libusbK.dll.REMOVED.git-id deleted file mode 100644 index 14163cc7..00000000 --- a/Desktop_Interface/build_win/libusbk/bin/dll/x86/libusbK.dll.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0d41062911fabaa111324b1e7887ccee4f491000 \ No newline at end of file diff --git a/Desktop_Interface/build_win/libusbk/bin/lib/amd64/libusbK.lib b/Desktop_Interface/build_win/libusbk/bin/lib/amd64/libusbK.lib new file mode 100644 index 00000000..c8358a40 Binary files /dev/null and b/Desktop_Interface/build_win/libusbk/bin/lib/amd64/libusbK.lib differ diff --git a/Desktop_Interface/build_win/libusbk/bin/lib/amd64/libusbK.lib.REMOVED.git-id b/Desktop_Interface/build_win/libusbk/bin/lib/amd64/libusbK.lib.REMOVED.git-id deleted file mode 100644 index 84f7a367..00000000 --- a/Desktop_Interface/build_win/libusbk/bin/lib/amd64/libusbK.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c8358a402616820ce03836fde9ec66d91c8f0293 \ No newline at end of file diff --git a/Desktop_Interface/build_win/libusbk/bin/lib/ia64/libusbK.lib.REMOVED.git-id b/Desktop_Interface/build_win/libusbk/bin/lib/ia64/libusbK.lib.REMOVED.git-id deleted file mode 100644 index f3b6f802..00000000 --- a/Desktop_Interface/build_win/libusbk/bin/lib/ia64/libusbK.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b8bdd81676ebb6d619fc044141a7fa6b07465f60 \ No newline at end of file diff --git a/Desktop_Interface/build_win/libusbk/bin/lib/static/amd64/libusbK.lib.REMOVED.git-id b/Desktop_Interface/build_win/libusbk/bin/lib/static/amd64/libusbK.lib.REMOVED.git-id deleted file mode 100644 index a76ba082..00000000 --- a/Desktop_Interface/build_win/libusbk/bin/lib/static/amd64/libusbK.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f20f18dea31b67c2b55a1b21508882403a6be68a \ No newline at end of file diff --git a/Desktop_Interface/build_win/libusbk/bin/lib/static/ia64/libusbK.lib.REMOVED.git-id b/Desktop_Interface/build_win/libusbk/bin/lib/static/ia64/libusbK.lib.REMOVED.git-id deleted file mode 100644 index 27a279a4..00000000 --- a/Desktop_Interface/build_win/libusbk/bin/lib/static/ia64/libusbK.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0e43a803c20310a795d9778dea7ab4827364daaa \ No newline at end of file diff --git a/Desktop_Interface/build_win/libusbk/bin/lib/static/x86/libusbK.lib.REMOVED.git-id b/Desktop_Interface/build_win/libusbk/bin/lib/static/x86/libusbK.lib.REMOVED.git-id deleted file mode 100644 index 2c585758..00000000 --- a/Desktop_Interface/build_win/libusbk/bin/lib/static/x86/libusbK.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f5ccfdfb550ef5608c7faac6769f63905ab5b927 \ No newline at end of file diff --git a/Desktop_Interface/build_win/libusbk/bin/lib/x86/libusbK.lib b/Desktop_Interface/build_win/libusbk/bin/lib/x86/libusbK.lib new file mode 100644 index 00000000..2f390040 Binary files /dev/null and b/Desktop_Interface/build_win/libusbk/bin/lib/x86/libusbK.lib differ diff --git a/Desktop_Interface/build_win/libusbk/bin/lib/x86/libusbK.lib.REMOVED.git-id b/Desktop_Interface/build_win/libusbk/bin/lib/x86/libusbK.lib.REMOVED.git-id deleted file mode 100644 index 1fa8e8a2..00000000 --- a/Desktop_Interface/build_win/libusbk/bin/lib/x86/libusbK.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2f390040f2c3f79b8dafb442c993ac36e2f6dc26 \ No newline at end of file diff --git a/Desktop_Interface/build_win/libusbk/includes/libusbk.h b/Desktop_Interface/build_win/libusbk/includes/libusbk.h new file mode 100644 index 00000000..bac5f81b --- /dev/null +++ b/Desktop_Interface/build_win/libusbk/includes/libusbk.h @@ -0,0 +1,4000 @@ +/*! \file libusbk.h +* \brief functions for usb device communication. +* +* \note +* This is the \b main libusbK USB user include file. +*/ + +#ifndef _LIBUSBK_H__ +#define _LIBUSBK_H__ + +#include "lusbk_shared.h" + +/////////////////////////////////////////////////////////////////////// +// L I B U S B K PUBLIC STRUCTS, DEFINES, AND ENUMS ////////////////// +/////////////////////////////////////////////////////////////////////// + +#ifndef _LIBUSBK_LIBK_TYPES + +/*! \addtogroup libk +* @{ +*/ + +#define _in +#define _inopt +#define _out +#define _outopt +#define _ref +#define _refopt + +//! UsbK base function pointer, See \ref LibK_GetProcAddress. +typedef INT_PTR (FAR WINAPI* KPROC)(); + +//! Indicates that a function is an exported API call. +#if defined(DYNAMIC_DLL) +#define KUSB_EXP +#else +#define KUSB_EXP +#endif + +//! Indicates the calling convention. This is always WINAPI (stdcall) by default. +#if !defined(KUSB_API) +#define KUSB_API WINAPI +#endif + +#pragma warning(disable:4201) + +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif +#pragma warning (disable:4201) +#pragma warning(disable:4214) // named type definition in parentheses + +//! User defined handle context space, see \ref LibK_GetContext. +typedef INT_PTR KLIB_USER_CONTEXT; + +//! KUSB control setup packet. +/*! +* This union structure is identical in size to a \ref WINUSB_SETUP_PACKET, +* but provides additional field accessors. (see \ref libusbk.h for structure details) +*/ +typedef union _KUSB_SETUP_PACKET +{ + UCHAR Bytes[8]; + USHORT Words[4]; + struct + { + //! Request value + struct + { + UCHAR Recipient: 2; + UCHAR Reserved: 3; + UCHAR Type: 2; + UCHAR Dir: 1; + } BmRequest; + + //! Request type value + UCHAR Request; + + //! wValue + USHORT Value; + + //! wIndex + USHORT Index; + + //! wLength ushort value + USHORT Length; + }; + struct + { + struct + { + UCHAR b0: 1; + UCHAR b1: 1; + UCHAR b2: 1; + UCHAR b3: 1; + UCHAR b4: 1; + UCHAR b5: 1; + UCHAR b6: 1; + UCHAR b7: 1; + } BmRequestBits; + + struct + { + UCHAR b0: 1; + UCHAR b1: 1; + UCHAR b2: 1; + UCHAR b3: 1; + UCHAR b4: 1; + UCHAR b5: 1; + UCHAR b6: 1; + UCHAR b7: 1; + } RequestBits; + + UCHAR ValueLo; + UCHAR ValueHi; + UCHAR IndexLo; + UCHAR IndexHi; + UCHAR LengthLo; + UCHAR LengthHi; + }; +} KUSB_SETUP_PACKET; +// setup packet is eight bytes -- defined by spec +C_ASSERT(sizeof(KUSB_SETUP_PACKET) == 8); + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif + + +//! Base handle type for all library handles, See \ref KLIB_HANDLE_TYPE. +typedef void* KLIB_HANDLE; + +//! Opaque UsbK handle, see \ref UsbK_Init. +typedef KLIB_HANDLE KUSB_HANDLE; + +//! Opaque LstK handle, see \ref LstK_Init. +typedef KLIB_HANDLE KLST_HANDLE; + +//! Opaque HotK handle, see \ref HotK_Init. +typedef KLIB_HANDLE KHOT_HANDLE; + +//! Opaque OvlK handle, see \ref OvlK_Acquire. +typedef KLIB_HANDLE KOVL_HANDLE; + + +//! Opaque OvlPoolK handle, see \ref OvlK_Init. +typedef KLIB_HANDLE KOVL_POOL_HANDLE; + +//! Opaque StmK handle, see \ref StmK_Init. +typedef KLIB_HANDLE KSTM_HANDLE; + +//! Handle type enumeration. +typedef enum _KLIB_HANDLE_TYPE +{ + //! Hot plug handle. \ref KHOT_HANDLE + KLIB_HANDLE_TYPE_HOTK, + + //! USB handle. \ref KUSB_HANDLE + KLIB_HANDLE_TYPE_USBK, + + //! Shared USB handle. \ref KUSB_HANDLE + KLIB_HANDLE_TYPE_USBSHAREDK, + + //! Device list handle. \ref KLST_HANDLE + KLIB_HANDLE_TYPE_LSTK, + + //! Device info handle. \ref KLST_DEVINFO_HANDLE + KLIB_HANDLE_TYPE_LSTINFOK, + + //! Overlapped handle. \ref KOVL_HANDLE + KLIB_HANDLE_TYPE_OVLK, + + //! Overlapped pool handle. \ref KOVL_POOL_HANDLE + KLIB_HANDLE_TYPE_OVLPOOLK, + + //! Pipe stream handle. \ref KSTM_HANDLE + KLIB_HANDLE_TYPE_STMK, + + //! Max handle type count. + KLIB_HANDLE_TYPE_COUNT +} KLIB_HANDLE_TYPE; + +//! Function typedef for \ref LibK_SetCleanupCallback. +typedef INT KUSB_API KLIB_HANDLE_CLEANUP_CB (_in KLIB_HANDLE Handle, _in KLIB_HANDLE_TYPE HandleType, _in KLIB_USER_CONTEXT UserContext); + +//! libusbK verson information structure. +typedef struct _KLIB_VERSION +{ + //! Major version number. + INT Major; + + //! Minor version number. + INT Minor; + + //! Micro version number. + INT Micro; + + //! Nano version number. + INT Nano; +} KLIB_VERSION; +//! Pointer to a \copybrief KLIB_VERSION +typedef KLIB_VERSION* PKLIB_VERSION; + +/*! @} */ +#endif + +#ifndef _LIBUSBK_ISOK_TYPES +/*! \addtogroup isok +* @{ +*/ + + +//! Callback function typedef for \ref IsoK_EnumPackets +typedef BOOL KUSB_API KISO_ENUM_PACKETS_CB (_in UINT PacketIndex, _in PKISO_PACKET IsoPacket, _in PVOID UserState); + +/*! @} */ +#endif + +#ifndef _LIBUSBK_LSTK_TYPES + +/*! \addtogroup lstk +* @{ +*/ + +//! Allocated length for all strings in a \ref KLST_DEVINFO structure. +#define KLST_STRING_MAX_LEN 256 + +//! Device list sync flags. +/*! +* These sync flags are also use by the hot plug module to indicate device +* arrival/removal notifications: +* - \b DeviceArrival = KLST_SYNC_FLAG_ADDED +* - \b DeviceRemoval = KLST_SYNC_FLAG_REMOVED +*/ +typedef enum _KLST_SYNC_FLAG +{ + //! Cleared/invalid state. + KLST_SYNC_FLAG_NONE = 0L, + + //! Unchanged state, + KLST_SYNC_FLAG_UNCHANGED = 0x0001, + + //! Added (Arrival) state, + KLST_SYNC_FLAG_ADDED = 0x0002, + + //! Removed (Unplugged) state, + KLST_SYNC_FLAG_REMOVED = 0x0004, + + //! Connect changed state. + KLST_SYNC_FLAG_CONNECT_CHANGE = 0x0008, + + //! All states. + KLST_SYNC_FLAG_MASK = 0x000F, +} KLST_SYNC_FLAG; + +//! Common usb device information structure +typedef struct _KLST_DEV_COMMON_INFO +{ + //! VendorID parsed from \ref KLST_DEVINFO::DeviceID + INT Vid; + + //! ProductID parsed from \ref KLST_DEVINFO::DeviceID + INT Pid; + + //! Composite interface number parsed from \ref KLST_DEVINFO::DeviceID. Set to \b -1 for devices that do not have the composite parent driver. + INT MI; + + // An ID that uniquely identifies a USB device. + CHAR InstanceID[KLST_STRING_MAX_LEN]; + +} KLST_DEV_COMMON_INFO; +//! Pointer to a \c KLST_DEV_COMMON_INFO structure. +typedef KLST_DEV_COMMON_INFO* PKLST_DEV_COMMON_INFO; + +//! Semi-opaque device information structure of a device list. +/*! +* +* \attention This structure is semi-opaque. +* +*/ +typedef struct _KLST_DEVINFO +{ + //! Common usb device information + KLST_DEV_COMMON_INFO Common; + + //! Driver id this device element is using + INT DriverID; + + //! Device interface GUID + CHAR DeviceInterfaceGUID[KLST_STRING_MAX_LEN]; + + //! Device instance ID. + /*! + * A Device instance ID has the following format: + * [enumerator]\[enumerator-specific-device-ID]\[instance-specific-ID] + * - [enumerator] + * - For USB device, the enumerator is always \c USB + * - [enumerator-specific-device-ID] + * - Contains the vendor and product id (VID_xxxx&PID_xxxx) + * - If present, contains the usbccgp (windows composite device layer) interface number (MI_xx) + * - [instance-specific-ID] + * - If the device is composite, contains a unique interface ID generated by Windows. + * - If the device is not composite and has a serial number, contains the devices serial number. + * - If the device does not have a serial number, contains a unique ID generated by Windows. + */ + CHAR DeviceID[KLST_STRING_MAX_LEN]; + + //! Class GUID. + CHAR ClassGUID[KLST_STRING_MAX_LEN]; + + //! Manufacturer name as specified in the INF file. + CHAR Mfg[KLST_STRING_MAX_LEN]; + + //! Device description as specified in the INF file. + CHAR DeviceDesc[KLST_STRING_MAX_LEN]; + + //! Driver service name. + CHAR Service[KLST_STRING_MAX_LEN]; + + //! Unique identifier. + CHAR SymbolicLink[KLST_STRING_MAX_LEN]; + + //! physical device filename used with the Windows \c CreateFile() + CHAR DevicePath[KLST_STRING_MAX_LEN]; + + //! libusb-win32 filter index id. + INT LUsb0FilterIndex; + + //! Indicates the devices connection state. + BOOL Connected; + + //! Synchronization flags. (internal use only) + KLST_SYNC_FLAG SyncFlags; + + INT BusNumber; + + INT DeviceAddress; + + //! If the the device is serialized, represents the string value of \ref USB_DEVICE_DESCRIPTOR::iSerialNumber. For Devices without a \b iSerialNumber, represents the unique \b InstanceID assigned by \b Windows. + CHAR SerialNumber[KLST_STRING_MAX_LEN]; + +} KLST_DEVINFO; +//! Pointer to a \ref KLST_DEVINFO structure. (semi-opaque) +typedef KLST_DEVINFO* KLST_DEVINFO_HANDLE; + +//! Device list initialization flags. +typedef enum _KLST_FLAG +{ + //! No flags (or 0) + KLST_FLAG_NONE = 0L, + + //! Enable listings for the raw device interface GUID \b only. {A5DCBF10-6530-11D2-901F-00C04FB951ED} + KLST_FLAG_INCLUDE_RAWGUID = 0x0001, + + //! List all libusbK devices including those not currently connected. + KLST_FLAG_INCLUDE_DISCONNECT = 0x0002, + +} KLST_FLAG; + +//! Device list/hot-plug pattern match structure. +/*! +* \fixedstruct{1024} +* +* These ansi char strings are used to specify which devices should be included in a device list. +* All strings file pattern match strings allowing asterisk or question mark chars as wildcards. +* +*/ +typedef struct _KLST_PATTERN_MATCH +{ + //! Pattern match a device instance id. + CHAR DeviceID[KLST_STRING_MAX_LEN]; + + //! Pattern match a device interface guid. + CHAR DeviceInterfaceGUID[KLST_STRING_MAX_LEN]; + + //! Pattern match a symbolic link. + CHAR ClassGUID[KLST_STRING_MAX_LEN]; + + //! fixed structure padding. + UCHAR z_F_i_x_e_d[1024 - KLST_STRING_MAX_LEN * 3]; + +} KLST_PATTERN_MATCH; +C_ASSERT(sizeof(KLST_PATTERN_MATCH) == 1024); + +//! Pointer to a \ref KLST_PATTERN_MATCH structure. +typedef KLST_PATTERN_MATCH* PKLST_PATTERN_MATCH; + +//! Device list enumeration function callback typedef. +/*! +* +* \param DeviceList +* The device list \c DeviceInfo belongs to +* +* \param DeviceInfo +* Device information +* +* \param Context +* User context that was passed into \ref LstK_Enumerate +* +* Use this typedef as a prototype for an enumeration function with \ref LstK_Enumerate. +* +*/ +typedef BOOL KUSB_API KLST_ENUM_DEVINFO_CB ( + _in KLST_HANDLE DeviceList, + _in KLST_DEVINFO_HANDLE DeviceInfo, + _in PVOID Context); + +/*! @} */ + +#endif + +#ifndef __USB_H__ + +#include + +/*! \addtogroup libk +* @{ +*/ + +//! Maximum value that can be added to the current start frame. +#define USBD_ISO_START_FRAME_RANGE 1024 + + +//! bmRequest.Dir +typedef enum _BMREQUEST_DIR +{ + BMREQUEST_DIR_HOST_TO_DEVICE = 0, + BMREQUEST_DIR_DEVICE_TO_HOST = 1, +} BMREQUEST_DIR; + +//! bmRequest.Type +typedef enum _BMREQUEST_TYPE +{ + //! Standard request. See \ref USB_REQUEST_ENUM + BMREQUEST_TYPE_STANDARD = 0, + + //! Class-specific request. + BMREQUEST_TYPE_CLASS = 1, + + //! Vendor-specific request + BMREQUEST_TYPE_VENDOR = 2, +} BMREQUEST_TYPE; + +//! bmRequest.Recipient +typedef enum _BMREQUEST_RECIPIENT +{ + //! Request is for a device. + BMREQUEST_RECIPIENT_DEVICE = 0, + + //! Request is for an interface of a device. + BMREQUEST_RECIPIENT_INTERFACE = 1, + + //! Request is for an endpoint of a device. + BMREQUEST_RECIPIENT_ENDPOINT = 2, + + //! Request is for a vendor-specific purpose. + BMREQUEST_RECIPIENT_OTHER = 3, +} BMREQUEST_RECIPIENT; + +//! Maximum length (in bytes) of a usb string. USB strings are always stored in wide-char format. +#define MAXIMUM_USB_STRING_LENGTH 255 + +//! Values for the bits returned by the \ref USB_REQUEST_GET_STATUS request. +typedef enum _USB_GETSTATUS +{ + //! Device is self powered + USB_GETSTATUS_SELF_POWERED = 0x01, + + //! Device can wake the system from a low power/sleeping state. + USB_GETSTATUS_REMOTE_WAKEUP_ENABLED = 0x02 +} USB_GETSTATUS; + +//! Standard USB descriptor types. For more information, see section 9-5 of the USB 3.0 specifications. +typedef enum _USB_DESCRIPTOR_TYPE +{ + //! Device descriptor type. + USB_DESCRIPTOR_TYPE_DEVICE = 0x01, + + //! Configuration descriptor type. + USB_DESCRIPTOR_TYPE_CONFIGURATION = 0x02, + + //! String descriptor type. + USB_DESCRIPTOR_TYPE_STRING = 0x03, + + //! Interface descriptor type. + USB_DESCRIPTOR_TYPE_INTERFACE = 0x04, + + //! Endpoint descriptor type. + USB_DESCRIPTOR_TYPE_ENDPOINT = 0x05, + + //! Device qualifier descriptor type. + USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER = 0x06, + + //! Config power descriptor type. + USB_DESCRIPTOR_TYPE_CONFIG_POWER = 0x07, + + //! Interface power descriptor type. + USB_DESCRIPTOR_TYPE_INTERFACE_POWER = 0x08, + + //! Interface association descriptor type. + USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION = 0x0B, +} USB_DESCRIPTOR_TYPE; + +//! Makes \c wValue for a \ref USB_REQUEST_GET_DESCRIPTOR or \ref USB_REQUEST_SET_DESCRIPTOR request. +#define USB_DESCRIPTOR_MAKE_TYPE_AND_INDEX(d, i) \ + ((USHORT)((USHORT)d<<8 | i)) + +//! Endpoint type mask for the \c bmAttributes field of a \ref USB_ENDPOINT_DESCRIPTOR +#define USB_ENDPOINT_TYPE_MASK 0x03 + +//! Indicates a control endpoint +#define USB_ENDPOINT_TYPE_CONTROL 0x00 + +//! Indicates an isochronous endpoint +#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 + +//! Indicates a bulk endpoint +#define USB_ENDPOINT_TYPE_BULK 0x02 + +//! Indicates an interrupt endpoint +#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 + +//! Config power mask for the \c bmAttributes field of a \ref USB_CONFIGURATION_DESCRIPTOR +#define USB_CONFIG_POWERED_MASK 0xc0 + +//! Values used in the \c bmAttributes field of a \ref USB_CONFIGURATION_DESCRIPTOR +enum USB_CONFIG_BM_ATTRIBUTE_ENUM +{ + //! The device is powered by it's host. + USB_CONFIG_BUS_POWERED = 0x80, + + //! The device has an external power source. + USB_CONFIG_SELF_POWERED = 0x40, + + //! The device is capable of waking the the host from a low power/sleeping state. + USB_CONFIG_REMOTE_WAKEUP = 0x20, +}; + +//! Endpoint direction mask for the \c bEndpointAddress field of a \ref USB_ENDPOINT_DESCRIPTOR +#define USB_ENDPOINT_DIRECTION_MASK 0x80 + +//! Endpoint address mask for the \c bEndpointAddress field of a \ref USB_ENDPOINT_DESCRIPTOR +#define USB_ENDPOINT_ADDRESS_MASK 0x0F + +//! Tests the \c bEndpointAddress direction bit. TRUE if the endpoint address is an OUT endpoint. (HostToDevice, PC Write) +/*! +* \param addr \c bEndpointAddress field of a \ref USB_ENDPOINT_DESCRIPTOR +*/ +#define USB_ENDPOINT_DIRECTION_OUT(addr) (!((addr) & USB_ENDPOINT_DIRECTION_MASK)) + +//! Tests the \c bEndpointAddress direction bit. TRUE if the endpoint address is an IN endpoint. (DeviceToHost, PC Read) +/*! +* \param addr \c bEndpointAddress field of a \ref USB_ENDPOINT_DESCRIPTOR +*/ +#define USB_ENDPOINT_DIRECTION_IN(addr) ((addr) & USB_ENDPOINT_DIRECTION_MASK) + +//! USB defined request codes +/* +* see Chapter 9 of the USB 2.0 specification for +* more information. +* +* These are the correct values based on the USB 2.0 specification. +*/ +enum USB_REQUEST_ENUM +{ + //! Request status of the specific recipient + USB_REQUEST_GET_STATUS = 0x00, + + //! Clear or disable a specific feature + USB_REQUEST_CLEAR_FEATURE = 0x01, + + //! Set or enable a specific feature + USB_REQUEST_SET_FEATURE = 0x03, + + //! Set device address for all future accesses + USB_REQUEST_SET_ADDRESS = 0x05, + + //! Get the specified descriptor + USB_REQUEST_GET_DESCRIPTOR = 0x06, + + //! Update existing descriptors or add new descriptors + USB_REQUEST_SET_DESCRIPTOR = 0x07, + + //! Get the current device configuration value + USB_REQUEST_GET_CONFIGURATION = 0x08, + + //! Set device configuration + USB_REQUEST_SET_CONFIGURATION = 0x09, + + //! Return the selected alternate setting for the specified interface + USB_REQUEST_GET_INTERFACE = 0x0A, + + //! Select an alternate interface for the specified interface + USB_REQUEST_SET_INTERFACE = 0x0B, + + //! Set then report an endpoint's synchronization frame + USB_REQUEST_SYNC_FRAME = 0x0C, +}; + +//! USB defined class codes +/*! +* see http://www.usb.org/developers/defined_class for more information. +* +*/ +enum USB_DEVICE_CLASS_ENUM +{ + //! Reserved class + USB_DEVICE_CLASS_RESERVED = 0x00, + + //! Audio class + USB_DEVICE_CLASS_AUDIO = 0x01, + + //! Communications class + USB_DEVICE_CLASS_COMMUNICATIONS = 0x02, + + //! Human Interface Device class + USB_DEVICE_CLASS_HUMAN_INTERFACE = 0x03, + + //! Imaging class + USB_DEVICE_CLASS_IMAGING = 0x06, + + //! Printer class + USB_DEVICE_CLASS_PRINTER = 0x07, + + //! Mass storage class + USB_DEVICE_CLASS_STORAGE = 0x08, + + //! Hub class + USB_DEVICE_CLASS_HUB = 0x09, + + //! vendor-specific class + USB_DEVICE_CLASS_VENDOR_SPECIFIC = 0xFF, +}; + +//! A structure representing the standard USB device descriptor. +/*! +* This descriptor is documented in section 9.6.1 of the USB 2.0 specification. +* All multiple-byte fields are represented in host-endian format. +*/ +typedef struct _USB_DEVICE_DESCRIPTOR +{ + //! Size of this descriptor (in bytes) + UCHAR bLength; + + //! Descriptor type + UCHAR bDescriptorType; + + //! USB specification release number in binary-coded decimal. + /*! + * A value of 0x0200 indicates USB 2.0, 0x0110 indicates USB 1.1, etc. + */ + USHORT bcdUSB; + + //! USB-IF class code for the device + UCHAR bDeviceClass; + + //! USB-IF subclass code for the device + UCHAR bDeviceSubClass; + + //! USB-IF protocol code for the device + UCHAR bDeviceProtocol; + + //! Maximum packet size for control endpoint 0 + UCHAR bMaxPacketSize0; + + //! USB-IF vendor ID + USHORT idVendor; + + //! USB-IF product ID + USHORT idProduct; + + //! Device release number in binary-coded decimal + USHORT bcdDevice; + + //! Index of string descriptor describing manufacturer + UCHAR iManufacturer; + + //! Index of string descriptor describing product + UCHAR iProduct; + + //! Index of string descriptor containing device serial number + UCHAR iSerialNumber; + + //! Number of possible configurations + UCHAR bNumConfigurations; + +} USB_DEVICE_DESCRIPTOR; +//! pointer to a \c USB_DEVICE_DESCRIPTOR +typedef USB_DEVICE_DESCRIPTOR* PUSB_DEVICE_DESCRIPTOR; + +//! A structure representing the standard USB endpoint descriptor. +/*! +* This descriptor is documented in section 9.6.3 of the USB 2.0 specification. +* All multiple-byte fields are represented in host-endian format. +*/ +typedef struct _USB_ENDPOINT_DESCRIPTOR +{ + //! Size of this descriptor (in bytes) + UCHAR bLength; + + //! Descriptor type + UCHAR bDescriptorType; + + //! The address of the endpoint described by this descriptor. + /*! + * - Bits 0:3 are the endpoint number + * - Bits 4:6 are reserved + * - Bit 7 indicates direction + */ + UCHAR bEndpointAddress; + + //! Attributes which apply to the endpoint when it is configured using the bConfigurationValue. + /*! + * - Bits 0:1 determine the transfer type. + * - Bits 2:3 are only used for isochronous endpoints and refer to sync type. + * - Bits 4:5 are also only used for isochronous endpoints and refer to usage type. + * - Bits 6:7 are reserved. + */ + UCHAR bmAttributes; + + //! Maximum packet size this endpoint is capable of sending/receiving. + USHORT wMaxPacketSize; + + //! Interval for polling endpoint for data transfers. + UCHAR bInterval; + +} USB_ENDPOINT_DESCRIPTOR; +//! pointer to a \c USB_ENDPOINT_DESCRIPTOR +typedef USB_ENDPOINT_DESCRIPTOR* PUSB_ENDPOINT_DESCRIPTOR; + +//! A structure representing the standard USB configuration descriptor. +/* +* +* This descriptor is documented in section 9.6.3 of the USB 2.0 specification. +* All multiple-byte fields are represented in host-endian format. +* +*/ +typedef struct _USB_CONFIGURATION_DESCRIPTOR +{ + //! Size of this descriptor (in bytes) + UCHAR bLength; + + //! Descriptor type + UCHAR bDescriptorType; + + //! Total length of data returned for this configuration + USHORT wTotalLength; + + //! Number of interfaces supported by this configuration + UCHAR bNumInterfaces; + + //! Identifier value for this configuration + UCHAR bConfigurationValue; + + //! Index of string descriptor describing this configuration + UCHAR iConfiguration; + + //! Configuration characteristics + UCHAR bmAttributes; + + //! Maximum power consumption of the USB device from this bus in this configuration when the device is fully operation. + /*! + * Expressed in units of 2 mA. + */ + UCHAR MaxPower; +} USB_CONFIGURATION_DESCRIPTOR; +//! pointer to a \c USB_CONFIGURATION_DESCRIPTOR +typedef USB_CONFIGURATION_DESCRIPTOR* PUSB_CONFIGURATION_DESCRIPTOR; + +//! A structure representing the standard USB interface descriptor. +/*! +* This descriptor is documented in section 9.6.5 of the USB 2.0 specification. +* All multiple-byte fields are represented in host-endian format. +*/ +typedef struct _USB_INTERFACE_DESCRIPTOR +{ + //! Size of this descriptor (in bytes) + UCHAR bLength; + + //! Descriptor type + UCHAR bDescriptorType; + + //! Number of this interface + UCHAR bInterfaceNumber; + + //! Value used to select this alternate setting for this interface + UCHAR bAlternateSetting; + + //! Number of endpoints used by this interface (excluding the control endpoint) + UCHAR bNumEndpoints; + + //! USB-IF class code for this interface + UCHAR bInterfaceClass; + + //! USB-IF subclass code for this interface + UCHAR bInterfaceSubClass; + + //! USB-IF protocol code for this interface + UCHAR bInterfaceProtocol; + + //! Index of string descriptor describing this interface + UCHAR iInterface; + +} USB_INTERFACE_DESCRIPTOR; +//! pointer to a \c USB_INTERFACE_DESCRIPTOR +typedef USB_INTERFACE_DESCRIPTOR* PUSB_INTERFACE_DESCRIPTOR; + +//! A structure representing the standard USB string descriptor. +/*! +* This descriptor is documented in section 9.6.5 of the USB 2.0 specification. +* All multiple-byte fields are represented in host-endian format. +*/ +typedef struct _USB_STRING_DESCRIPTOR +{ + //! Size of this descriptor (in bytes) + UCHAR bLength; + + //! Descriptor type + UCHAR bDescriptorType; + + //! Content of the string + WCHAR bString[1]; + +} USB_STRING_DESCRIPTOR; +//! pointer to a \c USB_STRING_DESCRIPTOR +typedef USB_STRING_DESCRIPTOR* PUSB_STRING_DESCRIPTOR; + +//! A structure representing the common USB descriptor. +typedef struct _USB_COMMON_DESCRIPTOR +{ + //! Size of this descriptor (in bytes) + UCHAR bLength; + + //! Descriptor type + UCHAR bDescriptorType; + +} USB_COMMON_DESCRIPTOR; +//! pointer to a \c USB_COMMON_DESCRIPTOR +typedef USB_COMMON_DESCRIPTOR* PUSB_COMMON_DESCRIPTOR; + +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif +#pragma warning (disable:4201) +#pragma warning(disable:4214) // named type definition in parentheses + +//! Allows hardware manufacturers to define groupings of interfaces. +/*! +* +* The ECN specifies a USB descriptor, called the Interface Association +* Descriptor (IAD). +* +* The Universal Serial Bus Specification, revision 2.0, does not support +* grouping more than one interface of a composite device within a single +* function. However, the USB Device Working Group (DWG) created USB device +* classes that allow for functions with multiple interfaces, and the USB +* Implementor's Forum issued an Engineering Change Notification (ECN) that +* defines a mechanism for grouping interfaces. +* +*/ +typedef struct _USB_INTERFACE_ASSOCIATION_DESCRIPTOR +{ + //! Size of this descriptor (in bytes) + UCHAR bLength; + + //! Descriptor type + UCHAR bDescriptorType; + + //! First interface number of the set of interfaces that follow this descriptor + UCHAR bFirstInterface; + + //! The Number of interfaces follow this descriptor that are considered "associated" + UCHAR bInterfaceCount; + + //! \c bInterfaceClass used for this associated interfaces + UCHAR bFunctionClass; + + //! \c bInterfaceSubClass used for the associated interfaces + UCHAR bFunctionSubClass; + + //! \c bInterfaceProtocol used for the associated interfaces + UCHAR bFunctionProtocol; + + //! Index of string descriptor describing the associated interfaces + UCHAR iFunction; + +} USB_INTERFACE_ASSOCIATION_DESCRIPTOR; +//! pointer to a \c USB_INTERFACE_ASSOCIATION_DESCRIPTOR +typedef USB_INTERFACE_ASSOCIATION_DESCRIPTOR* PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR; + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif + +/*! @} */ + +#include +#endif // __USB_H__ + +#ifndef _LIBUSBK_LIBK_TYPES + +/*! \addtogroup libk +* @{ +*/ + +//! Usb handle specific properties that can be retrieved with \ref UsbK_GetProperty. +typedef enum _KUSB_PROPERTY +{ + //! Get the internal device file handle used for operations such as GetOverlappedResult or DeviceIoControl. + KUSB_PROPERTY_DEVICE_FILE_HANDLE, + + KUSB_PROPERTY_COUNT + +} KUSB_PROPERTY; + +//! Supported driver id enumeration. +typedef enum _KUSB_DRVID +{ + //! libusbK.sys driver ID + KUSB_DRVID_LIBUSBK, + + //! libusb0.sys driver ID + KUSB_DRVID_LIBUSB0, + + //! WinUSB.sys driver ID + KUSB_DRVID_WINUSB, + + //! libusb0.sys filter driver ID + KUSB_DRVID_LIBUSB0_FILTER, + + //! Supported driver count + KUSB_DRVID_COUNT + +} KUSB_DRVID; + +//! Supported function id enumeration. +typedef enum _KUSB_FNID +{ + //! \ref UsbK_Init dynamic driver function id. + KUSB_FNID_Init, + + //! \ref UsbK_Free dynamic driver function id. + KUSB_FNID_Free, + + //! \ref UsbK_ClaimInterface dynamic driver function id. + KUSB_FNID_ClaimInterface, + + //! \ref UsbK_ReleaseInterface dynamic driver function id. + KUSB_FNID_ReleaseInterface, + + //! \ref UsbK_SetAltInterface dynamic driver function id. + KUSB_FNID_SetAltInterface, + + //! \ref UsbK_GetAltInterface dynamic driver function id. + KUSB_FNID_GetAltInterface, + + //! \ref UsbK_GetDescriptor dynamic driver function id. + KUSB_FNID_GetDescriptor, + + //! \ref UsbK_ControlTransfer dynamic driver function id. + KUSB_FNID_ControlTransfer, + + //! \ref UsbK_SetPowerPolicy dynamic driver function id. + KUSB_FNID_SetPowerPolicy, + + //! \ref UsbK_GetPowerPolicy dynamic driver function id. + KUSB_FNID_GetPowerPolicy, + + //! \ref UsbK_SetConfiguration dynamic driver function id. + KUSB_FNID_SetConfiguration, + + //! \ref UsbK_GetConfiguration dynamic driver function id. + KUSB_FNID_GetConfiguration, + + //! \ref UsbK_ResetDevice dynamic driver function id. + KUSB_FNID_ResetDevice, + + //! \ref UsbK_Initialize dynamic driver function id. + KUSB_FNID_Initialize, + + //! \ref UsbK_SelectInterface dynamic driver function id. + KUSB_FNID_SelectInterface, + + //! \ref UsbK_GetAssociatedInterface dynamic driver function id. + KUSB_FNID_GetAssociatedInterface, + + //! \ref UsbK_Clone dynamic driver function id. + KUSB_FNID_Clone, + + //! \ref UsbK_QueryInterfaceSettings dynamic driver function id. + KUSB_FNID_QueryInterfaceSettings, + + //! \ref UsbK_QueryDeviceInformation dynamic driver function id. + KUSB_FNID_QueryDeviceInformation, + + //! \ref UsbK_SetCurrentAlternateSetting dynamic driver function id. + KUSB_FNID_SetCurrentAlternateSetting, + + //! \ref UsbK_GetCurrentAlternateSetting dynamic driver function id. + KUSB_FNID_GetCurrentAlternateSetting, + + //! \ref UsbK_QueryPipe dynamic driver function id. + KUSB_FNID_QueryPipe, + + //! \ref UsbK_SetPipePolicy dynamic driver function id. + KUSB_FNID_SetPipePolicy, + + //! \ref UsbK_GetPipePolicy dynamic driver function id. + KUSB_FNID_GetPipePolicy, + + //! \ref UsbK_ReadPipe dynamic driver function id. + KUSB_FNID_ReadPipe, + + //! \ref UsbK_WritePipe dynamic driver function id. + KUSB_FNID_WritePipe, + + //! \ref UsbK_ResetPipe dynamic driver function id. + KUSB_FNID_ResetPipe, + + //! \ref UsbK_AbortPipe dynamic driver function id. + KUSB_FNID_AbortPipe, + + //! \ref UsbK_FlushPipe dynamic driver function id. + KUSB_FNID_FlushPipe, + + //! \ref UsbK_IsoReadPipe dynamic driver function id. + KUSB_FNID_IsoReadPipe, + + //! \ref UsbK_IsoWritePipe dynamic driver function id. + KUSB_FNID_IsoWritePipe, + + //! \ref UsbK_GetCurrentFrameNumber dynamic driver function id. + KUSB_FNID_GetCurrentFrameNumber, + + //! \ref UsbK_GetOverlappedResult dynamic driver function id. + KUSB_FNID_GetOverlappedResult, + + //! \ref UsbK_GetProperty dynamic driver function id. + KUSB_FNID_GetProperty, + + + //! Supported function count + KUSB_FNID_COUNT, + +} KUSB_FNID; + +typedef BOOL KUSB_API KUSB_Init ( + _out KUSB_HANDLE* InterfaceHandle, + _in KLST_DEVINFO_HANDLE DevInfo); + +typedef BOOL KUSB_API KUSB_Free ( + _in KUSB_HANDLE InterfaceHandle); + +typedef BOOL KUSB_API KUSB_ClaimInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex); + +typedef BOOL KUSB_API KUSB_ReleaseInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex); + +typedef BOOL KUSB_API KUSB_SetAltInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex, + _in UCHAR AltSettingNumber); + +typedef BOOL KUSB_API KUSB_GetAltInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex, + _out PUCHAR AltSettingNumber); + +typedef BOOL KUSB_API KUSB_GetDescriptor ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR DescriptorType, + _in UCHAR Index, + _in USHORT LanguageID, + _out PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred); + +typedef BOOL KUSB_API KUSB_ControlTransfer ( + _in KUSB_HANDLE InterfaceHandle, + _in WINUSB_SETUP_PACKET SetupPacket, + _refopt PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred, + _inopt LPOVERLAPPED Overlapped); + +typedef BOOL KUSB_API KUSB_SetPowerPolicy ( + _in KUSB_HANDLE InterfaceHandle, + _in UINT PolicyType, + _in UINT ValueLength, + _in PVOID Value); + +typedef BOOL KUSB_API KUSB_GetPowerPolicy ( + _in KUSB_HANDLE InterfaceHandle, + _in UINT PolicyType, + _ref PUINT ValueLength, + _out PVOID Value); + +typedef BOOL KUSB_API KUSB_SetConfiguration ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR ConfigurationNumber); + +typedef BOOL KUSB_API KUSB_GetConfiguration ( + _in KUSB_HANDLE InterfaceHandle, + _out PUCHAR ConfigurationNumber); + +typedef BOOL KUSB_API KUSB_ResetDevice ( + _in KUSB_HANDLE InterfaceHandle); + +typedef BOOL KUSB_API KUSB_Initialize ( + _in HANDLE DeviceHandle, + _out KUSB_HANDLE* InterfaceHandle); + +typedef BOOL KUSB_API KUSB_SelectInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex); + +typedef BOOL KUSB_API KUSB_GetAssociatedInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AssociatedInterfaceIndex, + _out KUSB_HANDLE* AssociatedInterfaceHandle); + +typedef BOOL KUSB_API KUSB_Clone ( + _in KUSB_HANDLE InterfaceHandle, + _out KUSB_HANDLE* DstInterfaceHandle); + +typedef BOOL KUSB_API KUSB_QueryInterfaceSettings ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AltSettingIndex, + _out PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor); + +typedef BOOL KUSB_API KUSB_QueryDeviceInformation ( + _in KUSB_HANDLE InterfaceHandle, + _in UINT InformationType, + _ref PUINT BufferLength, + _ref PVOID Buffer); + +typedef BOOL KUSB_API KUSB_SetCurrentAlternateSetting ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AltSettingNumber); + +typedef BOOL KUSB_API KUSB_GetCurrentAlternateSetting ( + _in KUSB_HANDLE InterfaceHandle, + _out PUCHAR AltSettingNumber); + +typedef BOOL KUSB_API KUSB_QueryPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AltSettingNumber, + _in UCHAR PipeIndex, + _out PWINUSB_PIPE_INFORMATION PipeInformation); + +typedef BOOL KUSB_API KUSB_SetPipePolicy ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in UINT PolicyType, + _in UINT ValueLength, + _in PVOID Value); + +typedef BOOL KUSB_API KUSB_GetPipePolicy ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in UINT PolicyType, + _ref PUINT ValueLength, + _out PVOID Value); + +typedef BOOL KUSB_API KUSB_ReadPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _out PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred, + _inopt LPOVERLAPPED Overlapped); + +typedef BOOL KUSB_API KUSB_WritePipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred, + _inopt LPOVERLAPPED Overlapped); + +typedef BOOL KUSB_API KUSB_ResetPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID); + +typedef BOOL KUSB_API KUSB_AbortPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID); + +typedef BOOL KUSB_API KUSB_FlushPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID); + +typedef BOOL KUSB_API KUSB_IsoReadPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _out PUCHAR Buffer, + _in UINT BufferLength, + _in LPOVERLAPPED Overlapped, + _refopt PKISO_CONTEXT IsoContext); + +typedef BOOL KUSB_API KUSB_IsoWritePipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in PUCHAR Buffer, + _in UINT BufferLength, + _in LPOVERLAPPED Overlapped, + _refopt PKISO_CONTEXT IsoContext); + +typedef BOOL KUSB_API KUSB_GetCurrentFrameNumber ( + _in KUSB_HANDLE InterfaceHandle, + _out PUINT FrameNumber); + +typedef BOOL KUSB_API KUSB_GetOverlappedResult ( + _in KUSB_HANDLE InterfaceHandle, + _in LPOVERLAPPED Overlapped, + _out PUINT lpNumberOfBytesTransferred, + _in BOOL bWait); + +typedef BOOL KUSB_API KUSB_GetProperty ( + _in KUSB_HANDLE InterfaceHandle, + _in KUSB_PROPERTY PropertyType, + _ref PUINT PropertySize, + _out PVOID Value); + + + +//! USB core driver API information structure. +/*! +* This structure is part of \ref KUSB_DRIVER_API and contains +* driver and user specific information. +* +*/ +typedef struct _KUSB_DRIVER_API_INFO +{ + //! \readonly Driver id of the driver api. + INT DriverID; + + //! \readonly Number of valid functions contained in the driver API. + INT FunctionCount; + +} KUSB_DRIVER_API_INFO; + +//! Driver API function set structure. +/* +* Contains the driver specific USB core function pointer set. +* +* \note +* This structure has a fixed 512 byte structure size. +*/ +typedef struct _KUSB_DRIVER_API +{ + //! Driver API information. + KUSB_DRIVER_API_INFO Info; + + /*! \fn BOOL KUSB_API Init (_out KUSB_HANDLE* InterfaceHandle, _in KLST_DEVINFO_HANDLE DevInfo) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_Init + */ + KUSB_Init* Init; + + /*! \fn BOOL KUSB_API Free (_in KUSB_HANDLE InterfaceHandle) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_Free + */ + KUSB_Free* Free; + + /*! \fn BOOL KUSB_API ClaimInterface (_in KUSB_HANDLE InterfaceHandle, _in UCHAR NumberOrIndex, _in BOOL IsIndex) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_ClaimInterface + */ + KUSB_ClaimInterface* ClaimInterface; + + /*! \fn BOOL KUSB_API ReleaseInterface (_in KUSB_HANDLE InterfaceHandle, _in UCHAR NumberOrIndex, _in BOOL IsIndex) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_ReleaseInterface + */ + KUSB_ReleaseInterface* ReleaseInterface; + + /*! \fn BOOL KUSB_API SetAltInterface (_in KUSB_HANDLE InterfaceHandle, _in UCHAR NumberOrIndex, _in BOOL IsIndex, _in UCHAR AltSettingNumber) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_SetAltInterface + */ + KUSB_SetAltInterface* SetAltInterface; + + /*! \fn BOOL KUSB_API GetAltInterface (_in KUSB_HANDLE InterfaceHandle, _in UCHAR NumberOrIndex, _in BOOL IsIndex, _out PUCHAR AltSettingNumber) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_GetAltInterface + */ + KUSB_GetAltInterface* GetAltInterface; + + /*! \fn BOOL KUSB_API GetDescriptor (_in KUSB_HANDLE InterfaceHandle, _in UCHAR DescriptorType, _in UCHAR Index, _in USHORT LanguageID, _out PUCHAR Buffer, _in UINT BufferLength, _outopt PUINT LengthTransferred) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_GetDescriptor + */ + KUSB_GetDescriptor* GetDescriptor; + + /*! \fn BOOL KUSB_API ControlTransfer (_in KUSB_HANDLE InterfaceHandle, _in WINUSB_SETUP_PACKET SetupPacket, _refopt PUCHAR Buffer, _in UINT BufferLength, _outopt PUINT LengthTransferred, _inopt LPOVERLAPPED Overlapped) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_ControlTransfer + */ + KUSB_ControlTransfer* ControlTransfer; + + /*! \fn BOOL KUSB_API SetPowerPolicy (_in KUSB_HANDLE InterfaceHandle, _in UINT PolicyType, _in UINT ValueLength, _in PVOID Value) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_SetPowerPolicy + */ + KUSB_SetPowerPolicy* SetPowerPolicy; + + /*! \fn BOOL KUSB_API GetPowerPolicy (_in KUSB_HANDLE InterfaceHandle, _in UINT PolicyType, _ref PUINT ValueLength, _out PVOID Value) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_GetPowerPolicy + */ + KUSB_GetPowerPolicy* GetPowerPolicy; + + /*! \fn BOOL KUSB_API SetConfiguration (_in KUSB_HANDLE InterfaceHandle, _in UCHAR ConfigurationNumber) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_SetConfiguration + */ + KUSB_SetConfiguration* SetConfiguration; + + /*! \fn BOOL KUSB_API GetConfiguration (_in KUSB_HANDLE InterfaceHandle, _out PUCHAR ConfigurationNumber) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_GetConfiguration + */ + KUSB_GetConfiguration* GetConfiguration; + + /*! \fn BOOL KUSB_API ResetDevice (_in KUSB_HANDLE InterfaceHandle) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_ResetDevice + */ + KUSB_ResetDevice* ResetDevice; + + /*! \fn BOOL KUSB_API Initialize (_in HANDLE DeviceHandle, _out KUSB_HANDLE* InterfaceHandle) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_Initialize + */ + KUSB_Initialize* Initialize; + + /*! \fn BOOL KUSB_API SelectInterface (_in KUSB_HANDLE InterfaceHandle, _in UCHAR NumberOrIndex, _in BOOL IsIndex) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_SelectInterface + */ + KUSB_SelectInterface* SelectInterface; + + /*! \fn BOOL KUSB_API GetAssociatedInterface (_in KUSB_HANDLE InterfaceHandle, _in UCHAR AssociatedInterfaceIndex, _out KUSB_HANDLE* AssociatedInterfaceHandle) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_GetAssociatedInterface + */ + KUSB_GetAssociatedInterface* GetAssociatedInterface; + + /*! \fn BOOL KUSB_API Clone (_in KUSB_HANDLE InterfaceHandle, _out KUSB_HANDLE* DstInterfaceHandle) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_Clone + */ + KUSB_Clone* Clone; + + /*! \fn BOOL KUSB_API QueryInterfaceSettings (_in KUSB_HANDLE InterfaceHandle, _in UCHAR AltSettingIndex, _out PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_QueryInterfaceSettings + */ + KUSB_QueryInterfaceSettings* QueryInterfaceSettings; + + /*! \fn BOOL KUSB_API QueryDeviceInformation (_in KUSB_HANDLE InterfaceHandle, _in UINT InformationType, _ref PUINT BufferLength, _ref PVOID Buffer) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_QueryDeviceInformation + */ + KUSB_QueryDeviceInformation* QueryDeviceInformation; + + /*! \fn BOOL KUSB_API SetCurrentAlternateSetting (_in KUSB_HANDLE InterfaceHandle, _in UCHAR AltSettingNumber) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_SetCurrentAlternateSetting + */ + KUSB_SetCurrentAlternateSetting* SetCurrentAlternateSetting; + + /*! \fn BOOL KUSB_API GetCurrentAlternateSetting (_in KUSB_HANDLE InterfaceHandle, _out PUCHAR AltSettingNumber) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_GetCurrentAlternateSetting + */ + KUSB_GetCurrentAlternateSetting* GetCurrentAlternateSetting; + + /*! \fn BOOL KUSB_API QueryPipe (_in KUSB_HANDLE InterfaceHandle, _in UCHAR AltSettingNumber, _in UCHAR PipeIndex, _out PWINUSB_PIPE_INFORMATION PipeInformation) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_QueryPipe + */ + KUSB_QueryPipe* QueryPipe; + + /*! \fn BOOL KUSB_API SetPipePolicy (_in KUSB_HANDLE InterfaceHandle, _in UCHAR PipeID, _in UINT PolicyType, _in UINT ValueLength, _in PVOID Value) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_SetPipePolicy + */ + KUSB_SetPipePolicy* SetPipePolicy; + + /*! \fn BOOL KUSB_API GetPipePolicy (_in KUSB_HANDLE InterfaceHandle, _in UCHAR PipeID, _in UINT PolicyType, _ref PUINT ValueLength, _out PVOID Value) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_GetPipePolicy + */ + KUSB_GetPipePolicy* GetPipePolicy; + + /*! \fn BOOL KUSB_API ReadPipe (_in KUSB_HANDLE InterfaceHandle, _in UCHAR PipeID, _out PUCHAR Buffer, _in UINT BufferLength, _outopt PUINT LengthTransferred, _inopt LPOVERLAPPED Overlapped) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_ReadPipe + */ + KUSB_ReadPipe* ReadPipe; + + /*! \fn BOOL KUSB_API WritePipe (_in KUSB_HANDLE InterfaceHandle, _in UCHAR PipeID, _in PUCHAR Buffer, _in UINT BufferLength, _outopt PUINT LengthTransferred, _inopt LPOVERLAPPED Overlapped) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_WritePipe + */ + KUSB_WritePipe* WritePipe; + + /*! \fn BOOL KUSB_API ResetPipe (_in KUSB_HANDLE InterfaceHandle, _in UCHAR PipeID) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_ResetPipe + */ + KUSB_ResetPipe* ResetPipe; + + /*! \fn BOOL KUSB_API AbortPipe (_in KUSB_HANDLE InterfaceHandle, _in UCHAR PipeID) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_AbortPipe + */ + KUSB_AbortPipe* AbortPipe; + + /*! \fn BOOL KUSB_API FlushPipe (_in KUSB_HANDLE InterfaceHandle, _in UCHAR PipeID) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_FlushPipe + */ + KUSB_FlushPipe* FlushPipe; + + /*! \fn BOOL KUSB_API IsoReadPipe (_in KUSB_HANDLE InterfaceHandle, _in UCHAR PipeID, _out PUCHAR Buffer, _in UINT BufferLength, _in LPOVERLAPPED Overlapped, _refopt PKISO_CONTEXT IsoContext) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_IsoReadPipe + */ + KUSB_IsoReadPipe* IsoReadPipe; + + /*! \fn BOOL KUSB_API IsoWritePipe (_in KUSB_HANDLE InterfaceHandle, _in UCHAR PipeID, _in PUCHAR Buffer, _in UINT BufferLength, _in LPOVERLAPPED Overlapped, _refopt PKISO_CONTEXT IsoContext) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_IsoWritePipe + */ + KUSB_IsoWritePipe* IsoWritePipe; + + /*! \fn BOOL KUSB_API GetCurrentFrameNumber (_in KUSB_HANDLE InterfaceHandle, _out PUINT FrameNumber) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_GetCurrentFrameNumber + */ + KUSB_GetCurrentFrameNumber* GetCurrentFrameNumber; + + /*! \fn BOOL KUSB_API GetOverlappedResult (_in KUSB_HANDLE InterfaceHandle, _in LPOVERLAPPED Overlapped, _out PUINT lpNumberOfBytesTransferred, _in BOOL bWait) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_GetOverlappedResult + */ + KUSB_GetOverlappedResult* GetOverlappedResult; + + /*! \fn BOOL KUSB_API GetProperty (_in KUSB_HANDLE InterfaceHandle, _in KUSB_PROPERTY PropertyType, _ref PUINT PropertySize, _out PVOID Value) + * \memberof KUSB_DRIVER_API + * \copydoc UsbK_GetProperty + */ + KUSB_GetProperty* GetProperty; + + //! fixed structure padding. + UCHAR z_F_i_x_e_d[512 - sizeof(KUSB_DRIVER_API_INFO) - sizeof(UINT_PTR) * KUSB_FNID_COUNT]; + +} KUSB_DRIVER_API; +typedef KUSB_DRIVER_API* PKUSB_DRIVER_API; +C_ASSERT(sizeof(KUSB_DRIVER_API) == 512); +/**@}*/ +#endif + +#ifndef _LIBUSBK_HOTK_TYPES + +/*! \addtogroup hotk +* @{ +*/ + +//! Hot plug config flags. +typedef enum _KHOT_FLAG +{ + //! No flags (or 0) + KHOT_FLAG_NONE, + + //! Notify all devices which match upon a succuessful call to \ref HotK_Init. + KHOT_FLAG_PLUG_ALL_ON_INIT = 0x0001, + + //! Allow other \ref KHOT_HANDLE instances to consume this match. + KHOT_FLAG_PASS_DUPE_INSTANCE = 0x0002, + + //! If a \c UserHwnd is specified, use \c PostMessage instead of \c SendMessage. + KHOT_FLAG_POST_USER_MESSAGE = 0x0004, +} KHOT_FLAG; + +//! Hot plug event function definition. +typedef VOID KUSB_API KHOT_PLUG_CB( + _in KHOT_HANDLE HotHandle, + _in KLST_DEVINFO_HANDLE DeviceInfo, + _in KLST_SYNC_FLAG PlugType); + +//! Power broadcast event function definition. +typedef VOID KUSB_API KHOT_POWER_BROADCAST_CB( + _in KHOT_HANDLE HotHandle, + _in KLST_DEVINFO_HANDLE DeviceInfo, + _in UINT PbtEvent); + +//! Hot plug parameter structure. +/*! +* \fixedstruct{2048} +* +* This structure is intially passed as a parameter to \ref HotK_Init. +* +*/ +typedef struct _KHOT_PARAMS +{ + //! Hot plug event window handle to send/post messages when notifications occur. + HWND UserHwnd; + + //! WM_USER message start offset used when sending/posting messages, See details. + /*! + * \attention The \ref hotk will send UserMessage+1 for arrival notifications and UserMessage+0 for removal notifications. + * + * - WPARAM = \ref KHOT_HANDLE + * - LPARAM = \ref KLST_DEVINFO_HANDLE + */ + UINT UserMessage; + + //! Additional init/config parameters + KHOT_FLAG Flags; + + //! File pattern matches for restricting notifcations to a single/group or all supported usb devices. + KLST_PATTERN_MATCH PatternMatch; + + //! Hot plug event callback function invoked when notifications occur. + /*! \fn VOID KUSB_API OnHotPlug (_in KHOT_HANDLE HotHandle, _in KLST_DEVINFO_HANDLE DeviceInfo, _in KLST_SYNC_FLAG PlugType) + * \memberof KHOT_PARAMS + */ + KHOT_PLUG_CB* OnHotPlug; + + //! \b WM_POWERBROADCAST event callback function invoked when a power-management event has occurred. + /*! \fn VOID KUSB_API OnPowerBroadcast (_in KHOT_HANDLE HotHandle, _in KLST_DEVINFO_HANDLE DeviceInfo, _in UINT PbtEvent) + * \memberof KHOT_PARAMS + */ + KHOT_POWER_BROADCAST_CB* OnPowerBroadcast; + + //! fixed structure padding. + UCHAR z_F_i_x_e_d[2048 - sizeof(KLST_PATTERN_MATCH) - sizeof(UINT_PTR) * 3 - sizeof(UINT) * 2]; + +} KHOT_PARAMS; +C_ASSERT(sizeof(KHOT_PARAMS) == 2048); + +//! Pointer to a \ref KHOT_PARAMS structure. +typedef KHOT_PARAMS* PKHOT_PARAMS; + +/**@}*/ + +#endif + +#ifndef _LIBUSBK_OVLK_TYPES + +/*! \addtogroup ovlk +* @{ +*/ + +//! \c WaitFlags used by \ref OvlK_Wait. +/*! +* +*/ +typedef enum _KOVL_WAIT_FLAG +{ + //! Do not perform any additional actions upon exiting \ref OvlK_Wait. + KOVL_WAIT_FLAG_NONE = 0L, + + //! If the i/o operation completes successfully, release the OverlappedK back to it's pool. + KOVL_WAIT_FLAG_RELEASE_ON_SUCCESS = 0x0001, + + //! If the i/o operation fails, release the OverlappedK back to it's pool. + KOVL_WAIT_FLAG_RELEASE_ON_FAIL = 0x0002, + + //! If the i/o operation fails or completes successfully, release the OverlappedK back to its pool. Perform no actions if it times-out. + KOVL_WAIT_FLAG_RELEASE_ON_SUCCESS_FAIL = 0x0003, + + //! If the i/o operation times-out cancel it, but do not release the OverlappedK back to its pool. + KOVL_WAIT_FLAG_CANCEL_ON_TIMEOUT = 0x0004, + + //! If the i/o operation times-out, cancel it and release the OverlappedK back to its pool. + KOVL_WAIT_FLAG_RELEASE_ON_TIMEOUT = 0x000C, + + //! Always release the OverlappedK back to its pool. If the operation timed-out, cancel it before releasing back to its pool. + KOVL_WAIT_FLAG_RELEASE_ALWAYS = 0x000F, + + //! Uses alterable wait functions. See http://msdn.microsoft.com/en-us/library/windows/desktop/ms687036%28v=vs.85%29.aspx + KOVL_WAIT_FLAG_ALERTABLE = 0x0010, + +} KOVL_WAIT_FLAG; + +//! \c Overlapped pool config flags. +/*! +* \attention Currently not used. +*/ +typedef enum _KOVL_POOL_FLAG +{ + KOVL_POOL_FLAG_NONE = 0L, +} KOVL_POOL_FLAG; + +/**@}*/ + +#endif + +#ifndef _LIBUSBK_STMK_TYPES + +/*! \addtogroup stmk +* @{ +*/ +//! Stream config flags. +/*! +* \attention Currently not used. +*/ +typedef enum _KSTM_FLAG +{ + //! None + KSTM_FLAG_NONE = 0L, + KSTM_FLAG_NO_PARTIAL_XFERS = 0x00100000, + KSTM_FLAG_USE_TIMEOUT = 0x80000000, + KSTM_FLAG_TIMEOUT_MASK = 0x0001FFFF +} KSTM_FLAG; + +//! Stream config flags. +/*! +* \attention Currently not used. +*/ +typedef enum _KSTM_COMPLETE_RESULT +{ + //! Valid + KSTM_COMPLETE_RESULT_VALID = 0L, + //! Invalid + KSTM_COMPLETE_RESULT_INVALID, +} KSTM_COMPLETE_RESULT; + +//! Stream transfer context structure. +/*! +* This structure is passed into the stream callback functions. +* The stream transfer context list is allocated upon a successful call to \ref StmK_Init. There is one +* transfer context for each transfer. (0 to \c MaxPendingTransfers). +* +*/ +typedef struct _KSTM_XFER_CONTEXT +{ + + //! Internal stream buffer. + PUCHAR Buffer; + + //! Size of internal stream buffer. + INT BufferSize; + + //! Number of bytes to write or number of bytes read. + INT TransferLength; + + //! User defined state. + PVOID UserState; + +} KSTM_XFER_CONTEXT; +//! Pointer to a \ref KSTM_XFER_CONTEXT structure. +typedef KSTM_XFER_CONTEXT* PKSTM_XFER_CONTEXT; + +//! Stream information structure. +/*! +* This structure is passed into the stream callback functions. +* The stream context is allocated upon a successful call to \ref StmK_Init. There is only one +* stream context per stream. +* +*/ +typedef struct _KSTM_INFO +{ + //! \ref KUSB_HANDLE this stream uses. + KUSB_HANDLE UsbHandle; + + //! This parameter corresponds to the bEndpointAddress field in the endpoint descriptor. + UCHAR PipeID; + + //! Maximum transfer read/write request allowed pending. + INT MaxPendingTransfers; + + //! Maximum transfer sage size. + INT MaxTransferSize; + + //! Maximum number of I/O request allowed pending. + INT MaxPendingIO; + + //! Populated with the endpoint descriptor for the specified \c PipeID. + USB_ENDPOINT_DESCRIPTOR EndpointDescriptor; + + //! Populated with the driver api for the specified \c UsbHandle. + KUSB_DRIVER_API DriverAPI; + + //! Populated with the device file handle for the specified \c UsbHandle. + HANDLE DeviceHandle; + + //! Stream handle. + KSTM_HANDLE StreamHandle; + + //! Stream info user defined state. + PVOID UserState; + +} KSTM_INFO; +//! Pointer to a \ref KSTM_INFO structure. +typedef KSTM_INFO* PKSTM_INFO; + +//! Function definition for an optional user-defined callback; executed when a transfer error occurs. +/*! \fn INT KUSB_API KSTM_ERROR_CB(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex, _in INT ErrorCode) +* \memberof KSTM_CALLBACK +*/ +typedef INT KUSB_API KSTM_ERROR_CB(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex, _in INT ErrorCode); + +//! Function definition for an optional user-defined callback; executed to submit a transfer. +/*! \fn INT KUSB_API KSTM_SUBMIT_CB(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex, _in LPOVERLAPPED Overlapped) +* \memberof KSTM_CALLBACK +*/ +typedef INT KUSB_API KSTM_SUBMIT_CB(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex, _in LPOVERLAPPED Overlapped); + +//! Function definition for an optional user-defined callback; executed for each transfer context when the stream is started with \ref StmK_Start. +/*! \fn INT KUSB_API KSTM_STARTED_CB(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex) +* \memberof KSTM_CALLBACK +*/ +typedef INT KUSB_API KSTM_STARTED_CB(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex); + +//! Function definition for an optional user-defined callback; executed for each transfer context when the stream is stopped with \ref StmK_Stop. +/*! \fn INT KUSB_API KSTM_STOPPED_CB(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex) +* \memberof KSTM_CALLBACK +*/ +typedef INT KUSB_API KSTM_STOPPED_CB(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex); + +//! Function definition for an optional user-defined callback; executed when a valid transfer completes. +/*! \fn INT KUSB_API KSTM_COMPLETE_CB(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex, _in INT ErrorCode) +* \memberof KSTM_CALLBACK +*/ +typedef INT KUSB_API KSTM_COMPLETE_CB(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex, _in INT ErrorCode); + +//! Function definition for an optional user-defined callback; executed immediately after a transfer completes. +/*! \fn KSTM_COMPLETE_RESULT KUSB_API KSTM_BEFORE_COMPLETE_CB(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex, _ref PINT ErrorCode) +* \memberof KSTM_CALLBACK +* +* This callback function allows the user to accept or reject the transfer: +* - IN (Read, DeviceToHost) endpoints. +* - KSTM_COMPLETE_RESULT_VALID +* Continue normal processing; add the transfer to the internal complete list and make it available to \ref StmK_Read. +* - KSTM_COMPLETE_RESULT_INVALID +* Ignore this transfer. +* - OUT (Write, HostToDevice) endpoints. +* - KSTM_COMPLETE_RESULT_VALID +* Continue normal processing; add the transfer to the internal complete list and make it available subsequent \ref StmK_Write requests. +* - KSTM_COMPLETE_RESULT_INVALID +* Return this transfer to the internal queued list for automatic resubmission to the device. +* +*/ +typedef KSTM_COMPLETE_RESULT KUSB_API KSTM_BEFORE_COMPLETE_CB(_in PKSTM_INFO StreamInfo, _in PKSTM_XFER_CONTEXT XferContext, _in INT XferContextIndex, _in PINT ErrorCode); + +//! Stream callback structure. +/*! +* \fixedstruct{64} +* +* These optional callback functions are executed from the streams internal thread at various stages of operation. +* +*/ +typedef struct _KSTM_CALLBACK +{ + //! Executed when a transfer error occurs. + KSTM_ERROR_CB* Error; + + //! Executed to submit a transfer. + KSTM_SUBMIT_CB* Submit; + + //! Executed when a valid transfer completes. + KSTM_COMPLETE_CB* Complete; + + //! Executed for every transfer context when the stream is started with \ref StmK_Start. + KSTM_STARTED_CB* Started; + + //! Executed for every transfer context when the stream is stopped with \ref StmK_Stop. + KSTM_STOPPED_CB* Stopped; + + //! Executed immediately after a transfer completes. + KSTM_BEFORE_COMPLETE_CB* BeforeComplete; + + //! fixed structure padding. + UCHAR z_F_i_x_e_d[64 - sizeof(UINT_PTR) * 6]; + +} KSTM_CALLBACK; +//! Pointer to a \ref KSTM_CALLBACK structure. +typedef KSTM_CALLBACK* PKSTM_CALLBACK; +C_ASSERT(sizeof(KSTM_CALLBACK) == 64); + +/**@}*/ + +#endif +/////////////////////////////////////////////////////////////////////// +// L I B U S B K PUBLIC FUNCTIONS //////////////////////////////////// +/////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _LIBUSBK_LIBK_FUNCTIONS + /*! \addtogroup libk + * @{ + */ + +//! Gets the internal user context for the specified \ref KLIB_HANDLE. + /*! + * + * \param[out] Version + * Receives the libusbK library verson information. + * + * \returns NONE + */ + KUSB_EXP VOID KUSB_API LibK_GetVersion(_out PKLIB_VERSION Version); + +//! Gets the internal user context for the specified \ref KLIB_HANDLE. + /*! + * + * \param[in] Handle + * The handle containg the context to retrieve. + * + * \param[in] HandleType + * Handle type of \c Handle. + * + * \returns + * - on success, The user context value. + * - On failure, returns NULL and sets last error to \c ERROR_INVALID_HANDLE. + * + */ + KUSB_EXP KLIB_USER_CONTEXT KUSB_API LibK_GetContext( + _in KLIB_HANDLE Handle, + _in KLIB_HANDLE_TYPE HandleType); + +//! Sets internal user context for the specified \ref KLIB_HANDLE. + /*! + * + * \param[in] Handle + * The handle containg the context to set. + * + * \param[in] HandleType + * Handle type of \c Handle. + * + * \param[in] ContextValue + * Value to assign to the handle user context space. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API LibK_SetContext( + _in KLIB_HANDLE Handle, + _in KLIB_HANDLE_TYPE HandleType, + _in KLIB_USER_CONTEXT ContextValue); + +//! Assigns a cleanup callback function to a \ref KLIB_HANDLE. + /*! + * + * \param[in] Handle + * The handle containg the cleanup callback function to set. + * + * \param[in] HandleType + * Handle type of \c Handle. + * + * \param[in] CleanupCB + * User supplied callback function to execute when the handles internal reference count reaches 0. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API LibK_SetCleanupCallback( + _in KLIB_HANDLE Handle, + _in KLIB_HANDLE_TYPE HandleType, + _in KLIB_HANDLE_CLEANUP_CB* CleanupCB); + +//! Initialize a driver API set. + /*! + * + * \param[out] DriverAPI + * A driver API structure to populate. + * + * \param[in] DriverID + * The driver id of the API set to retrieve. See \ref KUSB_DRVID + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API LibK_LoadDriverAPI( + _out PKUSB_DRIVER_API DriverAPI, + _in INT DriverID); + +//! Copies the driver API set out of a \ref KUSB_HANDLE + /*! + * + * \param[out] DriverAPI + * A driver API structure to populate. + * + * \param[in] UsbHandle + * Handle containing the desired driver API. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API LibK_CopyDriverAPI( + _out PKUSB_DRIVER_API DriverAPI, + _in KUSB_HANDLE UsbHandle); + +//! Initialize a driver API function. + /*! + * \param[out] ProcAddress + * Reference to a function pointer that will receive the API function pointer. + * + * \param[in] DriverID + * The driver id of the API to use. See \ref KUSB_DRVID + * + * \param[in] FunctionID + * The function id. See \ref KUSB_FNID + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API LibK_GetProcAddress( + _out KPROC* ProcAddress, + _in INT DriverID, + _in INT FunctionID); + +//! Sets the default user context for the specified \ref KLIB_HANDLE_TYPE. + /*! + * + * \param[in] HandleType + * The handle type which will be assigned the default ContextValue. + * + * \param[in] ContextValue + * Value assigned to the default user context for the specified \ref KLIB_HANDLE_TYPE. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API LibK_SetDefaultContext( + _in KLIB_HANDLE_TYPE HandleType, + _in KLIB_USER_CONTEXT ContextValue); + +//! Gets the default user context for the specified \ref KLIB_HANDLE_TYPE. + /*! + * + * \param[in] HandleType + * Handle type used to retrieve the default user context. + * + * \returns + * - on success, The default user context value. + * - On failure, returns NULL and sets last error to \c ERROR_INVALID_HANDLE. + * + */ + KUSB_EXP KLIB_USER_CONTEXT KUSB_API LibK_GetDefaultContext( + _in KLIB_HANDLE_TYPE HandleType); + +//! Initializes the global libusbK process context. + /*! + * + * If this function is not called at startup, libusbK initializes the global libusbK process context automatically. + * + * \param[in] Heap + * A handle to the memory heap libusbK will use for dynamic memory allocation. + * \note The process context itself is always allocated from the proccess heap. + * \note If \b Heap is \b NULL, dynamic memory is allocated from the proccess heap. + * + * \param[in] Reserved + * Reserved for future use. Must set to \b NULL. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API LibK_Context_Init( + _inopt HANDLE Heap, + _in PVOID Reserved); + +//! Frees the global libusbK process context. + /*! + * + * If this function is not called on exit, libusbK frees the global libusbK process context automatically when it terminates. + * + * \returns NONE. + * + */ + KUSB_EXP VOID KUSB_API LibK_Context_Free(VOID); + + + /**@}*/ +#endif + +#ifndef _LIBUSBK_USBK_FUNCTIONS + /*! \addtogroup usbk + * @{ + */ + +//! Creates/opens a libusbK interface handle from the device list. This is a preferred method. + /*! + * + * \param[out] InterfaceHandle + * Receives a handle configured to the first (default) interface on the device. This handle is required by + * other libusbK routines that perform operations on the default interface. The handle is opaque. To release + * this handle, call the \ref UsbK_Free function. + * + * \param[in] DevInfo + * The device list element to open. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * \c UsbK_Init performs the same tasks as \ref UsbK_Initialize with the following exceptions: + * - Uses a \ref KLST_DEVINFO instead of a file handle created with the Windows CreateFile() API function. + * - File handles are managed internally and are closed when the last \ref KUSB_HANDLE is closed with + * \ref UsbK_Free. To obtain the internal file device handle, See \ref UsbK_GetProperty. + * + * \note + * A \c KUSB_HANDLE is required by other library routines that perform operations on a device. Once + * initialized, it can access all interfaces/endpoints of a device. An initialized handle can be cloned with + * \ref UsbK_Clone or \ref UsbK_GetAssociatedInterface. A Cloned handle will behave just as the orignal + * except in will maintain it's own \b selected interface setting. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_Init ( + _out KUSB_HANDLE* InterfaceHandle, + _in KLST_DEVINFO_HANDLE DevInfo); + +//! Frees a libusbK interface handle. + /*! + * + * \param[in] InterfaceHandle + * Handle to an interface on the device. This handle must be created by a previous call to \ref UsbK_Init, + * \ref UsbK_Initialize, \ref UsbK_GetAssociatedInterface, or \ref UsbK_Clone. + * + * \returns TRUE. + * + * The \ref UsbK_Free function releases resources alocated to the InterfaceHandle. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_Free ( + _in KUSB_HANDLE InterfaceHandle); + +//! Claims the specified interface by number or index. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] NumberOrIndex + * Interfaces can be claimed or released by a interface index or \c bInterfaceNumber. + * - Interface indexes always start from 0 and continue sequentially for all interfaces of the device. + * - An interface number always represents the actual \ref USB_INTERFACE_DESCRIPTOR::bInterfaceNumber. + * Interface numbers are not guaranteed to be zero based or sequential. + * + * \param[in] IsIndex + * If TRUE, \c NumberOrIndex represents an interface index.\n if FALSE \c NumberOrIndex represents a + * \c bInterfaceNumber. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * Claiming an interface allows applications a way to prevent other applications or multiple instances of the + * same application from using an interface at the same time. + * + * When an interface is claimed with \ref UsbK_ClaimInterface it performs the following actions: + * - Checks if the interface exists. If it does not, returns FALSE and sets last error to + * ERROR_NO_MORE_ITEMS. + * - The default (or current) interface for the device is changed to \c NumberOrIndex. + * - libusb0.sys and libusbK.sys: + * - A request to claim the interface is sent to the driver. If the interface is not claimed or already + * claimed by the application the request succeeds. If the interface is claimed by another application, + * \ref UsbK_ClaimInterface returns FALSE and sets last error to \c ERROR_BUSY. In this case the The + * default (or current) interface for the device is \b still changed to \c NumberOrIndex. + * - WinUSB.sys: All WinUSB device interfaces are claimed when the device is opened. This function performs + * identically to \ref UsbK_SelectInterface + * + */ + KUSB_EXP BOOL KUSB_API UsbK_ClaimInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex); + +//! Releases the specified interface by number or index. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] NumberOrIndex + * Interfaces can be claimed or released by a interface index or \c bInterfaceNumber. + * - Interface indexes always start from 0 and continue sequentially for all interfaces of the device. + * - An interface number always represents the actual \ref USB_INTERFACE_DESCRIPTOR::bInterfaceNumber. + * Interface numbers are not guaranteed to be zero based or sequential. + * + * \param[in] IsIndex + * If TRUE, \c NumberOrIndex represents an interface index.\n if FALSE \c NumberOrIndex represents a + * \c bInterfaceNumber. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * When an interface is release with \ref UsbK_ReleaseInterface it performs the following actions: + * - Checks if the interface exists. If it does not, returns FALSE and sets last error to + * ERROR_NO_MORE_ITEMS. + * - The default (or current) interface for the device is changed to the previously claimed interface. + * - libusb0.sys and libusbK.sys: + * - A request to release the interface is sent to the driver. If the interface is not claimed by a + * different application the request succeeds. If the interface is claimed by another application, + * \ref UsbK_ReleaseInterface returns FALSE and sets last error to \c ERROR_BUSY. In this case, the + * default/current interface for the device is \b still changed to the previously claimed interface. + * - WinUSB.sys: No other action needed, returns TRUE. + * + * \note + * When an interface is released, it is moved to the bottom if an interface stack making a previously claimed + * interface the current. This will continue to occur regardless of whether the interface is claimed. For + * this reason, \ref UsbK_ReleaseInterface can be used as a means to change the current/default interface of + * an \c InterfaceHandle without claiming the interface. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_ReleaseInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex); + +//! Sets the alternate setting of the specified interface. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] NumberOrIndex + * Interfaces can be specified by a interface index or \c bInterfaceNumber. + * - Interface indexes always start from 0 and continue sequentially for all interfaces of the device. + * - An interface number always represents the actual \ref USB_INTERFACE_DESCRIPTOR::bInterfaceNumber. + * Interface numbers are not guaranteed to be zero based or sequential. + * + * \param[in] IsIndex + * If TRUE, \c NumberOrIndex represents an interface index.\n if FALSE \c NumberOrIndex represents a + * \c bInterfaceNumber. + * + * \param[in] AltSettingNumber + * The bAlternateSetting to activate. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * \ref UsbK_SetAltInterface performs the same task as \ref UsbK_SetCurrentAlternateSetting except it + * provides the option of specifying which interfaces alternate setting to activate. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_SetAltInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex, + _in UCHAR AltSettingNumber); + +//! Gets the alternate setting for the specified interface. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] NumberOrIndex + * Interfaces can be specified by a interface index or \c bInterfaceNumber. + * - Interface indexes always start from 0 and continue sequentially for all interfaces of the device. + * - An interface number always represents the actual \ref USB_INTERFACE_DESCRIPTOR::bInterfaceNumber. + * Interface numbers are not guaranteed to be zero based or sequential. + * + * \param[in] IsIndex + * If TRUE, \c NumberOrIndex represents an interface index.\n if FALSE \c NumberOrIndex represents a + * \c bInterfaceNumber. + * + * \param[out] AltSettingNumber + * On success, returns the active bAlternateSetting. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * \ref UsbK_GetAltInterface performs the same task as \ref UsbK_GetCurrentAlternateSetting except it + * provides the option of specifying which interfaces alternate setting is to be retrieved. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_GetAltInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex, + _out PUCHAR AltSettingNumber); + +//! Gets the requested descriptor. This is a synchronous operation. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] DescriptorType + * A value that specifies the type of descriptor to return. This parameter corresponds to the bDescriptorType + * field of a standard device descriptor, whose values are described in the Universal Serial Bus + * specification. + * + * \param[in] Index + * The descriptor index. For an explanation of the descriptor index, see the Universal Serial Bus + * specification (www.usb.org). + * + * \param[in] LanguageID + * A value that specifies the language identifier, if the requested descriptor is a string descriptor. + * + * \param[out] Buffer + * A caller-allocated buffer that receives the requested descriptor. + * + * \param[in] BufferLength + * The length, in bytes, of Buffer. + * + * \param[out] LengthTransferred + * The number of bytes that were copied into Buffer. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * If the device descriptor or active config descriptor is requested, \ref UsbK_GetDescriptor retrieves + * cached data and this becomes a non-blocking, non I/O request. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_GetDescriptor ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR DescriptorType, + _in UCHAR Index, + _in USHORT LanguageID, + _out PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred); + +//! Transmits control data over a default control endpoint. + /*! + * + * \param[in] InterfaceHandle + * A valid libusbK interface handle returned by: + * - \ref UsbK_Init + * - \ref UsbK_Initialize + * - \ref UsbK_GetAssociatedInterface + * - \ref UsbK_Clone + * + * \param[in] SetupPacket + * The 8-byte setup packet of type WINUSB_SETUP_PACKET. + * + * \param[in,out] Buffer + * A caller-allocated buffer that contains the data to transfer. + * + * \param[in] BufferLength + * The number of bytes to transfer, not including the setup packet. This number must be less than or equal to + * the size, in bytes, of Buffer. + * + * \param[out] LengthTransferred + * A pointer to a UINT variable that receives the actual number of transferred bytes. If the application + * does not expect any data to be transferred during the data phase (BufferLength is zero), LengthTransferred + * can be NULL. + * + * \param[in] Overlapped + * An optional pointer to an OVERLAPPED structure, which is used for asynchronous operations. If this + * parameter is specified, \ref UsbK_ControlTransfer immediately returns, and the event is signaled when the + * operation is complete. If Overlapped is not supplied, the \ref UsbK_ControlTransfer function transfers + * data synchronously. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. If an + * \c Overlapped member is supplied and the operation succeeds this function returns FALSE and sets last + * error to ERROR_IO_PENDING. + * + * A \ref UsbK_ControlTransfer is never cached. These requests always go directly to the usb device. + * + * \attention + * This function should not be used for operations supported by the library.\n e.g. + * \ref UsbK_SetConfiguration, \ref UsbK_SetAltInterface, etc.. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_ControlTransfer ( + _in KUSB_HANDLE InterfaceHandle, + _in WINUSB_SETUP_PACKET SetupPacket, + _refopt PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred, + _inopt LPOVERLAPPED Overlapped); + +//! Sets the power policy for a device. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] PolicyType + * A value that specifies the power policy to set. The following table describes symbolic constants that are + * defined in \ref lusbk_shared.h. + * + * - AUTO_SUSPEND (0x81) + * - Specifies the auto-suspend policy type; the power policy parameter must be specified by the caller in + * the Value parameter. + * - For auto-suspend, the Value parameter must point to a UCHAR variable. + * - If Value is TRUE (nonzero), the USB stack suspends the device if the device is idle. A device is idle + * if there are no transfers pending, or if the only pending transfers are IN transfers to interrupt or + * bulk endpoints. + * - The default value is determined by the value set in the DefaultIdleState registry setting. By default, + * this value is TRUE. + * + * - SUSPEND_DELAY (0x83) + * - Specifies the suspend-delay policy type; the power policy parameter must be specified by the caller in + * the Value parameter. + * - For suspend-delay, Value must point to a UINT variable. + * - Value specifies the minimum amount of time, in milliseconds, that the driver must wait post transfer + * before it can suspend the device. + * - The default value is determined by the value set in the DefaultIdleTimeout registry setting. By + * default, this value is five seconds. + * + * \param[in] ValueLength + * The size, in bytes, of the buffer at Value. + * + * \param[in] Value + * The new value for the power policy parameter. Data type and value for Value depends on the type of power + * policy passed in PolicyType. For more information, see PolicyType. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * The following list summarizes the effects of changes to power management states: + * - All pipe handles, interface handles, locks, and alternate settings are preserved across power management + * events. + * - Any transfers that are in progress are suspended when a device transfers to a low power state, and they + * are resumed when the device is restored to a working state. + * - The device and system must be in a working state before the client can restore a device-specific + * configuration. Clients can determine whether the device and system are in a working state from the + * WM_POWERBROADCAST message. + * - The client can indicate that an interface is idle by calling \ref UsbK_SetPowerPolicy. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_SetPowerPolicy ( + _in KUSB_HANDLE InterfaceHandle, + _in UINT PolicyType, + _in UINT ValueLength, + _in PVOID Value); + +//! Gets the power policy for a device. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] PolicyType + * A value that specifies the power policy parameter to retrieve in Value. The following table describes + * symbolic constants that are defined in \ref lusbk_shared.h. + * + * - AUTO_SUSPEND (0x81) + * - If the caller specifies a power policy of AUTO_SUSPEND, \ref UsbK_GetPowerPolicy returns the value of + * the auto suspend policy parameter in the Value parameter. + * - If Value is TRUE (that is, nonzero), the USB stack suspends the device when no transfers are pending + * or the only transfers pending are IN transfers on an interrupt or bulk endpoint. + * - The value of the DefaultIdleState registry value determines the default value of the auto suspend + * policy parameter. + * - The Value parameter must point to a UCHAR variable. + * + * - SUSPEND_DELAY (0x83) + * - If the caller specifies a power policy of SUSPEND_DELAY, \ref UsbK_GetPowerPolicy returns the value of + * the suspend delay policy parameter in Value. + * - The suspend delay policy parameter specifies the minimum amount of time, in milliseconds, that the + * driver must wait after any transfer before it can suspend the device. + * - Value must point to a UINT variable. + * + * \param[in,out] ValueLength + * A pointer to the size of the buffer that Value. On output, ValueLength receives the size of the data that + * was copied into the Value buffer. + * + * \param[out] Value + * A buffer that receives the specified power policy parameter. For more information, see PolicyType. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_GetPowerPolicy ( + _in KUSB_HANDLE InterfaceHandle, + _in UINT PolicyType, + _ref PUINT ValueLength, + _out PVOID Value); + +//! Sets the device configuration number. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] ConfigurationNumber + * The configuration number to activate. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * \ref UsbK_SetConfiguration is only supported with libusb0.sys. If the driver in not libusb0.sys, this + * function performs the following emulation actions: + * - If the requested configuration number is the current configuration number, returns TRUE. + * - If the requested configuration number is one other than the current configuration number, returns FALSE + * and set last error to \c ERROR_NO_MORE_ITEMS. + * + * This function will fail if there are pending I/O operations or there are other libusbK interface handles + * referencing the device. \sa UsbK_Free + * + */ + KUSB_EXP BOOL KUSB_API UsbK_SetConfiguration ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR ConfigurationNumber); + +//! Gets the device current configuration number. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[out] ConfigurationNumber + * On success, receives the active configuration number. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_GetConfiguration ( + _in KUSB_HANDLE InterfaceHandle, + _out PUCHAR ConfigurationNumber); + +//! Resets the usb device of the specified interface handle. (port cycle). + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_ResetDevice ( + _in KUSB_HANDLE InterfaceHandle); + +//! Creates a libusbK handle for the device specified by a file handle. + /*! + * + * \attention + * This function is supported for WinUSB API compatibility only and is not intended for new development. + * libusbK library users should use \ref UsbK_Init instead. (regardless of the driver they've selected) + * + * \param[in] DeviceHandle + * The handle to the device that CreateFile returned. libusbK uses overlapped I/O, so FILE_FLAG_OVERLAPPED + * must be specified in the dwFlagsAndAttributes parameter of CreateFile call for DeviceHandle to have the + * characteristics necessary for this to function properly. + * + * \param[out] InterfaceHandle + * Receives a handle configured to the first (default) interface on the device. This handle is required by + * other libusbK routines that perform operations on the default interface. The handle is opaque. To release + * this handle, call the \ref UsbK_Free function. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * When \ref UsbK_Initialize is called, the policy settings of the interface are reset to the default values. + * + * The \ref UsbK_Initialize call queries the underlying USB stack for various descriptors and allocates + * enough memory to store the retrieved descriptor data. + * + * \ref UsbK_Initialize first retrieves the device descriptor and then gets the associated configuration + * descriptor. From the configuration descriptor, the call derives the associated interface descriptors and + * stores them in an array. The interfaces in the array are identified by zero-based indexes. An index value + * of 0 indicates the first interface (the default interface), a value of 1 indicates the second associated + * interface, and so on. \ref UsbK_Initialize parses the default interface descriptor for the endpoint + * descriptors and caches information such as the associated pipes or state specific data. The handle + * received in the InterfaceHandle parameter will have its default interface configured to the first + * interface in the array. + * + * If an application wants to use another interface on the device, it can call + * \ref UsbK_GetAssociatedInterface, or \ref UsbK_ClaimInterface. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_Initialize ( + _in HANDLE DeviceHandle, + _out KUSB_HANDLE* InterfaceHandle); + +//! Selects the specified interface by number or index as the current interface. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] NumberOrIndex + * Interfaces can be claimed or released by a interface index or \c bInterfaceNumber. + * - Interface indexes always start from 0 and continue sequentially for all interfaces of the device. + * - An interface number always represents the actual \ref USB_INTERFACE_DESCRIPTOR::bInterfaceNumber. + * Interface numbers are not guaranteed to be zero based or sequential. + * + * \param[in] IsIndex + * If TRUE, \c NumberOrIndex represents an interface index.\n if FALSE \c NumberOrIndex represents a + * \c bInterfaceNumber. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * \sa UsbK_ClaimInterface + * + */ + KUSB_EXP BOOL KUSB_API UsbK_SelectInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex); + +//! Retrieves a handle for an associated interface. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] AssociatedInterfaceIndex + * An index that specifies the associated interface to retrieve. A value of 0 indicates the first associated + * interface, a value of 1 indicates the second associated interface, and so on. + * + * \param[out] AssociatedInterfaceHandle + * A handle for the associated interface. Callers must pass this interface handle to libusbK Functions + * exposed by libusbK.dll. To close this handle, call \ref UsbK_Free. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * The \ref UsbK_GetAssociatedInterface function retrieves an opaque handle for an associated interface. This + * is a synchronous operation. + * + * The first associated interface is the interface that immediately follows the current (or default) + * interface of the specified /c InterfaceHandle. + * + * The handle that \ref UsbK_GetAssociatedInterface returns must be released by calling \ref UsbK_Free. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_GetAssociatedInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AssociatedInterfaceIndex, + _out KUSB_HANDLE* AssociatedInterfaceHandle); + +//! Clones the specified interface handle. + /*! + * + * Each cloned interface handle maintains it's own selected interface. + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[out] DstInterfaceHandle + * On success, the cloned return handle. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_Clone ( + _in KUSB_HANDLE InterfaceHandle, + _out KUSB_HANDLE* DstInterfaceHandle); + +//! Retrieves the interface descriptor for the specified alternate interface settings for a particular interface handle. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] AltSettingIndex + * A value that indicates which alternate setting index to return. A value of 0 indicates the first alternate + * setting, a value of 1 indicates the second alternate setting, and so on. + * + * \param[out] UsbAltInterfaceDescriptor + * A pointer to a caller-allocated \ref USB_INTERFACE_DESCRIPTOR structure that contains information about + * the interface that AltSettingNumber specified. + * + * The \ref UsbK_QueryInterfaceSettings call searches the current/default interface array for the alternate + * interface specified by the caller in the AltSettingIndex. If the specified alternate interface is found, + * the function populates the caller-allocated USB_INTERFACE_DESCRIPTOR structure. If the specified alternate + * interface is not found, then the call fails with the ERROR_NO_MORE_ITEMS code. + * + * To change the current/default interface, see \ref UsbK_SelectInterface and \ref UsbK_ClaimInterface + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_QueryInterfaceSettings ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AltSettingIndex, + _out PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor); + +//! Retrieves information about the physical device that is associated with a libusbK handle. + /*! + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] InformationType + * A value that specifies which interface information value to retrieve. On input, InformationType must have + * the following value: \c DEVICE_SPEED (0x01). + * + * \param[in,out] BufferLength + * The maximum number of bytes to read. This number must be less than or equal to the size, in bytes, of + * Buffer. On output, BufferLength is set to the actual number of bytes that were copied into Buffer. + * + * \param[in,out] Buffer + * A caller-allocated buffer that receives the requested value. On output, Buffer indicates the device speed: + * - (0x01) low/full speed device. + * - (0x03) high speed device. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_QueryDeviceInformation ( + _in KUSB_HANDLE InterfaceHandle, + _in UINT InformationType, + _ref PUINT BufferLength, + _ref PVOID Buffer); + +//! Sets the alternate setting of an interface. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] AltSettingNumber + * The value that is contained in the bAlternateSetting member of the \ref USB_INTERFACE_DESCRIPTOR + * structure. This structure can be populated by the \ref UsbK_QueryInterfaceSettings routine. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * Sets the active bAlternateSetting for the current/default interface. + * + * To change the default/current interface see \ref UsbK_ClaimInterface and \ref UsbK_ReleaseInterface + * \sa UsbK_SetAltInterface + * + */ + KUSB_EXP BOOL KUSB_API UsbK_SetCurrentAlternateSetting ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AltSettingNumber); + +//! Gets the current alternate interface setting for an interface. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[out] AltSettingNumber + * A pointer to an unsigned character that receives an integer that indicates the current alternate setting. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * Gets the active bAlternateSetting for the current/default interface. + * + * To change the default/current interface see \ref UsbK_ClaimInterface and \ref UsbK_ReleaseInterface + * \sa UsbK_GetAltInterface + * + */ + KUSB_EXP BOOL KUSB_API UsbK_GetCurrentAlternateSetting ( + _in KUSB_HANDLE InterfaceHandle, + _out PUCHAR AltSettingNumber); + +//! Retrieves information about a pipe that is associated with an interface. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] AltSettingNumber + * A value that specifies the alternate interface to return the information for. + * + * \param[in] PipeIndex + * A value that specifies the pipe to return information about. This value is not the same as the + * bEndpointAddress field in the endpoint descriptor. A PipeIndex value of 0 signifies the first endpoint + * that is associated with the interface, a value of 1 signifies the second endpoint, and so on. PipeIndex + * must be less than the value in the bNumEndpoints field of the interface descriptor. + * + * \param[out] PipeInformation + * A pointer, on output, to a caller-allocated \ref WINUSB_PIPE_INFORMATION structure that contains pipe + * information. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * The \ref UsbK_QueryPipe function does not retrieve information about the control pipe. + * + * Each interface on the USB device can have multiple endpoints. To communicate with each of these endpoints, + * the bus driver creates pipes for each endpoint on the interface. The pipe indices are zero-based. + * Therefore for n number of endpoints, the pipes' indices are set from n-1. \ref UsbK_QueryPipe parses the + * configuration descriptor to get the interface specified by the caller. It searches the interface + * descriptor for the endpoint descriptor associated with the caller-specified pipe. If the endpoint is + * found, the function populates the caller-allocated \ref WINUSB_PIPE_INFORMATION structure with information + * from the endpoint descriptor. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_QueryPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AltSettingNumber, + _in UCHAR PipeIndex, + _out PWINUSB_PIPE_INFORMATION PipeInformation); + +//! Sets the policy for a specific pipe associated with an endpoint on the device. This is a synchronous operation. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] PipeID + * An 8-bit value that consists of a 7-bit address and a direction bit. This parameter corresponds to the + * bEndpointAddress field in the endpoint descriptor. + * + * \param[in] PolicyType + * A UINT variable that specifies the policy parameter to change. The Value parameter contains the new value + * for the policy parameter. See the remarks section for information about each of the pipe policies and the + * resulting behavior. + * + * \param[in] ValueLength + * The size, in bytes, of the buffer at Value. + * + * \param[in] Value + * The new value for the policy parameter that PolicyType specifies. The size of this input parameter depends + * on the policy to change. For information about the size of this parameter, see the description of the + * PolicyType parameter. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * The following list describes symbolic constants that are defined in \ref lusbk_shared.h + * + * - \c SHORT_PACKET_TERMINATE (0x01) + * - The default value is \c FALSE. + * - To enable \c SHORT_PACKET_TERMINATE, in Value pass the address of a caller-allocated \c UCHAR variable + * set to \c TRUE (nonzero). + * - Enabling \c SHORT_PACKET_TERMINATE causes the driver to send a zero-length packet at the end of every + * write request to the host controller. + * + * - \c AUTO_CLEAR_STALL (0x02) + * - The default value is \c FALSE. To enable \c AUTO_CLEAR_STALL, in Value pass the address of a + * caller-allocated \c UCHAR variable set to \c TRUE (nonzero). + * - Enabling \c AUTO_CLEAR_STALL causes libusbK to reset the pipe in order to automatically clear the + * stall condition. Data continues to flow on the bulk and interrupt \c IN endpoints again as soon as a + * new or a queued transfer arrives on the endpoint. This policy parameter does not affect control pipes. + * - Disabling \c AUTO_CLEAR_STALL causes all transfers (that arrive to the endpoint after the stalled + * transfer) to fail until the caller manually resets the endpoint's pipe by calling \ref UsbK_ResetPipe. + * + * - \c PIPE_TRANSFER_TIMEOUT (0x03) + * - The default value is zero. To set a time-out value, in Value pass the address of a caller-allocated + * \c UINT variable that contains the time-out interval. + * - The \c PIPE_TRANSFER_TIMEOUT value specifies the time-out interval, in milliseconds. The host + * controller cancels transfers that do not complete within the specified time-out interval. + * - A value of zero (default) indicates that transfers do not time out because the host controller never + * cancels the transfer. + * + * - \c IGNORE_SHORT_PACKETS (0x04) + * - The default value is \c FALSE. To enable \c IGNORE_SHORT_PACKETS, in Value pass the address of a + * caller-allocated \c UCHAR variable set to \c TRUE (nonzero). + * - Enabling \c IGNORE_SHORT_PACKETS causes the host controller to not complete a read operation after it + * receives a short packet. Instead, the host controller completes the operation only after the host has + * read the specified number of bytes. + * - Disabling \c IGNORE_SHORT_PACKETS causes the host controller to complete a read operation when either + * the host has read the specified number of bytes or the host has received a short packet. + * + * - \c ALLOW_PARTIAL_READS (0x05) + * - The default value is \c TRUE (nonzero). To disable \c ALLOW_PARTIAL_READS, in Value pass the address + * of a caller-allocated \c UCHAR variable set to \c FALSE (zero). + * - Disabling \c ALLOW_PARTIAL_READS causes the read requests to fail whenever the device returns more + * data (on bulk and interrupt \c IN endpoints) than the caller requested. + * - Enabling \c ALLOW_PARTIAL_READS causes libusbK to save or discard the extra data when the device + * returns more data (on bulk and interrupt \c IN endpoints) than the caller requested. This behavior is + * defined by setting the \c AUTO_FLUSH value. + * + * - \c AUTO_FLUSH (0x06) + * - The default value is \c FALSE (zero). To enable \c AUTO_FLUSH, in Value pass the address of a + * caller-allocated \c UCHAR variable set to \c TRUE (nonzero). + * - \c AUTO_FLUSH must be used with \c ALLOW_PARTIAL_READS enabled. If \c ALLOW_PARTIAL_READS is \c TRUE, + * the value of \c AUTO_FLUSH determines the action taken by libusbK when the device returns more data + * than the caller requested. + * - Disabling \c ALLOW_PARTIAL_READS causes libusbK to ignore the \c AUTO_FLUSH value. + * - Disabling \c AUTO_FLUSH with \c ALLOW_PARTIAL_READS enabled causes libusbK to save the extra data, add + * the data to the beginning of the caller's next read request, and send it to the caller in the next + * read operation. + * - Enabling \c AUTO_FLUSH with \c ALLOW_PARTIAL_READS enabled causes libusbK to discard the extra data + * remaining from the read request. + * + * - \c RAW_IO (0x07) + * - The default value is \c FALSE (zero). To enable \c RAW_IO, in Value pass the address of a + * caller-allocated \c UCHAR variable set to \c TRUE (nonzero). + * - Enabling \c RAW_IO causes libusbK to send data directly to the \c USB driver stack, bypassing + * libusbK's queuing and error handling mechanism. + * - The buffers that are passed to \ref UsbK_ReadPipe must be configured by the caller as follows: + * - The buffer length must be a multiple of the maximum endpoint packet size. + * - The length must be less than or equal to the value of \c MAXIMUM_TRANSFER_SIZE retrieved by + * \ref UsbK_GetPipePolicy. + * - Disabling \c RAW_IO (\c FALSE) does not impose any restriction on the buffers that are passed to + * \ref UsbK_ReadPipe. + * + * - \c RESET_PIPE_ON_RESUME (0x09) + * - The default value is \c FALSE (zero). To enable \c RESET_PIPE_ON_RESUME, in Value pass the address of + * a caller-allocated \c UCHAR variable set to \c TRUE (nonzero). + * - \c TRUE (or a nonzero value) indicates that on resume from suspend, libusbK resets the endpoint before + * it allows the caller to send new requests to the endpoint. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_SetPipePolicy ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in UINT PolicyType, + _in UINT ValueLength, + _in PVOID Value); + +//! Gets the policy for a specific pipe (endpoint). + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] PipeID + * An 8-bit value that consists of a 7-bit address and a direction bit. This parameter corresponds to the + * bEndpointAddress field in the endpoint descriptor. + * + * \param[in] PolicyType + * A UINT variable that specifies the policy parameter to retrieve. The current value for the policy + * parameter is retrieved the Value parameter. + * + * \param[in,out] ValueLength + * A pointer to the size, in bytes, of the buffer that Value points to. On output, ValueLength receives the + * size, in bytes, of the data that was copied into the Value buffer. + * + * \param[out] Value + * A pointer to a buffer that receives the specified pipe policy value. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_GetPipePolicy ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in UINT PolicyType, + _ref PUINT ValueLength, + _out PVOID Value); + +//! Reads data from the specified pipe. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] PipeID + * An 8-bit value that consists of a 7-bit address and a direction bit. This parameter corresponds to the + * bEndpointAddress field in the endpoint descriptor. + * + * \param[out] Buffer + * A caller-allocated buffer that receives the data that is read. + * + * \param[in] BufferLength + * The maximum number of bytes to read. This number must be less than or equal to the size, in bytes, of + * Buffer. + * + * \param[out] LengthTransferred + * A pointer to a UINT variable that receives the actual number of bytes that were copied into Buffer. For + * more information, see Remarks. + * + * \param[in] Overlapped + * An optional pointer to an overlapped structure for asynchronous operations. This can be a \ref KOVL_HANDLE + * or a pointer to a standard windows OVERLAPPED structure. If this parameter is specified, \c UsbK_ReadPipe + * returns immediately rather than waiting synchronously for the operation to complete before returning. An + * event is signaled when the operation is complete. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_ReadPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _out PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred, + _inopt LPOVERLAPPED Overlapped); + +//! Writes data to a pipe. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] PipeID + * An 8-bit value that consists of a 7-bit address and a direction bit. This parameter corresponds to the + * bEndpointAddress field in the endpoint descriptor. + * + * \param[in] Buffer + * A caller-allocated buffer the data is written from. + * + * \param[in] BufferLength + * The maximum number of bytes to write. This number must be less than or equal to the size, in bytes, of + * Buffer. + * + * \param[out] LengthTransferred + * A pointer to a UINT variable that receives the actual number of bytes that were transferred from Buffer. + * For more information, see Remarks. + * + * \param[in] Overlapped + * An optional pointer to an overlapped structure for asynchronous operations. This can be a \ref KOVL_HANDLE + * or a pointer to a standard windows OVERLAPPED structure. If this parameter is specified, \c UsbK_WritePipe + * returns immediately rather than waiting synchronously for the operation to complete before returning. An + * event is signaled when the operation is complete. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_WritePipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred, + _inopt LPOVERLAPPED Overlapped); + +//! Resets the data toggle and clears the stall condition on a pipe. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] PipeID + * An 8-bit value that consists of a 7-bit address and a direction bit. This parameter corresponds to the + * bEndpointAddress field in the endpoint descriptor. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_ResetPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID); + +//! Aborts all of the pending transfers for a pipe. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] PipeID + * An 8-bit value that consists of a 7-bit address and a direction bit. This parameter corresponds to the + * bEndpointAddress field in the endpoint descriptor. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_AbortPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID); + +//! Discards any data that is cached in a pipe. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] PipeID + * An 8-bit value that consists of a 7-bit address and a direction bit. This parameter corresponds to the + * bEndpointAddress field in the endpoint descriptor. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_FlushPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID); + +//! Reads from an isochronous pipe. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] PipeID + * An 8-bit value that consists of a 7-bit address and a direction bit. This parameter corresponds to the + * bEndpointAddress field in the endpoint descriptor. + * + * \param[out] Buffer + * A caller-allocated buffer that receives the data that is read. + * + * \param[in] BufferLength + * The maximum number of bytes to read. This number must be less than or equal to the size, in bytes, of + * Buffer. + * + * \param[in] Overlapped + * A \b required pointer to an overlapped structure for asynchronous operations. This can be a + * \ref KOVL_HANDLE or a pointer to a standard windows OVERLAPPED structure. If this parameter is specified, + * \c UsbK_IsoReadPipe returns immediately rather than waiting synchronously for the operation to complete + * before returning. An event is signaled when the operation is complete. + * + * \param[in,out] IsoContext + * Pointer to an isochronous transfer context created with \ref IsoK_Init. If \c IsoContext is NULL, + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * \par Overlapped I/O considerations + * If an \c Overlapped parameter is specified and the transfer is submitted successfully, the function + * returns \b FALSE and sets last error to \c ERROR_IO_PENDING. When using overlapped I/O, users may ignore + * the return results of this function and instead use the return results from one of the \ref ovlk wait + * functions or from \ref UsbK_GetOverlappedResult. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_IsoReadPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _out PUCHAR Buffer, + _in UINT BufferLength, + _in LPOVERLAPPED Overlapped, + _refopt PKISO_CONTEXT IsoContext); + +//! Writes to an isochronous pipe. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] PipeID + * An 8-bit value that consists of a 7-bit address and a direction bit. This parameter corresponds to the + * bEndpointAddress field in the endpoint descriptor. + * + * \param[in] Buffer + * A caller-allocated buffer that receives the data that is read. + * + * \param[in] BufferLength + * The maximum number of bytes to write. This number must be less than or equal to the size, in bytes, of + * Buffer. + * + * \param[in] Overlapped + * An optional pointer to an overlapped structure for asynchronous operations. This can be a \ref KOVL_HANDLE + * or a pointer to a standard windows OVERLAPPED structure. If this parameter is specified, + * \c UsbK_IsoWritePipe returns immediately rather than waiting synchronously for the operation to complete + * before returning. An event is signaled when the operation is complete. + * + * \param[in,out] IsoContext + * Pointer to an isochronous transfer context created with \ref IsoK_Init. See remarks below. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_IsoWritePipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in PUCHAR Buffer, + _in UINT BufferLength, + _in LPOVERLAPPED Overlapped, + _refopt PKISO_CONTEXT IsoContext); + +//! Retrieves the current USB frame number. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[out] FrameNumber + * A pointer to a location that receives the current 32-bit frame number on the USB bus (from the host + * controller driver). + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_GetCurrentFrameNumber ( + _in KUSB_HANDLE InterfaceHandle, + _out PUINT FrameNumber); + +//! Retrieves the results of an overlapped operation on the specified libusbK handle. + /*! + * + * \param[in] InterfaceHandle + * An initialized usb handle, see \ref UsbK_Init. + * + * \param[in] Overlapped + * A pointer to a standard windows OVERLAPPED structure that was specified when the overlapped operation was + * started. + * + * \param[out] lpNumberOfBytesTransferred + * A pointer to a variable that receives the number of bytes that were actually transferred by a read or + * write operation. + * + * \param[in] bWait + * If this parameter is TRUE, the function does not return until the operation has been completed. If this + * parameter is FALSE and the operation is still pending, the function returns FALSE and the GetLastError + * function returns ERROR_IO_INCOMPLETE. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * This function is like the Win32 API routine, GetOverlappedResult, with one difference; instead of passing + * a file handle that is returned from CreateFile, the caller passes an interface handle that is returned + * from \ref UsbK_Initialize, \ref UsbK_Init, or \ref UsbK_GetAssociatedInterface. The caller can use either + * API routine, if the appropriate handle is passed. The \ref UsbK_GetOverlappedResult function extracts the + * file handle from the interface handle and then calls GetOverlappedResult. \n + * + * The results that are reported by the \ref UsbK_GetOverlappedResult function are those from the specified + * handle's last overlapped operation to which the specified standard windows OVERLAPPED structure was + * provided, and for which the operation's results were pending. A pending operation is indicated when the + * function that started the operation returns FALSE, and the GetLastError routine returns ERROR_IO_PENDING. + * When an I/O operation is pending, the function that started the operation resets the hEvent member of the + * standard windows OVERLAPPED structure to the nonsignaled state. Then when the pending operation has been + * completed, the system sets the event object to the signaled state. \n + * + * The caller can specify that an event object is manually reset in the standard windows OVERLAPPED + * structure. If an automatic reset event object is used, the event handle must not be specified in any other + * wait operation in the interval between starting the overlapped operation and the call to + * \ref UsbK_GetOverlappedResult. For example, the event object is sometimes specified in one of the wait + * routines to wait for the operation to be completed. When the wait routine returns, the system sets an + * auto-reset event's state to nonsignaled, and a successive call to \ref UsbK_GetOverlappedResult with the + * bWait parameter set to TRUE causes the function to be blocked indefinitely. + * + * If the bWait parameter is TRUE, \ref UsbK_GetOverlappedResult determines whether the pending operation has + * been completed by waiting for the event object to be in the signaled state. + * + * If the hEvent member of the standard windows OVERLAPPED structure is NULL, the system uses the state of + * the file handle to signal when the operation has been completed. Do not use file handles for this purpose. + * It is better to use an event object because of the confusion that can occur when multiple concurrent + * overlapped operations are performed on the same file. In this situation, you cannot know which operation + * caused the state of the object to be signaled. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_GetOverlappedResult ( + _in KUSB_HANDLE InterfaceHandle, + _in LPOVERLAPPED Overlapped, + _out PUINT lpNumberOfBytesTransferred, + _in BOOL bWait); + +//! Gets a USB device (driver specific) property from usb handle. + /*! + * + * \param[in] InterfaceHandle + * USB handle of the property to retrieve. + * + * \param[in] PropertyType + * The propety type to retrieve. + * + * \param[in,out] PropertySize + * Size in bytes of \c Value. + * + * \param[out] Value + * On success, receives the proprty data. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API UsbK_GetProperty ( + _in KUSB_HANDLE InterfaceHandle, + _in KUSB_PROPERTY PropertyType, + _ref PUINT PropertySize, + _out PVOID Value); + + /*! @} */ + + +#endif + +#ifndef _LIBUSBK_LSTK_FUNCTIONS + /*! \addtogroup lstk + *@{ + */ + +//! Initializes a new usb device list containing all supported devices. + /*! + * + * \param[out] DeviceList + * Pointer reference that will receive a populated device list. + * + * \param[in] Flags + * Search, filter, and listing options. see \c KLST_FLAG + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * \c LstK_Init populates \c DeviceList with connected usb devices that can be used by libusbK. + * + * \note if \ref LstK_Init returns TRUE, the device list must be freed with \ref LstK_Free when it is no + * longer needed. + * + */ + KUSB_EXP BOOL KUSB_API LstK_Init( + _out KLST_HANDLE* DeviceList, + _in KLST_FLAG Flags); + +//! Initializes a new usb device list containing only devices matching a specific class GUID. + /*! + * + * \param[out] DeviceList + * Pointer reference that will receive a populated device list. + * + * \param[in] Flags + * Search, filter, and listing options. see \c KLST_FLAG + * + * \param[in] PatternMatch + * Pattern Search filter. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * \c LstK_InitEx populates \c DeviceList with usb devices that can be used by libusbK. Only device + * matching the \ref KLST_PATTERN_MATCH string are included in the list. + * + * \note + * This function significantly improves performance when used with a device interface guid pattern patch. + * + * \note if \ref LstK_InitEx returns TRUE, the device list must be freed with \ref LstK_Free when it it's no + * longer needed. + * + */ + KUSB_EXP BOOL KUSB_API LstK_InitEx( + _out KLST_HANDLE* DeviceList, + _in KLST_FLAG Flags, + _in PKLST_PATTERN_MATCH PatternMatch); + + //! Frees a usb device list. + /*! + * + * \note if \ref LstK_Init returns TRUE, the device list must be freed with \ref LstK_Free when it is no + * longer needed. + * + * \param[in] DeviceList + * The \c DeviceList to free. + * + * \returns NONE + * + * Frees all resources that were allocated to \c DeviceList by \ref LstK_Init. + * + */ + KUSB_EXP BOOL KUSB_API LstK_Free( + _in KLST_HANDLE DeviceList); + +//! Enumerates \ref KLST_DEVINFO elements of a \ref KLST_HANDLE. + /*! + * + * \param[in] DeviceList + * The \c DeviceList to enumerate. + * + * \param[in] EnumDevListCB + * Function to call for each iteration. + * + * \param[in] Context + * Optional user context pointer. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * Calls \c EnumDevListCB for each element in the device list or until \c EnumDevListCB returns FALSE. + * + */ + KUSB_EXP BOOL KUSB_API LstK_Enumerate( + _in KLST_HANDLE DeviceList, + _in KLST_ENUM_DEVINFO_CB* EnumDevListCB, + _inopt PVOID Context); + +//! Gets the \ref KLST_DEVINFO element for the current position. + /*! + * + * \param[in] DeviceList + * The \c DeviceList to retrieve a current \ref KLST_DEVINFO for. + * + * \param[out] DeviceInfo + * The device information. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * After a \c DeviceList is created or after the \ref LstK_MoveReset method is called, the \c LstK_MoveNext + * method must be called to advance the device list enumerator to the first element of the \c DeviceList + * before calling \c LstK_Current otherwise, \c DeviceInfo is undefined. + * + * \c LstK_Current returns \c FALSE and sets last error to \c ERROR_NO_MORE_ITEMS if the last call to + * \c LstK_MoveNext returned \c FALSE, which indicates the end of the \c DeviceList. + * + * \c LstK_Current does not move the position of the device list enumerator, and consecutive calls to + * \c LstK_Current return the same object until either \c LstK_MoveNext or \ref LstK_MoveReset is called. + * + */ + KUSB_EXP BOOL KUSB_API LstK_Current( + _in KLST_HANDLE DeviceList, + _out KLST_DEVINFO_HANDLE* DeviceInfo); + +//! Advances the device list current \ref KLST_DEVINFO position. + /*! + * \param[in] DeviceList + * A usb device list returned by \ref LstK_Init + * + * \param[out] DeviceInfo + * On success, contains a pointer to the device information for the current enumerators position. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * After a \c DeviceList is created or after \ref LstK_MoveReset is called, an enumerator is positioned + * before the first element of the \c DeviceList and the \b first call to \c LstK_MoveNext moves the + * enumerator over the first element of the \c DeviceList. + * + * If \c LstK_MoveNext passes the end of the \c DeviceList, the enumerator is positioned after the last + * element in the \c DeviceList and \c LstK_MoveNext returns \c FALSE. When the enumerator is at this + * position, a subsequent call to \c LstK_MoveNext will reset the enumerator and it continues from the + * beginning. + * + */ + KUSB_EXP BOOL KUSB_API LstK_MoveNext( + _in KLST_HANDLE DeviceList, + _outopt KLST_DEVINFO_HANDLE* DeviceInfo); + +//! Sets the device list to its initial position, which is before the first element in the list. + /*! + * + * \param[in] DeviceList + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP VOID KUSB_API LstK_MoveReset( + _in KLST_HANDLE DeviceList); + +//! Find a device by vendor and product id + /*! + * + * \param[in] DeviceList + * The \c DeviceList to retrieve a current \ref KLST_DEVINFO for. + * + * \param[in] Vid + * ID is used in conjunction with the \c Pid to uniquely identify USB devices, providing traceability to the + * OEM. + * + * \param[in] Pid + * ID is used in conjunction with the \c Pid to uniquely identify USB devices, providing traceability to the + * OEM. + * + * \param[out] DeviceInfo + * On success, the device information pointer, otherwise NULL. + * + * \returns + * - TRUE if the device was found + * - FALSE if the device was \b not found or an error occurred. + * - Sets last error to \c ERROR_NO_MORE_ITEMS if the device was \b not found. + * + * Searches all elements in \c DeviceList for usb device matching the specified. + * + */ + KUSB_EXP BOOL KUSB_API LstK_FindByVidPid( + _in KLST_HANDLE DeviceList, + _in INT Vid, + _in INT Pid, + _out KLST_DEVINFO_HANDLE* DeviceInfo); + +//! Counts the number of device info elements in a device list. + /*! + * + * \param[in] DeviceList + * The deice list to count. + * + * \param[in,out] Count + * On success, receives the number of \ref KLST_DEVINFO elements in the list. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API LstK_Count( + _in KLST_HANDLE DeviceList, + _ref PUINT Count); + + + /**@}*/ + +#endif + +#ifndef _LIBUSBK_HOTK_FUNCTIONS + /*! \addtogroup hotk + * @{ + */ + +//! Creates a new hot-plug handle for USB device arrival/removal event monitoring. + /*! + * + * \param[out] Handle + * Reference to a handle pointer that will receive the initialized hot-plug handle. + * + * \param[in,out] InitParams + * Hot plug handle initialization structure. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API HotK_Init( + _out KHOT_HANDLE* Handle, + _ref PKHOT_PARAMS InitParams); + +//! Frees the specified hot-plug handle. + /*! + * + * \param[in] Handle + * hot-plug handle pointer to free. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API HotK_Free( + _in KHOT_HANDLE Handle); + + //! Frees all hot-plug handles initialized with \ref HotK_Init. + /*! + * + */ + KUSB_EXP VOID KUSB_API HotK_FreeAll(VOID); + + /**@}*/ + +#endif + +#ifndef _LIBUSBK_OVLK_FUNCTIONS + /*! \addtogroup ovlk + * @{ + */ + +//! Gets a preallocated \c OverlappedK structure from the specified/default pool. + /*! + * + * \param[out] OverlappedK + * On Success, receives the overlapped handle. + * + * \param[in] PoolHandle + * The overlapped pool used to retrieve the next available \c OverlappedK. + * + * \returns On success, the next unused overlappedK available in the pool. Otherwise NULL. Use + * \c GetLastError() to get extended error information. + * + * After calling \ref OvlK_Acquire or \ref OvlK_ReUse the \c OverlappedK is ready to be used in an I/O + * operation. See one of the \c UsbK core transfer functions such as \ref UsbK_ReadPipe or + * \ref UsbK_WritePipe for more information. + * + * If the pools internal refurbished list (a re-usable list of \c OverlappedK structures) is not empty, the + * \ref OvlK_Acquire function will choose an overlapped from the refurbished list. + * + */ + KUSB_EXP BOOL KUSB_API OvlK_Acquire( + _out KOVL_HANDLE* OverlappedK, + _in KOVL_POOL_HANDLE PoolHandle); + +//! Returns an \c OverlappedK structure to it's pool. + /*! + * + * \param[in] OverlappedK + * The overlappedK to release. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * When an overlapped is returned to pool, it resources are \b not freed. Instead, it is added to an internal + * refurbished list (a re-usable list of \c OverlappedK structures). + * + * \warning This function must not be called when the OverlappedK is in-use. If unsure, consider using + * \ref OvlK_WaitAndRelease instead. + * + */ + KUSB_EXP BOOL KUSB_API OvlK_Release( + _in KOVL_HANDLE OverlappedK); + + +//! Creates a new overlapped pool. + /*! + * + * \param[out] PoolHandle + * On success, receives the new pool handle. + * + * \param[in] UsbHandle + * USB handle to associate with the pool. + * + * \param[in] MaxOverlappedCount + * Maximum number of overkappedK handles allowed in the pool. + * + * \param[in] Flags + * Pool flags. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API OvlK_Init ( + _out KOVL_POOL_HANDLE* PoolHandle, + _in KUSB_HANDLE UsbHandle, + _in INT MaxOverlappedCount, + _inopt KOVL_POOL_FLAG Flags); + +//! Destroys the specified pool and all resources it created. + /*! + * + * \param[in] PoolHandle + * The overlapped pool to destroy. Once destroyed, the pool and all resources which belong to it can no + * longer be used. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * \warning A pool should not be destroyed until all OverlappedKs acquired from it are no longer in-use. For + * more information see \ref OvlK_WaitAndRelease or \ref OvlK_Release. + * + */ + KUSB_EXP BOOL KUSB_API OvlK_Free( + _in KOVL_POOL_HANDLE PoolHandle); + + +//! Returns the internal event handle used to signal IO operations. + /*! + * + * \param[in] OverlappedK + * The overlappedK used to return the internal event handle. + * + * \returns On success, The manual reset event handle being used by this overlappedK. Otherwise NULL. Use + * \c GetLastError() to get extended error information. + * + * \ref OvlK_GetEventHandle is useful for applications that must to their own event handling. It exposes the + * windows \c OVERLAPPED \c hEvent used for i/o completion signaling. This event handle can be used by the + * standard event wait functions; /c WaitForMultipleObjectsEx for example. + * + * \warning Use \ref OvlK_GetEventHandle with caution. Event handles returned by this function should never + * be used unless the OverlappedK has been \b acquired by the application. + * + */ + KUSB_EXP HANDLE KUSB_API OvlK_GetEventHandle( + _in KOVL_HANDLE OverlappedK); + +//! Waits for overlapped I/O completion, and performs actions specified in \c WaitFlags. + /*! + * + * \param[in] OverlappedK + * The overlappedK to wait on. + * + * \param[in] TimeoutMS + * Number of milliseconds to wait for overlapped completion. + * + * \param[in] WaitFlags + * See /ref KOVL_WAIT_FLAG + * + * \param[out] TransferredLength + * On success, returns the number of bytes transferred by this overlappedK. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. See + * the remarks section below for details on relevant error codes. + * + * \c OvlK_Wait waits the time interval specified in \c TimeoutMS for the overlapped I/O operation to + * complete. Different actions can then taken depending on the flags specified in \c WaitFlags. + * + * \WINERRORTABLE + * + * \WINERROR{ERROR_CANCELLED,1223} + * - The I/O was cancelled by the user. The transfer complete event was not signalled within the alotted + * transfer timeout time and the OvlK_Wait function issued a CancelIoEx/CancelIo request because the + * \ref KOVL_WAIT_FLAG_CANCEL_ON_TIMEOUT flag bit was set. + * \ENDWINERROR + * + * \WINERROR{ERROR_OPERATION_ABORTED,995} + * - The transfer complete event is signalled but the overlapped result was allready cancelled. The + * overlapped I/O may have bee cancelled for one of the following reasons: + * - Driver cancelled because of pipe timeout policy expiration. + * - The device was disconnected. + * - A \ref UsbK_AbortPipe request was issued. + * \ENDWINERROR + * + * \ENDWINERRORTABLE + * + */ + KUSB_EXP BOOL KUSB_API OvlK_Wait( + _in KOVL_HANDLE OverlappedK, + _inopt INT TimeoutMS, + _inopt KOVL_WAIT_FLAG WaitFlags, + _out PUINT TransferredLength); + +//! Waits for overlapped I/O completion on the oldest acquired OverlappedK handle and performs actions specified in \c WaitFlags. + /*! + * + * \param[in] PoolHandle + * The pool handle containing one or more acuired OverlappedKs. + * + * \param[out] OverlappedK + * On success, set to the oldest overlappedK in the acquired list. + * + * \param[in] TimeoutMS + * See /ref OvlK_Wait + * + * \param[in] WaitFlags + * See /ref KOVL_WAIT_FLAG + * + * \param[out] TransferredLength + * See /ref OvlK_Wait + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. See + * See /ref OvlK_Wait + */ + KUSB_EXP BOOL KUSB_API OvlK_WaitOldest( + _in KOVL_POOL_HANDLE PoolHandle, + _outopt KOVL_HANDLE* OverlappedK, + _inopt INT TimeoutMS, + _inopt KOVL_WAIT_FLAG WaitFlags, + _out PUINT TransferredLength); + +//! Waits for overlapped I/O completion, cancels on a timeout error. + /*! + * + * \param[in] OverlappedK + * The overlappedK to wait on. + * + * \param[in] TimeoutMS + * Number of milliseconds to wait for overlapped completion. + * + * \param[out] TransferredLength + * On success, returns the number of bytes transferred by this overlappedK. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. See + * \ref OvlK_Wait for details on relevant win32 error codes. + * + * \note This convenience function calls \ref OvlK_Wait with \ref KOVL_WAIT_FLAG_CANCEL_ON_TIMEOUT. + * + * \c OvlK_WaitOrCancel waits the the time interval specified by \c TimeoutMS for an overlapped result. If + * the \c TimeoutMS interval expires the I/O operation is cancelled. The \c OverlappedK is not released back + * to its pool. + * + */ + KUSB_EXP BOOL KUSB_API OvlK_WaitOrCancel( + _in KOVL_HANDLE OverlappedK, + _inopt INT TimeoutMS, + _out PUINT TransferredLength); + +//! Waits for overlapped I/O completion, cancels on a timeout error and always releases the OvlK handle back to its pool. + /*! + * + * \param[in] OverlappedK + * The overlappedK to wait on. + * + * \param[in] TimeoutMS + * Number of milliseconds to wait for overlapped completion. + * + * \param[out] TransferredLength + * On success, returns the number of bytes transferred by this overlappedK. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. See + * \ref OvlK_Wait for details on relevant win32 error codes. + * + * \note This convenience function calls \ref OvlK_Wait with \ref KOVL_WAIT_FLAG_RELEASE_ALWAYS. + * + * \c OvlK_WaitAndRelease waits the the time interval specified by \c TimeoutMS for an overlapped result. + * When \c OvlK_WaitOrCancel returns, the I/O operation has either been completed or cancelled. The + * \c OverlappedK is always released back to its pool where it can be re-acquired with \ref OvlK_Acquire. + * + */ + KUSB_EXP BOOL KUSB_API OvlK_WaitAndRelease( + _in KOVL_HANDLE OverlappedK, + _inopt INT TimeoutMS, + _out PUINT TransferredLength); + +//! Checks for i/o completion; returns immediately. (polling) + /*! + * + * \param[in] OverlappedK + * The overlappedK to check for completion. + * + * \warning \ref OvlK_IsComplete does \b no validation on the OverlappedK. It's purpose is to check the event + * signal state as fast as possible. + * + * \returns TRUE if the \c OverlappedK has completed, otherwise FALSE. + * + * \c OvlK_IsComplete quickly checks if the \c OverlappedK i/o operation has completed. + */ + KUSB_EXP BOOL KUSB_API OvlK_IsComplete( + _in KOVL_HANDLE OverlappedK); + +//! Initializes an overlappedK for re-use. The overlappedK is not return to its pool. + /*! + * + * \param[in] OverlappedK + * The overlappedK to re-use. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * This function performs the following actions: + * - Resets the overlapped event to non-signaled via ResetEvent(). + * - Clears the internal overlapped information. + * - Clears the 'Internal' and 'InternalHigh' members of the windows overlapped structure. + * + * \note + * Re-using OverlappedKs is the most efficient means of OverlappedK management. When an OverlappedK is + * "re-used" it is not returned to the pool. Instead, the application retains ownership for use in another + * i/o operation. + * + */ + KUSB_EXP BOOL KUSB_API OvlK_ReUse( + _in KOVL_HANDLE OverlappedK); + + /**@}*/ + +#endif + +#ifndef _LIBUSBK_STMK_FUNCTIONS + + /*! \addtogroup stmk + * @{ + */ + +//! Initializes a new uni-directional pipe stream. + /*! + * + * \param[out] StreamHandle + * On success, receives the new stream handle. + * + * \param[in] UsbHandle + * Usb handle to associate with this stream. + * + * \param[in] PipeID + * Endpoint address of USB pipe to associate with this stream. + * + * \param[in] MaxTransferSize + * Maximum number of bytes transferred at once. Larger transfers committed with the stream read/write + * functions are automatically split into multiple smaller chunks. + * + * \param[in] MaxPendingTransfers + * Maximum number of transfers allowed to be outstanding and the total number of transfer contexts that are + * allocated to the stream. + * + * \param[in] MaxPendingIO + * Maximum number of I/O requests the internal stream thread is allowed to have submit at any given time. + * (Pending I/O) + * + * \param[in] Callbacks + * Optional user callback functions. If specified, these callback functions will be executed in real time + * (from within the context of the internal stream thread) as transfers go through the various states. + * + * \param[in] Flags + * Additional stream flags. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * \par + * When a stream is initialized, it validates input parameters and allocates the required memory for the + * transfer context array and transfer lists from a private memory heap. The stream is not started and no I/O + * requests are sent to the device until \ref StmK_Start is executed. + * + */ + KUSB_EXP BOOL KUSB_API StmK_Init( + _out KSTM_HANDLE* StreamHandle, + _in KUSB_HANDLE UsbHandle, + _in UCHAR PipeID, + _in INT MaxTransferSize, + _in INT MaxPendingTransfers, + _in INT MaxPendingIO, + _inopt PKSTM_CALLBACK Callbacks, + _inopt KSTM_FLAG Flags); + +//! Frees resources allocated by a stream handle. + /*! + * + * \param[in] StreamHandle + * The stream handle to free. + * + * \returns TRUE. + * + * If the stream is currently started it is automatically stopped before its resources are freed. + * + */ + KUSB_EXP BOOL KUSB_API StmK_Free( + _in KSTM_HANDLE StreamHandle); + +//! Starts the internal stream thread. + /*! + * + * \param[in] StreamHandle + * The stream to start. A stream handle is created with \ref StmK_Init. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * \par + * When a stream is started, an internal thread is created for managing pipe I/O operations. If a + * \ref KSTM_CALLBACK::Started callback function is assgined, it is executed \b for each transfer context. + * (\b MaxPendingTransfers) See \ref StmK_Init. + * + */ + KUSB_EXP BOOL KUSB_API StmK_Start( + _in KSTM_HANDLE StreamHandle); + +//! Stops the internal stream thread. + /*! + * + * \param[in] StreamHandle + * The stream to stop. + * + * \param[in] TimeoutCancelMS + * Number of milliseconds the internal stream thread should wait for pending I/O to complete before + * cancelling all pending requests. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + */ + KUSB_EXP BOOL KUSB_API StmK_Stop( + _in KSTM_HANDLE StreamHandle, + _in INT TimeoutCancelMS); + +//! Reads data from the stream buffer. + /*! + * + * \param[in] StreamHandle + * The stream to read. + * + * \param[out] Buffer + * A caller-allocated buffer that receives the data that is read. + * + * \param[in] Offset + * Read start offset of \c Buffer. + * + * \param[in] Length + * Size of \c Buffer. + * + * \param[out] TransferredLength + * On success, receives the actual number of bytes that were copied into \c Buffer. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * - Read Stream Operations: + * -# The internal stream thread will always try and keep reads pending as specified by \b MaxPendingIO in + * \ref StmK_Init. + * -# As the stream submits transfers, it increments the \b PendingIO and \b PendingTransfer counts. As it + * completes transfers, it decrements the \b PendingIO count. As the user processes transfers with + * \ref StmK_Read, it decrements the \b PendingTransfer count and release control of the transfer context + * back to the stream where it is re-used. + * -# When the pending I/O count reaches \c MaxPendingIO, the stream completes the oldest + * \b PendingTransfer and moves it into a FIFO complete where it awaits user processing via the + * \ref StmK_Read function. + * -# If the stream has not exhausted its MaxPendingTransfers count, another read request is submitted + * immediately to satisfy \b MaxPendingIO. + * + */ + KUSB_EXP BOOL KUSB_API StmK_Read( + _in KSTM_HANDLE StreamHandle, + _out PUCHAR Buffer, + _in INT Offset, + _in INT Length, + _out PUINT TransferredLength); + +//! Writes data to the stream buffer. + /*! + * + * \param[in] StreamHandle + * The stream to write. + * + * \param[in] Buffer + * A caller-allocated buffer the data is written from. + * + * \param[in] Offset + * Write start offset of \c Buffer. + * + * \param[in] Length + * Number of bytes to copy into the stream buffer. + * + * \param[out] TransferredLength + * On success, receives the actual number of bytes that were copied into the stream buffer. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * - Write Stream Operations: + * -# The internal stream thread will always try and exhaust all pending transfers submitted by the user + * via \ref StmK_Write. + * -# As the user submits transfers via \ref StmK_Write, the \b PendingTransfer count is inceremented and + * transfers are added to a queued FIFO list where they await processing by the internal stream thread. + * -# While the queued FIFO list is not empty and \b PendingIO count is less than \b MaxPendingIO, The + * \b PendingIO count increments and the request is sent to the device. + * -# When a transfer completes, the internal pending I/O count is decremented and the transfers is moved + * back into the idle list where it can be reused again by subsequent \ref StmK_Write requests. + * + */ + KUSB_EXP BOOL KUSB_API StmK_Write( + _in KSTM_HANDLE StreamHandle, + _in PUCHAR Buffer, + _in INT Offset, + _in INT Length, + _out PUINT TransferredLength); + /**@}*/ + +#endif + +#ifndef _LIBUSBK_ISOK_FUNCTIONS + /*! \addtogroup isok + * @{ + */ + +//! Creates a new isochronous transfer context. + /*! + * + * \param[out] IsoContext + * Receives a new isochronous transfer context. + * + * \param[in] NumberOfPackets + * The number of \ref KISO_PACKET structures allocated to \c IsoContext. Assigned to + * \ref KISO_CONTEXT::NumberOfPackets. The \ref KISO_CONTEXT::NumberOfPackets field is assignable by + * \c IsoK_Init only and must not be changed by the user. + * + * \param[in] StartFrame + * The USB frame number this request must start on (or \b 0 for ASAP) and assigned to + * \ref KISO_CONTEXT::StartFrame. The \ref KISO_CONTEXT::StartFrame may be chamged by the user in subsequent + * request. For more information, see \ref KISO_CONTEXT::StartFrame. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * \c IsoK_Init is performs the following tasks in order: + * -# Allocates the \c IsoContext and the required \ref KISO_PACKET structures. + * -# Zero-initializes all ISO context memory. + * -# Assigns \b NumberOfPackets, \b PipeID, and \b StartFrame to \c IsoContext. + * + */ + KUSB_EXP BOOL KUSB_API IsoK_Init( + _out PKISO_CONTEXT* IsoContext, + _in INT NumberOfPackets, + _inopt INT StartFrame); + +//! Destroys an isochronous transfer context. + /*! + * \param[in] IsoContext + * A pointer to an isochronous transfer context created with \ref IsoK_Init. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + */ + KUSB_EXP BOOL KUSB_API IsoK_Free( + _in PKISO_CONTEXT IsoContext); + +//! Convenience function for setting the offset of all ISO packets of an isochronous transfer context. + /*! + * \param[in] IsoContext + * A pointer to an isochronous transfer context. + * + * \param[in] PacketSize + * The packet size used to calculate and assign the absolute data offset for each \ref KISO_PACKET in + * \c IsoContext. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * \c IsoK_SetPackets updates all \ref KISO_PACKET::Offset fields in a \ref KISO_CONTEXT so all offset are + * \c PacketSize apart. For example: + * - The offset of the first (0-index) packet is 0. + * - The offset of the second (1-index) packet is PacketSize. + * - The offset of the third (2-index) packet is PacketSize*2. + * + * \code + * for (packetIndex = 0; packetIndex < IsoContext->NumberOfPackets; packetIndex++) + * IsoContext->IsoPackets[packetIndex].Offset = packetIndex * PacketSize; + * \endcode + * + */ + KUSB_EXP BOOL KUSB_API IsoK_SetPackets( + _in PKISO_CONTEXT IsoContext, + _in INT PacketSize); + +//! Convenience function for setting all fields of a \ref KISO_PACKET. + /*! + * \param[in] IsoContext + * A pointer to an isochronous transfer context. + * + * \param[in] PacketIndex + * The packet index to set. + * + * \param[in] IsoPacket + * Pointer to a user allocated \c KISO_PACKET which is copied into the PKISO_CONTEXT::IsoPackets array at the + * specified index. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + */ + KUSB_EXP BOOL KUSB_API IsoK_SetPacket( + _in PKISO_CONTEXT IsoContext, + _in INT PacketIndex, + _in PKISO_PACKET IsoPacket); + +//! Convenience function for getting all fields of a \ref KISO_PACKET. + /*! + * \param[in] IsoContext + * A pointer to an isochronous transfer context. + * + * \param[in] PacketIndex + * The packet index to get. + * + * \param[out] IsoPacket + * Pointer to a user allocated \c KISO_PACKET which receives a copy of the ISO packet in the + * PKISO_CONTEXT::IsoPackets array at the specified index. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + */ + KUSB_EXP BOOL KUSB_API IsoK_GetPacket( + _in PKISO_CONTEXT IsoContext, + _in INT PacketIndex, + _out PKISO_PACKET IsoPacket); + +//! Convenience function for enumerating ISO packets of an isochronous transfer context. + /*! + * \param[in] IsoContext + * A pointer to an isochronous transfer context. + * + * \param[in] EnumPackets + * Pointer to a user supplied callback function which is executed for all ISO packets in \c IsoContext or + * until the user supplied callback function returns \c FALSE. + * + * \param[in] StartPacketIndex + * The zero-based ISO packet index to begin enumeration at. + * + * \param[in] UserState + * A user defined value which is passed as a parameter to the user supplied callback function. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + */ + KUSB_EXP BOOL KUSB_API IsoK_EnumPackets( + _in PKISO_CONTEXT IsoContext, + _in KISO_ENUM_PACKETS_CB* EnumPackets, + _inopt INT StartPacketIndex, + _inopt PVOID UserState); + +//! Convenience function for re-using an isochronous transfer context in a subsequent request. + /*! + * \param[in,out] IsoContext + * A pointer to an isochronous transfer context. + * + * \returns On success, TRUE. Otherwise FALSE. Use \c GetLastError() to get extended error information. + * + * \c IsoK_ReUse does the following: + * -# Zero-initializes the \b Length and \b Status fields of all \ref KISO_PACKET structures. + * -# Zero-initializes the \b StartFrame and \b ErrorCount of the \ref KISO_CONTEXT. + * + */ + KUSB_EXP BOOL KUSB_API IsoK_ReUse( + _ref PKISO_CONTEXT IsoContext); + + /*! @} */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif // _LIBUSBK_H__ diff --git a/Desktop_Interface/build_win/libusbk/includes/libusbk.h.REMOVED.git-id b/Desktop_Interface/build_win/libusbk/includes/libusbk.h.REMOVED.git-id deleted file mode 100644 index 1455df63..00000000 --- a/Desktop_Interface/build_win/libusbk/includes/libusbk.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bac5f81b4b7c7358636ed45329651ea7bd92d647 \ No newline at end of file diff --git a/Desktop_Interface/build_win/libusbk/includes/lusbk_dynapi.c b/Desktop_Interface/build_win/libusbk/includes/lusbk_dynapi.c new file mode 100644 index 00000000..3b414327 --- /dev/null +++ b/Desktop_Interface/build_win/libusbk/includes/lusbk_dynapi.c @@ -0,0 +1,1915 @@ +/*!******************************************************************** +libusbK - Multi-driver USB library. +Copyright (C) 2012 Travis Lee Robinson. All Rights Reserved. +libusb-win32.sourceforge.net + +Development : Travis Lee Robinson (libusbdotnet@gmail.com) +Testing : Xiaofan Chen (xiaofanc@gmail.com) + +At the discretion of the user of this library, this software may be +licensed under the terms of the GNU Public License v3 or a BSD-Style +license as outlined in the following files: +* LICENSE-gpl3.txt +* LICENSE-bsd.txt + +License files are located in a license folder at the root of source and +binary distributions. +********************************************************************!*/ + +#include +#include "libusbk.h" + +#define mLoadLibraryExA LoadLibraryExA +#define mFreeLibrary FreeLibrary + +HMODULE mLibusbK_ModuleHandle = NULL; + +VOID LibusbK_DynApi_Free(VOID); +INT LibusbK_DynApi_Init(_inopt LPCSTR DllFullPathName); + +// Function typedefs: + +typedef VOID KUSB_API LibK_GetVersion_T(_out PKLIB_VERSION Version); + +typedef KLIB_USER_CONTEXT KUSB_API LibK_GetContext_T( + _in KLIB_HANDLE Handle, + _in KLIB_HANDLE_TYPE HandleType); + +typedef BOOL KUSB_API LibK_SetContext_T( + _in KLIB_HANDLE Handle, + _in KLIB_HANDLE_TYPE HandleType, + _in KLIB_USER_CONTEXT ContextValue); + +typedef BOOL KUSB_API LibK_SetCleanupCallback_T( + _in KLIB_HANDLE Handle, + _in KLIB_HANDLE_TYPE HandleType, + _in KLIB_HANDLE_CLEANUP_CB* CleanupCB); + +typedef BOOL KUSB_API LibK_LoadDriverAPI_T( + _out PKUSB_DRIVER_API DriverAPI, + _in INT DriverID); + +typedef BOOL KUSB_API LibK_CopyDriverAPI_T( + _out PKUSB_DRIVER_API DriverAPI, + _in KUSB_HANDLE UsbHandle); + +typedef BOOL KUSB_API LibK_GetProcAddress_T( + _out KPROC* ProcAddress, + _in INT DriverID, + _in INT FunctionID); + +typedef BOOL KUSB_API LibK_SetDefaultContext_T( + _in KLIB_HANDLE_TYPE HandleType, + _in KLIB_USER_CONTEXT ContextValue); + +typedef KLIB_USER_CONTEXT KUSB_API LibK_GetDefaultContext_T( + _in KLIB_HANDLE_TYPE HandleType); + +typedef BOOL KUSB_API LibK_Context_Init_T( + _inopt HANDLE Heap, + _in PVOID Reserved); + +typedef VOID KUSB_API LibK_Context_Free_T(VOID); + +typedef BOOL KUSB_API UsbK_Init_T ( + _out KUSB_HANDLE* InterfaceHandle, + _in KLST_DEVINFO_HANDLE DevInfo); + +typedef BOOL KUSB_API UsbK_Free_T ( + _in KUSB_HANDLE InterfaceHandle); + +typedef BOOL KUSB_API UsbK_ClaimInterface_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex); + +typedef BOOL KUSB_API UsbK_ReleaseInterface_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex); + +typedef BOOL KUSB_API UsbK_SetAltInterface_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex, + _in UCHAR AltSettingNumber); + +typedef BOOL KUSB_API UsbK_GetAltInterface_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex, + _out PUCHAR AltSettingNumber); + +typedef BOOL KUSB_API UsbK_GetDescriptor_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR DescriptorType, + _in UCHAR Index, + _in USHORT LanguageID, + _out PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred); + +typedef BOOL KUSB_API UsbK_ControlTransfer_T ( + _in KUSB_HANDLE InterfaceHandle, + _in WINUSB_SETUP_PACKET SetupPacket, + _refopt PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred, + _inopt LPOVERLAPPED Overlapped); + +typedef BOOL KUSB_API UsbK_SetPowerPolicy_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UINT PolicyType, + _in UINT ValueLength, + _in PVOID Value); + +typedef BOOL KUSB_API UsbK_GetPowerPolicy_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UINT PolicyType, + _ref PUINT ValueLength, + _out PVOID Value); + +typedef BOOL KUSB_API UsbK_SetConfiguration_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR ConfigurationNumber); + +typedef BOOL KUSB_API UsbK_GetConfiguration_T ( + _in KUSB_HANDLE InterfaceHandle, + _out PUCHAR ConfigurationNumber); + +typedef BOOL KUSB_API UsbK_ResetDevice_T ( + _in KUSB_HANDLE InterfaceHandle); + +typedef BOOL KUSB_API UsbK_Initialize_T ( + _in HANDLE DeviceHandle, + _out KUSB_HANDLE* InterfaceHandle); + +typedef BOOL KUSB_API UsbK_SelectInterface_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex); + +typedef BOOL KUSB_API UsbK_GetAssociatedInterface_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AssociatedInterfaceIndex, + _out KUSB_HANDLE* AssociatedInterfaceHandle); + +typedef BOOL KUSB_API UsbK_Clone_T ( + _in KUSB_HANDLE InterfaceHandle, + _out KUSB_HANDLE* DstInterfaceHandle); + +typedef BOOL KUSB_API UsbK_QueryInterfaceSettings_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AltSettingIndex, + _out PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor); + +typedef BOOL KUSB_API UsbK_QueryDeviceInformation_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UINT InformationType, + _ref PUINT BufferLength, + _ref PVOID Buffer); + +typedef BOOL KUSB_API UsbK_SetCurrentAlternateSetting_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AltSettingNumber); + +typedef BOOL KUSB_API UsbK_GetCurrentAlternateSetting_T ( + _in KUSB_HANDLE InterfaceHandle, + _out PUCHAR AltSettingNumber); + +typedef BOOL KUSB_API UsbK_QueryPipe_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AltSettingNumber, + _in UCHAR PipeIndex, + _out PWINUSB_PIPE_INFORMATION PipeInformation); + +typedef BOOL KUSB_API UsbK_SetPipePolicy_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in UINT PolicyType, + _in UINT ValueLength, + _in PVOID Value); + +typedef BOOL KUSB_API UsbK_GetPipePolicy_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in UINT PolicyType, + _ref PUINT ValueLength, + _out PVOID Value); + +typedef BOOL KUSB_API UsbK_ReadPipe_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _out PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred, + _inopt LPOVERLAPPED Overlapped); + +typedef BOOL KUSB_API UsbK_WritePipe_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred, + _inopt LPOVERLAPPED Overlapped); + +typedef BOOL KUSB_API UsbK_ResetPipe_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID); + +typedef BOOL KUSB_API UsbK_AbortPipe_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID); + +typedef BOOL KUSB_API UsbK_FlushPipe_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID); + +typedef BOOL KUSB_API UsbK_IsoReadPipe_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _out PUCHAR Buffer, + _in UINT BufferLength, + _in LPOVERLAPPED Overlapped, + _refopt PKISO_CONTEXT IsoContext); + +typedef BOOL KUSB_API UsbK_IsoWritePipe_T ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in PUCHAR Buffer, + _in UINT BufferLength, + _in LPOVERLAPPED Overlapped, + _refopt PKISO_CONTEXT IsoContext); + +typedef BOOL KUSB_API UsbK_GetCurrentFrameNumber_T ( + _in KUSB_HANDLE InterfaceHandle, + _out PUINT FrameNumber); + +typedef BOOL KUSB_API UsbK_GetOverlappedResult_T ( + _in KUSB_HANDLE InterfaceHandle, + _in LPOVERLAPPED Overlapped, + _out PUINT lpNumberOfBytesTransferred, + _in BOOL bWait); + +typedef BOOL KUSB_API UsbK_GetProperty_T ( + _in KUSB_HANDLE InterfaceHandle, + _in KUSB_PROPERTY PropertyType, + _ref PUINT PropertySize, + _out PVOID Value); + +typedef BOOL KUSB_API LstK_Init_T( + _out KLST_HANDLE* DeviceList, + _in KLST_FLAG Flags); + +typedef BOOL KUSB_API LstK_InitEx_T( + _out KLST_HANDLE* DeviceList, + _in KLST_FLAG Flags, + _in PKLST_PATTERN_MATCH PatternMatch); + +typedef BOOL KUSB_API LstK_Free_T( + _in KLST_HANDLE DeviceList); + +typedef BOOL KUSB_API LstK_Enumerate_T( + _in KLST_HANDLE DeviceList, + _in KLST_ENUM_DEVINFO_CB* EnumDevListCB, + _inopt PVOID Context); + +typedef BOOL KUSB_API LstK_Current_T( + _in KLST_HANDLE DeviceList, + _out KLST_DEVINFO_HANDLE* DeviceInfo); + +typedef BOOL KUSB_API LstK_MoveNext_T( + _in KLST_HANDLE DeviceList, + _outopt KLST_DEVINFO_HANDLE* DeviceInfo); + +typedef VOID KUSB_API LstK_MoveReset_T( + _in KLST_HANDLE DeviceList); + +typedef BOOL KUSB_API LstK_FindByVidPid_T( + _in KLST_HANDLE DeviceList, + _in INT Vid, + _in INT Pid, + _out KLST_DEVINFO_HANDLE* DeviceInfo); + +typedef BOOL KUSB_API LstK_Count_T( + _in KLST_HANDLE DeviceList, + _ref PUINT Count); + +typedef BOOL KUSB_API HotK_Init_T( + _out KHOT_HANDLE* Handle, + _ref PKHOT_PARAMS InitParams); + +typedef BOOL KUSB_API HotK_Free_T( + _in KHOT_HANDLE Handle); + +typedef VOID KUSB_API HotK_FreeAll_T(VOID); + +typedef BOOL KUSB_API OvlK_Acquire_T( + _out KOVL_HANDLE* OverlappedK, + _in KOVL_POOL_HANDLE PoolHandle); + +typedef BOOL KUSB_API OvlK_Release_T( + _in KOVL_HANDLE OverlappedK); + +typedef BOOL KUSB_API OvlK_Init_T ( + _out KOVL_POOL_HANDLE* PoolHandle, + _in KUSB_HANDLE UsbHandle, + _in INT MaxOverlappedCount, + _inopt KOVL_POOL_FLAG Flags); + +typedef BOOL KUSB_API OvlK_Free_T( + _in KOVL_POOL_HANDLE PoolHandle); + +typedef HANDLE KUSB_API OvlK_GetEventHandle_T( + _in KOVL_HANDLE OverlappedK); + +typedef BOOL KUSB_API OvlK_Wait_T( + _in KOVL_HANDLE OverlappedK, + _inopt INT TimeoutMS, + _inopt KOVL_WAIT_FLAG WaitFlags, + _out PUINT TransferredLength); + +typedef BOOL KUSB_API OvlK_WaitOldest_T( + _in KOVL_POOL_HANDLE PoolHandle, + _outopt KOVL_HANDLE* OverlappedK, + _inopt INT TimeoutMS, + _inopt KOVL_WAIT_FLAG WaitFlags, + _out PUINT TransferredLength); + +typedef BOOL KUSB_API OvlK_WaitOrCancel_T( + _in KOVL_HANDLE OverlappedK, + _inopt INT TimeoutMS, + _out PUINT TransferredLength); + +typedef BOOL KUSB_API OvlK_WaitAndRelease_T( + _in KOVL_HANDLE OverlappedK, + _inopt INT TimeoutMS, + _out PUINT TransferredLength); + +typedef BOOL KUSB_API OvlK_IsComplete_T( + _in KOVL_HANDLE OverlappedK); + +typedef BOOL KUSB_API OvlK_ReUse_T( + _in KOVL_HANDLE OverlappedK); + +typedef BOOL KUSB_API StmK_Init_T( + _out KSTM_HANDLE* StreamHandle, + _in KUSB_HANDLE UsbHandle, + _in UCHAR PipeID, + _in INT MaxTransferSize, + _in INT MaxPendingTransfers, + _in INT MaxPendingIO, + _inopt PKSTM_CALLBACK Callbacks, + _inopt KSTM_FLAG Flags); + +typedef BOOL KUSB_API StmK_Free_T( + _in KSTM_HANDLE StreamHandle); + +typedef BOOL KUSB_API StmK_Start_T( + _in KSTM_HANDLE StreamHandle); + +typedef BOOL KUSB_API StmK_Stop_T( + _in KSTM_HANDLE StreamHandle, + _in INT TimeoutCancelMS); + +typedef BOOL KUSB_API StmK_Read_T( + _in KSTM_HANDLE StreamHandle, + _out PUCHAR Buffer, + _in INT Offset, + _in INT Length, + _out PUINT TransferredLength); + +typedef BOOL KUSB_API StmK_Write_T( + _in KSTM_HANDLE StreamHandle, + _in PUCHAR Buffer, + _in INT Offset, + _in INT Length, + _out PUINT TransferredLength); + +typedef BOOL KUSB_API IsoK_Init_T( + _out PKISO_CONTEXT* IsoContext, + _in INT NumberOfPackets, + _inopt INT StartFrame); + +typedef BOOL KUSB_API IsoK_Free_T( + _in PKISO_CONTEXT IsoContext); + +typedef BOOL KUSB_API IsoK_SetPackets_T( + _in PKISO_CONTEXT IsoContext, + _in INT PacketSize); + +typedef BOOL KUSB_API IsoK_SetPacket_T( + _in PKISO_CONTEXT IsoContext, + _in INT PacketIndex, + _in PKISO_PACKET IsoPacket); + +typedef BOOL KUSB_API IsoK_GetPacket_T( + _in PKISO_CONTEXT IsoContext, + _in INT PacketIndex, + _out PKISO_PACKET IsoPacket); + +typedef BOOL KUSB_API IsoK_EnumPackets_T( + _in PKISO_CONTEXT IsoContext, + _in KISO_ENUM_PACKETS_CB* EnumPackets, + _inopt INT StartPacketIndex, + _inopt PVOID UserState); + +typedef BOOL KUSB_API IsoK_ReUse_T( + _ref PKISO_CONTEXT IsoContext); + + + +/////////////////////////////////////////////////////////////////////// + +// Function pointers: + +static LibK_GetVersion_T* pLibK_GetVersion = NULL; + +static LibK_GetContext_T* pLibK_GetContext = NULL; + +static LibK_SetContext_T* pLibK_SetContext = NULL; + +static LibK_SetCleanupCallback_T* pLibK_SetCleanupCallback = NULL; + +static LibK_LoadDriverAPI_T* pLibK_LoadDriverAPI = NULL; + +static LibK_CopyDriverAPI_T* pLibK_CopyDriverAPI = NULL; + +static LibK_GetProcAddress_T* pLibK_GetProcAddress = NULL; + +static LibK_SetDefaultContext_T* pLibK_SetDefaultContext = NULL; + +static LibK_GetDefaultContext_T* pLibK_GetDefaultContext = NULL; + +static LibK_Context_Init_T* pLibK_Context_Init = NULL; + +static LibK_Context_Free_T* pLibK_Context_Free = NULL; + +static UsbK_Init_T* pUsbK_Init = NULL; + +static UsbK_Free_T* pUsbK_Free = NULL; + +static UsbK_ClaimInterface_T* pUsbK_ClaimInterface = NULL; + +static UsbK_ReleaseInterface_T* pUsbK_ReleaseInterface = NULL; + +static UsbK_SetAltInterface_T* pUsbK_SetAltInterface = NULL; + +static UsbK_GetAltInterface_T* pUsbK_GetAltInterface = NULL; + +static UsbK_GetDescriptor_T* pUsbK_GetDescriptor = NULL; + +static UsbK_ControlTransfer_T* pUsbK_ControlTransfer = NULL; + +static UsbK_SetPowerPolicy_T* pUsbK_SetPowerPolicy = NULL; + +static UsbK_GetPowerPolicy_T* pUsbK_GetPowerPolicy = NULL; + +static UsbK_SetConfiguration_T* pUsbK_SetConfiguration = NULL; + +static UsbK_GetConfiguration_T* pUsbK_GetConfiguration = NULL; + +static UsbK_ResetDevice_T* pUsbK_ResetDevice = NULL; + +static UsbK_Initialize_T* pUsbK_Initialize = NULL; + +static UsbK_SelectInterface_T* pUsbK_SelectInterface = NULL; + +static UsbK_GetAssociatedInterface_T* pUsbK_GetAssociatedInterface = NULL; + +static UsbK_Clone_T* pUsbK_Clone = NULL; + +static UsbK_QueryInterfaceSettings_T* pUsbK_QueryInterfaceSettings = NULL; + +static UsbK_QueryDeviceInformation_T* pUsbK_QueryDeviceInformation = NULL; + +static UsbK_SetCurrentAlternateSetting_T* pUsbK_SetCurrentAlternateSetting = NULL; + +static UsbK_GetCurrentAlternateSetting_T* pUsbK_GetCurrentAlternateSetting = NULL; + +static UsbK_QueryPipe_T* pUsbK_QueryPipe = NULL; + +static UsbK_SetPipePolicy_T* pUsbK_SetPipePolicy = NULL; + +static UsbK_GetPipePolicy_T* pUsbK_GetPipePolicy = NULL; + +static UsbK_ReadPipe_T* pUsbK_ReadPipe = NULL; + +static UsbK_WritePipe_T* pUsbK_WritePipe = NULL; + +static UsbK_ResetPipe_T* pUsbK_ResetPipe = NULL; + +static UsbK_AbortPipe_T* pUsbK_AbortPipe = NULL; + +static UsbK_FlushPipe_T* pUsbK_FlushPipe = NULL; + +static UsbK_IsoReadPipe_T* pUsbK_IsoReadPipe = NULL; + +static UsbK_IsoWritePipe_T* pUsbK_IsoWritePipe = NULL; + +static UsbK_GetCurrentFrameNumber_T* pUsbK_GetCurrentFrameNumber = NULL; + +static UsbK_GetOverlappedResult_T* pUsbK_GetOverlappedResult = NULL; + +static UsbK_GetProperty_T* pUsbK_GetProperty = NULL; + +static LstK_Init_T* pLstK_Init = NULL; + +static LstK_InitEx_T* pLstK_InitEx = NULL; + +static LstK_Free_T* pLstK_Free = NULL; + +static LstK_Enumerate_T* pLstK_Enumerate = NULL; + +static LstK_Current_T* pLstK_Current = NULL; + +static LstK_MoveNext_T* pLstK_MoveNext = NULL; + +static LstK_MoveReset_T* pLstK_MoveReset = NULL; + +static LstK_FindByVidPid_T* pLstK_FindByVidPid = NULL; + +static LstK_Count_T* pLstK_Count = NULL; + +static HotK_Init_T* pHotK_Init = NULL; + +static HotK_Free_T* pHotK_Free = NULL; + +static HotK_FreeAll_T* pHotK_FreeAll = NULL; + +static OvlK_Acquire_T* pOvlK_Acquire = NULL; + +static OvlK_Release_T* pOvlK_Release = NULL; + +static OvlK_Init_T* pOvlK_Init = NULL; + +static OvlK_Free_T* pOvlK_Free = NULL; + +static OvlK_GetEventHandle_T* pOvlK_GetEventHandle = NULL; + +static OvlK_Wait_T* pOvlK_Wait = NULL; + +static OvlK_WaitOldest_T* pOvlK_WaitOldest = NULL; + +static OvlK_WaitOrCancel_T* pOvlK_WaitOrCancel = NULL; + +static OvlK_WaitAndRelease_T* pOvlK_WaitAndRelease = NULL; + +static OvlK_IsComplete_T* pOvlK_IsComplete = NULL; + +static OvlK_ReUse_T* pOvlK_ReUse = NULL; + +static StmK_Init_T* pStmK_Init = NULL; + +static StmK_Free_T* pStmK_Free = NULL; + +static StmK_Start_T* pStmK_Start = NULL; + +static StmK_Stop_T* pStmK_Stop = NULL; + +static StmK_Read_T* pStmK_Read = NULL; + +static StmK_Write_T* pStmK_Write = NULL; + +static IsoK_Init_T* pIsoK_Init = NULL; + +static IsoK_Free_T* pIsoK_Free = NULL; + +static IsoK_SetPackets_T* pIsoK_SetPackets = NULL; + +static IsoK_SetPacket_T* pIsoK_SetPacket = NULL; + +static IsoK_GetPacket_T* pIsoK_GetPacket = NULL; + +static IsoK_EnumPackets_T* pIsoK_EnumPackets = NULL; + +static IsoK_ReUse_T* pIsoK_ReUse = NULL; + + + +/////////////////////////////////////////////////////////////////////// + + +VOID LibusbK_DynApi_Free(VOID) +{ + if (mLibusbK_ModuleHandle) + { + mFreeLibrary(mLibusbK_ModuleHandle); + mLibusbK_ModuleHandle = NULL; + + // Set all function pointers to null: + + pLibK_GetVersion = NULL; + + pLibK_GetContext = NULL; + + pLibK_SetContext = NULL; + + pLibK_SetCleanupCallback = NULL; + + pLibK_LoadDriverAPI = NULL; + + pLibK_CopyDriverAPI = NULL; + + pLibK_GetProcAddress = NULL; + + pLibK_SetDefaultContext = NULL; + + pLibK_GetDefaultContext = NULL; + + pLibK_Context_Init = NULL; + + pLibK_Context_Free = NULL; + + pUsbK_Init = NULL; + + pUsbK_Free = NULL; + + pUsbK_ClaimInterface = NULL; + + pUsbK_ReleaseInterface = NULL; + + pUsbK_SetAltInterface = NULL; + + pUsbK_GetAltInterface = NULL; + + pUsbK_GetDescriptor = NULL; + + pUsbK_ControlTransfer = NULL; + + pUsbK_SetPowerPolicy = NULL; + + pUsbK_GetPowerPolicy = NULL; + + pUsbK_SetConfiguration = NULL; + + pUsbK_GetConfiguration = NULL; + + pUsbK_ResetDevice = NULL; + + pUsbK_Initialize = NULL; + + pUsbK_SelectInterface = NULL; + + pUsbK_GetAssociatedInterface = NULL; + + pUsbK_Clone = NULL; + + pUsbK_QueryInterfaceSettings = NULL; + + pUsbK_QueryDeviceInformation = NULL; + + pUsbK_SetCurrentAlternateSetting = NULL; + + pUsbK_GetCurrentAlternateSetting = NULL; + + pUsbK_QueryPipe = NULL; + + pUsbK_SetPipePolicy = NULL; + + pUsbK_GetPipePolicy = NULL; + + pUsbK_ReadPipe = NULL; + + pUsbK_WritePipe = NULL; + + pUsbK_ResetPipe = NULL; + + pUsbK_AbortPipe = NULL; + + pUsbK_FlushPipe = NULL; + + pUsbK_IsoReadPipe = NULL; + + pUsbK_IsoWritePipe = NULL; + + pUsbK_GetCurrentFrameNumber = NULL; + + pUsbK_GetOverlappedResult = NULL; + + pUsbK_GetProperty = NULL; + + pLstK_Init = NULL; + + pLstK_InitEx = NULL; + + pLstK_Free = NULL; + + pLstK_Enumerate = NULL; + + pLstK_Current = NULL; + + pLstK_MoveNext = NULL; + + pLstK_MoveReset = NULL; + + pLstK_FindByVidPid = NULL; + + pLstK_Count = NULL; + + pHotK_Init = NULL; + + pHotK_Free = NULL; + + pHotK_FreeAll = NULL; + + pOvlK_Acquire = NULL; + + pOvlK_Release = NULL; + + pOvlK_Init = NULL; + + pOvlK_Free = NULL; + + pOvlK_GetEventHandle = NULL; + + pOvlK_Wait = NULL; + + pOvlK_WaitOldest = NULL; + + pOvlK_WaitOrCancel = NULL; + + pOvlK_WaitAndRelease = NULL; + + pOvlK_IsComplete = NULL; + + pOvlK_ReUse = NULL; + + pStmK_Init = NULL; + + pStmK_Free = NULL; + + pStmK_Start = NULL; + + pStmK_Stop = NULL; + + pStmK_Read = NULL; + + pStmK_Write = NULL; + + pIsoK_Init = NULL; + + pIsoK_Free = NULL; + + pIsoK_SetPackets = NULL; + + pIsoK_SetPacket = NULL; + + pIsoK_GetPacket = NULL; + + pIsoK_EnumPackets = NULL; + + pIsoK_ReUse = NULL; + + + + /////////////////////////////////////////////////////////////////////// + } +} + +INT LibusbK_DynApi_Init(_inopt LPCSTR DllFullPathName) +{ + LPCSTR dllFullPathName = (DllFullPathName == NULL) ? "libusbK.dll" : DllFullPathName; + INT funcLoadFailCount = 0; + + if (mLibusbK_ModuleHandle) LibusbK_DynApi_Free(); + + if (DllFullPathName) + mLibusbK_ModuleHandle = mLoadLibraryExA(dllFullPathName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + else + mLibusbK_ModuleHandle = mLoadLibraryExA(dllFullPathName, NULL, 0); + + if (mLibusbK_ModuleHandle == NULL) return -1; + + + // Function loads: + + if ((pLibK_GetVersion = (LibK_GetVersion_T*)GetProcAddress(mLibusbK_ModuleHandle, "LibK_GetVersion")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LibK_GetVersion.\n"); + } + + if ((pLibK_GetContext = (LibK_GetContext_T*)GetProcAddress(mLibusbK_ModuleHandle, "LibK_GetContext")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LibK_GetContext.\n"); + } + + if ((pLibK_SetContext = (LibK_SetContext_T*)GetProcAddress(mLibusbK_ModuleHandle, "LibK_SetContext")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LibK_SetContext.\n"); + } + + if ((pLibK_SetCleanupCallback = (LibK_SetCleanupCallback_T*)GetProcAddress(mLibusbK_ModuleHandle, "LibK_SetCleanupCallback")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LibK_SetCleanupCallback.\n"); + } + + if ((pLibK_LoadDriverAPI = (LibK_LoadDriverAPI_T*)GetProcAddress(mLibusbK_ModuleHandle, "LibK_LoadDriverAPI")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LibK_LoadDriverAPI.\n"); + } + + if ((pLibK_CopyDriverAPI = (LibK_CopyDriverAPI_T*)GetProcAddress(mLibusbK_ModuleHandle, "LibK_CopyDriverAPI")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LibK_CopyDriverAPI.\n"); + } + + if ((pLibK_GetProcAddress = (LibK_GetProcAddress_T*)GetProcAddress(mLibusbK_ModuleHandle, "LibK_GetProcAddress")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LibK_GetProcAddress.\n"); + } + + if ((pLibK_SetDefaultContext = (LibK_SetDefaultContext_T*)GetProcAddress(mLibusbK_ModuleHandle, "LibK_SetDefaultContext")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LibK_SetDefaultContext.\n"); + } + + if ((pLibK_GetDefaultContext = (LibK_GetDefaultContext_T*)GetProcAddress(mLibusbK_ModuleHandle, "LibK_GetDefaultContext")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LibK_GetDefaultContext.\n"); + } + + if ((pLibK_Context_Init = (LibK_Context_Init_T*)GetProcAddress(mLibusbK_ModuleHandle, "LibK_Context_Init")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LibK_Context_Init.\n"); + } + + if ((pLibK_Context_Free = (LibK_Context_Free_T*)GetProcAddress(mLibusbK_ModuleHandle, "LibK_Context_Free")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LibK_Context_Free.\n"); + } + + if ((pUsbK_Init = (UsbK_Init_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_Init")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_Init.\n"); + } + + if ((pUsbK_Free = (UsbK_Free_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_Free")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_Free.\n"); + } + + if ((pUsbK_ClaimInterface = (UsbK_ClaimInterface_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_ClaimInterface")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_ClaimInterface.\n"); + } + + if ((pUsbK_ReleaseInterface = (UsbK_ReleaseInterface_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_ReleaseInterface")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_ReleaseInterface.\n"); + } + + if ((pUsbK_SetAltInterface = (UsbK_SetAltInterface_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_SetAltInterface")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_SetAltInterface.\n"); + } + + if ((pUsbK_GetAltInterface = (UsbK_GetAltInterface_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_GetAltInterface")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_GetAltInterface.\n"); + } + + if ((pUsbK_GetDescriptor = (UsbK_GetDescriptor_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_GetDescriptor")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_GetDescriptor.\n"); + } + + if ((pUsbK_ControlTransfer = (UsbK_ControlTransfer_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_ControlTransfer")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_ControlTransfer.\n"); + } + + if ((pUsbK_SetPowerPolicy = (UsbK_SetPowerPolicy_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_SetPowerPolicy")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_SetPowerPolicy.\n"); + } + + if ((pUsbK_GetPowerPolicy = (UsbK_GetPowerPolicy_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_GetPowerPolicy")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_GetPowerPolicy.\n"); + } + + if ((pUsbK_SetConfiguration = (UsbK_SetConfiguration_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_SetConfiguration")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_SetConfiguration.\n"); + } + + if ((pUsbK_GetConfiguration = (UsbK_GetConfiguration_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_GetConfiguration")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_GetConfiguration.\n"); + } + + if ((pUsbK_ResetDevice = (UsbK_ResetDevice_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_ResetDevice")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_ResetDevice.\n"); + } + + if ((pUsbK_Initialize = (UsbK_Initialize_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_Initialize")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_Initialize.\n"); + } + + if ((pUsbK_SelectInterface = (UsbK_SelectInterface_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_SelectInterface")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_SelectInterface.\n"); + } + + if ((pUsbK_GetAssociatedInterface = (UsbK_GetAssociatedInterface_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_GetAssociatedInterface")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_GetAssociatedInterface.\n"); + } + + if ((pUsbK_Clone = (UsbK_Clone_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_Clone")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_Clone.\n"); + } + + if ((pUsbK_QueryInterfaceSettings = (UsbK_QueryInterfaceSettings_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_QueryInterfaceSettings")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_QueryInterfaceSettings.\n"); + } + + if ((pUsbK_QueryDeviceInformation = (UsbK_QueryDeviceInformation_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_QueryDeviceInformation")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_QueryDeviceInformation.\n"); + } + + if ((pUsbK_SetCurrentAlternateSetting = (UsbK_SetCurrentAlternateSetting_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_SetCurrentAlternateSetting")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_SetCurrentAlternateSetting.\n"); + } + + if ((pUsbK_GetCurrentAlternateSetting = (UsbK_GetCurrentAlternateSetting_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_GetCurrentAlternateSetting")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_GetCurrentAlternateSetting.\n"); + } + + if ((pUsbK_QueryPipe = (UsbK_QueryPipe_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_QueryPipe")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_QueryPipe.\n"); + } + + if ((pUsbK_SetPipePolicy = (UsbK_SetPipePolicy_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_SetPipePolicy")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_SetPipePolicy.\n"); + } + + if ((pUsbK_GetPipePolicy = (UsbK_GetPipePolicy_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_GetPipePolicy")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_GetPipePolicy.\n"); + } + + if ((pUsbK_ReadPipe = (UsbK_ReadPipe_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_ReadPipe")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_ReadPipe.\n"); + } + + if ((pUsbK_WritePipe = (UsbK_WritePipe_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_WritePipe")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_WritePipe.\n"); + } + + if ((pUsbK_ResetPipe = (UsbK_ResetPipe_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_ResetPipe")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_ResetPipe.\n"); + } + + if ((pUsbK_AbortPipe = (UsbK_AbortPipe_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_AbortPipe")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_AbortPipe.\n"); + } + + if ((pUsbK_FlushPipe = (UsbK_FlushPipe_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_FlushPipe")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_FlushPipe.\n"); + } + + if ((pUsbK_IsoReadPipe = (UsbK_IsoReadPipe_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_IsoReadPipe")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_IsoReadPipe.\n"); + } + + if ((pUsbK_IsoWritePipe = (UsbK_IsoWritePipe_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_IsoWritePipe")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_IsoWritePipe.\n"); + } + + if ((pUsbK_GetCurrentFrameNumber = (UsbK_GetCurrentFrameNumber_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_GetCurrentFrameNumber")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_GetCurrentFrameNumber.\n"); + } + + if ((pUsbK_GetOverlappedResult = (UsbK_GetOverlappedResult_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_GetOverlappedResult")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_GetOverlappedResult.\n"); + } + + if ((pUsbK_GetProperty = (UsbK_GetProperty_T*)GetProcAddress(mLibusbK_ModuleHandle, "UsbK_GetProperty")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function UsbK_GetProperty.\n"); + } + + if ((pLstK_Init = (LstK_Init_T*)GetProcAddress(mLibusbK_ModuleHandle, "LstK_Init")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LstK_Init.\n"); + } + + if ((pLstK_InitEx = (LstK_InitEx_T*)GetProcAddress(mLibusbK_ModuleHandle, "LstK_InitEx")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LstK_InitEx.\n"); + } + + if ((pLstK_Free = (LstK_Free_T*)GetProcAddress(mLibusbK_ModuleHandle, "LstK_Free")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LstK_Free.\n"); + } + + if ((pLstK_Enumerate = (LstK_Enumerate_T*)GetProcAddress(mLibusbK_ModuleHandle, "LstK_Enumerate")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LstK_Enumerate.\n"); + } + + if ((pLstK_Current = (LstK_Current_T*)GetProcAddress(mLibusbK_ModuleHandle, "LstK_Current")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LstK_Current.\n"); + } + + if ((pLstK_MoveNext = (LstK_MoveNext_T*)GetProcAddress(mLibusbK_ModuleHandle, "LstK_MoveNext")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LstK_MoveNext.\n"); + } + + if ((pLstK_MoveReset = (LstK_MoveReset_T*)GetProcAddress(mLibusbK_ModuleHandle, "LstK_MoveReset")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LstK_MoveReset.\n"); + } + + if ((pLstK_FindByVidPid = (LstK_FindByVidPid_T*)GetProcAddress(mLibusbK_ModuleHandle, "LstK_FindByVidPid")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LstK_FindByVidPid.\n"); + } + + if ((pLstK_Count = (LstK_Count_T*)GetProcAddress(mLibusbK_ModuleHandle, "LstK_Count")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function LstK_Count.\n"); + } + + if ((pHotK_Init = (HotK_Init_T*)GetProcAddress(mLibusbK_ModuleHandle, "HotK_Init")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function HotK_Init.\n"); + } + + if ((pHotK_Free = (HotK_Free_T*)GetProcAddress(mLibusbK_ModuleHandle, "HotK_Free")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function HotK_Free.\n"); + } + + if ((pHotK_FreeAll = (HotK_FreeAll_T*)GetProcAddress(mLibusbK_ModuleHandle, "HotK_FreeAll")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function HotK_FreeAll.\n"); + } + + if ((pOvlK_Acquire = (OvlK_Acquire_T*)GetProcAddress(mLibusbK_ModuleHandle, "OvlK_Acquire")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function OvlK_Acquire.\n"); + } + + if ((pOvlK_Release = (OvlK_Release_T*)GetProcAddress(mLibusbK_ModuleHandle, "OvlK_Release")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function OvlK_Release.\n"); + } + + if ((pOvlK_Init = (OvlK_Init_T*)GetProcAddress(mLibusbK_ModuleHandle, "OvlK_Init")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function OvlK_Init.\n"); + } + + if ((pOvlK_Free = (OvlK_Free_T*)GetProcAddress(mLibusbK_ModuleHandle, "OvlK_Free")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function OvlK_Free.\n"); + } + + if ((pOvlK_GetEventHandle = (OvlK_GetEventHandle_T*)GetProcAddress(mLibusbK_ModuleHandle, "OvlK_GetEventHandle")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function OvlK_GetEventHandle.\n"); + } + + if ((pOvlK_Wait = (OvlK_Wait_T*)GetProcAddress(mLibusbK_ModuleHandle, "OvlK_Wait")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function OvlK_Wait.\n"); + } + + if ((pOvlK_WaitOldest = (OvlK_WaitOldest_T*)GetProcAddress(mLibusbK_ModuleHandle, "OvlK_WaitOldest")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function OvlK_WaitOldest.\n"); + } + + if ((pOvlK_WaitOrCancel = (OvlK_WaitOrCancel_T*)GetProcAddress(mLibusbK_ModuleHandle, "OvlK_WaitOrCancel")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function OvlK_WaitOrCancel.\n"); + } + + if ((pOvlK_WaitAndRelease = (OvlK_WaitAndRelease_T*)GetProcAddress(mLibusbK_ModuleHandle, "OvlK_WaitAndRelease")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function OvlK_WaitAndRelease.\n"); + } + + if ((pOvlK_IsComplete = (OvlK_IsComplete_T*)GetProcAddress(mLibusbK_ModuleHandle, "OvlK_IsComplete")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function OvlK_IsComplete.\n"); + } + + if ((pOvlK_ReUse = (OvlK_ReUse_T*)GetProcAddress(mLibusbK_ModuleHandle, "OvlK_ReUse")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function OvlK_ReUse.\n"); + } + + if ((pStmK_Init = (StmK_Init_T*)GetProcAddress(mLibusbK_ModuleHandle, "StmK_Init")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function StmK_Init.\n"); + } + + if ((pStmK_Free = (StmK_Free_T*)GetProcAddress(mLibusbK_ModuleHandle, "StmK_Free")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function StmK_Free.\n"); + } + + if ((pStmK_Start = (StmK_Start_T*)GetProcAddress(mLibusbK_ModuleHandle, "StmK_Start")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function StmK_Start.\n"); + } + + if ((pStmK_Stop = (StmK_Stop_T*)GetProcAddress(mLibusbK_ModuleHandle, "StmK_Stop")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function StmK_Stop.\n"); + } + + if ((pStmK_Read = (StmK_Read_T*)GetProcAddress(mLibusbK_ModuleHandle, "StmK_Read")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function StmK_Read.\n"); + } + + if ((pStmK_Write = (StmK_Write_T*)GetProcAddress(mLibusbK_ModuleHandle, "StmK_Write")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function StmK_Write.\n"); + } + + if ((pIsoK_Init = (IsoK_Init_T*)GetProcAddress(mLibusbK_ModuleHandle, "IsoK_Init")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function IsoK_Init.\n"); + } + + if ((pIsoK_Free = (IsoK_Free_T*)GetProcAddress(mLibusbK_ModuleHandle, "IsoK_Free")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function IsoK_Free.\n"); + } + + if ((pIsoK_SetPackets = (IsoK_SetPackets_T*)GetProcAddress(mLibusbK_ModuleHandle, "IsoK_SetPackets")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function IsoK_SetPackets.\n"); + } + + if ((pIsoK_SetPacket = (IsoK_SetPacket_T*)GetProcAddress(mLibusbK_ModuleHandle, "IsoK_SetPacket")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function IsoK_SetPacket.\n"); + } + + if ((pIsoK_GetPacket = (IsoK_GetPacket_T*)GetProcAddress(mLibusbK_ModuleHandle, "IsoK_GetPacket")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function IsoK_GetPacket.\n"); + } + + if ((pIsoK_EnumPackets = (IsoK_EnumPackets_T*)GetProcAddress(mLibusbK_ModuleHandle, "IsoK_EnumPackets")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function IsoK_EnumPackets.\n"); + } + + if ((pIsoK_ReUse = (IsoK_ReUse_T*)GetProcAddress(mLibusbK_ModuleHandle, "IsoK_ReUse")) == NULL) + { + funcLoadFailCount++; + OutputDebugStringA("Failed loading function IsoK_ReUse.\n"); + } + + + + /////////////////////////////////////////////////////////////////////// + + return funcLoadFailCount; +} + +// Function wrappers: + +KUSB_EXP VOID KUSB_API LibK_GetVersion(_out PKLIB_VERSION Version) +{ + pLibK_GetVersion(Version); +} + +KUSB_EXP KLIB_USER_CONTEXT KUSB_API LibK_GetContext( + _in KLIB_HANDLE Handle, + _in KLIB_HANDLE_TYPE HandleType) +{ + return pLibK_GetContext(Handle, HandleType); +} + +KUSB_EXP BOOL KUSB_API LibK_SetContext( + _in KLIB_HANDLE Handle, + _in KLIB_HANDLE_TYPE HandleType, + _in KLIB_USER_CONTEXT ContextValue) +{ + return pLibK_SetContext(Handle, HandleType, ContextValue); +} + +KUSB_EXP BOOL KUSB_API LibK_SetCleanupCallback( + _in KLIB_HANDLE Handle, + _in KLIB_HANDLE_TYPE HandleType, + _in KLIB_HANDLE_CLEANUP_CB* CleanupCB) +{ + return pLibK_SetCleanupCallback(Handle, HandleType, CleanupCB); +} + +KUSB_EXP BOOL KUSB_API LibK_LoadDriverAPI( + _out PKUSB_DRIVER_API DriverAPI, + _in INT DriverID) +{ + return pLibK_LoadDriverAPI(DriverAPI, DriverID); +} + +KUSB_EXP BOOL KUSB_API LibK_CopyDriverAPI( + _out PKUSB_DRIVER_API DriverAPI, + _in KUSB_HANDLE UsbHandle) +{ + return pLibK_CopyDriverAPI(DriverAPI, UsbHandle); +} + +KUSB_EXP BOOL KUSB_API LibK_GetProcAddress( + _out KPROC* ProcAddress, + _in INT DriverID, + _in INT FunctionID) +{ + return pLibK_GetProcAddress(ProcAddress, DriverID, FunctionID); +} + +KUSB_EXP BOOL KUSB_API LibK_SetDefaultContext( + _in KLIB_HANDLE_TYPE HandleType, + _in KLIB_USER_CONTEXT ContextValue) +{ + return pLibK_SetDefaultContext(HandleType, ContextValue); +} + +KUSB_EXP KLIB_USER_CONTEXT KUSB_API LibK_GetDefaultContext( + _in KLIB_HANDLE_TYPE HandleType) +{ + return pLibK_GetDefaultContext(HandleType); +} + +KUSB_EXP BOOL KUSB_API LibK_Context_Init( + _inopt HANDLE Heap, + _in PVOID Reserved) +{ + return pLibK_Context_Init(Heap, Reserved); +} + +KUSB_EXP VOID KUSB_API LibK_Context_Free(VOID) +{ + pLibK_Context_Free(); +} + +KUSB_EXP BOOL KUSB_API UsbK_Init ( + _out KUSB_HANDLE* InterfaceHandle, + _in KLST_DEVINFO_HANDLE DevInfo) +{ + return pUsbK_Init(InterfaceHandle, DevInfo); +} + +KUSB_EXP BOOL KUSB_API UsbK_Free ( + _in KUSB_HANDLE InterfaceHandle) +{ + return pUsbK_Free(InterfaceHandle); +} + +KUSB_EXP BOOL KUSB_API UsbK_ClaimInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex) +{ + return pUsbK_ClaimInterface(InterfaceHandle, NumberOrIndex, IsIndex); +} + +KUSB_EXP BOOL KUSB_API UsbK_ReleaseInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex) +{ + return pUsbK_ReleaseInterface(InterfaceHandle, NumberOrIndex, IsIndex); +} + +KUSB_EXP BOOL KUSB_API UsbK_SetAltInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex, + _in UCHAR AltSettingNumber) +{ + return pUsbK_SetAltInterface(InterfaceHandle, NumberOrIndex, IsIndex, AltSettingNumber); +} + +KUSB_EXP BOOL KUSB_API UsbK_GetAltInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex, + _out PUCHAR AltSettingNumber) +{ + return pUsbK_GetAltInterface(InterfaceHandle, NumberOrIndex, IsIndex, AltSettingNumber); +} + +KUSB_EXP BOOL KUSB_API UsbK_GetDescriptor ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR DescriptorType, + _in UCHAR Index, + _in USHORT LanguageID, + _out PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred) +{ + return pUsbK_GetDescriptor(InterfaceHandle, DescriptorType, Index, LanguageID, Buffer, BufferLength, LengthTransferred); +} + +KUSB_EXP BOOL KUSB_API UsbK_ControlTransfer ( + _in KUSB_HANDLE InterfaceHandle, + _in WINUSB_SETUP_PACKET SetupPacket, + _refopt PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred, + _inopt LPOVERLAPPED Overlapped) +{ + return pUsbK_ControlTransfer(InterfaceHandle, SetupPacket, Buffer, BufferLength, LengthTransferred, Overlapped); +} + +KUSB_EXP BOOL KUSB_API UsbK_SetPowerPolicy ( + _in KUSB_HANDLE InterfaceHandle, + _in UINT PolicyType, + _in UINT ValueLength, + _in PVOID Value) +{ + return pUsbK_SetPowerPolicy(InterfaceHandle, PolicyType, ValueLength, Value); +} + +KUSB_EXP BOOL KUSB_API UsbK_GetPowerPolicy ( + _in KUSB_HANDLE InterfaceHandle, + _in UINT PolicyType, + _ref PUINT ValueLength, + _out PVOID Value) +{ + return pUsbK_GetPowerPolicy(InterfaceHandle, PolicyType, ValueLength, Value); +} + +KUSB_EXP BOOL KUSB_API UsbK_SetConfiguration ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR ConfigurationNumber) +{ + return pUsbK_SetConfiguration(InterfaceHandle, ConfigurationNumber); +} + +KUSB_EXP BOOL KUSB_API UsbK_GetConfiguration ( + _in KUSB_HANDLE InterfaceHandle, + _out PUCHAR ConfigurationNumber) +{ + return pUsbK_GetConfiguration(InterfaceHandle, ConfigurationNumber); +} + +KUSB_EXP BOOL KUSB_API UsbK_ResetDevice ( + _in KUSB_HANDLE InterfaceHandle) +{ + return pUsbK_ResetDevice(InterfaceHandle); +} + +KUSB_EXP BOOL KUSB_API UsbK_Initialize ( + _in HANDLE DeviceHandle, + _out KUSB_HANDLE* InterfaceHandle) +{ + return pUsbK_Initialize(DeviceHandle, InterfaceHandle); +} + +KUSB_EXP BOOL KUSB_API UsbK_SelectInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR NumberOrIndex, + _in BOOL IsIndex) +{ + return pUsbK_SelectInterface(InterfaceHandle, NumberOrIndex, IsIndex); +} + +KUSB_EXP BOOL KUSB_API UsbK_GetAssociatedInterface ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AssociatedInterfaceIndex, + _out KUSB_HANDLE* AssociatedInterfaceHandle) +{ + return pUsbK_GetAssociatedInterface(InterfaceHandle, AssociatedInterfaceIndex, AssociatedInterfaceHandle); +} + +KUSB_EXP BOOL KUSB_API UsbK_Clone ( + _in KUSB_HANDLE InterfaceHandle, + _out KUSB_HANDLE* DstInterfaceHandle) +{ + return pUsbK_Clone(InterfaceHandle, DstInterfaceHandle); +} + +KUSB_EXP BOOL KUSB_API UsbK_QueryInterfaceSettings ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AltSettingIndex, + _out PUSB_INTERFACE_DESCRIPTOR UsbAltInterfaceDescriptor) +{ + return pUsbK_QueryInterfaceSettings(InterfaceHandle, AltSettingIndex, UsbAltInterfaceDescriptor); +} + +KUSB_EXP BOOL KUSB_API UsbK_QueryDeviceInformation ( + _in KUSB_HANDLE InterfaceHandle, + _in UINT InformationType, + _ref PUINT BufferLength, + _ref PVOID Buffer) +{ + return pUsbK_QueryDeviceInformation(InterfaceHandle, InformationType, BufferLength, Buffer); +} + +KUSB_EXP BOOL KUSB_API UsbK_SetCurrentAlternateSetting ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AltSettingNumber) +{ + return pUsbK_SetCurrentAlternateSetting(InterfaceHandle, AltSettingNumber); +} + +KUSB_EXP BOOL KUSB_API UsbK_GetCurrentAlternateSetting ( + _in KUSB_HANDLE InterfaceHandle, + _out PUCHAR AltSettingNumber) +{ + return pUsbK_GetCurrentAlternateSetting(InterfaceHandle, AltSettingNumber); +} + +KUSB_EXP BOOL KUSB_API UsbK_QueryPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR AltSettingNumber, + _in UCHAR PipeIndex, + _out PWINUSB_PIPE_INFORMATION PipeInformation) +{ + return pUsbK_QueryPipe(InterfaceHandle, AltSettingNumber, PipeIndex, PipeInformation); +} + +KUSB_EXP BOOL KUSB_API UsbK_SetPipePolicy ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in UINT PolicyType, + _in UINT ValueLength, + _in PVOID Value) +{ + return pUsbK_SetPipePolicy(InterfaceHandle, PipeID, PolicyType, ValueLength, Value); +} + +KUSB_EXP BOOL KUSB_API UsbK_GetPipePolicy ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in UINT PolicyType, + _ref PUINT ValueLength, + _out PVOID Value) +{ + return pUsbK_GetPipePolicy(InterfaceHandle, PipeID, PolicyType, ValueLength, Value); +} + +KUSB_EXP BOOL KUSB_API UsbK_ReadPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _out PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred, + _inopt LPOVERLAPPED Overlapped) +{ + return pUsbK_ReadPipe(InterfaceHandle, PipeID, Buffer, BufferLength, LengthTransferred, Overlapped); +} + +KUSB_EXP BOOL KUSB_API UsbK_WritePipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in PUCHAR Buffer, + _in UINT BufferLength, + _outopt PUINT LengthTransferred, + _inopt LPOVERLAPPED Overlapped) +{ + return pUsbK_WritePipe(InterfaceHandle, PipeID, Buffer, BufferLength, LengthTransferred, Overlapped); +} + +KUSB_EXP BOOL KUSB_API UsbK_ResetPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID) +{ + return pUsbK_ResetPipe(InterfaceHandle, PipeID); +} + +KUSB_EXP BOOL KUSB_API UsbK_AbortPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID) +{ + return pUsbK_AbortPipe(InterfaceHandle, PipeID); +} + +KUSB_EXP BOOL KUSB_API UsbK_FlushPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID) +{ + return pUsbK_FlushPipe(InterfaceHandle, PipeID); +} + +KUSB_EXP BOOL KUSB_API UsbK_IsoReadPipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _out PUCHAR Buffer, + _in UINT BufferLength, + _in LPOVERLAPPED Overlapped, + _refopt PKISO_CONTEXT IsoContext) +{ + return pUsbK_IsoReadPipe(InterfaceHandle, PipeID, Buffer, BufferLength, Overlapped, IsoContext); +} + +KUSB_EXP BOOL KUSB_API UsbK_IsoWritePipe ( + _in KUSB_HANDLE InterfaceHandle, + _in UCHAR PipeID, + _in PUCHAR Buffer, + _in UINT BufferLength, + _in LPOVERLAPPED Overlapped, + _refopt PKISO_CONTEXT IsoContext) +{ + return pUsbK_IsoWritePipe(InterfaceHandle, PipeID, Buffer, BufferLength, Overlapped, IsoContext); +} + +KUSB_EXP BOOL KUSB_API UsbK_GetCurrentFrameNumber ( + _in KUSB_HANDLE InterfaceHandle, + _out PUINT FrameNumber) +{ + return pUsbK_GetCurrentFrameNumber(InterfaceHandle, FrameNumber); +} + +KUSB_EXP BOOL KUSB_API UsbK_GetOverlappedResult ( + _in KUSB_HANDLE InterfaceHandle, + _in LPOVERLAPPED Overlapped, + _out PUINT lpNumberOfBytesTransferred, + _in BOOL bWait) +{ + return pUsbK_GetOverlappedResult(InterfaceHandle, Overlapped, lpNumberOfBytesTransferred, bWait); +} + +KUSB_EXP BOOL KUSB_API UsbK_GetProperty ( + _in KUSB_HANDLE InterfaceHandle, + _in KUSB_PROPERTY PropertyType, + _ref PUINT PropertySize, + _out PVOID Value) +{ + return pUsbK_GetProperty(InterfaceHandle, PropertyType, PropertySize, Value); +} + +KUSB_EXP BOOL KUSB_API LstK_Init( + _out KLST_HANDLE* DeviceList, + _in KLST_FLAG Flags) +{ + return pLstK_Init(DeviceList, Flags); +} + +KUSB_EXP BOOL KUSB_API LstK_InitEx( + _out KLST_HANDLE* DeviceList, + _in KLST_FLAG Flags, + _in PKLST_PATTERN_MATCH PatternMatch) +{ + return pLstK_InitEx(DeviceList, Flags, PatternMatch); +} + +KUSB_EXP BOOL KUSB_API LstK_Free( + _in KLST_HANDLE DeviceList) +{ + return pLstK_Free(DeviceList); +} + +KUSB_EXP BOOL KUSB_API LstK_Enumerate( + _in KLST_HANDLE DeviceList, + _in KLST_ENUM_DEVINFO_CB* EnumDevListCB, + _inopt PVOID Context) +{ + return pLstK_Enumerate(DeviceList, EnumDevListCB, Context); +} + +KUSB_EXP BOOL KUSB_API LstK_Current( + _in KLST_HANDLE DeviceList, + _out KLST_DEVINFO_HANDLE* DeviceInfo) +{ + return pLstK_Current(DeviceList, DeviceInfo); +} + +KUSB_EXP BOOL KUSB_API LstK_MoveNext( + _in KLST_HANDLE DeviceList, + _outopt KLST_DEVINFO_HANDLE* DeviceInfo) +{ + return pLstK_MoveNext(DeviceList, DeviceInfo); +} + +KUSB_EXP VOID KUSB_API LstK_MoveReset( + _in KLST_HANDLE DeviceList) +{ + pLstK_MoveReset(DeviceList); +} + +KUSB_EXP BOOL KUSB_API LstK_FindByVidPid( + _in KLST_HANDLE DeviceList, + _in INT Vid, + _in INT Pid, + _out KLST_DEVINFO_HANDLE* DeviceInfo) +{ + return pLstK_FindByVidPid(DeviceList, Vid, Pid, DeviceInfo); +} + +KUSB_EXP BOOL KUSB_API LstK_Count( + _in KLST_HANDLE DeviceList, + _ref PUINT Count) +{ + return pLstK_Count(DeviceList, Count); +} + +KUSB_EXP BOOL KUSB_API HotK_Init( + _out KHOT_HANDLE* Handle, + _ref PKHOT_PARAMS InitParams) +{ + return pHotK_Init(Handle, InitParams); +} + +KUSB_EXP BOOL KUSB_API HotK_Free( + _in KHOT_HANDLE Handle) +{ + return pHotK_Free(Handle); +} + +KUSB_EXP VOID KUSB_API HotK_FreeAll(VOID) +{ + pHotK_FreeAll(); +} + +KUSB_EXP BOOL KUSB_API OvlK_Acquire( + _out KOVL_HANDLE* OverlappedK, + _in KOVL_POOL_HANDLE PoolHandle) +{ + return pOvlK_Acquire(OverlappedK, PoolHandle); +} + +KUSB_EXP BOOL KUSB_API OvlK_Release( + _in KOVL_HANDLE OverlappedK) +{ + return pOvlK_Release(OverlappedK); +} + +KUSB_EXP BOOL KUSB_API OvlK_Init ( + _out KOVL_POOL_HANDLE* PoolHandle, + _in KUSB_HANDLE UsbHandle, + _in INT MaxOverlappedCount, + _inopt KOVL_POOL_FLAG Flags) +{ + return pOvlK_Init(PoolHandle, UsbHandle, MaxOverlappedCount, Flags); +} + +KUSB_EXP BOOL KUSB_API OvlK_Free( + _in KOVL_POOL_HANDLE PoolHandle) +{ + return pOvlK_Free(PoolHandle); +} + +KUSB_EXP HANDLE KUSB_API OvlK_GetEventHandle( + _in KOVL_HANDLE OverlappedK) +{ + return pOvlK_GetEventHandle(OverlappedK); +} + +KUSB_EXP BOOL KUSB_API OvlK_Wait( + _in KOVL_HANDLE OverlappedK, + _inopt INT TimeoutMS, + _inopt KOVL_WAIT_FLAG WaitFlags, + _out PUINT TransferredLength) +{ + return pOvlK_Wait(OverlappedK, TimeoutMS, WaitFlags, TransferredLength); +} + +KUSB_EXP BOOL KUSB_API OvlK_WaitOldest( + _in KOVL_POOL_HANDLE PoolHandle, + _outopt KOVL_HANDLE* OverlappedK, + _inopt INT TimeoutMS, + _inopt KOVL_WAIT_FLAG WaitFlags, + _out PUINT TransferredLength) +{ + return pOvlK_WaitOldest(PoolHandle, OverlappedK, TimeoutMS, WaitFlags, TransferredLength); +} + +KUSB_EXP BOOL KUSB_API OvlK_WaitOrCancel( + _in KOVL_HANDLE OverlappedK, + _inopt INT TimeoutMS, + _out PUINT TransferredLength) +{ + return pOvlK_WaitOrCancel(OverlappedK, TimeoutMS, TransferredLength); +} + +KUSB_EXP BOOL KUSB_API OvlK_WaitAndRelease( + _in KOVL_HANDLE OverlappedK, + _inopt INT TimeoutMS, + _out PUINT TransferredLength) +{ + return pOvlK_WaitAndRelease(OverlappedK, TimeoutMS, TransferredLength); +} + +KUSB_EXP BOOL KUSB_API OvlK_IsComplete( + _in KOVL_HANDLE OverlappedK) +{ + return pOvlK_IsComplete(OverlappedK); +} + +KUSB_EXP BOOL KUSB_API OvlK_ReUse( + _in KOVL_HANDLE OverlappedK) +{ + return pOvlK_ReUse(OverlappedK); +} + +KUSB_EXP BOOL KUSB_API StmK_Init( + _out KSTM_HANDLE* StreamHandle, + _in KUSB_HANDLE UsbHandle, + _in UCHAR PipeID, + _in INT MaxTransferSize, + _in INT MaxPendingTransfers, + _in INT MaxPendingIO, + _inopt PKSTM_CALLBACK Callbacks, + _inopt KSTM_FLAG Flags) +{ + return pStmK_Init(StreamHandle, UsbHandle, PipeID, MaxTransferSize, MaxPendingTransfers, MaxPendingIO, Callbacks, Flags); +} + +KUSB_EXP BOOL KUSB_API StmK_Free( + _in KSTM_HANDLE StreamHandle) +{ + return pStmK_Free(StreamHandle); +} + +KUSB_EXP BOOL KUSB_API StmK_Start( + _in KSTM_HANDLE StreamHandle) +{ + return pStmK_Start(StreamHandle); +} + +KUSB_EXP BOOL KUSB_API StmK_Stop( + _in KSTM_HANDLE StreamHandle, + _in INT TimeoutCancelMS) +{ + return pStmK_Stop(StreamHandle, TimeoutCancelMS); +} + +KUSB_EXP BOOL KUSB_API StmK_Read( + _in KSTM_HANDLE StreamHandle, + _out PUCHAR Buffer, + _in INT Offset, + _in INT Length, + _out PUINT TransferredLength) +{ + return pStmK_Read(StreamHandle, Buffer, Offset, Length, TransferredLength); +} + +KUSB_EXP BOOL KUSB_API StmK_Write( + _in KSTM_HANDLE StreamHandle, + _in PUCHAR Buffer, + _in INT Offset, + _in INT Length, + _out PUINT TransferredLength) +{ + return pStmK_Write(StreamHandle, Buffer, Offset, Length, TransferredLength); +} + +KUSB_EXP BOOL KUSB_API IsoK_Init( + _out PKISO_CONTEXT* IsoContext, + _in INT NumberOfPackets, + _inopt INT StartFrame) +{ + return pIsoK_Init(IsoContext, NumberOfPackets, StartFrame); +} + +KUSB_EXP BOOL KUSB_API IsoK_Free( + _in PKISO_CONTEXT IsoContext) +{ + return pIsoK_Free(IsoContext); +} + +KUSB_EXP BOOL KUSB_API IsoK_SetPackets( + _in PKISO_CONTEXT IsoContext, + _in INT PacketSize) +{ + return pIsoK_SetPackets(IsoContext, PacketSize); +} + +KUSB_EXP BOOL KUSB_API IsoK_SetPacket( + _in PKISO_CONTEXT IsoContext, + _in INT PacketIndex, + _in PKISO_PACKET IsoPacket) +{ + return pIsoK_SetPacket(IsoContext, PacketIndex, IsoPacket); +} + +KUSB_EXP BOOL KUSB_API IsoK_GetPacket( + _in PKISO_CONTEXT IsoContext, + _in INT PacketIndex, + _out PKISO_PACKET IsoPacket) +{ + return pIsoK_GetPacket(IsoContext, PacketIndex, IsoPacket); +} + +KUSB_EXP BOOL KUSB_API IsoK_EnumPackets( + _in PKISO_CONTEXT IsoContext, + _in KISO_ENUM_PACKETS_CB* EnumPackets, + _inopt INT StartPacketIndex, + _inopt PVOID UserState) +{ + return pIsoK_EnumPackets(IsoContext, EnumPackets, StartPacketIndex, UserState); +} + +KUSB_EXP BOOL KUSB_API IsoK_ReUse( + _ref PKISO_CONTEXT IsoContext) +{ + return pIsoK_ReUse(IsoContext); +} + + + +/////////////////////////////////////////////////////////////////////// diff --git a/Desktop_Interface/build_win/libusbk/includes/lusbk_dynapi.c.REMOVED.git-id b/Desktop_Interface/build_win/libusbk/includes/lusbk_dynapi.c.REMOVED.git-id deleted file mode 100644 index 0efb631b..00000000 --- a/Desktop_Interface/build_win/libusbk/includes/lusbk_dynapi.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3b414327d759fdb4927753daeab25ad6c3d00855 \ No newline at end of file diff --git a/Desktop_Interface/build_win/libusbk/includes/lusbk_shared.h b/Desktop_Interface/build_win/libusbk/includes/lusbk_shared.h new file mode 100644 index 00000000..ddfa3fa9 --- /dev/null +++ b/Desktop_Interface/build_win/libusbk/includes/lusbk_shared.h @@ -0,0 +1,309 @@ +/*! \file lusbk_shared.h +* \brief Types and defines shared with the driver. +*/ + +#ifndef __LUSBK_SHARED_H_ +#define __LUSBK_SHARED_H_ + +#ifndef __USB_H__ + +//! Values used in the \c bmAttributes field of a \ref USB_ENDPOINT_DESCRIPTOR +typedef enum _USBD_PIPE_TYPE +{ + //! Indicates a control endpoint + UsbdPipeTypeControl, + + //! Indicates an isochronous endpoint + UsbdPipeTypeIsochronous, + + //! Indicates a bulk endpoint + UsbdPipeTypeBulk, + + //! Indicates an interrupt endpoint + UsbdPipeTypeInterrupt, +} USBD_PIPE_TYPE; + +#endif + +#if !defined(__WINUSB_COMPAT_IO_H__) && !defined(__WUSBIO_H__) + +// pipe policy types /////////////// +#define SHORT_PACKET_TERMINATE 0x01 +#define AUTO_CLEAR_STALL 0x02 +#define PIPE_TRANSFER_TIMEOUT 0x03 +#define IGNORE_SHORT_PACKETS 0x04 +#define ALLOW_PARTIAL_READS 0x05 +#define AUTO_FLUSH 0x06 +#define RAW_IO 0x07 +#define MAXIMUM_TRANSFER_SIZE 0x08 +#define RESET_PIPE_ON_RESUME 0x09 + +// libusbK ISO pipe policy types /// +#define ISO_START_LATENCY 0x20 +#define ISO_ALWAYS_START_ASAP 0x21 +#define ISO_NUM_FIXED_PACKETS 0x22 + +// http://msdn.microsoft.com/en-us/library/windows/hardware/ff552359%28v=vs.85%29.aspx +// Settings.Parallel.NumberOfPresentedRequests +// Maximum number of transfers that can be asynchronously delivered at a +// time. Available in version 1.9 and later versions of KMDF. +#define SIMUL_PARALLEL_REQUESTS 0x30 + +// Power policy types ////////////// +#define AUTO_SUSPEND 0x81 +#define SUSPEND_DELAY 0x83 + +// Device Information types //////// +#define DEVICE_SPEED 0x01 + +// Device Speeds +#define LowSpeed 0x01 +#define FullSpeed 0x02 +#define HighSpeed 0x03 + +//! The \c WINUSB_PIPE_INFORMATION structure contains pipe information that the \ref UsbK_QueryPipe routine retrieves. +typedef struct _WINUSB_PIPE_INFORMATION +{ + //! A \c USBD_PIPE_TYPE enumeration value that specifies the pipe type + USBD_PIPE_TYPE PipeType; + + //! The pipe identifier (ID) + UCHAR PipeId; + + //! The maximum size, in bytes, of the packets that are transmitted on the pipe + USHORT MaximumPacketSize; + + //! The pipe interval + UCHAR Interval; + +} WINUSB_PIPE_INFORMATION; +//! Pointer to a \ref WINUSB_PIPE_INFORMATION structure +typedef WINUSB_PIPE_INFORMATION* PWINUSB_PIPE_INFORMATION; +C_ASSERT(sizeof(WINUSB_PIPE_INFORMATION) == 12); + +#include + +//! The \c WINUSB_SETUP_PACKET structure describes a USB setup packet. +/*! +* It is often more convient to use this structure in combination with a \ref KUSB_SETUP_PACKET. +* For example: +* \code + +* \endcode +*/ +typedef struct _WINUSB_SETUP_PACKET +{ + //! The request type. The values that are assigned to this member are defined in Table 9.2 of section 9.3 of the Universal Serial Bus (USB) specification (www.usb.org). + UCHAR RequestType; + + //! The device request. The values that are assigned to this member are defined in Table 9.3 of section 9.4 of the Universal Serial Bus (USB) specification. + UCHAR Request; + + //! The meaning of this member varies according to the request. For an explanation of this member, see the Universal Serial Bus (USB) specification. + USHORT Value; + + //! The meaning of this member varies according to the request. For an explanation of this member, see the Universal Serial Bus (USB) specification. + USHORT Index; + + //! The number of bytes to transfer. (not including the \c WINUSB_SETUP_PACKET itself) + USHORT Length; + +} WINUSB_SETUP_PACKET; +//! pointer to a \c WINUSB_SETUP_PACKET structure +typedef WINUSB_SETUP_PACKET* PWINUSB_SETUP_PACKET; +C_ASSERT(sizeof(WINUSB_SETUP_PACKET) == 8); + +#include + +#endif // __WUSBIO_H__ __WINUSB_COMPAT_IO_H__ + +#include + +/*! \addtogroup isok +* @{ +*/ + +//! Structure describing an isochronous transfer packet. +typedef struct _KISO_PACKET +{ + //! Specifies the offset, in bytes, of the buffer for this packet from the beginning of the entire isochronous transfer data buffer. + /*! + * \c Offset represents an absolute data offset from the start of the \c Buffer parameter \ref UsbK_IsoReadPipe or \ref UsbK_IsoWritePipe. + * + * \note This field is assigned by the user application only and used by the driver upon transfer submission and completion. + */ + UINT Offset; + + //! Set by the host controller to indicate the actual number of bytes received by the device for isochronous IN transfers. Length not used for isochronous OUT transfers. + /*! + * \note This field is is not user assignable and is updated by the driver upon transfer completion. + */ + USHORT Length; + + //! Contains the 16 least significant USBD status bits, on return from the host controller driver, of this transfer packet. + /*! + * See MSDN for USBD status codes: USBD status code reference + * + * \note This field is is not user assignable and is updated by the driver upon transfer completion. + */ + USHORT Status; + +} KISO_PACKET; +//! pointer to a \c KISO_PACKET structure +typedef KISO_PACKET* PKISO_PACKET; + +#pragma warning(disable:4200) + +//! Additional ISO transfer flags. +typedef enum _KISO_FLAG +{ + KISO_FLAG_NONE = 0, + + //! Do not start the transfer immediately, instead use \ref KISO_CONTEXT::StartFrame. + /*! + * By default, isochronous transfers start on the next frame and \ref KISO_CONTEXT::StartFrame is + * ignored. If this flag is specified, the transfer is postponed until the current usb frame number + * equals that specified by \ref KISO_CONTEXT::StartFrame. + * + * Under certain circumstances, the driver can specify 0 for \ref KISO_CONTEXT::StartFrame, and the bus + * driver will begin the transaction in the next available frame. + * + * Specifing \b 0 for \ref KISO_CONTEXT::StartFrame (start transfer ASAP) is restricted to the first + * transaction on a newly opened or reset pipe. Furthermore, the USB stack contains a bug in Microsoft + * Windows Server 2003 and Windows XP that limits the use of this to an isochronous context with 255 or fewer + * packets. + * + * For more information about resetting pipes, see \ref UsbK_ResetPipe. + */ + KISO_FLAG_SET_START_FRAME = 0x00000001, +} KISO_FLAG; + +//! Structure describing a user defined isochronous transfer. +/*! +* +* \fixedstruct{16} +* +* The \ref KISO_CONTEXT::StartFrame member of the \ref KISO_CONTEXT specifies the starting USB frame number +* for the transaction. The driver can use \ref UsbK_GetCurrentFrameNumber to request the current frame +* number. +* +* In full-speed transmissions, the frame number for any particular packet will be the sum of the start frame +* number and the packet index. For instance, the fourth packet in the \ref KISO_CONTEXT has an index of 3, so +* its frame number will be StartFrame + 3. In a write transfer, the port driver loads this frame with the +* buffer data at the data buffer offset specified by IsoPacket[3].Offset. +* +* When the driver processes the \ref KISO_CONTEXT, it discards all packets in the \ref KISO_CONTEXT whose +* frame numbers are lower than the current frame number. The port driver sets the Status member of the packet +* descriptor for each discarded packet to USBD_STATUS_ISO_NA_LATE_USBPORT, USBD_STATUS_ISO_NOT_ACCESSED_BY_HW +* or USBD_STATUS_ISO_NOT_ACCESSED_LATE. Even if it discards some packets, the port driver attempts to +* transmit those packets in the \ref KISO_CONTEXT whose frame numbers are higher than the current frame +* number. +* +* The check for a valid StartFrame member is slightly more complicated in high-speed transmissions because +* the port driver loads each packet into a high-speed microframe; however, the value in StartFrame refers to +* the 1 millisecond (full-speed) frame number, not the microframe. For example, if the StartFrame value +* recorded in the \ref KISO_CONTEXT is one less than the current frame, the port driver will discard as many +* as eight packets. The exact number of packets that the port driver discards depends on the period +* associated with the isochronous pipe. +* +* High-speed isochronous pipes can have periods of 1, 2, 4, or 8. The period number specifies the frequency +* with which the port driver inserts packets into the data stream. If the period is 2, for example, the port +* driver will insert a packet into the data stream every two microframes. This means that it will only use +* four of the eight microframes available within each 1-millisecond frame for isochronous data transmission. +* +* In general, the higher the period, the fewer packets the port driver will discard when a \ref KISO_CONTEXT +* arrives late. Assume the period on an isochronous pipe is 2. With a period of 2, each 1-millisecond speed +* frame will carry four packets of isochronous data for that pipe. So, for example, if CurrentFrame - +* StartFrame = 3, the port driver will discard 3 * 4 = 12 packets. On the other hand, if the period is 4, +* each 1-millisecond frame carries only two packets of isochronous data for the pipe. Therefore, if the +* \ref KISO_CONTEXT arrives three 1-millisecond frames late, as in the previous example, the port driver will +* discard 3 * 2 = 6 packets, instead of 12 packets. +* +* For all types of isochronous pipe, the distance between the current frame and the StartFrame value +* specified in the \ref KISO_CONTEXT must be less than USBD_ISO_START_FRAME_RANGE. If StartFrame is not +* within the proper range, the driver sets the Status member of the \ref KISO_PACKET +* \c USBD_STATUS_BAD_START_FRAME and discards the entire \ref KISO_CONTEXT. The following code example shows +* the precise check that the port driver does on the \ref KISO_CONTEXT start frame: +* \code +* if (abs((CurrentFrame - StartFrame)) > USBD_ISO_START_FRAME_RANGE) +* { +* // discard the KISO_CONTEXT +* } +* \endcode +* +*/ +typedef struct _KISO_CONTEXT +{ + //! Additional ISO transfer flags. See \ref KISO_FLAG. + KISO_FLAG Flags; + + //! Specifies the frame number that the transfer should begin on (0 for ASAP). + /*! + * This variable must be within a system-defined range of the current frame. The range is specified by the + * constant \ref USBD_ISO_START_FRAME_RANGE. + * + * If /ref KISO_FLAG_SET_START_FRAME was specified, this member contains the frame number that the transfer should begin on. + * When the request is returned by the host controller driver, this member is updated to reflect the frame number this transfer + * did begin on. + * + * \note This field may be assigned by the user application and is updated by the driver upon transfer + * completion. + */ + UINT StartFrame; + + //! Contains the number of packets that completed with an error condition on return from the host controller driver. + /*! + * \note This field is is not user assignable and is updated by the driver upon transfer completion. + */ + SHORT ErrorCount; + + //! Specifies the number of packets that are described by the variable-length array member \c IsoPacket. + /* + * \note This field is assigned by the user application only and used by the driver upon transfer submission + * and completion. + */ + SHORT NumberOfPackets; + + //! Contains the URB Hdr.Status value on return from the host controller driver. + /*! + * \note This field is is not user assignable and is updated by the driver upon transfer completion. + * + * The USB bus driver always returns a value of USBD_STATUS_SUCCESS in + * Hdr.Status, unless every packet in the transfer generated an error or + * the request was not well-formed and could not be executed at all. The + * following table includes possible error codes returned in Hdr.Status: + * - USBD_STATUS_ISOCH_REQUEST_FAILED + * Indicates that every packet of an isochronous request was completed with + * errors. + * - USBD_STATUS_BAD_START_FRAME + * Indicates that the requested start frame is not within + * USBD_ISO_START_FRAME_RANGE of the current USB frame. + * - USBD_ISO_NOT_ACCESSED_LATE + * Indicates that every packet was submitted too late for the packet to be + * sent, based on the requested start frame. + * - USBD_STATUS_INVALID_PARAMETER + * Indicates that one of the URB parameters was incorrect. + */ + UINT UrbHdrStatus; + + //! Contains a variable-length array of \c KISO_PACKET structures that describe the isochronous transfer packets to be transferred on the USB bus. + /* + * \note This field is assigned by the user application, used by the driver upon transfer submission, and + * updated by the driver upon transfer completion. + */ + KISO_PACKET IsoPackets[0]; + +} KISO_CONTEXT; +C_ASSERT(sizeof(KISO_CONTEXT) == 16); + +//! pointer to a \c KISO_CONTEXT structure +typedef KISO_CONTEXT* PKISO_CONTEXT; + +/*! @} */ + +#pragma warning(default:4200) + +#include + +#endif // __LUSBK_SHARED_H_ + diff --git a/Desktop_Interface/build_win/libusbk/includes/lusbk_shared.h.REMOVED.git-id b/Desktop_Interface/build_win/libusbk/includes/lusbk_shared.h.REMOVED.git-id deleted file mode 100644 index 803612dc..00000000 --- a/Desktop_Interface/build_win/libusbk/includes/lusbk_shared.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ddfa3fa9ee3b225f7f62f2f089d39b1fd0c3ca2c \ No newline at end of file diff --git a/Desktop_Interface/build_win/platformspecific.h b/Desktop_Interface/build_win/platformspecific.h new file mode 100644 index 00000000..da5c9d2c --- /dev/null +++ b/Desktop_Interface/build_win/platformspecific.h @@ -0,0 +1,10 @@ +#ifndef PLATFORMSPECIFIC_H +#define PLATFORMSPECIFIC_H + +#include "winusbdriver.h" +#define _PLATFORM_DEPENDENT_USB_OBJECT winUsbDriver +#define PLATFORM_WINDOWS +#define _PLATFORM_DEPENDENT_FOLDER_ACTION + + +#endif // PLATFORMSPECIFIC_H diff --git a/Desktop_Interface/build_win/platformspecific.h.REMOVED.git-id b/Desktop_Interface/build_win/platformspecific.h.REMOVED.git-id deleted file mode 100644 index 5c83c530..00000000 --- a/Desktop_Interface/build_win/platformspecific.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -da5c9d2c6e747ffe72824375351bc20cd9f96b13 \ No newline at end of file diff --git a/Desktop_Interface/cursorenabler.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/cursorenabler.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 30c811ec..00000000 --- a/Desktop_Interface/cursorenabler.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -16909ca49f69c3194fce8553a520f064696c5e22 \ No newline at end of file diff --git a/Desktop_Interface/cursorenabler.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/cursorenabler.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 78191383..00000000 --- a/Desktop_Interface/cursorenabler.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -496cd248c34c44884b581ff9f85738819257d5e2 \ No newline at end of file diff --git a/Desktop_Interface/desktop_settings.cpp b/Desktop_Interface/desktop_settings.cpp new file mode 100644 index 00000000..ea9a61aa --- /dev/null +++ b/Desktop_Interface/desktop_settings.cpp @@ -0,0 +1,28 @@ +#include "desktop_settings.h" + +//USB iso stuff +int MAX_TRANSFER_SIZE = 1023; +int MAX_PENDING_TRANSFERS = 512; +int MAX_PENDING_IO = 16; + +//Plot settings +int GRAPH_SAMPLES = 1024; +int TIMER_PERIOD = 17; +int ISO_RECOVERY_TIME = (200); +int MAX_WINDOW_SIZE = 10; +int TICK_SEPARATION = 96; + +//Multimeter settings +int MULTIMETER_PERIOD = 500; + +double SERIAL_DELAY = 0.01; //100 baud? + +QMutex tcBlockMutex; +QMutex unixDriverDeleteMutex; + +unsigned char expected_variant; + +#ifndef PLATFORM_WINDOWS +struct timeval tv; +#endif + diff --git a/Desktop_Interface/desktop_settings.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/desktop_settings.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 0e5afc39..00000000 --- a/Desktop_Interface/desktop_settings.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7fa176861d6907e271e5c4fa388c1acb6f693110 \ No newline at end of file diff --git a/Desktop_Interface/desktop_settings.h b/Desktop_Interface/desktop_settings.h new file mode 100644 index 00000000..2c29d780 --- /dev/null +++ b/Desktop_Interface/desktop_settings.h @@ -0,0 +1,48 @@ +#ifndef DESKTOP_SETTINGS_H +#define DESKTOP_SETTINGS_H + +#include + +//Just a whole lot of variables not directly related to xmega. + +//USB iso stuff +extern int MAX_TRANSFER_SIZE; +extern int MAX_PENDING_TRANSFERS; +extern int MAX_PENDING_IO; + +//Plot settings +extern int GRAPH_SAMPLES; +extern int TIMER_PERIOD; +extern int ISO_RECOVERY_TIME; +extern int MAX_WINDOW_SIZE; +extern int TICK_SEPARATION; +#define TRIGGER_COUNT_THRESH (7 + log10(window)) //Is this the right number? + +//Multimeter settings +extern int MULTIMETER_PERIOD; + +extern double SERIAL_DELAY; + +extern QMutex tcBlockMutex; +extern QMutex unixDriverDeleteMutex; +extern struct timeval tv; + +extern unsigned char expected_variant; + +#define DEBUG_SETTINGSDOTSET + +#define USB_RECONNECT_PERIOD 420 + +#define VALID_DATA_PER_375 375 + +#define VALID_DATA_PER_750 750 + +#define COLUMN_BREAK VALID_DATA_PER_750 + +//#define MAX_CONSOLE_BLOCK_COUNT 512 +#define SERIAL_BUFFER_LENGTH 8192 + +#define ANDROID_SCALE_INSENSITIVITY 1.2 + +#endif // DESKTOP_SETTINGS_H + diff --git a/Desktop_Interface/desktop_settings.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/desktop_settings.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 85777e9e..00000000 --- a/Desktop_Interface/desktop_settings.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f4d06a31a3f772ee96a213091197b6a5c6b66ad4 \ No newline at end of file diff --git a/Desktop_Interface/desktop_settings.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/desktop_settings.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index ee9753dc..00000000 --- a/Desktop_Interface/desktop_settings.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6df08bbf1d1106731ce0a088fdec8ac4be74525e \ No newline at end of file diff --git a/Desktop_Interface/desktop_settings.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/desktop_settings.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 76e7f802..00000000 --- a/Desktop_Interface/desktop_settings.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1d996ddd2f4c4aa60289aa8af3c69760324566f4 \ No newline at end of file diff --git a/Desktop_Interface/deviceconnecteddisplay.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/deviceconnecteddisplay.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index c9bcc0e6..00000000 --- a/Desktop_Interface/deviceconnecteddisplay.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a7e6780b18f19f636067f71b0709ded56a8038c0 \ No newline at end of file diff --git a/Desktop_Interface/deviceconnecteddisplay.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/deviceconnecteddisplay.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 53caba73..00000000 --- a/Desktop_Interface/deviceconnecteddisplay.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b6ce41ee819ea80b6256babc038a1c980d15601b \ No newline at end of file diff --git a/Desktop_Interface/espocombobox.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/espocombobox.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index c4bf1e04..00000000 --- a/Desktop_Interface/espocombobox.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8c0d75e037bcfc048070feac6bff6239fd69157f \ No newline at end of file diff --git a/Desktop_Interface/espocombobox.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/espocombobox.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index cd636a1b..00000000 --- a/Desktop_Interface/espocombobox.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -915a7de1d4888aa3cda0ccd52199d7f3dd012b47 \ No newline at end of file diff --git a/Desktop_Interface/esposlider.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/esposlider.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index cf2b1cb1..00000000 --- a/Desktop_Interface/esposlider.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9976e4860913162c81e12c1e46c1f693d202eb79 \ No newline at end of file diff --git a/Desktop_Interface/esposlider.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/esposlider.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 690be291..00000000 --- a/Desktop_Interface/esposlider.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -81e96fb74ea38c124a37a72c17882e8895efdebf \ No newline at end of file diff --git a/Desktop_Interface/espospinbox.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/espospinbox.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index c0afd0af..00000000 --- a/Desktop_Interface/espospinbox.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3b886df20ca5f00710e59b350a70c2ca9e9b68fe \ No newline at end of file diff --git a/Desktop_Interface/espospinbox.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/espospinbox.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index c0c9170d..00000000 --- a/Desktop_Interface/espospinbox.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -dbaf6ec51d533b50f9337974b7300d6f2917590d \ No newline at end of file diff --git a/Desktop_Interface/functiongencontrol.cpp b/Desktop_Interface/functiongencontrol.cpp new file mode 100644 index 00000000..54936d6b --- /dev/null +++ b/Desktop_Interface/functiongencontrol.cpp @@ -0,0 +1,234 @@ +#include "functiongencontrol.h" +#include "platformspecific.h" + + +functionGenControl::functionGenControl(QWidget *parent) : QLabel(parent) +{ + this->hide(); + samples_CH1 = (unsigned char *) malloc(0); + samples_CH2 = (unsigned char *) malloc(0); + +} + +void functionGenControl::waveformName_CH1(QString newName) +{ + qDebug() << "newName = " << newName; + newName.append(".tlw"); + + //QDir *dir = new QDir(); + //QString directory = dir->currentPath(); + +#ifdef PLATFORM_ANDROID + QString waveformFilePath("assets:/waveforms/"); + waveformFilePath.append(newName); + + QFile fptr(waveformFilePath); + bool success = fptr.open(QIODevice::ReadOnly); + + QByteArray line; + char lengthString[16]; + char divisibilityString[16]; + + line = fptr.readLine(); + strcpy(lengthString, line.data()); + sscanf(lengthString, "%d", &length_CH1); + qDebug() << "lengthString" << lengthString; + + line = fptr.readLine(); + strcpy(divisibilityString, line.data()); + sscanf(divisibilityString, "%d", &divisibility_CH1); + qDebug() << "divisibilityString" << divisibilityString; + + qDebug() << "Length = " << length_CH1; + qDebug() << "Divisibility = " << divisibility_CH1; + + QByteArray remainingData = fptr.readAll(); + char *dataString = remainingData.data(); + + free(samples_CH1); + samples_CH1 = (unsigned char *) malloc(length_CH1); + + int dummy; + char *dataStringCurrent = dataString; + for (int i=0;i>(divisibility_CH1-1))); + setMinFreq_CH1((double) CLOCK_FREQ/1024/65535/length_CH1); + functionGenToUpdate(0, this); +} + +void functionGenControl::freqUpdate_CH1(double newFreq){ + qDebug() << "newFreq = " << newFreq; + freq_CH1 = newFreq; + functionGenToUpdate(0, this); +} + +void functionGenControl::amplitudeUpdate_CH1(double newAmplitude){ + qDebug() << "newAmplitude = " << newAmplitude; + amplitude_CH1 = newAmplitude; + functionGenToUpdate(0, this); +} + +void functionGenControl::offsetUpdate_CH1(double newOffset){ + qDebug() << "newOffset = " << newOffset; + offset_CH1 = newOffset; + functionGenToUpdate(0, this); +} + +void functionGenControl::waveformName_CH2(QString newName) +{ + qDebug() << "newName = " << newName; + newName.append(".tlw"); + +#ifdef PLATFORM_ANDROID + QString waveformFilePath("assets:/waveforms/"); + waveformFilePath.append(newName); + + QFile fptr(waveformFilePath); + bool success = fptr.open(QIODevice::ReadOnly); + + QByteArray line; + char lengthString[16]; + char divisibilityString[16]; + + line = fptr.readLine(); + strcpy(lengthString, line.data()); + sscanf(lengthString, "%d", &length_CH2); + qDebug() << "lengthString" << lengthString; + + line = fptr.readLine(); + strcpy(divisibilityString, line.data()); + sscanf(divisibilityString, "%d", &divisibility_CH2); + qDebug() << "divisibilityString" << divisibilityString; + + qDebug() << "Length = " << length_CH2; + qDebug() << "Divisibility = " << divisibility_CH2; + + QByteArray remainingData = fptr.readAll(); + char *dataString = remainingData.data(); + + free(samples_CH2); + samples_CH2 = (unsigned char *) malloc(length_CH2); + + int dummy; + char *dataStringCurrent = dataString; + for (int i=0;i>(divisibility_CH2-1))); + setMinFreq_CH2((double) CLOCK_FREQ/1024/65535/length_CH2); + functionGenToUpdate(1, this); +} + +void functionGenControl::freqUpdate_CH2(double newFreq){ + qDebug() << "newFreq2 = " << newFreq; + freq_CH2 = newFreq; + functionGenToUpdate(1, this); +} + +void functionGenControl::amplitudeUpdate_CH2(double newAmplitude){ + qDebug() << "newAmplitude2 = " << newAmplitude; + amplitude_CH2 = newAmplitude; + functionGenToUpdate(1, this); +} + +void functionGenControl::offsetUpdate_CH2(double newOffset){ + qDebug() << "newOffset2 = " << newOffset; + offset_CH2 = newOffset; + functionGenToUpdate(1, this); +} diff --git a/Desktop_Interface/functiongencontrol.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/functiongencontrol.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 88aedb19..00000000 --- a/Desktop_Interface/functiongencontrol.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -869933074e623d2c021d3f6902d4cee9bd761745 \ No newline at end of file diff --git a/Desktop_Interface/functiongencontrol.h b/Desktop_Interface/functiongencontrol.h new file mode 100644 index 00000000..34be187f --- /dev/null +++ b/Desktop_Interface/functiongencontrol.h @@ -0,0 +1,39 @@ +#ifndef FUNCTIONGENCONTROL_H +#define FUNCTIONGENCONTROL_H + +#include +#include +#include +#include +#include +#include "xmega.h" +#include + +//functionGenControl is a centralised object to control all of the high-level function gen commands for both channels. + +class functionGenControl : public QLabel +{ + Q_OBJECT +public: + explicit functionGenControl(QWidget *parent = 0); + unsigned char *samples_CH1, *samples_CH2; + int length_CH1, divisibility_CH1, length_CH2, divisibility_CH2; + double freq_CH1 = 1000, amplitude_CH1 = 0, offset_CH1 = 0, freq_CH2 = 1000, amplitude_CH2 = 0, offset_CH2 = 0; +signals: + void functionGenToUpdate(int channel, functionGenControl *fGenControl); + void setMaxFreq_CH1(double maxFreq); + void setMinFreq_CH1(double minFreq); + void setMaxFreq_CH2(double maxFreq); + void setMinFreq_CH2(double minFreq); +public slots: + void waveformName_CH1(QString newName); + void freqUpdate_CH1(double newFreq); + void amplitudeUpdate_CH1(double newAmplitude); + void offsetUpdate_CH1(double newOffset); + void waveformName_CH2(QString newName); + void freqUpdate_CH2(double newFreq); + void amplitudeUpdate_CH2(double newAmplitude); + void offsetUpdate_CH2(double newOffset); +}; + +#endif // FUNCTIONGENCONTROL_H diff --git a/Desktop_Interface/functiongencontrol.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/functiongencontrol.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 4f152c44..00000000 --- a/Desktop_Interface/functiongencontrol.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9a2c1bf3007ab0d0cae64e131151f6cada462cdc \ No newline at end of file diff --git a/Desktop_Interface/functiongencontrol.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/functiongencontrol.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 33a3646b..00000000 --- a/Desktop_Interface/functiongencontrol.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -670ed68cea5fee8c6c45efdc3905e59ad56587a0 \ No newline at end of file diff --git a/Desktop_Interface/functiongencontrol.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/functiongencontrol.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 5d38abac..00000000 --- a/Desktop_Interface/functiongencontrol.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -34fdb4ab56df3ebe4a72e5a3d30ce1dac6abaff6 \ No newline at end of file diff --git a/Desktop_Interface/gahnooslashlinuxusbdriver.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/gahnooslashlinuxusbdriver.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 1fc2d1c6..00000000 --- a/Desktop_Interface/gahnooslashlinuxusbdriver.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7201b2744c84e38e914307d9a1ebbdebb664a380 \ No newline at end of file diff --git a/Desktop_Interface/genericusbdriver.cpp b/Desktop_Interface/genericusbdriver.cpp new file mode 100644 index 00000000..015d5f67 --- /dev/null +++ b/Desktop_Interface/genericusbdriver.cpp @@ -0,0 +1,409 @@ +#include "genericusbdriver.h" +#include "platformspecific.h" + +genericUsbDriver::genericUsbDriver(QWidget *parent) : QLabel(parent) +{ + connectedStatus(false); + qDebug() << "Making USB Driver invisible!!"; + this->hide(); + + //Double buffers are used to send the transfers to isoDriver. outBuffers and bufferLengths store the actual data from each transfer as well as length. They are read by isoDriver when it calls isoRead(). + outBuffers[0] = (unsigned char *) calloc(ISO_PACKET_SIZE*ISO_PACKETS_PER_CTX*NUM_ISO_ENDPOINTS + 8, 1); + outBuffers[1] = (unsigned char *) calloc(ISO_PACKET_SIZE*ISO_PACKETS_PER_CTX*NUM_ISO_ENDPOINTS + 8, 1); + bufferLengths[0] = 0; + bufferLengths[1] = 0; + + for(int k=0; kstop(); + recoveryTimer->stop(); + isoTimer->stop(); + delete(psuTimer); + delete(recoveryTimer); + delete(isoTimer); + } + qDebug() << "genericUsbDriver dectructor completed"; +} + + +void genericUsbDriver::setPsu(double voltage){ + + qDebug() << "New voltage =" << voltage; + currentPsuVoltage = voltage; + //if(deviceMode > 6) qFatal("setPsu is not configured for mode 7!!!"); + double vinp = voltage/11; + double vinn = 0; + //double vref = 1.65; + double gainPsu = 1; + + dutyPsu = (int) ((vinp - vinn)/vref * gainPsu * PSU_ADC_TOP); + + qDebug() << "Going to send value " << dutyPsu; +} + +void genericUsbDriver::setFunctionGen(int channel, functionGenControl *fGenControl){ + //////////////////////////// + ////NO RESIZING (YET)!!!//// + //////////////////////////// + + ////////////////////////////////////// + //// CH1 is AUX!! CH2 is "MAIN"!!//// + ////////////////////////////////////// + + int length, maxLength, numDivides, maxDivides; + double freq, amplitude, offset; + unsigned char *samples; + + //For recalling on crash. + if (channel == 0) fGenPtr_CH1 = fGenControl; + else fGenPtr_CH2 = fGenControl; + + //Reading in data + if (channel == 0){ + length = fGenControl->length_CH1; + freq = fGenControl->freq_CH1; + amplitude = fGenControl->amplitude_CH1; + offset = fGenControl->offset_CH1; + samples = (unsigned char *) malloc(length); + memcpy(samples, fGenControl->samples_CH1, (unsigned int) length); + numDivides = fGenControl->divisibility_CH1; + } + else if(channel == 1){ + length = fGenControl->length_CH2; + freq = fGenControl->freq_CH2; + amplitude = fGenControl->amplitude_CH2; + offset = fGenControl->offset_CH2; + samples = (unsigned char *) malloc(length); + memcpy(samples, fGenControl->samples_CH2, (unsigned int) length); + numDivides = fGenControl->divisibility_CH2; + } + + //Triple mode + if ((amplitude+offset) > FGEN_LIMIT){ + amplitude = amplitude / 3; + offset = offset / 3; + fGenTriple |= ((unsigned char) !channel + 1); + } + else fGenTriple &= ((unsigned char) (254 - !channel)); + + //qDebug() << "fGenTriple = " << fGenTriple << "fGenControl = " << fGenControl << "length = " << length << "freq = " << freq << "amplitude = " << amplitude << "offset = " << offset << "samples = " << samples; + + //Waveform scaling in V + double tempDouble; + amplitude = (amplitude * 255) / FGEN_LIMIT; + offset = (offset * 255) / FGEN_LIMIT; + if (offset5) + amplitude -= FGEN_OFFSET; + else + amplitude = 0; + offset = FGEN_OFFSET; + } + +#ifdef INVERT_TRIPLE + unsigned char fGenTemp = 0; + fGenTemp |= (fGenTriple & 0x01)<<1; + fGenTemp |= (fGenTriple & 0x02)>>1; + usbSendControl(0x40, 0xa4, fGenTemp, 0, 0, NULL); +#else + usbSendControl(0x40, 0xa4, fGenTriple, 0, 0, NULL); +#endif + + //Applying amplitude and offset to all samples. + for (int i=0;i DAC_SPS){ + loop_entered = true; + numDivides--; + if (numDivides==0){ + qDebug("numDivides = 0 - in T-stretching of genericUsbDriver:: setFunctionGen"); + } + + int shiftTemp = (maxDivides - numDivides); + length = length >> 1; + + free(tempSamples); + tempSamples = (unsigned char *) malloc(length); + for (int i=0; i 2) sendClearBuffer(1,0,0); + setVisible_CH2(0); + checkXY(0); + break; + case 1: + if(oldMode > 2) sendClearBuffer(1,0,0); + sendClearBuffer(0,1,0); + setVisible_CH2(1); + checkXY(0); + break; + case 2: + if(oldMode > 2) sendClearBuffer(1,0,0); + sendClearBuffer(0,1,0); + setVisible_CH2(1); + break; + case 3: + if(oldMode != 4) sendClearBuffer(1,0,0); + sendClearBuffer(0,1,0); + setVisible_CH2(0); + checkXY(0); + break; + case 4: + if(oldMode != 3) sendClearBuffer(1,0,0); + sendClearBuffer(0,1,0); + setVisible_CH2(1); + checkXY(0); + break; + case 5: + setVisible_CH2(0); + checkXY(0); + break; + case 6: + sendClearBuffer(0,0,1); + setVisible_CH2(0); + checkXY(0); + break; + case 7: + sendClearBuffer(1,0,0); + enableMMTimer(); + checkXY(0); + break; + default: + qFatal("Error in genericUsbDriver::setDeviceMode. Invalid device mode."); + } + +} + +void genericUsbDriver::psuTick(){ + if(dutyTemp == dutyPsu) return; + + if (dutyTemp > dutyPsu){ + if((dutyTemp - dutyPsu)> PSU_STEP){ + dutyTemp -= PSU_STEP; + } else dutyTemp = dutyPsu; + } + + if (dutyTemp < dutyPsu){ + if((dutyPsu - dutyTemp)> PSU_STEP){ + dutyTemp += PSU_STEP; + } else dutyTemp = dutyPsu; + } + + if ((dutyTemp>106) || (dutyTemp<21)){ + qDebug("PSU DUTY CYCLE of dutyTemp = %d OUT OF RANGE (could underflow on SOF)!!! ABORTING!!!", dutyTemp); + } + usbSendControl(0x40, 0xa3, dutyTemp, 0, 0, NULL); +} + +void genericUsbDriver::setGain(double newGain){ + if (newGain == scopeGain) return; //No update! + gainBuffers(scopeGain/newGain); + scopeGain = newGain; + //See XMEGA_AU Manual, page 359. ADC.CTRL.GAIN. + if(newGain==0.5) gainMask = 0x07; + else if (newGain == 1) gainMask = 0x00; + else if (newGain == 2) gainMask = 0x01; + else if (newGain == 4) gainMask = 0x02; + else if (newGain == 8) gainMask = 0x03; + else if (newGain == 16) gainMask = 0x04; + else if (newGain == 32) gainMask = 0x05; + else if (newGain == 64) gainMask = 0x06; + else qFatal("genericUsbDriver::setGain attempted to set invalid gain value"); + gainMask = gainMask << 2; + gainMask |= (gainMask << 8); + /* + * This bit had to be removed because Android doesn't like log2() + * if (newGain == 0.5){ + gainMask = 7<<2 | 7<<10; + } + else gainMask = (unsigned short)(log2(newGain))<<2 | (unsigned short)(log2(newGain))<<10; + */ + qDebug("newGain = %f", newGain); + qDebug("gainMask = %x", gainMask); + usbSendControl(0x40, 0xa5, deviceMode, gainMask, 0, NULL); +} + +void genericUsbDriver::avrDebug(void){ + usbSendControl(0xc0, 0xa0, 0, 0, sizeof(unified_debug), NULL); +#ifndef PLATFORM_ANDROID + unified_debug *udsPtr = (unified_debug *) inBuffer; + uint16_t trfcnt0 = (udsPtr->trfcntH0 << 8) + udsPtr->trfcntL0; + uint16_t trfcnt1 = (udsPtr->trfcntH1 << 8) + udsPtr->trfcntL1; + uint16_t medianTrfcnt = (udsPtr->medianTrfcntH << 8) + udsPtr->medianTrfcntL; + uint16_t outOfRange = (udsPtr->outOfRangeH << 8) + udsPtr->outOfRangeL; + uint16_t counter = (udsPtr->counterH << 8) + udsPtr->counterL; + uint16_t dma_ch0_cnt = (udsPtr->dma_ch0_cntH << 8) + udsPtr->dma_ch0_cntL; + uint16_t dma_ch1_cnt = (udsPtr->dma_ch1_cntH << 8) + udsPtr->dma_ch1_cntL; + + + qDebug("%s", udsPtr->header); + qDebug() << "trfcnt0 =" << trfcnt0; + qDebug() << "trfcnt1 =" << trfcnt1; + qDebug() << "medianTrfcnt =" << medianTrfcnt; + qDebug() << "outOfRange = " << outOfRange; + qDebug() << "counter = " << counter; + qDebug() << "calValNeg = " << udsPtr->calValNeg; + qDebug() << "calValPos = " << udsPtr->calValPos; qDebug() << "CALA = " << udsPtr->CALA; + qDebug() << "CALB = " << udsPtr->CALB; + qDebug() << "dma_ch0_cnt = " << dma_ch0_cnt; + qDebug() << "dma_ch1_cnt = " << dma_ch1_cnt; +#endif +} + +void genericUsbDriver::requestFirmwareVersion(void){ + usbSendControl(0xc0, 0xa8, 0, 0, 2, NULL); + firmver = *((unsigned short *) inBuffer); +} + +void genericUsbDriver::requestFirmwareVariant(void){ + usbSendControl(0xc0, 0xa9, 0, 0, 1, NULL); + variant = *((unsigned char *) inBuffer); +} + + +void genericUsbDriver::saveState(int *_out_deviceMode, double *_out_scopeGain, double *_out_currentPsuVoltage, int *_out_digitalPinState){ + *(_out_deviceMode) = deviceMode; + *(_out_scopeGain) = scopeGain; + *(_out_currentPsuVoltage) = currentPsuVoltage; + *(_out_digitalPinState) = digitalPinState; + return; +} + +void genericUsbDriver::checkConnection(){ + //This will connect to the board, then wait one more period before actually starting the stack. + if(!connected){ + qDebug() << "CHECKING CONNECTION!"; + connected = !(usbInit(BOARD_VID, BOARD_PID)); + qDebug() << "Connected"; + return; + } + connectTimer->stop(); + + requestFirmwareVersion(); + qDebug("BOARD IS RUNNING FIRMWARE VERSION 0x%04hx", firmver); + qDebug("EXPECTING FIRMWARE VERSION 0x%04hx", EXPECTED_FIRMWARE_VERSION); + requestFirmwareVariant(); + qDebug("FIRMWARE VARIANT = 0x%02hx", variant); + qDebug("EXPECTED VARIANT = 0x%02hx", DEFINED_EXPECTED_VARIANT); + + if((firmver != EXPECTED_FIRMWARE_VERSION) || (variant != DEFINED_EXPECTED_VARIANT)){ + qDebug() << "Unexpected Firmware!!"; + int flashRet = flashFirmware(); + connected = false; + connectTimer->start(); + return; + } + + qDebug() << "Connecting now!"; + + //This is the actual setup code. + connectTimer->stop(); + delete(connectTimer); + + connectedStatus(true); + + + setDeviceMode(deviceMode); + newDig(digitalPinState); + usbIsoInit(); + + psuTimer = new QTimer(); + psuTimer->setTimerType(Qt::PreciseTimer); + psuTimer->start(PSU_PERIOD); + connect(psuTimer, SIGNAL(timeout()), this, SLOT(psuTick())); + + if(killOnConnect) usbSendControl(0x40, 0xa7, 0, 0, 0, NULL); + + recoveryTimer = new QTimer(); + recoveryTimer->setTimerType(Qt::PreciseTimer); + recoveryTimer->start(RECOVERY_PERIOD); + connect(recoveryTimer, SIGNAL(timeout()), this, SLOT(recoveryTick())); + initialConnectComplete(); +} + +void genericUsbDriver::bootloaderJump(){ + usbSendControl(0x40, 0xa7, 1, 0, 0, NULL); +} + diff --git a/Desktop_Interface/genericusbdriver.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/genericusbdriver.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index e80bb688..00000000 --- a/Desktop_Interface/genericusbdriver.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -62530b6720ab2395386deacba73a167eef1de0fe \ No newline at end of file diff --git a/Desktop_Interface/genericusbdriver.h b/Desktop_Interface/genericusbdriver.h new file mode 100644 index 00000000..929c0cfa --- /dev/null +++ b/Desktop_Interface/genericusbdriver.h @@ -0,0 +1,125 @@ +#ifndef GENERICUSBDRIVER_H +#define GENERICUSBDRIVER_H + +#include +#include +#include +#include +#include +#include +#include + +#include "functiongencontrol.h" +#include "xmega.h" +#include "desktop_settings.h" +#include "buffercontrol.h" +#include "unified_debug_structure.h" + +#define EXPECTED_FIRMWARE_VERSION 0x0003 + +#ifdef BABABOOEY_BABABOOEY_HOWARD_STERNS_PENIS + #define DEFINED_EXPECTED_VARIANT 1 + #define ISO_PACKET_SIZE 125 + #define NUM_ISO_ENDPOINTS (6) +#else + #define DEFINED_EXPECTED_VARIANT 2 + #define ISO_PACKET_SIZE 750 + #define NUM_ISO_ENDPOINTS (1) +#endif + +#ifdef PLATFORM_WINDOWS +#define ISO_PACKETS_PER_CTX 17 +#define NUM_FUTURE_CTX 40 +#elif defined PLATFORM_RASPBERRY_PI +#define ISO_PACKETS_PER_CTX 66 //15fps... +#define NUM_FUTURE_CTX 4 +#else +#define ISO_PACKETS_PER_CTX 33 +#define NUM_FUTURE_CTX 4 +#endif +#define ISO_TIMER_PERIOD 1 +#define MAX_OVERLAP (NUM_FUTURE_CTX*NUM_ISO_ENDPOINTS + 1) + +#define RECOVERY_PERIOD 1000 +#define BOARD_VID 0x03eb +#define BOARD_PID 0xba94 + + +//genericUsbDriver handles the parts of the USB stack that are not platform-dependent. +//It exists as a superclass for winUsbDriver (on Windows) or unixUsbDriver (on Linux) + +class genericUsbDriver : public QLabel +{ + Q_OBJECT +public: + //State Vars + int deviceMode = INIT_DEVICE_MODE; + double scopeGain = 0.5; + int dutyTemp = 21; + bool killOnConnect = false; + //Generic Vars + unsigned char *outBuffers[2]; + unsigned int bufferLengths[2]; + bool connected = false; + //Generic Functions + explicit genericUsbDriver(QWidget *parent = 0); + ~genericUsbDriver(); + virtual char *isoRead(unsigned int *newLength) = 0; + void setBufferPtr(bufferControl *newPtr); + void saveState(int *_out_deviceMode, double *_out_scopeGain, double *_out_currentPsuVoltage, int *_out_digitalPinState); + virtual void usbSendControl(uint8_t RequestType, uint8_t Request, uint16_t Value, uint16_t Index, uint16_t Length, unsigned char *LDATA) = 0; +protected: + //State Vars + unsigned char fGenTriple=0; + unsigned short gainMask = 2056; + functionGenControl *fGenPtr_CH1 = NULL, *fGenPtr_CH2 = NULL; + int dutyPsu = 0; + double currentPsuVoltage; + int digitalPinState = 0; + unsigned char firmver = 0; + unsigned char variant = 0; + //Generic Vars + bufferControl *bufferPtr = NULL; + QTimer *psuTimer; + unsigned char pipeID[3]; + QTimer *isoTimer; + QTimer *connectTimer; + QTimer *recoveryTimer; + unsigned char currentWriteBuffer = 0; + unsigned long timerCount = 0; + unsigned char inBuffer[256]; + //Generic Functions + void requestFirmwareVersion(void); + void requestFirmwareVariant(void); + virtual unsigned char usbInit(unsigned long VIDin, unsigned long PIDin) = 0; + virtual unsigned char usbIsoInit(void) = 0; + virtual int flashFirmware(void) = 0; + uint8_t numero_uno = 1; +signals: + void sendClearBuffer(bool ch3751, bool ch3752, bool ch750); + void setVisible_CH2(bool visible); + void gainBuffers(double multiplier); + void disableWindow(bool enabled); + void enableMMTimer(); + void checkXY(bool); + void upTick(void); + void killMe(void); + void connectedStatus(bool status); + void initialConnectComplete(void); +public slots: + void setPsu(double voltage); + void setFunctionGen(int channel, functionGenControl *fGenControl); + void setDeviceMode(int mode); + void newDig(int digState); + void psuTick(void); + void setGain(double newGain); + void avrDebug(void); + virtual void isoTimerTick(void) = 0; + virtual void recoveryTick() = 0; + virtual void shutdownProcedure() = 0; + void checkConnection(); + void bootloaderJump(); +}; + + +#endif // GENERICUSBDRIVER_H diff --git a/Desktop_Interface/genericusbdriver.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/genericusbdriver.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index ceb1eb79..00000000 --- a/Desktop_Interface/genericusbdriver.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f163273c11a2d4a0d8fd84d2a324edb653fd5922 \ No newline at end of file diff --git a/Desktop_Interface/genericusbdriver.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/genericusbdriver.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 6437d139..00000000 --- a/Desktop_Interface/genericusbdriver.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5f600d0fd0d923cc1b52736733b08b14c0c53d6b \ No newline at end of file diff --git a/Desktop_Interface/genericusbdriver.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/genericusbdriver.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 48191e39..00000000 --- a/Desktop_Interface/genericusbdriver.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -eee2af9849300ec3e5875f32fa2466160577a8e1 \ No newline at end of file diff --git a/Desktop_Interface/isobuffer.cpp b/Desktop_Interface/isobuffer.cpp new file mode 100644 index 00000000..132a581d --- /dev/null +++ b/Desktop_Interface/isobuffer.cpp @@ -0,0 +1,439 @@ +#include "isobuffer.h" +#include "isodriver.h" + + +isoBuffer::isoBuffer(QWidget *parent, int bufferLen, isoDriver *caller, unsigned char channel_value) : QWidget(parent) +{ + buffer = (short *) calloc(bufferLen*2, sizeof(short)); + bufferEnd = bufferLen-1; + samplesPerSecond = (double) bufferLen/(double)21; + samplesPerSecond = samplesPerSecond/375*VALID_DATA_PER_375; + sampleRate_bit = samplesPerSecond * 8; + virtualParent = caller; + channel = channel_value; + + updateTimer = new QTimer(); + updateTimer->setTimerType(Qt::PreciseTimer); + updateTimer->start(CONSOLE_UPDATE_TIMER_PERIOD); + connect(updateTimer, SIGNAL(timeout()), this, SLOT(updateConsole())); + + serialBuffer = new isoBufferBuffer(SERIAL_BUFFER_LENGTH*2); + +} +void isoBuffer::openFile(QString newFile) +{ + if (fptr != NULL){ + fclose(fptr); + } + if (newFile.isEmpty()){ + fptr = NULL; + } + else { + QByteArray temp = newFile.toLatin1(); + char *fileName = temp.data(); + fptr = fopen(fileName, "w"); + if (fptr == NULL) qFatal("Null fptr in isoBuffer::openFile"); + qDebug() << "opening file" << fileName; + qDebug() << "fptr = " << fptr; + } +} + +void isoBuffer::writeBuffer_char(char* data, int len) +{ + double convertedSample; + for (int i=0; iwrite(numStr); + currentColumn++; + if (currentColumn > COLUMN_BREAK){ + currentFile->write("\n"); + currentColumn = 0; + } + + } + } + return; +} + +void isoBuffer::writeBuffer_short(short* data, int len) +{ + //for (int i=(len-1);i>-1;i--){ + for (int i=0; iopen(QIODevice::WriteOnly); + currentFile = file; + fileIOEnabled = true; + return; +} + +void isoBuffer::disableFileIO(){ + fileIOEnabled = false; + currentColumn = 0; + currentFile->close(); + return; +} + +double isoBuffer::sampleConvert(short sample, int TOP, bool AC){ + + double scope_gain = (double)(virtualParent->driver->scopeGain); + double voltageLevel; + + voltageLevel = (sample * (vcc/2)) / (frontendGain*scope_gain*TOP); + if (virtualParent->driver->deviceMode != 7) voltageLevel += voltage_ref; + #ifdef INVERT_MM + if(virtualParent->driver->deviceMode == 7) voltageLevel *= -1; + #endif + + if(AC){ + voltageLevel -= virtualParent->currentVmean; //This is old (1 frame in past) value and might not be good for signals with large variations in DC level (although the cap should filter that anyway)?? + } + return voltageLevel; +} + +void isoBuffer::updateConsole(){ + if(!newUartSymbol) return; + qDebug() << numCharsInBuffer; + + console -> setPlainText(QString::fromLocal8Bit(serialBuffer->get(numCharsInBuffer), numCharsInBuffer)); + if(serialAutoScroll){ + //http://stackoverflow.com/questions/21059678/how-can-i-set-auto-scroll-for-a-qtgui-qtextedit-in-pyqt4 DANKON + QTextCursor c = console->textCursor(); + c.movePosition(QTextCursor::End); + console->setTextCursor(c); + // txtedit.ensureCursorVisible(); // you might need this also + } + newUartSymbol = false; + //charPos = 0; +} + +void isoBuffer::serialDecode(double baudRate) +{ + double dist_seconds = (double)serialDistance()/sampleRate_bit; + double bitPeriod_seconds = 1/baudRate; + + if(channel == 1) console = console1; + else if(channel == 2) console = console2; + else qFatal("Nonexistant console requested in isoBuffer::serialDecode"); + + + while(dist_seconds > (bitPeriod_seconds + SERIAL_DELAY)){ + //Read next uart bit + unsigned char uart_bit = getNextUartBit(); + //Process it + if(uartTransmitting){ + decodeNextUartBit(uart_bit); + //qDebug() << "uart_bit = " << uart_bit; + } else{ + uartTransmitting = (uart_bit==1) ? false : true; + jitterCompensationNeeded = true; + //if(uartTransmitting) qDebug() << "Decoding symbol!"; + } + //Update the pointer, accounting for jitter + updateSerialPtr(baudRate, uart_bit); + //Calculate stopping condition + dist_seconds = (double)serialDistance()/sampleRate_bit; + } + //qDebug() << "\n\n\n\n\n"; +} + +int isoBuffer::serialDistance() +{ + int back_bit = back * 8; + int bufferEnd_bit = bufferEnd * 8; + if(back_bit >= serialPtr_bit){ + return back_bit - serialPtr_bit; + }else return bufferEnd_bit - serialPtr_bit + back_bit; +} + +void isoBuffer::updateSerialPtr(double baudRate, unsigned char current_bit) +{ + if(jitterCompensationNeeded && uartTransmitting){ + jitterCompensationNeeded = jitterCompensationProcedure(baudRate, current_bit); + //qDebug() << "JitterCompensation Needed?" << jitterCompensationNeeded; + } + + int distance_between_bits = sampleRate_bit/baudRate; + if(uartTransmitting){ + serialPtr_bit += distance_between_bits; + } else serialPtr_bit += (distance_between_bits - 1); //Less than one baud period so that it will always see that start bit. + + if (serialPtr_bit > (bufferEnd * 8)){ + serialPtr_bit -= (bufferEnd * 8); + } +} + +unsigned char isoBuffer::getNextUartBit(){ + int coord_byte = serialPtr_bit/8; + int coord_bit = serialPtr_bit - (8*coord_byte); + unsigned char dataByte = buffer[coord_byte]; + unsigned char mask = (1 << coord_bit); + return ((dataByte & mask) ? 1 : 0); +} + +void isoBuffer::decodeNextUartBit(unsigned char bitValue) +{ + if(dataBit_current == dataBit_max){ + if(numCharsInBufferadd(currentUartSymbol); + currentUartSymbol = 0; + dataBit_current = 0; + uartTransmitting = false; + newUartSymbol = true; + return; + } + //else + currentUartSymbol |= (bitValue << dataBit_current); + dataBit_current++; +} + +bool isoBuffer::jitterCompensationProcedure(double baudRate, unsigned char current_bit){ + + if(current_bit !=0){ + //qDebug() << "Current bit not zero!!"; + return true; + } + + int left_coord = serialPtr_bit - sampleRate_bit/baudRate; + if (left_coord < 0){ + return true; //Don't want to read out of bounds!! + } + + unsigned char left_byte = (buffer[left_coord/8] & 0xff); + //qDebug() << "current_bit" << current_bit; + //qDebug() << "left_byte" << left_byte; + + if(left_byte > 0){ + //qDebug() << "Recalibration Opportunity"; + unsigned char temp_bit = 0; + //Go back to 1-0 transition point + while(!temp_bit){ + temp_bit = getNextUartBit(); + serialPtr_bit--; + } + //Jump by half a uart bit period. + serialPtr_bit += (sampleRate_bit/baudRate)/2; + return false; + } + + return true; +} + +short isoBuffer::inverseSampleConvert(double voltageLevel, int TOP, bool AC){ + + double scope_gain = (double)(virtualParent->driver->scopeGain); + short sample; + + if(AC){ + voltageLevel += virtualParent->currentVmean; //This is old (1 frame in past) value and might not be good for signals with large variations in DC level (although the cap should filter that anyway)?? + } +#ifdef INVERT_MM + if(virtualParent->driver->deviceMode == 7) voltageLevel *= -1; +#endif + if (virtualParent->driver->deviceMode != 7) voltageLevel -= voltage_ref; + + //voltageLevel = (sample * (vcc/2)) / (frontendGain*scope_gain*TOP); + sample = (voltageLevel * (frontendGain*scope_gain*TOP))/(vcc/2); + return sample; +} + +#define NUM_SAMPLES_SEEKING_CAP (20) + +#ifdef INVERT_MM + #define X0_COMPARISON_CAP > + #define X1_X2_COMPARISON_CAP < +#else + #define X0_COMPARISON_CAP < + #define X1_X2_COMPARISON_CAP > +#endif + + +int isoBuffer::cap_x0fromLast(double seconds, double vbot){ + int samplesInPast = seconds * samplesPerSecond; + if(back < samplesInPast){ + return -1; //too hard, not really important + } + short vbot_s = inverseSampleConvert(vbot, 2048, 0); + qDebug() << "vbot_s (x0) = " << vbot_s; + + int num_found = 0; + for(int i=samplesInPast; i; i--){ + short currentSample = buffer[back - i]; + if(currentSample X0_COMPARISON_CAP vbot_s){ + num_found++; + } else num_found--; + if(num_found < 0){ + num_found = 0; + } + if (num_found > NUM_SAMPLES_SEEKING_CAP){ + return samplesInPast-i; + } + } + return -1; +} + +int isoBuffer::cap_x1fromLast(double seconds, int x0, double vbot){ + int samplesInPast = seconds * samplesPerSecond; + samplesInPast -= x0; + if(back < samplesInPast){ + return -1; //too hard, not really important + } + short vbot_s = inverseSampleConvert(vbot, 2048, 0); + qDebug() << "vbot_s (x1) = " << vbot_s; + + int num_found = 0; + for(int i=samplesInPast; i; i--){ + short currentSample = buffer[back - i]; + if(currentSample X1_X2_COMPARISON_CAP vbot_s){ + num_found++; + } else num_found--; + if(num_found < 0){ + num_found = 0; + } + if (num_found > NUM_SAMPLES_SEEKING_CAP){ + return samplesInPast-i + x0; + } + + } + return -1; +} + +int isoBuffer::cap_x2fromLast(double seconds, int x1, double vtop){ + int samplesInPast = seconds * samplesPerSecond; + samplesInPast -= x1; + if(back < samplesInPast){ + return -1; //too hard, not really important + } + short vtop_s = inverseSampleConvert(vtop, 2048, 0); + qDebug() << "vtop_s (x2) = " << vtop_s; + + int num_found = 0; + for(int i=samplesInPast; i; i--){ + short currentSample = buffer[back - i]; + if(currentSample X1_X2_COMPARISON_CAP vtop_s){ + num_found++; + } else num_found--; + if(num_found < 0){ + num_found = 0; + } + if (num_found > NUM_SAMPLES_SEEKING_CAP){ + return samplesInPast-i + x1; + } + } + return -1; +} + + + + diff --git a/Desktop_Interface/isobuffer.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/isobuffer.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index af71f8d4..00000000 --- a/Desktop_Interface/isobuffer.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -965177869cc8e3a1360efe237913aec9312d26b4 \ No newline at end of file diff --git a/Desktop_Interface/isobuffer.h b/Desktop_Interface/isobuffer.h new file mode 100644 index 00000000..5679f963 --- /dev/null +++ b/Desktop_Interface/isobuffer.h @@ -0,0 +1,86 @@ +#ifndef ISOBUFFER_H +#define ISOBUFFER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xmega.h" +#include "desktop_settings.h" +#include "isobufferbuffer.h" +#include "genericusbdriver.h" + + +class isoDriver; + +//isoBuffer is a generic class that enables O(1) read times (!!!) on all read/write operations, while maintaining a huge buffer size. +//Imagine it as a circular buffer, but with access functions specifically designed for isochronous data from an Xmega. + +#define CONSOLE_UPDATE_TIMER_PERIOD (ISO_PACKETS_PER_CTX * 2) + +class isoBuffer : public QWidget +{ + Q_OBJECT +public: + isoBuffer(QWidget *parent = 0, int bufferLen = 0, isoDriver *caller = 0, unsigned char channel_value = 0); + //Generic Functions + void openFile(QString newFile); + void writeBuffer_char(char *data, int len); + void writeBuffer_short(short *data, int len); + short *readBuffer(double sampleWindow, int numSamples, bool singleBit, double delayOffset); + void clearBuffer(); + void gainBuffer(int gain_log); + void glitchInsert(short type); + void serialDecode(double baudRate); + int serialDistance(); + double sampleConvert(short sample, int TOP, bool AC); + short inverseSampleConvert(double voltageLevel, int TOP, bool AC); + int cap_x0fromLast(double seconds, double vbot); + int cap_x1fromLast(double seconds, int x0, double vbot); + int cap_x2fromLast(double seconds, int x1, double vtop); + //Generic Vars + QPlainTextEdit *console, *console1, *console2; + bool serialAutoScroll = true; + unsigned char channel = 255; + QTimer *updateTimer; + double voltage_ref = 1.65; + double frontendGain = (R4 / (R3 + R4)); + int samplesPerSecond; +private: + //Generic Vars + short *buffer, *readData = NULL; + int bufferEnd, back = 0; + int sampleRate_bit; + bool firstTime = true; + //File I/O + bool fileIOEnabled = false; + FILE* fptr = NULL; + QFile *currentFile; + isoDriver *parent; + unsigned int currentColumn = 0; + isoDriver *virtualParent; + //Serial Decode + int serialPtr_bit = 0; + bool uartTransmitting = false; + isoBufferBuffer *serialBuffer; + bool newUartSymbol = false; + int dataBit_current = 0, dataBit_max = 7; + int numCharsInBuffer = 0; + unsigned short currentUartSymbol = 0; + bool jitterCompensationNeeded = true; + void updateSerialPtr(double baudRate, unsigned char current_bit); + unsigned char getNextUartBit(); + void decodeNextUartBit(unsigned char bitValue); + bool jitterCompensationProcedure(double baudRate, unsigned char current_bit); +public slots: + void enableFileIO(QFile *file); + void disableFileIO(); + void updateConsole(); +}; + +#endif // ISOBUFFER_H diff --git a/Desktop_Interface/isobuffer.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/isobuffer.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 3ef89983..00000000 --- a/Desktop_Interface/isobuffer.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3ab576b9f29ebd765049c9b4e7ac2da1282fadfe \ No newline at end of file diff --git a/Desktop_Interface/isobuffer.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/isobuffer.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 95c890e5..00000000 --- a/Desktop_Interface/isobuffer.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ad55a4a0bf031d04353c7eec0cfcd3152ed0b524 \ No newline at end of file diff --git a/Desktop_Interface/isobuffer.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/isobuffer.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 75a3eea7..00000000 --- a/Desktop_Interface/isobuffer.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -36f5813bdda621d938d21fc823d2bc9ba8d222cd \ No newline at end of file diff --git a/Desktop_Interface/isobufferbuffer.cpp b/Desktop_Interface/isobufferbuffer.cpp new file mode 100644 index 00000000..2d6e44e2 --- /dev/null +++ b/Desktop_Interface/isobufferbuffer.cpp @@ -0,0 +1,25 @@ +#include "isobufferbuffer.h" + +isoBufferBuffer::isoBufferBuffer(int length) +{ + bufferLength = length; + mid = length/2; + buffer = (char *) malloc((length * 3) / 2); +} + +void isoBufferBuffer::add(char newChar){ + buffer[ptr] = newChar; + if(ptr= bufferLength){ + ptr = 0; + } + else ptr++; +} + +char *isoBufferBuffer::get(int length){ + if (length>mid) qFatal("isoBuffer::get; length requested is too high."); + if(ptr +#include + +class isoBufferBuffer +{ +public: + isoBufferBuffer(int length); + void add(char newChar); + char *get(int length); +private: + int bufferLength; + int mid; + int ptr; + char *buffer; +}; + +#endif // ISOBUFFERBUFFER_H diff --git a/Desktop_Interface/isobufferbuffer.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/isobufferbuffer.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index cb3b4631..00000000 --- a/Desktop_Interface/isobufferbuffer.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -239a1235cfeb471f1657b91d7418d30b190a9ebc \ No newline at end of file diff --git a/Desktop_Interface/isobufferbuffer.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/isobufferbuffer.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index bddd096f..00000000 --- a/Desktop_Interface/isobufferbuffer.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -390a6f153065fbed7ba6a75b16c94d08d0a1671b \ No newline at end of file diff --git a/Desktop_Interface/isobufferbuffer.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/isobufferbuffer.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 54807e26..00000000 --- a/Desktop_Interface/isobufferbuffer.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c3080ab7009fd2e35e183bbae8372e131ce51012 \ No newline at end of file diff --git a/Desktop_Interface/isodriver.cpp b/Desktop_Interface/isodriver.cpp new file mode 100644 index 00000000..c1c8f939 --- /dev/null +++ b/Desktop_Interface/isodriver.cpp @@ -0,0 +1,1230 @@ +#include "isodriver.h" +#include "isobuffer.h" +#include "platformspecific.h" +#include + + +isoDriver::isoDriver(QWidget *parent) : QLabel(parent) +{ + this->hide(); + internalBuffer375_CH1 = new isoBuffer(this, MAX_WINDOW_SIZE*ADC_SPS/20*21, this, 1); + internalBuffer375_CH2 = new isoBuffer(this, MAX_WINDOW_SIZE*ADC_SPS/20*21, this, 1); + internalBuffer750 = new isoBuffer(this, MAX_WINDOW_SIZE*ADC_SPS/10*21, this, 1); + + isoTemp = (char *) malloc(TIMER_PERIOD*ADC_SPF + 8); //8-byte header contains (unsigned long) length + + char volts[2] = "V"; + char seconds[2] = "s"; + char hertz[3] = "Hz"; + + v0 = new siprint(volts, 1234); + v1 = new siprint(volts, 0); + dv = new siprint(volts, 0); + t0 = new siprint(seconds, 0); + t1 = new siprint(seconds, 0); + dt = new siprint(seconds, 0); + f = new siprint(hertz, 0); + + startTimer(); + + slowTimer = new QTimer; + slowTimer->setTimerType(Qt::PreciseTimer); + slowTimer->start(MULTIMETER_PERIOD); + connect(slowTimer, SIGNAL(timeout()), this, SLOT(slowTimerTick())); +} + +void isoDriver::setDriver(genericUsbDriver *newDriver){ + driver = newDriver; + qDebug() << "driver = " << driver; +} + +void isoDriver::setAxes(QCustomPlot *newAxes){ + axes = newAxes; + qDebug() << "axes = " << axes; +} + +void isoDriver::setWindow(int newWindow){ + window = pow( (double)10, ( (double)newWindow / 10) ); + windowAtPause = window; + qDebug() << "window = " << window; +} + +void isoDriver::timerTick(void){ + //qDebug() << "isoDriver SEZ Tick!"; + if(firstFrame){ + autoGain(); + firstFrame = false; + } + + isoTemp = driver->isoRead(&length); + //qDebug() << length << "read in!!"; + total_read += length; + + if (length==0){ + //Zero length packet means something's gone wrong. Probably a disconnect. + qDebug() << "Zero length iso packet!"; + //driver->killMe(); + return; + } + + switch(driver->deviceMode){ + case 0: + frameActionGeneric(1,0); + break; + case 1: + internalBuffer375_CH2->channel = 1; + frameActionGeneric(1,2); + if(serialDecodeEnabled_CH1){ + internalBuffer375_CH2->serialDecode(baudRate_CH1); + } + break; + case 2: + frameActionGeneric(1,1); + break; + case 3: + frameActionGeneric(2,0); + if(serialDecodeEnabled_CH1){ + internalBuffer375_CH1->serialDecode(baudRate_CH1); + } + break; + case 4: + internalBuffer375_CH2->channel = 2; + frameActionGeneric(2,2); + if(serialDecodeEnabled_CH1){ + internalBuffer375_CH1->serialDecode(baudRate_CH1); + } + if(serialDecodeEnabled_CH2){ + internalBuffer375_CH2->serialDecode(baudRate_CH2); + } + break; + case 5: + break; + case 6: + frameActionGeneric(-1,0); + break; + case 7: + multimeterAction(); + break; + default: + qFatal("Error in isoDriver::timerTick. Invalid device mode."); + } + //free(isoTemp); +} + +void isoDriver::analogConvert(short *shortPtr, QVector *doublePtr, int TOP, bool AC, int channel){ + + double scope_gain = (double)(driver->scopeGain); + double accumulated = 0; + currentVmax = -20; + currentVmin = 20; + + double ref = (channel == 1 ? ch1_ref : ch2_ref); + double frontendGain = (channel == 1 ? frontendGain_CH1 : frontendGain_CH2); + + double *data = doublePtr->data(); + for (int i=0;ideviceMode != 7) data[i] += ref; + #ifdef INVERT_MM + if(driver->deviceMode == 7) data[i] *= -1; + #endif + + accumulated += data[i]; + if (data[i] > currentVmax) currentVmax = data[i]; + if (data[i] < currentVmin) currentVmin = data[i]; + } + currentVmean = accumulated / GRAPH_SAMPLES; + if(AC){ + for (int i=0;i *doublePtr){ + + double *data = doublePtr->data(); + double top = topRange - (topRange - botRange)/10; + double bot = botRange + (topRange - botRange)/10; + for (int i=0;isetTimerType(Qt::PreciseTimer); + isoTimer->start(TIMER_PERIOD); + connect(isoTimer, SIGNAL(timeout()), this, SLOT(timerTick())); + //qFatal("ISO TIMER STARTED");*/ +} + +void isoDriver::clearBuffers(bool ch3751, bool ch3752, bool ch750){ + if(ch3751) internalBuffer375_CH1->clearBuffer(); + if(ch3752) internalBuffer375_CH2->clearBuffer(); + if(ch750) internalBuffer750->clearBuffer(); +} + +void isoDriver::setVisible_CH2(bool visible){ + axes->graph(1)->setVisible(visible); +} + +void isoDriver::setVoltageRange(QWheelEvent *event){ + if(doNotTouchGraph == true) return; + + if (!(event->modifiers() == Qt::ControlModifier)){ + double c = (topRange - botRange) / (double)400; + + QCPRange range = axes->yAxis->range(); + + double pixPct = (double)100 - ((double)100 * (((double)axes->yAxis->pixelToCoord(event->y())-range.lower) / (double)(range.upper - range.lower))); + if (pixPct<0) pixPct = 0; + if (pixPct>100) pixPct = 100; + + + qDebug() << "WHEEL @ " << pixPct << "%"; + qDebug() << range.upper; + //qDebug() << event->delta(); + + if (event->delta()==120){ + topRange -= c* ((double)pixPct); + botRange += c* ((double)100 - (double)pixPct); + } + else{ + topRange += c* ((double)pixPct); + botRange -= c* ((double)100 - (double)pixPct); + } + + if (topRange > (double)20) topRange = (double)20; + if (botRange <- (double)20) botRange = (double)-20; + if (autoGainEnabled && !properlyPaused()) autoGain(); + } + else if(properlyPaused()){ + double c = (window) / (double)200; + QCPRange range = axes->xAxis->range(); + + double pixPct = (double)100 * (((double)axes->xAxis->pixelToCoord(event->x())-range.lower) / (double)(range.upper - range.lower)); + if (pixPct<0) pixPct = 0; + if (pixPct>100) pixPct = 100; + + qDebug() << "WHEEL @ " << pixPct << "%"; + qDebug() << event->delta(); + + if (event->delta()==120){ + window -= c* ((double)pixPct); + delay += c* ((double)100 - (double)pixPct) * pixPct/100; + } + else{ + window += c* ((double)pixPct); + delay -= c* ((double)100 - (double)pixPct) * pixPct/100; + } + + if (window > (double)MAX_WINDOW_SIZE) window = (double)MAX_WINDOW_SIZE; + if ((window + delay) > MAX_WINDOW_SIZE) delay -= window + delay - (double)MAX_WINDOW_SIZE; + if (delay < 0) delay = 0; + qDebug() << window << delay; + } else { + qDebug() << "TIGGERED"; + double c = (window) / (double)200; + QCPRange range = axes->xAxis->range(); + + double pixPct = (double)100 * (((double)axes->xAxis->pixelToCoord(event->x())-range.lower) / (double)(window)); + if (pixPct<0) pixPct = 0; + if (pixPct>100) pixPct = 100; + + qDebug() << "WHEEL @ " << pixPct << "%"; + qDebug() << event->delta(); + qDebug() << "upper = " << range.upper << "lower = " << range.lower; + qDebug() << "triggerDelay = " << triggerDelay; + qDebug() << "window = " << window; + qDebug() << c* ((double)pixPct); + qDebug() << c* ((double)100 - (double)pixPct) * pixPct/100; + + if (event->delta()==120){ + window -= c* ((double)pixPct); + delay += c* ((double)100 - (double)pixPct) * pixPct/100; + } + else{ + window += c* ((double)pixPct); + delay -= c* ((double)100 - (double)pixPct) * pixPct/100; + } + + if (window > (double)MAX_WINDOW_SIZE) window = (double)MAX_WINDOW_SIZE; + if ((window + delay) > MAX_WINDOW_SIZE) delay -= window + delay - (double)MAX_WINDOW_SIZE; + if (delay < 0) delay = 0; + windowAtPause = window; + qDebug() << window << delay; + } + //changeTimeAxis(event->delta()==-120); + //qDebug() << window; +} + +bool isoDriver::properlyPaused(){ + if(paused_CH1 & paused_CH2){ + qDebug() << "Properly paused"; + return true; + } + if ((driver->deviceMode == 0) || (driver->deviceMode == 3) || (driver->deviceMode == 6)){ + if(paused_CH1) qDebug() << "Properly paused"; else qDebug() << "Not properly paused"; + return paused_CH1; + } + if(paused_multimeter){ + qDebug() << "Properly paused"; + return true; + } + qDebug() << "Not properly paused"; + return false; +} + +void isoDriver::pauseEnable_CH1(bool enabled){ + paused_CH1 = enabled; + + if(!properlyPaused()) { + delay = 0; + if (autoGainEnabled) autoGain(); + //window = windowAtPause; + } + + if(!enabled) clearBuffers(1,0,1); + qDebug() << "pauseEnable_CH1" << enabled; +} + + +void isoDriver::pauseEnable_CH2(bool enabled){ + paused_CH2 = enabled; + + if(!properlyPaused()){ + delay = 0; + if (autoGainEnabled) autoGain(); + //window = windowAtPause; + } + + if(!enabled) clearBuffers(0,1,0); +} + +void isoDriver::pauseEnable_multimeter(bool enabled){ + paused_multimeter = enabled; + + if(!properlyPaused()) { + delay = 0; + //window = windowAtPause; + } + + if(!enabled) clearBuffers(1,0,0); + qDebug() << "pauseEnable_multimeter" << enabled; +} + + +void isoDriver::autoGain(){ + double maxgain = vcc / (2 * ((double)topRange - vref) * R4/(R3+R4)); + double mingain = vcc / (2 * ((double)botRange - vref) * R4/(R3+R4)); + maxgain = fmin(fabs(mingain) * 0.98, fabs(maxgain) * 0.98); + + double snap[8] = {64, 32, 16, 8, 4, 2, 1, 0.5}; + + for (int i=0;i<8;i++){ + if (maxgain>snap[i]){ + setGain(snap[i]); + return; + } + } +} + +void isoDriver::gainBuffers(double multiplier){ + multi = multiplier; + QTimer::singleShot(TIMER_PERIOD*4, this, SLOT(gainTick())); +} + +void isoDriver::gainTick(void){ +#ifdef PLATFORM_ANDROID +#warning: "gainTick does nothing on Android!!" +#else + qDebug() << "Multiplying by " << multi; + if (driver->deviceMode <5) internalBuffer375_CH1->gainBuffer(log2(multi)); + if ((driver->deviceMode == 1) | (driver->deviceMode == 2) | (driver->deviceMode == 4)) internalBuffer375_CH2->gainBuffer(log2(multi)); + if ((driver->deviceMode == 6) | (driver->deviceMode == 7)) internalBuffer750->gainBuffer(log2(multi)); +#endif +} + +void isoDriver::setAutoGain(bool enabled){ + autoGainEnabled = enabled; + if(enabled){ + autoGain(); + } +} + +void isoDriver::graphMousePress(QMouseEvent *event){ + qDebug() << event->button(); + if (horiCursorEnabled && (event->button() == Qt::LeftButton)){ + placingHoriAxes = true; + y0 = axes->yAxis->pixelToCoord(event->y()); +#ifndef PLATFORM_ANDROID + }else if(vertCursorEnabled && (event->button() == Qt::RightButton)){ +#else + }if(vertCursorEnabled){ +#endif + placingVertAxes = true; + x0 = axes->xAxis->pixelToCoord(event->x()); + } + qDebug() << "x0 =" << x0 << "x1 =" << x1 << "y0 =" << y0 << "y1 =" << y1; +} + +void isoDriver::graphMouseRelease(QMouseEvent *event){ + if(horiCursorEnabled && placingHoriAxes && (event->button() == Qt::LeftButton)){ + placingHoriAxes = false; +#ifndef PLATFORM_ANDROID + } else if (vertCursorEnabled && placingVertAxes && (event->button() == Qt::RightButton)){ +#else + } if (vertCursorEnabled && placingVertAxes){ +#endif + placingVertAxes = false; + } + qDebug() << "x0 =" << x0 << "x1 =" << x1 << "y0 =" << y0 << "y1 =" << y1; +} + +void isoDriver::graphMouseMove(QMouseEvent *event){ + if(horiCursorEnabled && placingHoriAxes){ + y1 = axes->yAxis->pixelToCoord(event->y()); +#ifndef PLATFORM_ANDROID + } else if(vertCursorEnabled && placingVertAxes){ +#else + } if(vertCursorEnabled && placingVertAxes){ +#endif + x1 = axes->xAxis->pixelToCoord(event->x()); + } +} + +void isoDriver::cursorEnableHori(bool enabled){ + horiCursorEnabled = enabled; + axes->graph(4)->setVisible(enabled); + axes->graph(5)->setVisible(enabled); +} + +void isoDriver::cursorEnableVert(bool enabled){ + vertCursorEnabled = enabled; + axes->graph(2)->setVisible(enabled); + axes->graph(3)->setVisible(enabled); +} + +void isoDriver::udateCursors(void){ + if(!(vertCursorEnabled || horiCursorEnabled)){ +#if QCP_VER == 1 + cursorTextPtr->setVisible(0); +#endif + return; + } + + QVector vert0x(2), vert1x(2), hori0x(2), hori1x(2), vert0y(2), vert1y(2), hori0y(2), hori1y(2); + + vert0x[0] = x0; + vert0x[1] = x0; + vert0y[0] = botRange; + vert0y[1] = topRange; + + vert1x[0] = x1; + vert1x[1] = x1; + vert1y[0] = botRange; + vert1y[1] = topRange; + + hori0x[0] = -window - delay; + hori0x[1] = -delay; + hori0y[0] = y0; + hori0y[1] = y0; + + hori1x[0] = -window - delay; + hori1x[1] = -delay; + hori1y[0] = y1; + hori1y[1] = y1; + + if(vertCursorEnabled){ + axes->graph(2)->setData(vert0x, vert0y); + axes->graph(3)->setData(vert1x, vert1y); + } + if(horiCursorEnabled){ + axes->graph(4)->setData(hori0x, hori0y); + axes->graph(5)->setData(hori1x, hori1y); + } +#if QCP_VER == 1 + cursorTextPtr->setVisible(cursorStatsEnabled); +#endif + if (!cursorStatsEnabled) return; + + QString *cursorStatsString = new QString(); + + v0->value = y0; + v1->value = y1; + dv->value = y0-y1; + t0->value = x0; + t1->value = x1; + dt->value = fabs(x0-x1); + f->value = 1/(x1-x0); + + char temp_hori[64]; + char temp_vert[64]; + char temp_separator[2]; + sprintf(temp_hori, "V0=%s, V1=%s, ΔV=%s", v0->printVal(), v1->printVal(), dv->printVal()); + sprintf(temp_vert, "t0=%s, t1=%s, Δt=%s, f=%s", t0->printVal(), t1->printVal(), dt->printVal(), f->printVal()); + sprintf(temp_separator, "\n"); + + //sprintf(temp, "hello!"); + if(horiCursorEnabled) cursorStatsString->append(temp_hori); + if(horiCursorEnabled && vertCursorEnabled) cursorStatsString->append(temp_separator); + if(vertCursorEnabled) cursorStatsString->append(temp_vert); + //qDebug() << temp; +#if QCP_VER == 1 + cursorTextPtr->setText(*(cursorStatsString)); +#endif + delete cursorStatsString; +} + +int isoDriver::trigger(void){ + if(driver->deviceMode>2 && driver->deviceMode < 6){ //No scope + return -2; + } + if(triggerType>1 && driver->deviceMode!=2){ //No CH2! + return -1; + } + + bool AC = (triggerType > 1) ? AC_CH2 : AC_CH1; + double offsetMean = AC ? currentVmean : 0; + + short target = (triggerType%2) ? reverseFrontEnd(triggerLevel*1.1 + offsetMean) : reverseFrontEnd(triggerLevel + offsetMean); + short lowThresh = (triggerType%2) ? reverseFrontEnd(triggerLevel + offsetMean) : reverseFrontEnd(triggerLevel*0.9 + offsetMean); + + int location = -1; + + if(driver->deviceMode == 7){ + for (unsigned int i=0;i= VALID_DATA_PER_750) continue; //Not a valid sample + + //A bit of thresholding... + //Gives DAT STABILITY + + //qDebug() << isoTemp_short[i+4]; + + if(isoTemp_short[i] >= target){ + triggerCountSeeking = (triggerType % 2) ? 0 : triggerCountSeeking + 1; + triggerCountNotSeeking = (triggerType % 2) ? triggerCountNotSeeking + 1 : 0; + } + else if (isoTemp_short[i] < lowThresh){ + triggerCountNotSeeking = (triggerType % 2) ? 0 : triggerCountNotSeeking + 1; + triggerCountSeeking = (triggerType % 2) ? triggerCountSeeking + 1 : 0; + } + else{ + triggerCountSeeking = 0; + triggerCountNotSeeking = 0; + } + + //Check for found + if(triggerSeeking && (triggerCountSeeking > TRIGGER_COUNT_THRESH)){ + if(location == -1) location = i; + triggerSeeking = false; + } + + //Check for lost + if((!triggerSeeking) && (triggerCountNotSeeking > TRIGGER_COUNT_THRESH)){ + triggerSeeking = true; + } + } + } + else{ + for (unsigned int i=0;ideviceMode != 6){ + if(((i%750 > VALID_DATA_PER_375) && (triggerType<2)) || (((i%750 < 375) || (i%750 == VALID_DATA_PER_750)) && (triggerType>1))) continue; //Not a valid sample + } + + //A bit of thresholding... + //Gives DAT STABILITY + + if(isoTemp[i] >= target){ + triggerCountSeeking = (triggerType % 2) ? 0 : triggerCountSeeking + 1; + triggerCountNotSeeking = (triggerType % 2) ? triggerCountNotSeeking + 1 : 0; + } + else if (isoTemp[i] < lowThresh){ + triggerCountNotSeeking = (triggerType % 2) ? 0 : triggerCountNotSeeking + 1; + triggerCountSeeking = (triggerType % 2) ? triggerCountSeeking + 1 : 0; + } + else{ + triggerCountSeeking = 0; + triggerCountNotSeeking = 0; + } + + //Check for found + if(triggerSeeking && (triggerCountSeeking > TRIGGER_COUNT_THRESH)){ + if(location == -1) location = i; + triggerSeeking = false; + } + + //Check for lost + if((!triggerSeeking) && (triggerCountNotSeeking > TRIGGER_COUNT_THRESH)){ + triggerSeeking = true; + } + } + } + + if(singleShotEnabled && (location != -1)) { + delay = triggerDelay; + singleShotTriggered(1); + } + return location; +} + +short isoDriver::reverseFrontEnd(double voltage){ + //qFatal("reverseFrontEnd driver mode 7"); + #ifdef INVERT_MM + if(driver->deviceMode == 7) voltage *= -1; + #endif + + + double vn = vcc * (R2/(R1+R2)); + double vx = vn + (voltage - vn) * (R4 / (R3+R4)); + double TOP = (driver->deviceMode == 7) ? 2048 : 128; + + if (driver->deviceMode == 7){ + qDebug() << "SEEEKING"; + qDebug() << ((vx - vn)/vref * (double)driver->scopeGain * (double)TOP + (double)0.5); + qDebug() << "SEEEKING"; + return ((vx - vn)/vref * (double)driver->scopeGain * (double)TOP + (double)0.5); + } + + //qDebug() << "seeking" << voltage << "V"; + + + return ((vx - vn)/vref * (double)driver->scopeGain * (double)TOP + (double)0.5); +} + +void isoDriver::setTriggerEnabled(bool enabled){ + triggerEnabled = enabled; +} + +void isoDriver::setTriggerLevel(double level){ + triggerLevel = level; +} + +void isoDriver::setSingleShotEnabled(bool enabled){ + singleShotEnabled = enabled; +} + +void isoDriver::setTriggerMode(int newMode){ + triggerType = (triggerType_enum)newMode; +} + +void isoDriver::frameActionGeneric(char CH1_mode, char CH2_mode) //0 for off, 1 for ana, 2 for dig, -1 for ana750 +{ + //qDebug() << "made it to frameActionGeneric"; + if(!paused_CH1 && CH1_mode == - 1){ + for (unsigned int i=0;i<(length/ADC_SPF);i++){ + internalBuffer750->writeBuffer_char(&isoTemp[ADC_SPF*i], VALID_DATA_PER_750); + } + } + + if(!paused_CH1 && CH1_mode > 0){ + for (unsigned int i=0;i<(length/ADC_SPF);i++){ + internalBuffer375_CH1->writeBuffer_char(&isoTemp[ADC_SPF*i], VALID_DATA_PER_375); + } + } + + if(!paused_CH2 && CH2_mode > 0){ + for (unsigned int i=0;i<(length/ADC_SPF);i++){ + internalBuffer375_CH2->writeBuffer_char(&isoTemp[ADC_SPF*i+ADC_SPF/2], VALID_DATA_PER_375); //+375 to get the second half of the packet + } + } + + if(!paused_CH1){ + int offset = -2; //No trigger! + if(triggerEnabled && (triggerWaiting == 0) ){ + offset = trigger(); + } + if(offset == -1){ //Trigger is active but nothing found! + return; + } + + //qDebug() << "offset =" << offset; + + int backLength = length/750; + backLength *= (CH1_mode == -1) ? VALID_DATA_PER_750 : VALID_DATA_PER_375; + + if(offset>0){ + int temp_offset = offset % 750; + offset /= 750; + offset *= (CH1_mode == -1) ? VALID_DATA_PER_750 : VALID_DATA_PER_375; + offset += temp_offset; + } + + //qDebug() << "Now offset = " << offset; + + if((!paused_CH1) && triggerEnabled && (triggerWaiting == 0)){ + triggerDelay = backLength - offset; + triggerDelay /= (CH1_mode == -1) ? (VALID_DATA_PER_750 * 1000) : (VALID_DATA_PER_375*1000); + triggerDelay += delay; + triggerWaiting = (triggerDelay<(window/2)) * 2; + } + + //qDebug() << "triggerDelay = " << triggerDelay; + + //qDebug() << "triggerWaiting =" << triggerWaiting; + + if(triggerWaiting == 1) triggerWaiting = 0; + + //qDebug() << "triggerWaiting =" << triggerWaiting; + + if(triggerEnabled && triggerWaiting){ + triggerDelay += (double)TIMER_PERIOD/(double)1000; + triggerWaiting = (triggerDelay<(window/2)) + 1; + return; + } + } + + readData375_CH1 = internalBuffer375_CH1->readBuffer(window,GRAPH_SAMPLES,CH1_mode==2, delay + ((triggerEnabled&&!paused_CH1) ? triggerDelay + window/2 : 0)); + if(CH2_mode) readData375_CH2 = internalBuffer375_CH2->readBuffer(window,GRAPH_SAMPLES,CH2_mode==2, delay + (triggerEnabled ? triggerDelay + window/2 : 0)); + if(CH1_mode == -1) readData750 = internalBuffer750->readBuffer(window,GRAPH_SAMPLES,false, delay + (triggerEnabled ? triggerDelay + window/2 : 0)); + + + //qDebug() << "Trigger Delay =" << triggerDelay; + + QVector x(GRAPH_SAMPLES), CH1(GRAPH_SAMPLES), CH2(GRAPH_SAMPLES); + + + if (CH1_mode == 1){ + analogConvert(readData375_CH1, &CH1, 128, AC_CH1, 1); + xmin = (currentVmin < xmin) ? currentVmin : xmin; + xmax = (currentVmax > xmax) ? currentVmax : xmax; + broadcastStats(0); + } + if (CH1_mode == 2) digitalConvert(readData375_CH1, &CH1); + + if (CH2_mode == 1){ + analogConvert(readData375_CH2, &CH2, 128, AC_CH2, 2); + ymin = (currentVmin < ymin) ? currentVmin : ymin; + ymax = (currentVmax > ymax) ? currentVmax : ymax; + broadcastStats(1); + } + if (CH2_mode == 2) digitalConvert(readData375_CH2, &CH2); + + if(CH1_mode == -1) { + analogConvert(readData750, &CH1, 128, AC_CH1, 1); + xmin = (currentVmin < xmin) ? currentVmin : xmin; + xmax = (currentVmax > xmax) ? currentVmax : xmax; + broadcastStats(0); + } + + for (double i=0; i0) { + CH1[i] = 0; + CH2[i] = 0; + } + } + + udateCursors(); + + if(XYmode){ + axes->graph(0)->setData(CH1,CH2); + axes->xAxis->setRange(xmin, xmax); + axes->yAxis->setRange(ymin, ymax); + }else{ + axes->graph(0)->setData(x,CH1); + if(CH2_mode) axes->graph(1)->setData(x,CH2); + axes->xAxis->setRange(-window-delay,-delay); + axes->yAxis->setRange(topRange, botRange); + } + + if(snapshotEnabled){ + snapshotFile_CH1->open(QIODevice::WriteOnly); + snapshotFile_CH1->write("t, v\n"); + + snapshotFile_CH2->open(QIODevice::WriteOnly); + snapshotFile_CH2->write("t, v\n"); + + char tempchar[32]; + for(int i=0; iwrite(tempchar); + + sprintf(tempchar, "%f, %f\n", x.at(i), CH2.at(i)); + snapshotFile_CH2->write(tempchar); + } + snapshotEnabled = false; + snapshotFile_CH1->close(); + delete(snapshotFile_CH1); + + snapshotFile_CH2->close(); + delete(snapshotFile_CH2); + + } + + axes->replot(); +} + +void isoDriver::multimeterAction(){ + isoTemp_short = (short *)isoTemp; + if(!paused_multimeter){ + for (unsigned int i=0;i<(length/ADC_SPF);i++){ + internalBuffer375_CH1->writeBuffer_short(&isoTemp_short[ADC_SPF/2*i], ADC_SPF/2-1); //Offset because the first 8 bytes of the array contain the length (no samples!!)! + } + } + + if(!paused_multimeter){ + int offset = -2; //No trigger! + if(triggerEnabled && (triggerWaiting == 0) ){ + offset = trigger(); + } + if(offset == -1){ //Trigger is active but nothing found! + return; + } + + //qDebug() << "offset =" << offset; + + int backLength = length/750; + backLength *= VALID_DATA_PER_375; + + if(offset>0){ + int temp_offset = offset % 750; + offset /= 750; + offset *= VALID_DATA_PER_375; + offset += temp_offset; + } + + //qDebug() << "Now offset = " << offset; + + if((!paused_CH1) && triggerEnabled && (triggerWaiting == 0)){ + triggerDelay = backLength - offset; + triggerDelay /= (VALID_DATA_PER_375*1000); + triggerDelay += delay; + triggerWaiting = (triggerDelay<(window/2)) * 2; + } + + //qDebug() << "triggerDelay = " << triggerDelay; + + //qDebug() << "triggerWaiting =" << triggerWaiting; + + if(triggerWaiting == 1) triggerWaiting = 0; + + //qDebug() << "triggerWaiting =" << triggerWaiting; + + if(triggerEnabled && triggerWaiting){ + triggerDelay += (double)TIMER_PERIOD/(double)1000; + triggerWaiting = (triggerDelay<(window/2)) + 1; + return; + } + } + + //qDebug() << triggerEnabled; + //qDebug() << !paused_multimeter; + //qDebug() << (triggerEnabled&&!paused_multimeter); + + //qDebug() << ((triggerEnabled&&!paused_multimeter) ? triggerDelay + window/2 : 0); + + readData375_CH1 = internalBuffer375_CH1->readBuffer(window,GRAPH_SAMPLES, false, delay + ((triggerEnabled&&!paused_multimeter) ? triggerDelay + window/2 : 0)); + + QVector x(GRAPH_SAMPLES), CH1(GRAPH_SAMPLES); + analogConvert(readData375_CH1, &CH1, 2048, 0, 1); //No AC coupling! + + for (double i=0; i0) { + CH1[i] = 0; + } + } + axes->graph(0)->setData(x,CH1); + + udateCursors(); + + axes->xAxis->setRange(-window-delay,-delay); + axes->yAxis->setRange(topRange, botRange); + + axes->replot(); + multimeterStats(); +} + +void isoDriver::setAC_CH1(bool enabled){ + AC_CH1 = enabled; +} + +void isoDriver::setAC_CH2(bool enabled){ + AC_CH2 = enabled; +} + +void isoDriver::setMultimeterType(int type){ + multimeterType = (multimeterType_enum) type; + switch (type){ + + case R: + multimeterREnabled(multimeterRsource); + break; + case C: + multimeterREnabled(254); + break; + default: + multimeterREnabled(255); + } + + qDebug() << "multimeterType = " << multimeterType; +} + +void isoDriver::setSeriesResistance(double resistance){ + seriesResistance = resistance; + qDebug() << "seriesResistance = " << seriesResistance; +} + +void isoDriver::multimeterStats(){ + //qDebug() << "Entering isoDriver::multimeterStats()"; + if (!multimeterShow) return; + + QTimer::singleShot(MULTIMETER_PERIOD, this, SLOT(enableMM())); + + multimeterShow = false; + bool mvMax, mvMin, mvMean, mvRMS, maMax, maMin, maMean, maRMS, kOhms, uFarads; //We'll let the compiler work out this one. + + if(autoMultimeterV){ + mvMax = currentVmax < 1; + mvMin = currentVmin < 1; + mvMean = currentVmean < 1; + mvRMS = currentVRMS < 1; + } + if(autoMultimeterI){ + maMax = (currentVmax / seriesResistance) < 1; + maMin = (currentVmin / seriesResistance) < 1; + maMean = (currentVmean / seriesResistance) < 1; + maRMS = (currentVRMS / seriesResistance) < 1; + } + + if(forceMillivolts){ + mvMax = true; + mvMin = true; + mvMean = true; + mvRMS = true; + } + if(forceMilliamps){ + maMax = true; + maMin = true; + maMean = true; + maRMS = true; + } + if(forceKiloOhms){ + kOhms = true; + } + if(forceUFarads){ + uFarads = true; + } + + if(forceVolts){ + mvMax = false; + mvMin = false; + mvMean = false; + mvRMS = false; + } + if(forceAmps){ + maMax = false; + maMin = false; + maMean = false; + maRMS = false; + } + if(forceOhms){ + kOhms = false; + } + if(forceNFarads){ + uFarads = false; + } + + if(multimeterType == V){ + if(mvMax){ + currentVmax *= 1000; + sendMultimeterLabel1("Max (mV)"); + }else sendMultimeterLabel1("Max (V)"); + + if(mvMin){ + currentVmin *= 1000; + sendMultimeterLabel2("Min (mV)"); + }else sendMultimeterLabel2("Min (V)"); + + if(mvMean){ + currentVmean *= 1000; + sendMultimeterLabel3("Mean (mV)"); + }else sendMultimeterLabel3("Mean (V)"); + + if(mvRMS){ + currentVRMS *= 1000; + sendMultimeterLabel4("RMS (mV)"); + }else sendMultimeterLabel4("RMS (V)"); + + multimeterMax(currentVmax); + multimeterMin(currentVmin); + multimeterMean(currentVmean); + multimeterRMS(currentVRMS); + return; + } + + if(multimeterType == I){ + if(maMax){ + currentVmax *= 1000; + sendMultimeterLabel1("Max (mA)"); + }else sendMultimeterLabel1("Max (A)"); + + if(maMin){ + currentVmin *= 1000; + sendMultimeterLabel2("Min (mA)"); + }else sendMultimeterLabel2("Min (A)"); + + if(maMean){ + currentVmean *= 1000; + sendMultimeterLabel3("Mean (mA)"); + }else sendMultimeterLabel3("Mean (A)"); + + if(maRMS){ + currentVRMS *= 1000; + sendMultimeterLabel4("RMS (mA)"); + }else sendMultimeterLabel4("RMS (A)"); + + + multimeterMax(currentVmax / seriesResistance); + multimeterMin(currentVmin / seriesResistance); + multimeterMean(currentVmean / seriesResistance); + multimeterRMS(currentVRMS / seriesResistance); + return; + } + + if(multimeterType == R){ + if(estimated_resistance!=estimated_resistance){ + estimated_resistance = 0; //Reset resistance if it's NaN + } + double Vm = meanVoltageLast((double)MULTIMETER_PERIOD/(double)1000, 1, 2048); + double rtest_para_r = 1/(1/seriesResistance + 1/estimated_resistance); + double perturbation = ch2_ref * (rtest_para_r / (R3 + R4 + rtest_para_r)); + Vm = Vm - perturbation; + double Vin = (multimeterRsource * 2) + 3; + double Vrat = (Vin-Vm)/Vin; + double Rp = 1/(1/seriesResistance + 1/(R3+R4)); + estimated_resistance = ((1-Vrat)/Vrat) * Rp; //Perturbation term on V2 ignored. V1 = Vin. V2 = Vin(Rp/(R+Rp)) + Vn(Rtest||R / (R34 + (Rtest||R34)); + //qDebug() << "Vm = " << Vm; + //qDebug() << "Vin = " << Vin; + //qDebug() << "perturbation = " << perturbation; + //qDebug() << "Vrat = " << Vrat; + //qDebug() << "Rp = " << Rp; + //qDebug() << "estimated_resistance = " << estimated_resistance; + multimeterMax(0); + multimeterMin(0); + multimeterMean(0); + + if(autoMultimeterR){ + kOhms = (estimated_resistance) > 1000; + } + + if(kOhms){ + estimated_resistance /= 1000; + sendMultimeterLabel4("Resistance (kΩ)"); + }else sendMultimeterLabel4("Resistance (Ω)"); + multimeterRMS(estimated_resistance); + } + if(multimeterType == C){ + double cap_vbot = 0.8; + double cap_vtop = 2.5; + + int cap_x0 = internalBuffer375_CH1->cap_x0fromLast(1, cap_vbot); + if(cap_x0 == -1){ + qDebug() << "cap_x0 == -1"; + return; + } + int cap_x1 = internalBuffer375_CH1->cap_x1fromLast(1, cap_x0, cap_vbot); + if(cap_x1 == -1){ + qDebug() << "cap_x1 == -1"; + return; + } + int cap_x2 = internalBuffer375_CH1->cap_x2fromLast(1, cap_x1, cap_vtop); + if(cap_x2 == -1){ + qDebug() << "cap_x2 == -1"; + return; + } + qDebug() << "x0 = " << cap_x0; + qDebug() << "x1 = " << cap_x1; + qDebug() << "x2 = " << cap_x2; + qDebug() << "dt = " << cap_x2-cap_x1; + + double dt = (double)(cap_x2-cap_x1)/internalBuffer375_CH1->samplesPerSecond; + double Cm = -dt/(seriesResistance * log((vcc-cap_vtop)/(vcc-cap_vbot))); + qDebug() << "Cm = " << Cm; + + if(autoMultimeterC){ + uFarads = (Cm) > 1e-6; + } + + if(uFarads){ + sendMultimeterLabel4("Capacitance (μF)"); + Cm = Cm*1000000; + } else { + sendMultimeterLabel4("Capacitance (nF)"); + Cm = Cm*1000000000; + } + multimeterRMS(Cm); + } + +} + +void isoDriver::enableMM(){ + multimeterShow = true; +} + + +void isoDriver::setAutoMultimeterV(bool enabled){ + autoMultimeterV = enabled; +} + +void isoDriver::setAutoMultimeterI(bool enabled){ + autoMultimeterI = enabled; +} + +void isoDriver::setAutoMultimeterR(bool enabled){ + autoMultimeterR = enabled; +} + +void isoDriver::setAutoMultimeterC(bool enabled){ + autoMultimeterC = enabled; +} + +void isoDriver::setForceMillivolts(bool enabled){ + forceMillivolts = enabled; +} + +void isoDriver::setForceMilliamps(bool enabled){ + forceMilliamps = enabled; +} + +void isoDriver::setForceKiloOhms(bool enabled){ + forceKiloOhms = enabled; +} + +void isoDriver::setForceUFarads(bool enabled){ + forceUFarads = enabled; +} + +void isoDriver::setForceVolts(bool enabled){ + forceVolts = enabled; +} + +void isoDriver::setForceAmps(bool enabled){ + forceAmps = enabled; +} + +void isoDriver::setForceOhms(bool enabled){ + forceOhms = enabled; +} + +void isoDriver::setForceNFarads(bool enabled){ + forceNFarads = enabled; +} + +void isoDriver::setSerialDecodeEnabled_CH1(bool enabled){ + serialDecodeEnabled_CH1 = enabled; +} + +void isoDriver::setSerialDecodeEnabled_CH2(bool enabled){ + serialDecodeEnabled_CH2 = enabled; +} + +void isoDriver::setXYmode(bool enabled){ + XYmode = enabled; + if(!enabled){ + xmin = 20; + xmax = -20; + ymin = 20; + ymax = -20; + } + axes->graph(1)->setVisible(!enabled); +} + +void isoDriver::triggerGroupStateChange(bool enabled){ + if(enabled) sendTriggerValue((currentVmax-currentVmin)*0.85 + currentVmin); +} + +void isoDriver::broadcastStats(bool CH2){ + if(CH2){ + if(!update_CH2) return; + update_CH2 = false; + sendVmax_CH2(currentVmax); + sendVmin_CH2(currentVmin); + sendVmean_CH2(currentVmean); + //sendVrms_CH2(currentVrms); + } else{ + if(!update_CH1) return; + update_CH1 = false; + sendVmax_CH1(currentVmax); + sendVmin_CH1(currentVmin); + sendVmean_CH1(currentVmean); + //sendVrms_CH1(currentVrms); + } +} + +void isoDriver::slowTimerTick(){ + update_CH1 = true; + update_CH2 = true; +} + +void isoDriver::setTopRange(double newTop){ + topRange = newTop; +} + +void isoDriver::setBotRange(double newBot){ + botRange = newBot; +} + +void isoDriver::setTimeWindow(double newWindow){ + window = newWindow; + windowAtPause = window; +} + +void isoDriver::takeSnapshot(){ + snapshotEnabled = true; + + QDateTime now = QDateTime::currentDateTime(); + QString fileName_CH1 = now.toString("yyyyMMddhhmmsszzz"); + fileName_CH1.append("_CH1.csv"); + + QString fileName_CH2 = now.toString("yyyyMMddhhmmsszzz"); + fileName_CH2.append("_CH2.csv"); + + QDir *dir = new QDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)); + dir->mkdir("EspoTek"); + dir->cd("EspoTek"); + dir->mkdir("snapshots"); + dir->cd("snapshots"); + + snapshotFile_CH1 = new QFile(dir->filePath(fileName_CH1)); + snapshotFile_CH2 = new QFile(dir->filePath(fileName_CH2)); + + free(dir); +} + +double isoDriver::meanVoltageLast(double seconds, unsigned char channel, int TOP){ + isoBuffer *currentBuffer; + switch (channel){ + case 1: + currentBuffer = internalBuffer375_CH1; + break; + case 2: + currentBuffer = internalBuffer375_CH2; + break; + case 3: + currentBuffer = internalBuffer750; + break; + } + + short * tempBuffer = currentBuffer->readBuffer(seconds,1024, 0, 0); + double sum = 0; + double temp; + for(int i = 0; i<1024; i++){ + temp = currentBuffer->sampleConvert(tempBuffer[i], TOP, 0); + sum += temp; + } + return sum / 1024; +} + +void isoDriver::rSourceChanged(int newSource){ + multimeterRsource = newSource; +} diff --git a/Desktop_Interface/isodriver.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/isodriver.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 1ff46f2b..00000000 --- a/Desktop_Interface/isodriver.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6f3a826304450e2140a77bd5f5dd63125cace4ef \ No newline at end of file diff --git a/Desktop_Interface/isodriver.h b/Desktop_Interface/isodriver.h new file mode 100644 index 00000000..cacddd20 --- /dev/null +++ b/Desktop_Interface/isodriver.h @@ -0,0 +1,188 @@ +#ifndef ISODRIVER_H +#define ISODRIVER_H + +#include +#include +#include +#include +#include "qcustomplot.h" +#include "genericusbdriver.h" +#include "desktop_settings.h" +#include "siprint.h" + +class isoBuffer; + +//isoDriver is a huge class. It handles everything related to the isochronous IN stream - and perhaps that constraint was applied a bit too loosely (spot the C programmer...). +//Too much stuff is handled in this class, and it's too heavily entangled with the (generic/win/unix)UsbDriver classes. +//That is one of the things I plan on fixing, and in fact the reason why I began the commenting! + +class isoDriver : public QLabel +{ + Q_OBJECT +public: + explicit isoDriver(QWidget *parent = 0); + //Generic Vars + isoBuffer *internalBuffer375_CH1, *internalBuffer375_CH2, *internalBuffer750; +#if QCP_VER == 1 + QCPItemText *cursorTextPtr; +#endif + genericUsbDriver *driver; + bool doNotTouchGraph = true; + double ch1_ref = 1.65, ch2_ref = 1.65; + double frontendGain_CH1 = (R4/(R3+R4)), frontendGain_CH2 = (R4/(R3+R4)); + //State Vars + bool AC_CH1 = false, AC_CH2 = false; + bool cursorStatsEnabled = true; + int baudRate_CH1 = 9600, baudRate_CH2 = 9600; + double currentVmean; + //Display Control Vars (Variables that control how the buffers are displayed) + double delay = 0, window = 0.01; + double y0=0, y1=0, x0=0, x1=0; + double topRange=2.5, botRange=-0.5; + //Generic Functions + void setDriver(genericUsbDriver *newDriver); + void setAxes(QCustomPlot *newAxes); + double meanVoltageLast(double seconds, unsigned char channel, int TOP); +private: + //Those bloody bools that just Enable/Disable a single property + bool paused_CH1 = false, paused_CH2 = false, paused_multimeter = false; + bool autoGainEnabled = true; + bool placingHoriAxes = false, placingVertAxes = false, horiCursorEnabled = false, vertCursorEnabled = false; + bool triggerSeeking = true; + bool triggerEnabled = false; + bool multimeterShow = true; + bool autoMultimeterV = true; + bool autoMultimeterI = true; + bool autoMultimeterR = true; + bool autoMultimeterC = true; + bool forceMillivolts = false; + bool forceMilliamps = false; + bool forceKiloOhms = false; + bool forceUFarads = false; + bool forceVolts = false; + bool forceAmps = false; + bool forceOhms = false; + bool forceNFarads = false; + bool serialDecodeEnabled_CH1 = false, serialDecodeEnabled_CH2 = false; + bool XYmode = false; + bool update_CH1 = true, update_CH2 = true; + bool snapshotEnabled = false; + bool firstFrame = true; + double triggerDelay; + bool singleShotEnabled = false; + //Generic Functions + void analogConvert(short *shortPtr, QVector *doublePtr, int TOP, bool AC, int channel); + void digitalConvert(short *shortPtr, QVector *doublePtr); + bool properlyPaused(); + void autoGain(void); + void udateCursors(void); + short reverseFrontEnd(double voltage); + int trigger(void); + void multimeterAction(); + void broadcastStats(bool CH2); + void frameActionGeneric(char CH1_mode, char CH2_mode); + //Variables that are just pointers to other classes/vars + QCustomPlot *axes; + short *readData375_CH1, *readData375_CH2, *readData750; + char *isoTemp = NULL; + short *isoTemp_short = NULL; + siprint *v0, *v1, *dv, *t0, *t1, *dt, *f; + //Scope/MM++ related variables + double currentVmax, currentVmin, currentVRMS; + double triggerLevel = 0; + enum triggerType_enum {rising_ch1 = 0, falling_ch1 = 1, rising_ch2 = 2, falling_ch2 = 3}; + triggerType_enum triggerType = rising_ch1; + double multi = 0; + int triggerCountSeeking = 0, triggerCountNotSeeking = 0; + unsigned char triggerWaiting = 0; + double xmin = 20, xmax = -20, ymin = 20, ymax = -20; + double estimated_resistance = 0; + int multimeterRsource = 0; + //Pure MM++ related variables + enum multimeterType_enum {V = 0, I = 1, R = 2, C = 3}; + multimeterType_enum multimeterType = V; + double seriesResistance = 0; + //Generic Vars + double windowAtPause = 0.01; + QTimer* isoTimer = NULL, *slowTimer = NULL; + long total_read = 0; + unsigned int length; + QFile *snapshotFile_CH1; + QFile *snapshotFile_CH2; + +signals: + void setGain(double newGain); + void disableWindow(bool enabled); + void setCursorStatsVisible(bool enabled); + void sendCursorStatsText(QString text); + void singleShotTriggered(bool triggered); + void multimeterMax(double); + void multimeterMin(double); + void multimeterMean(double); + void multimeterRMS(double); + void sendMultimeterLabel1(QString); + void sendMultimeterLabel2(QString); + void sendMultimeterLabel3(QString); + void sendMultimeterLabel4(QString); + void changeTimeAxis(bool positive); + void sendTriggerValue(double); + void sendVmax_CH1(double); + void sendVmin_CH1(double); + void sendVmean_CH1(double); + void sendVmax_CH2(double); + void sendVmin_CH2(double); + void sendVmean_CH2(double); + void multimeterREnabled(int source); +public slots: + void setWindow(int newWindow); + void setVoltageRange(QWheelEvent *event); + void timerTick(void); + void pauseEnable_CH1(bool enabled); + void pauseEnable_CH2(bool enabled); + void pauseEnable_multimeter(bool enabled); + void startTimer(); + void clearBuffers(bool ch3751, bool ch3752, bool ch750); + void setVisible_CH2(bool visible); + void gainBuffers(double multiplier); + void gainTick(void); + void setAutoGain(bool enabled); + void graphMousePress(QMouseEvent *event); + void graphMouseRelease(QMouseEvent *event); + void graphMouseMove(QMouseEvent *event); + void cursorEnableHori(bool enabled); + void cursorEnableVert(bool enabled); + void setTriggerEnabled(bool enabled); + void setTriggerLevel(double level); + void setSingleShotEnabled(bool enabled); + void setTriggerMode(int newMode); + void setAC_CH1(bool enabled); + void setAC_CH2(bool enabled); + void setMultimeterType(int type); + void setSeriesResistance(double resistance); + void multimeterStats(); + void enableMM(); + void setAutoMultimeterV(bool enabled); + void setAutoMultimeterI(bool enabled); + void setAutoMultimeterR(bool enabled); + void setAutoMultimeterC(bool enabled); + void setForceMillivolts(bool enabled); + void setForceMilliamps(bool enabled); + void setForceKiloOhms(bool enabled); + void setForceUFarads(bool enabled); + void setForceVolts(bool enabled); + void setForceAmps(bool enabled); + void setForceOhms(bool enabled); + void setForceNFarads(bool enabled); + void setSerialDecodeEnabled_CH1(bool enabled); + void setSerialDecodeEnabled_CH2(bool enabled); + void setXYmode(bool enabled); + void triggerGroupStateChange(bool enabled); + void slowTimerTick(); + void setTopRange(double newTop); + void setBotRange(double newBot); + void setTimeWindow(double newWindow); + void takeSnapshot(); + void rSourceChanged(int newSource); +}; + +#endif // ISODRIVER_H diff --git a/Desktop_Interface/isodriver.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/isodriver.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 406de9fe..00000000 --- a/Desktop_Interface/isodriver.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -76ca5a9c35b5991dc151eebfb5b4af6b7634b1c2 \ No newline at end of file diff --git a/Desktop_Interface/isodriver.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/isodriver.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 7ad3fa84..00000000 --- a/Desktop_Interface/isodriver.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -df6483612a5f705231beb2851c631f35681b3702 \ No newline at end of file diff --git a/Desktop_Interface/isodriver.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/isodriver.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index e891e276..00000000 --- a/Desktop_Interface/isodriver.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ebe355c4ceafd6e16e4068159e6fbfe02462a2a0 \ No newline at end of file diff --git a/Desktop_Interface/labrador_plugin_import.cpp b/Desktop_Interface/labrador_plugin_import.cpp new file mode 100644 index 00000000..551efd75 --- /dev/null +++ b/Desktop_Interface/labrador_plugin_import.cpp @@ -0,0 +1,6 @@ +// This file is autogenerated by qmake. It imports static plugin classes for +// static plugins specified using QTPLUGIN and QT_PLUGIN_CLASS. variables. +#include +Q_IMPORT_PLUGIN(QXcbIntegrationPlugin) +Q_IMPORT_PLUGIN(QXcbGlxIntegrationPlugin) +Q_IMPORT_PLUGIN(QICOPlugin) diff --git a/Desktop_Interface/labrador_plugin_import.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/labrador_plugin_import.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index de15369a..00000000 --- a/Desktop_Interface/labrador_plugin_import.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b998e67842590f2ce31476409ab2f47ed55c9d9a \ No newline at end of file diff --git a/Desktop_Interface/libc.so.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/libc.so.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index cd1e24d1..00000000 --- a/Desktop_Interface/libc.so.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f16175126f56fd7a8414f7977cb0d91f4cfe8935 \ No newline at end of file diff --git a/Desktop_Interface/macusbdriver.cpp b/Desktop_Interface/macusbdriver.cpp new file mode 100644 index 00000000..818ee66f --- /dev/null +++ b/Desktop_Interface/macusbdriver.cpp @@ -0,0 +1,203 @@ +#include "macUsbDriver.h" + +QMutex tcBlockMutex; + +macUsbDriver::macUsbDriver(QWidget *parent) : genericUsbDriver(parent) +{ + unsigned char error = 1; + while(error){ + error = usbInit(0x03eb, 0xa000); + if(error)QThread::msleep(64); + } + setDeviceMode(deviceMode); + newDig(digitalPinState); + usbIsoInit(); + + psuTimer = new QTimer(); + psuTimer->setTimerType(Qt::PreciseTimer); + psuTimer->start(PSU_PERIOD); + + recoveryTimer = new QTimer(); + recoveryTimer->setTimerType(Qt::PreciseTimer); + recoveryTimer->start(RECOVERY_PERIOD); + connect(recoveryTimer, SIGNAL(timeout()), this, SLOT(recoveryTick())); +} + +macUsbDriver::~macUsbDriver(void){ + qDebug() << "\n\nmacUsbDriver destructor ran!"; + workerThread->quit(); + workerThread->deleteLater(); + delete(isoHandler); + delete(psuTimer); + delete(recoveryTimer); + delete(isoTimer); + libusb_release_interface(handle, 0); + libusb_exit(ctx); +} + +unsigned char macUsbDriver::usbInit(unsigned long VIDin, unsigned long PIDin){ + qDebug() << "Entering macUsbDriver::usbInit"; + + int error = libusb_init(&ctx); + if(error){ + qDebug() << "libusb_init FAILED"; + return error; + } else qDebug() << "Libusb context initialised"; + + libusb_set_debug(ctx, 3); + + handle = libusb_open_device_with_vid_pid(ctx, VIDin, PIDin); + if(handle==NULL){ + qDebug() << "DEVICE NOT FOUND"; + return -1; + } + qDebug() << "Device found!!"; + + qDebug() << (libusb_kernel_driver_active(handle, 0) ? "KERNEL DRIVER ACTIVE" : "KERNEL DRIVER INACTIVE"); + if(libusb_kernel_driver_active(handle, 0)){ + libusb_detach_kernel_driver(handle, 0); + } + error = libusb_claim_interface(handle, 0); + if(error){ + qDebug() << "libusb_claim_interface FAILED"; + qDebug() << "ERROR" << error << libusb_error_name(error); + return error; + } else qDebug() << "Interface claimed!"; + + return 0; +} + +void macUsbDriver::usbSendControl(uint8_t RequestType, uint8_t Request, uint16_t Value, uint16_t Index, uint16_t Length, unsigned char *LDATA){ + qDebug("Sending Control packet! 0x%x,\t0x%x,\t%u,\t%u,\t%d,\t%u", RequestType, Request, Value, Index, LDATA, Length); + int error = libusb_control_transfer(handle, RequestType, Request, Value, Index, LDATA, Length, 4000); + if(error){ + qDebug("macUsbDriver::usbSendControl FAILED with error %s", libusb_error_name(error)); + } else qDebug() << "macUsbDriver::usbSendControl SUCCESS"; + if(error == LIBUSB_ERROR_NO_DEVICE){ + qDebug() << "Device not found. Becoming an hero."; + killMe(); + } + return; +} + +unsigned char macUsbDriver::usbIsoInit(void){ + int error; + + for(int n=0;nsetTimerType(Qt::PreciseTimer); + isoTimer->start(ISO_TIMER_PERIOD); + connect(isoTimer, SIGNAL(timeout()), this, SLOT(isoTimerTick())); + + qDebug() << "Setup successful!"; + + isoHandler = new worker(); + workerThread = new QThread(); + + isoHandler->ctx = ctx; + isoHandler->moveToThread(workerThread); + connect(workerThread, SIGNAL(started()), isoHandler, SLOT(handle())); + + workerThread->start(); + + qDebug() << "MAIN THREAD ID" << QThread::currentThreadId(); + //QThread::sleep(1); + qDebug() << "Iso Stack initialised!"; + return 1; +} + +void macUsbDriver::isoTimerTick(void){ + timerCount++; + + char subString[3] = "th"; + if(timerCount%10 == 1) strcpy(subString, "st"); + if(timerCount%10 == 2) strcpy(subString, "nd"); + if(timerCount%10 == 3) strcpy(subString, "rd"); + if((timerCount<20) && (timerCount > 10)) strcpy(subString, "th"); + + //qDebug("\n\nThis is the %d%s Tick!", timerCount, subString); + + int n, error, earliest = MAX_OVERLAP; + qint64 minFrame = 9223372036854775807; //max value for 64 bit signed + + unsigned int i, packetLength = 0; + unsigned char* packetPointer; + + tcBlockMutex.lock(); + for (n=0; nnum_iso_packets;i++){ + packetPointer = libusb_get_iso_packet_buffer_simple(isoCtx[earliest], i); + //qDebug() << packetLength; + memcpy(&(outBuffers[currentWriteBuffer][packetLength]), packetPointer, isoCtx[earliest]->iso_packet_desc[i].actual_length); + packetLength += isoCtx[earliest]->iso_packet_desc[i].actual_length; + } + + //Control data for isoDriver + bufferLengths[currentWriteBuffer] = packetLength; + currentWriteBuffer = !currentWriteBuffer; + + //Setup next transfer + transferCompleted[earliest].completed = false; + error = libusb_submit_transfer(isoCtx[earliest]); + if(error){ + qDebug() << "libusb_submit_transfer FAILED"; + qDebug() << "ERROR" << libusb_error_name(error); + } //else qDebug() << "isoCtx submitted successfully!"; + tcBlockMutex.unlock(); + qDebug() << "Returning at Uptick()"; + upTick(); + return; +} + +char *macUsbDriver::isoRead(unsigned int *newLength){ + //*(newLength) = 0; + //return (char*) NULL; + qDebug() << "macUsbDriver::isoRead"; + *(newLength) = bufferLengths[!currentWriteBuffer]; + return (char*) outBuffers[(unsigned char) !currentWriteBuffer]; +} + +void macUsbDriver::recoveryTick(void){ + //avrDebug(); +} + +static void LIBUSB_CALL isoCallback(struct libusb_transfer * transfer){ + tcBlockMutex.lock(); + //int number = ((tcBlock *)transfer->user_data)->number; + //bool completed = ((tcBlock *)transfer->user_data)->completed; + + //qDebug() << "CALLBACK"; + //qDebug() << completed; + + ((tcBlock *)transfer->user_data)->completed = true; + ((tcBlock *)transfer->user_data)->timeReceived = QDateTime::currentMSecsSinceEpoch(); + //qDebug() << ((tcBlock *)transfer->user_data)->timeReceived; + tcBlockMutex.unlock(); + return; +} diff --git a/Desktop_Interface/macusbdriver.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/macusbdriver.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 4f3bee7c..00000000 --- a/Desktop_Interface/macusbdriver.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e8ccf39410d441f6163de91093d0a02a14a36a41 \ No newline at end of file diff --git a/Desktop_Interface/macusbdriver.h b/Desktop_Interface/macusbdriver.h new file mode 100644 index 00000000..a3678b32 --- /dev/null +++ b/Desktop_Interface/macusbdriver.h @@ -0,0 +1,72 @@ +#ifndef macUsbDriver_H +#define macUsbDriver_H + +#include +#include +#include +#include + +#include "genericusbdriver.h" +#include "libusb.h" + +#define RECOVERY_PERIOD 250 + +typedef struct tcBlock{ + int number; + bool completed; + qint64 timeReceived; +} tcBlock; + +extern QMutex tcBlockMutex; + +class worker : public QObject +{ + Q_OBJECT + +public: + worker(){}; + ~worker(){}; + libusb_context *ctx; +public slots: + void handle(){ + qDebug() << "SUB THREAD ID" << QThread::currentThreadId(); + while(1){ + if(libusb_event_handling_ok(ctx)){ + libusb_handle_events(ctx); + //qDebug() << "HANDLED"; + } + } + } +}; + +class macUsbDriver : public genericUsbDriver +{ + Q_OBJECT +public: + explicit macUsbDriver(QWidget *parent = 0); + ~macUsbDriver(); + void usbSendControl(uint8_t RequestType, uint8_t Request, uint16_t Value, uint16_t Index, uint16_t Length, unsigned char *LDATA); + char *isoRead(unsigned int *newLength); +private: + //USB Vars + libusb_context *ctx; + libusb_device_handle *handle = NULL; + QTimer *recoveryTimer; + //USBIso Vars + libusb_transfer *isoCtx[NUM_FUTURE_CTX]; + tcBlock transferCompleted[NUM_FUTURE_CTX]; + unsigned char dataBuffer[NUM_FUTURE_CTX][ISO_PACKET_SIZE*ISO_PACKETS_PER_CTX]; + worker *isoHandler; + QThread *workerThread; + //Generic Functions + unsigned char usbInit(unsigned long VIDin, unsigned long PIDin); + unsigned char usbIsoInit(void); +signals: +public slots: + void isoTimerTick(void); + void recoveryTick(void); +}; + +static void LIBUSB_CALL isoCallback(struct libusb_transfer *transfer); + +#endif // macUsbDriver_H diff --git a/Desktop_Interface/macusbdriver.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/macusbdriver.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index be9fd0dd..00000000 --- a/Desktop_Interface/macusbdriver.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cde0203b8ac27370f7ce62f65d8a59f822146635 \ No newline at end of file diff --git a/Desktop_Interface/macusbdriver.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/macusbdriver.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 32b7d254..00000000 --- a/Desktop_Interface/macusbdriver.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2334fa606a7d203c05e213a16add6a579e326efb \ No newline at end of file diff --git a/Desktop_Interface/main.cpp b/Desktop_Interface/main.cpp new file mode 100644 index 00000000..c580ac90 --- /dev/null +++ b/Desktop_Interface/main.cpp @@ -0,0 +1,19 @@ +#include "mainwindow.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + +#ifdef PLATFORM_ANDROID + //Android default font sizes are just plain ridiculous + QFont font = qApp->font(); + font.setPointSize(8); + qApp->setFont(font); +#endif + + MainWindow w; + w.show(); + + return a.exec(); +} diff --git a/Desktop_Interface/main.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/main.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 89556129..00000000 --- a/Desktop_Interface/main.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3b3e14ecd7133ec17785ed0c4a3b049662cc6500 \ No newline at end of file diff --git a/Desktop_Interface/main.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/main.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 46a7c8ae..00000000 --- a/Desktop_Interface/main.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4c07e5d36adea51d1b4be322bf99d043174311b6 \ No newline at end of file diff --git a/Desktop_Interface/main.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/main.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 935e45db..00000000 --- a/Desktop_Interface/main.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c6622aaacb05ab1d94292d731a36e7039ad32775 \ No newline at end of file diff --git a/Desktop_Interface/mainwindow.cpp b/Desktop_Interface/mainwindow.cpp new file mode 100644 index 00000000..ed3e98cf --- /dev/null +++ b/Desktop_Interface/mainwindow.cpp @@ -0,0 +1,1545 @@ +#include "mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainWindow) +{ + ui->setupUi(this); + ui->psuDisplay->display("4.00"); + ui->bufferDisplay->refreshImage(); + + ui->waveformSelect_CH1->readWaveformList(); + ui->waveformSelect_CH2->readWaveformList(); + + labelPsu(); + + ui->psuDisplay->display("4.50"); + + ui->controller_iso->setDriver(new _PLATFORM_DEPENDENT_USB_OBJECT()); + ui->controller_iso->setAxes(ui->scopeAxes); + + ui->timeBaseSlider->setMaximum(10*log10(MAX_WINDOW_SIZE)); + + ui->controller_iso->driver->setBufferPtr(ui->bufferDisplay); + ui->cursorStatsLabel->hide(); + initialisePlot(); + menuSetup(); + readSettingsFile(); + + ui->voltageInfoMaxDisplay_CH1->display(5312); + ui->voltageInfoMinDisplay_CH1->display(0.01); + ui->voltageInfoMeanDisplay_CH1->display(0.02); + ui->voltageInfoRmsDisplay_CH1->display(6.00); + connectDisplaySignals(); + + ui->controller_iso->internalBuffer375_CH1->console1 = ui->console1; + ui->controller_iso->internalBuffer375_CH1->console2 = ui->console2; + + ui->controller_iso->internalBuffer375_CH2->console1 = ui->console1; + ui->controller_iso->internalBuffer375_CH2->console2 = ui->console2; + initShortcuts(); + + ui->debugButton1->setVisible(0); + ui->debugButton2->setVisible(0); + ui->debugButton3->setVisible(0); + ui->debugConsole->setVisible(0); +#ifndef PLATFORM_ANDROID + ui->console1->setVisible(0); + ui->console2->setVisible(0); +#endif + ui->timeBaseSlider->setVisible(0); + + //ui->pausedLabel_CH2->setVisible(0); + ui->filterLabel_CH1->setVisible(0); + ui->filterLabel_CH2->setVisible(0); + + //Reset the device to ensure Labrador_libusbk gets handle!! + #ifdef PLATFORM_WINDOWS + //ui->controller_iso->driver->usbSendControl(0x40, 0xa7, 0, 0, 0, NULL); + //reinitUsb(); + ui->controller_iso->driver->killOnConnect = true; + #endif + #ifdef PLATFORM_LINUX + reinitUsb(); + #endif + #ifdef PLATFORM_MAC + reinitUsb(); + /* + //Reconnect the other objects. + ui->controller_iso->driver->setBufferPtr(ui->bufferDisplay); + connect(ui->debugButton1, SIGNAL(clicked()), ui->controller_iso->driver, SLOT(avrDebug())); + connect(ui->debugButton3, SIGNAL(clicked()), ui->controller_iso->driver, SLOT(avrDebug())); + connect(ui->psuSlider, SIGNAL(voltageChanged(double)), ui->controller_iso->driver, SLOT(setPsu(double))); + connect(ui->controller_iso, SIGNAL(setGain(double)), ui->controller_iso->driver, SLOT(setGain(double))); + connect(ui->controller_fg, SIGNAL(functionGenToUpdate(int,functionGenControl*)), ui->controller_iso->driver, SLOT(setFunctionGen(int,functionGenControl*))); + connect(ui->bufferDisplay, SIGNAL(modeChange(int)), ui->controller_iso->driver, SLOT(setDeviceMode(int))); + connect(ui->bufferDisplay, SIGNAL(updateDig(int)), ui->controller_iso->driver, SLOT(newDig(int))); + + //Set the settings again! + connect(ui->controller_iso->driver, SIGNAL(gainBuffers(double)), ui->controller_iso, SLOT(gainBuffers(double))); + connect(ui->controller_iso->driver, SIGNAL(disableWindow(bool)), this, SLOT(setEnabled(bool))); + connect(ui->controller_iso->driver, SIGNAL(sendClearBuffer(bool,bool,bool)), ui->controller_iso, SLOT(clearBuffers(bool,bool,bool))); + //connect(ui->controller_iso->driver, SIGNAL(startIsoTimer()), ui->controller_iso, SLOT(startTimer())); + connect(ui->controller_iso->driver, SIGNAL(setVisible_CH2(bool)), ui->controller_iso, SLOT(setVisible_CH2(bool))); + //connect(ui->controller_iso->driver, SIGNAL(enableMMTimer()), ui->controller_iso, SLOT(enableMM())); + connect(ui->controller_iso->driver, SIGNAL(checkXY(bool)), ui->xyDisplayLabel, SLOT(setChecked(bool))); + connect(ui->controller_iso->driver, SIGNAL(disableWindow(bool)), ui->deviceConnected, SLOT(connectedStatusChanged(bool))); + connect(ui->controller_iso->driver, SIGNAL(upTick()), ui->controller_iso, SLOT(timerTick())); + connect(ui->controller_iso->driver, SIGNAL(connectedStatus(bool)), ui->deviceConnected, SLOT(connectedStatusChanged(bool))); + connect(ui->controller_iso->driver, SIGNAL(initialConnectComplete(void)), ui->deviceConnected, SLOT(resetUsbState(bool)));*/ + #endif + #ifdef PLATFORM_ANDROID + ui->actionAutomatically_Enable_Cursors->setVisible(false); + //hide second pause label + ui->pausedLabel_CH2->setVisible(false); + //Capture pinches + ui->scopeAxes->grabGesture(Qt::PinchGesture); + ui->scopeAxes->installEventFilter(this); + //Mutually exclude pinches/cursors + connect(ui->scaleHoriCheck, SIGNAL(clicked(bool)), + this, SLOT(horiScaleEvent(bool))); + connect(ui->scaleVertCheck, SIGNAL(clicked(bool)), + this, SLOT(vertScaleEvent(bool))); + //Screen Rotation. Thanks, Hamlet. https://forum.qt.io/topic/66240/how-to-detect-rotate-on-android + screenPtr = QGuiApplication::primaryScreen(); + connect(screenPtr, SIGNAL(orientationChanged(Qt::ScreenOrientation)), + this, SLOT(screenRotateEvent(Qt::ScreenOrientation))); + + screenPtr->setOrientationUpdateMask( + Qt::PortraitOrientation + | Qt::LandscapeOrientation + | Qt::InvertedPortraitOrientation + | Qt::InvertedLandscapeOrientation); + + //Hide the PSU page + ui->stackedWidget->removeWidget(ui->page_5); + + //Reconnect the other objects. + ui->controller_iso->driver->setBufferPtr(ui->bufferDisplay); + connect(ui->debugButton1, SIGNAL(clicked()), ui->controller_iso->driver, SLOT(avrDebug())); + connect(ui->psuSlider, SIGNAL(voltageChanged(double)), ui->controller_iso->driver, SLOT(setPsu(double))); + connect(ui->controller_iso, SIGNAL(setGain(double)), ui->controller_iso->driver, SLOT(setGain(double))); + connect(ui->controller_fg, SIGNAL(functionGenToUpdate(int,functionGenControl*)), ui->controller_iso->driver, SLOT(setFunctionGen(int,functionGenControl*))); + connect(ui->bufferDisplay, SIGNAL(modeChange(int)), ui->controller_iso->driver, SLOT(setDeviceMode(int))); + connect(ui->bufferDisplay, SIGNAL(updateDig(int)), ui->controller_iso->driver, SLOT(newDig(int))); + + //Set the settings again! + connect(ui->controller_iso->driver, SIGNAL(gainBuffers(double)), ui->controller_iso, SLOT(gainBuffers(double))); + connect(ui->controller_iso->driver, SIGNAL(disableWindow(bool)), this, SLOT(setEnabled(bool))); + connect(ui->controller_iso->driver, SIGNAL(sendClearBuffer(bool,bool,bool)), ui->controller_iso, SLOT(clearBuffers(bool,bool,bool))); + //connect(ui->controller_iso->driver, SIGNAL(startIsoTimer()), ui->controller_iso, SLOT(startTimer())); + connect(ui->controller_iso->driver, SIGNAL(setVisible_CH2(bool)), ui->controller_iso, SLOT(setVisible_CH2(bool))); + //connect(ui->controller_iso->driver, SIGNAL(enableMMTimer()), ui->controller_iso, SLOT(enableMM())); + connect(ui->controller_iso->driver, SIGNAL(checkXY(bool)), ui->xyDisplayLabel, SLOT(setChecked(bool))); + connect(ui->controller_iso->driver, SIGNAL(disableWindow(bool)), ui->deviceConnected, SLOT(connectedStatusChanged(bool))); + connect(ui->controller_iso->driver, SIGNAL(upTick()), ui->controller_iso, SLOT(timerTick())); + connect(ui->controller_iso->driver, SIGNAL(connectedStatus(bool)), ui->deviceConnected, SLOT(connectedStatusChanged(bool))); + #endif + + connect(ui->controller_iso->driver, SIGNAL(killMe()), this, SLOT(reinitUsb())); + //ui->console1->setMaximumBlockCount(MAX_CONSOLE_BLOCK_COUNT); + //ui->console2->setMaximumBlockCount(MAX_CONSOLE_BLOCK_COUNT); + //ui->frequencyValue_CH2->setValue(369); + //ui->amplitudeValue_CH2->setValue(2); + ui->controller_iso->doNotTouchGraph = false; + + calibrationMessages = new QMessageBox(); +#ifndef PLATFORM_ANDROID + ui->multimeterRLabel->setVisible(false); + ui->multimeterRComboBox->setVisible(false); +#endif + + connect(ui->controller_iso, SIGNAL(multimeterREnabled(int)), this, SLOT(rSourceIndexChanged(int))); + connect(ui->controller_iso, SIGNAL(multimeterRMS(double)), ui->multimeterRmsDisplay, SLOT(display(double))); + connect(ui->controller_iso, SIGNAL(sendMultimeterLabel4(QString)), ui->multimeterRmsLabel, SLOT(setText(QString))); + +} + +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::initialisePlot() +{ + ui->scopeAxes->addGraph(); + ui->scopeAxes->addGraph(); + ui->scopeAxes->addGraph(); + ui->scopeAxes->addGraph(); + ui->scopeAxes->addGraph(); + ui->scopeAxes->addGraph(); + +#if QCP_VER == 1 + textLabel = new QCPItemText(ui->scopeAxes); + ui->scopeAxes->addItem(textLabel); + textLabel->setPositionAlignment(Qt::AlignTop|Qt::AlignRight); + textLabel->position->setType(QCPItemPosition::ptAxisRectRatio); + textLabel->position->setCoords(0.99, 0); // place position at center/top of axis rect + textLabel->setText("Cursor Label Here"); + textLabel->setFont(QFont("Courier New", 12)); + textLabel->setColor(Qt::white); + textLabel->setPen(QPen(Qt::white)); + textLabel->setBrush(QBrush(Qt::black)); + + textLabel->setVisible(0); + ui->controller_iso->cursorTextPtr = textLabel; + + ui->scopeAxes->yAxis->setAutoTickCount(9); + ui->scopeAxes->xAxis->setAutoTickCount(9); +#endif + +#if QCP_VER == 2 + ui->scopeAxes->setOpenGl(true); + QSharedPointer xTicker(new QCPAxisTicker); + xTicker->setTickCount(9); + ui->scopeAxes->xAxis->setTicker(xTicker); + + QSharedPointer yTicker(new QCPAxisTicker); + yTicker->setTickCount(9); + ui->scopeAxes->yAxis->setTicker(yTicker); +#endif + + QPen *dashPen = new QPen(Qt::white, 2); + dashPen->setStyle(Qt::DashLine); + + ui->scopeAxes->graph(0)->setPen(QPen(Qt::yellow, 1)); + ui->scopeAxes->graph(1)->setPen(QPen(Qt::cyan, 1)); + ui->scopeAxes->graph(2)->setPen(QPen(Qt::white, 2)); + ui->scopeAxes->graph(3)->setPen(*(dashPen)); + ui->scopeAxes->graph(4)->setPen(QPen(Qt::white, 2)); + ui->scopeAxes->graph(5)->setPen(*(dashPen)); + + + ui->scopeAxes->xAxis->setBasePen(QPen(Qt::white, 1)); + ui->scopeAxes->yAxis->setBasePen(QPen(Qt::white, 1)); + ui->scopeAxes->xAxis->setTickPen(QPen(Qt::white, 1)); + ui->scopeAxes->yAxis->setTickPen(QPen(Qt::white, 1)); + ui->scopeAxes->xAxis->setSubTickPen(QPen(Qt::white, 1)); + ui->scopeAxes->yAxis->setSubTickPen(QPen(Qt::white, 1)); + ui->scopeAxes->xAxis->setTickLength(6); + ui->scopeAxes->yAxis->setTickLength(6); + ui->scopeAxes->xAxis->setSubTickLength(4); + ui->scopeAxes->yAxis->setSubTickLength(4); + ui->scopeAxes->xAxis->setTickLabelColor(Qt::white); + ui->scopeAxes->yAxis->setTickLabelColor(Qt::white); + + ui->scopeAxes->setBackground(Qt::black); + + + ui->scopeAxes->replot(); +} + +void MainWindow::labelPsu(){ + char tempString[4]; + int tempInt = ui->psuSlider->maximum(); + int tempCounter = 0; + while(tempInt>90){ + sprintf(tempString, "%dV", tempInt/20); + ui->psuSlider->setTickLabel(tempString, tempCounter); + tempInt -= 20; + tempCounter++; + } + ui->psuSlider->setTickLabel("4.5V", 11); +} + +void MainWindow::resizeEvent(QResizeEvent *event){ + //ui->scopeAxes->yAxis->setAutoTickCount((ui->scopeAxes->height() + TICK_SEPARATION / 2) / TICK_SEPARATION); + //ui->scopeAxes->xAxis->setAutoTickCount((ui->scopeAxes->width() + TICK_SEPARATION / 2) / TICK_SEPARATION); + + //ui->scopeAxes->resize(ui->scopeAxes->height(), ui->scopeAxes->height()); + //qDebug() << ui->scopeAxes->yAxis->autoTickCount() << ui->scopeAxes->xAxis->autoTickCount(); + + if(forceSquare){ + int tempHeight = ui->scopeAxes->height(); + int tempWidth = ui->scopeAxes->width(); + int newDims = (tempHeight > tempWidth) ? tempWidth : tempHeight; + ui->scopeAxes->resize(newDims, newDims); + if(tempWidth > tempHeight){ + ui->scopeAxes->move(tempWidth-tempHeight, ui->scopeAxes->y()); + }else{ + ui->scopeAxes->move(ui->scopeAxes->x(), ui->scopeAxes->y() + (tempHeight - tempWidth) / 2); + } + } +} + +void MainWindow::menuSetup(){ + gainGroup = new QActionGroup(this); + gainGroup->addAction(ui->actionGainAuto); + gainGroup->addAction(ui->actionGain0_5); + gainGroup->addAction(ui->actionGain1); + gainGroup->addAction(ui->actionGain2); + gainGroup->addAction(ui->actionGain4); + gainGroup->addAction(ui->actionGain8); + gainGroup->addAction(ui->actionGain16); + gainGroup->addAction(ui->actionGain32); + gainGroup->addAction(ui->actionGain64); + ui->actionGainAuto->setChecked(1); + + rangeGroupV = new QActionGroup(this); + rangeGroupV->addAction(ui->actionAutoV); + rangeGroupV->addAction(ui->actionMV); + rangeGroupV->addAction(ui->actionV); + + rangeGroupI = new QActionGroup(this); + rangeGroupI->addAction(ui->actionAutoI); + rangeGroupI->addAction(ui->actionMA); + rangeGroupI->addAction(ui->actionA); + + rangeGroupR = new QActionGroup(this); + rangeGroupR->addAction(ui->actionAutoR); + rangeGroupR->addAction(ui->actionKOhm); + rangeGroupR->addAction(ui->actionOhm); + + rangeGroupC = new QActionGroup(this); + rangeGroupC->addAction(ui->actionAutoC); + rangeGroupC->addAction(ui->actionNF); + rangeGroupC->addAction(ui->action_F); + + fpsGroup = new QActionGroup(this); + fpsGroup->addAction(ui->action60FPS); + fpsGroup->addAction(ui->action30FPS); + fpsGroup->addAction(ui->action20FPS); + fpsGroup->addAction(ui->action15FPS); + fpsGroup->addAction(ui->action10FPS); + fpsGroup->addAction(ui->action5FPS); + + + connect(ui->actionAutoV, SIGNAL(toggled(bool)), ui->controller_iso, SLOT(setAutoMultimeterV(bool))); + connect(ui->actionV, SIGNAL(toggled(bool)), ui->controller_iso, SLOT(setForceVolts(bool))); + connect(ui->actionMV, SIGNAL(toggled(bool)), ui->controller_iso, SLOT(setForceMillivolts(bool))); + connect(ui->actionAutoI, SIGNAL(toggled(bool)), ui->controller_iso, SLOT(setAutoMultimeterI(bool))); + connect(ui->actionA, SIGNAL(toggled(bool)), ui->controller_iso, SLOT(setForceAmps(bool))); + connect(ui->actionMA, SIGNAL(toggled(bool)), ui->controller_iso, SLOT(setForceMilliamps(bool))); + connect(ui->actionAutoR, SIGNAL(toggled(bool)), ui->controller_iso, SLOT(setAutoMultimeterR(bool))); + connect(ui->actionOhm, SIGNAL(toggled(bool)), ui->controller_iso, SLOT(setForceOhms(bool))); + connect(ui->actionKOhm, SIGNAL(toggled(bool)), ui->controller_iso, SLOT(setForceKiloOhms(bool))); + connect(ui->actionAutoC, SIGNAL(toggled(bool)), ui->controller_iso, SLOT(setAutoMultimeterC(bool))); + connect(ui->actionNF, SIGNAL(toggled(bool)), ui->controller_iso, SLOT(setForceNFarads(bool))); + connect(ui->action_F, SIGNAL(toggled(bool)), ui->controller_iso, SLOT(setForceUFarads(bool))); + + + uartBaudGroup_CH1 = new QActionGroup(this); + uartBaudGroup_CH1->addAction(ui->action300); + uartBaudGroup_CH1->addAction(ui->action600); + uartBaudGroup_CH1->addAction(ui->action1200); + uartBaudGroup_CH1->addAction(ui->action2400); + uartBaudGroup_CH1->addAction(ui->action4800); + uartBaudGroup_CH1->addAction(ui->action9600); + uartBaudGroup_CH1->addAction(ui->action14400); + uartBaudGroup_CH1->addAction(ui->action19200); + uartBaudGroup_CH1->addAction(ui->action28800); + uartBaudGroup_CH1->addAction(ui->action38400); + uartBaudGroup_CH1->addAction(ui->action57600); + uartBaudGroup_CH1->addAction(ui->action115200); + ui->action9600->setChecked(1); + + uartBaudGroup_CH2 = new QActionGroup(this); + uartBaudGroup_CH2->addAction(ui->action300_2); + uartBaudGroup_CH2->addAction(ui->action600_2); + uartBaudGroup_CH2->addAction(ui->action1200_2); + uartBaudGroup_CH2->addAction(ui->action2400_2); + uartBaudGroup_CH2->addAction(ui->action4800_2); + uartBaudGroup_CH2->addAction(ui->action9600_2); + uartBaudGroup_CH2->addAction(ui->action14400_2); + uartBaudGroup_CH2->addAction(ui->action19200_2); + uartBaudGroup_CH2->addAction(ui->action28800_2); + uartBaudGroup_CH2->addAction(ui->action38400_2); + uartBaudGroup_CH2->addAction(ui->action57600_2); + uartBaudGroup_CH2->addAction(ui->action115200_2); + ui->action9600_2->setChecked(1); + + connectionTypeGroup = new QActionGroup(this); + connectionTypeGroup->addAction(ui->actionLo_bw); + connectionTypeGroup->addAction(ui->actionSingle_ep_msync); + connectionTypeGroup->addAction(ui->actionSingle_ep_async); + ui->actionLo_bw->setChecked(1); + expected_variant = 1; //for default Lo_bw mode; + + ui->actionLo_bw->setVisible(false); + ui->actionSingle_ep_msync->setVisible(false); + ui->actionSingle_ep_async->setVisible(false); + ui->menuConnection_Type->menuAction()->setVisible(false); + + //Hide unsupported option!!! + ui->menuFrame_rate->menuAction()->setVisible(false); + +} + +void MainWindow::on_actionGain0_5_triggered() +{ + ui->controller_iso->driver->setGain(0.5); + ui->controller_iso->setAutoGain(0); +} + +void MainWindow::on_actionGain1_triggered() +{ + ui->controller_iso->driver->setGain(1); + ui->controller_iso->setAutoGain(0); +} + +void MainWindow::on_actionGain2_triggered() +{ + ui->controller_iso->driver->setGain(2); + ui->controller_iso->setAutoGain(0); +} + +void MainWindow::on_actionGain4_triggered() +{ + ui->controller_iso->driver->setGain(4); + ui->controller_iso->setAutoGain(0); +} + +void MainWindow::on_actionGain8_triggered() +{ + ui->controller_iso->driver->setGain(8); + ui->controller_iso->setAutoGain(0); +} + +void MainWindow::on_actionGain16_triggered() +{ + ui->controller_iso->driver->setGain(16); + ui->controller_iso->setAutoGain(0); +} + +void MainWindow::on_actionGain32_triggered() +{ + ui->controller_iso->driver->setGain(32); + ui->controller_iso->setAutoGain(0); +} + +void MainWindow::on_actionGain64_triggered() +{ + ui->controller_iso->driver->setGain(64); + ui->controller_iso->setAutoGain(0); +} +void MainWindow::on_actionGainAuto_triggered() +{ + ui->controller_iso->setAutoGain(1); +} + +void MainWindow::on_actionCursor_Stats_triggered(bool checked) +{ + ui->controller_iso->cursorStatsEnabled = checked; +} + +void MainWindow::connectDisplaySignals(){ + connect(ui->actionMax, SIGNAL(toggled(bool)), ui->voltageInfoMaxLabel_CH1, SLOT(setVisible(bool))); + connect(ui->actionMax, SIGNAL(toggled(bool)), ui->voltageInfoMaxDisplay_CH1, SLOT(setVisible(bool))); + + connect(ui->actionMin, SIGNAL(toggled(bool)), ui->voltageInfoMinLabel_CH1, SLOT(setVisible(bool))); + connect(ui->actionMin, SIGNAL(toggled(bool)), ui->voltageInfoMinDisplay_CH1, SLOT(setVisible(bool))); + + connect(ui->actionMean, SIGNAL(toggled(bool)), ui->VoltageInfoMeanLabel_CH1, SLOT(setVisible(bool))); + connect(ui->actionMean, SIGNAL(toggled(bool)), ui->voltageInfoMeanDisplay_CH1, SLOT(setVisible(bool))); + + connect(ui->actionRMS, SIGNAL(toggled(bool)), ui->voltageInfoRmsLabel_CH1, SLOT(setVisible(bool))); + connect(ui->actionRMS, SIGNAL(toggled(bool)), ui->voltageInfoRmsDisplay_CH1, SLOT(setVisible(bool))); + + ui->voltageInfoMaxLabel_CH1->setVisible(0); + ui->voltageInfoMaxDisplay_CH1->setVisible(0); + ui->voltageInfoMinLabel_CH1->setVisible(0); + ui->voltageInfoMinDisplay_CH1->setVisible(0); + ui->VoltageInfoMeanLabel_CH1->setVisible(0); + ui->voltageInfoMeanDisplay_CH1->setVisible(0); + ui->voltageInfoRmsLabel_CH1->setVisible(0); + ui->voltageInfoRmsDisplay_CH1->setVisible(0); + + connect(ui->actionMax_2, SIGNAL(toggled(bool)), ui->voltageInfoMaxLabel_CH2, SLOT(setVisible(bool))); + connect(ui->actionMax_2, SIGNAL(toggled(bool)), ui->voltageInfoMaxDisplay_CH2, SLOT(setVisible(bool))); + + connect(ui->actionMin_2, SIGNAL(toggled(bool)), ui->voltageInfoMinLabel_CH2, SLOT(setVisible(bool))); + connect(ui->actionMin_2, SIGNAL(toggled(bool)), ui->voltageInfoMinDisplay_CH2, SLOT(setVisible(bool))); + + connect(ui->actionMean_2, SIGNAL(toggled(bool)), ui->VoltageInfoMeanLabel_CH2, SLOT(setVisible(bool))); + connect(ui->actionMean_2, SIGNAL(toggled(bool)), ui->voltageInfoMeanDisplay_CH2, SLOT(setVisible(bool))); + + connect(ui->actionRMS_2, SIGNAL(toggled(bool)), ui->voltageInfoRmsLabel_CH2, SLOT(setVisible(bool))); + connect(ui->actionRMS_2, SIGNAL(toggled(bool)), ui->voltageInfoRmsDisplay_CH2, SLOT(setVisible(bool))); + + ui->voltageInfoMaxLabel_CH2->setVisible(0); + ui->voltageInfoMaxDisplay_CH2->setVisible(0); + ui->voltageInfoMinLabel_CH2->setVisible(0); + ui->voltageInfoMinDisplay_CH2->setVisible(0); + ui->VoltageInfoMeanLabel_CH2->setVisible(0); + ui->voltageInfoMeanDisplay_CH2->setVisible(0); + ui->voltageInfoRmsLabel_CH2->setVisible(0); + ui->voltageInfoRmsDisplay_CH2->setVisible(0); +} + + + +void MainWindow::on_action300_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH1 = 300; + } +} + +void MainWindow::on_action600_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH1 = 600; + } +} + +void MainWindow::on_action1200_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH1 = 1200; + } +} + +void MainWindow::on_action2400_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH1 = 2400; + } +} + +void MainWindow::on_action4800_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH1 = 4800; + } +} + +void MainWindow::on_action9600_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH1 = 9600; + } +} + +void MainWindow::on_action14400_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH1 = 14400; + } +} + +void MainWindow::on_action19200_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH1 = 19200; + } +} + +void MainWindow::on_action28800_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH1 = 28800; + } +} + +void MainWindow::on_action38400_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH1 = 38400; + } +} + +void MainWindow::on_action57600_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH1 = 57600; + } +} + +void MainWindow::on_action115200_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH1 = 115200; + } +} + +void MainWindow::on_action300_2_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH2 = 300; + } +} + +void MainWindow::on_action600_2_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH2 = 600; + } +} + +void MainWindow::on_action1200_2_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH2 = 1200; + } +} + +void MainWindow::on_action2400_2_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH2 = 2400; + } +} + +void MainWindow::on_action4800_2_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH2 = 4800; + } +} + +void MainWindow::on_action9600_2_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH2 = 9600; + } +} + +void MainWindow::on_action14400_2_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH2 = 14400; + } +} + +void MainWindow::on_action19200_2_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH2 = 19200; + } +} + +void MainWindow::on_action28800_2_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH2 = 28800; + } +} + +void MainWindow::on_action38400_2_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH2 = 38400; + } +} + +void MainWindow::on_action57600_2_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH2 = 57600; + } +} + +void MainWindow::on_action115200_2_toggled(bool arg1) +{ + if(arg1){ + ui->controller_iso->baudRate_CH2 = 115200; + } +} + +void MainWindow::cycleBaudRate_CH1(){ + QAction *currentAction = uartBaudGroup_CH1->checkedAction(); + qDebug() << currentAction; + if(currentAction==ui->action300){ + ui->action600->setChecked(1); + return; + } + if(currentAction==ui->action600){ + ui->action1200->setChecked(1); + return; + } + if(currentAction==ui->action1200){ + ui->action2400->setChecked(1); + return; + } + if(currentAction==ui->action2400){ + ui->action4800->setChecked(1); + return; + } + if(currentAction==ui->action4800){ + ui->action9600->setChecked(1); + return; + } + if(currentAction==ui->action9600){ + ui->action14400->setChecked(1); + return; + } + if(currentAction==ui->action14400){ + ui->action19200->setChecked(1); + return; + } + if(currentAction==ui->action19200){ + ui->action28800->setChecked(1); + return; + } + if(currentAction==ui->action28800){ + ui->action38400->setChecked(1); + return; + } + if(currentAction==ui->action38400){ + ui->action57600->setChecked(1); + return; + } + if(currentAction==ui->action57600){ + ui->action115200->setChecked(1); + return; + } + if(currentAction==ui->action115200){ + ui->action300->setChecked(1); + return; + } + qFatal("Invalid state in MainWindow::cycleBaudRate_CH1()"); +} + +void MainWindow::cycleBaudRateBackwards_CH1(){ + QAction *currentAction = uartBaudGroup_CH1->checkedAction(); + qDebug() << currentAction; + if(currentAction==ui->action1200){ + ui->action600->setChecked(1); + return; + } + if(currentAction==ui->action2400){ + ui->action1200->setChecked(1); + return; + } + if(currentAction==ui->action4800){ + ui->action2400->setChecked(1); + return; + } + if(currentAction==ui->action9600){ + ui->action4800->setChecked(1); + return; + } + if(currentAction==ui->action14400){ + ui->action9600->setChecked(1); + return; + } + if(currentAction==ui->action19200){ + ui->action14400->setChecked(1); + return; + } + if(currentAction==ui->action28800){ + ui->action19200->setChecked(1); + return; + } + if(currentAction==ui->action38400){ + ui->action28800->setChecked(1); + return; + } + if(currentAction==ui->action57600){ + ui->action38400->setChecked(1); + return; + } + if(currentAction==ui->action115200){ + ui->action57600->setChecked(1); + return; + } + if(currentAction==ui->action300){ + ui->action115200->setChecked(1); + return; + } + if(currentAction==ui->action600){ + ui->action300->setChecked(1); + return; + } + qFatal("Invalid state in MainWindow::cycleBaudRateBackwards_CH1()"); +} + +void MainWindow::cycleBaudRate_CH2(){ + QAction *currentAction = uartBaudGroup_CH2->checkedAction(); + qDebug() << currentAction; + if(currentAction==ui->action300_2){ + ui->action600_2->setChecked(1); + return; + } + if(currentAction==ui->action600_2){ + ui->action1200_2->setChecked(1); + return; + } + if(currentAction==ui->action1200_2){ + ui->action2400_2->setChecked(1); + return; + } + if(currentAction==ui->action2400_2){ + ui->action4800_2->setChecked(1); + return; + } + if(currentAction==ui->action4800_2){ + ui->action9600_2->setChecked(1); + return; + } + if(currentAction==ui->action9600_2){ + ui->action14400_2->setChecked(1); + return; + } + if(currentAction==ui->action14400_2){ + ui->action19200_2->setChecked(1); + return; + } + if(currentAction==ui->action19200_2){ + ui->action28800_2->setChecked(1); + return; + } + if(currentAction==ui->action28800_2){ + ui->action38400_2->setChecked(1); + return; + } + if(currentAction==ui->action38400_2){ + ui->action57600_2->setChecked(1); + return; + } + if(currentAction==ui->action57600_2){ + ui->action115200_2->setChecked(1); + return; + } + if(currentAction==ui->action115200_2){ + ui->action300_2->setChecked(1); + return; + } + qFatal("Invalid state in MainWindow::cycleBaudRate_CH2()"); +} + +void MainWindow::cycleBaudRateBackwards_CH2(){ + QAction *currentAction = uartBaudGroup_CH2->checkedAction(); + qDebug() << currentAction; + if(currentAction==ui->action1200_2){ + ui->action600_2->setChecked(1); + return; + } + if(currentAction==ui->action2400_2){ + ui->action1200_2->setChecked(1); + return; + } + if(currentAction==ui->action4800_2){ + ui->action2400_2->setChecked(1); + return; + } + if(currentAction==ui->action9600_2){ + ui->action4800_2->setChecked(1); + return; + } + if(currentAction==ui->action14400_2){ + ui->action9600_2->setChecked(1); + return; + } + if(currentAction==ui->action19200_2){ + ui->action14400_2->setChecked(1); + return; + } + if(currentAction==ui->action28800_2){ + ui->action19200_2->setChecked(1); + return; + } + if(currentAction==ui->action38400_2){ + ui->action28800_2->setChecked(1); + return; + } + if(currentAction==ui->action57600_2){ + ui->action38400_2->setChecked(1); + return; + } + if(currentAction==ui->action115200_2){ + ui->action57600_2->setChecked(1); + return; + } + if(currentAction==ui->action300_2){ + ui->action115200_2->setChecked(1); + return; + } + if(currentAction==ui->action600_2){ + ui->action300_2->setChecked(1); + return; + } + qFatal("Invalid state in MainWindow::cycleBaudRateBackwards_CH2()"); +} + +void MainWindow::initShortcuts(){ + shortcut_cycleBaudRate_CH1 = new QShortcut(QKeySequence("Ctrl+B"), ui->menuBar); + shortcut_cycleBaudRateBackwards_CH1 = new QShortcut(QKeySequence("Ctrl+Shift+B"), ui->menuBar); + shortcut_cycleBaudRate_CH2 = new QShortcut(QKeySequence("Ctrl+Alt+B"), ui->menuBar); + shortcut_cycleBaudRateBackwards_CH2 = new QShortcut(QKeySequence("Ctrl+Shift+Alt+B"), ui->menuBar); + shortcut_snapScopeToCursors = new QShortcut(QKeySequence("Z"), ui->menuBar); + shortcut_manualRange = new QShortcut(QKeySequence("M"), ui->menuBar); + shortcut_snapshot = new QShortcut(QKeySequence("c"), this); + + shortcut_ArrowUp = new QShortcut(QKeySequence("Up"), ui->menuBar); + shortcut_ArrowDown = new QShortcut(QKeySequence("Down"), ui->menuBar); + shortcut_CtrlArrowUp = new QShortcut(QKeySequence("Ctrl+Up"), ui->menuBar); + shortcut_CtrlArrowDown = new QShortcut(QKeySequence("Ctrl+Down"), ui->menuBar); + shortcut_w = new QShortcut(QKeySequence("w"), ui->menuBar); + shortcut_s = new QShortcut(QKeySequence("s"), ui->menuBar); + shortcut_ctrlW = new QShortcut(QKeySequence("Ctrl+w"), ui->menuBar); + shortcut_ctrlS = new QShortcut(QKeySequence("Ctrl+s"), ui->menuBar); + + shortcut_a = new QShortcut(QKeySequence("a"), this); + shortcut_d = new QShortcut(QKeySequence("d"), this); + shortcut_ArrowLeft = new QShortcut(QKeySequence("Left"), this); + shortcut_ArrowRight = new QShortcut(QKeySequence("Right"), this); + + + shortcut_Debug = new QShortcut(QKeySequence("Home"), this); + shortcut_Esc = new QShortcut(QKeySequence("Esc"), this); + + + connect(shortcut_cycleBaudRate_CH1, SIGNAL(activated()), this, SLOT(cycleBaudRate_CH1())); + connect(shortcut_cycleBaudRateBackwards_CH1, SIGNAL(activated()), this, SLOT(cycleBaudRateBackwards_CH1())); + connect(shortcut_cycleBaudRate_CH2, SIGNAL(activated()), this, SLOT(cycleBaudRate_CH2())); + connect(shortcut_cycleBaudRateBackwards_CH2, SIGNAL(activated()), this, SLOT(cycleBaudRateBackwards_CH2())); + connect(shortcut_snapshot, SIGNAL(activated()), this, SLOT(on_actionTake_Snapshot_triggered())); + + connect(shortcut_ArrowUp, SIGNAL(activated()), this, SLOT(arrowUpTriggered())); + connect(shortcut_ArrowDown, SIGNAL(activated()), this, SLOT(arrowDownTriggered())); + connect(shortcut_CtrlArrowUp, SIGNAL(activated()), this, SLOT(ctrlArrowUpTriggered())); + connect(shortcut_CtrlArrowDown, SIGNAL(activated()), this, SLOT(ctrlArrowDownTriggered())); + connect(shortcut_w, SIGNAL(activated()), this, SLOT(arrowUpTriggered())); + connect(shortcut_s, SIGNAL(activated()), this, SLOT(arrowDownTriggered())); + connect(shortcut_ctrlW, SIGNAL(activated()), this, SLOT(ctrlArrowUpTriggered())); + connect(shortcut_ctrlS, SIGNAL(activated()), this, SLOT(ctrlArrowDownTriggered())); + + connect(shortcut_a, SIGNAL(activated()), this, SLOT(cycleDelayLeft())); + connect(shortcut_d, SIGNAL(activated()), this, SLOT(cycleDelayRight())); + + connect(shortcut_ArrowLeft, SIGNAL(activated()), this, SLOT(cycleDelayLeft())); + connect(shortcut_ArrowRight, SIGNAL(activated()), this, SLOT(cycleDelayRight())); + + connect(shortcut_snapScopeToCursors, SIGNAL(activated()), this, SLOT(on_actionSnap_to_Cursors_triggered())); + connect(shortcut_manualRange, SIGNAL(activated()), this, SLOT(on_actionEnter_Manually_triggered())); + + connect(shortcut_Debug, SIGNAL(activated()), this, SLOT(enableLabradorDebugging())); + connect(shortcut_Esc, SIGNAL(activated()), this, SLOT(reinitUsb())); + +} + +void MainWindow::timeBaseNeedsChanging(bool positive){ + int tempVal = ui->timeBaseSlider->value(); + tempVal += positive ? 1 : -1; + ui->timeBaseSlider->setValue(tempVal); +} + +void MainWindow::on_actionForce_Square_triggered(bool checked) +{ + forceSquare = checked; + //Force redraw! + int tempHeight = this->height(); + int tempWidth = this->width(); + this->resize(tempWidth+1, tempHeight+1); + this->resize(tempWidth, tempHeight); +} + +void MainWindow::arrowUpTriggered(){ + qDebug() << "Boy UP!"; + if(!(ui->scopeAxes->underMouse())) return; + + QPoint point = ui->scopeAxes->mapFromGlobal(QCursor::pos()); + wheelEmu = new QWheelEvent(point, 120, 0, 0, Qt::Vertical); + ui->controller_iso->setVoltageRange(wheelEmu); +} + +void MainWindow::arrowDownTriggered(){ + qDebug() << "Boy DOWN!"; + if(!(ui->scopeAxes->underMouse())) return; + + QPoint point = ui->scopeAxes->mapFromGlobal(QCursor::pos()); + wheelEmu = new QWheelEvent(point, -120, 0, 0, Qt::Vertical); + ui->controller_iso->setVoltageRange(wheelEmu); +} + +void MainWindow::ctrlArrowUpTriggered(){ + qDebug() << "Boy (ctrl) UP!"; + if(!(ui->scopeAxes->underMouse())) return; + + QPoint point = ui->scopeAxes->mapFromGlobal(QCursor::pos()); + wheelEmu = new QWheelEvent(point, 120, 0, Qt::ControlModifier, Qt::Vertical); + ui->controller_iso->setVoltageRange(wheelEmu); +} + +void MainWindow::ctrlArrowDownTriggered(){ + qDebug() << "Boy (ctrl) DOWN!"; + if(!(ui->scopeAxes->underMouse())) return; + + QPoint point = ui->scopeAxes->mapFromGlobal(QCursor::pos()); + wheelEmu = new QWheelEvent(point, -120, 0, Qt::ControlModifier, Qt::Vertical); + ui->controller_iso->setVoltageRange(wheelEmu); +} + +void MainWindow::cycleDelayRight(){ + qDebug() << "RIGHT"; + ui->controller_iso->delay -= ui->controller_iso->window/10; + if(ui->controller_iso->delay < 0) ui->controller_iso->delay = 0; +} + +void MainWindow::cycleDelayLeft(){ + qDebug() << "LEFT"; + ui->controller_iso->delay += ui->controller_iso->window/10; + if(ui->controller_iso->delay > (MAX_WINDOW_SIZE - ui->controller_iso->window)) ui->controller_iso->delay = (MAX_WINDOW_SIZE - ui->controller_iso->window); +} + +void MainWindow::enableLabradorDebugging(){ + qDebug() << "DEBUG MODE ACTIVE"; + + ui->debugButton1->setVisible(1); + ui->debugButton2->setVisible(1); + ui->debugButton3->setVisible(1); + ui->debugConsole->setVisible(1); + + new Q_DebugStream(std::cout, ui->debugConsole); //Redirect Console output to QTextEdit + Q_DebugStream::registerQDebugMessageHandler(); //Redirect qDebug() output to QTextEdit + qDebug() << "DEBUG MODE ACTIVE"; +} + +void MainWindow::on_actionAutomatically_Enable_Cursors_toggled(bool enabled) +{ + ui->makeCursorsNicer->setTurnedOn(enabled); +} + +void MainWindow::on_action60FPS_toggled(bool enabled) +{ + if(enabled){ + TIMER_PERIOD = 17; + ui->controller_iso->startTimer(); + } +} +void MainWindow::on_action30FPS_toggled(bool enabled) +{ + if(enabled){ + TIMER_PERIOD = 33; + ui->controller_iso->startTimer(); + } +} +void MainWindow::on_action20FPS_toggled(bool enabled) +{ + if(enabled){ + TIMER_PERIOD = 40; + ui->controller_iso->startTimer(); + } +} +void MainWindow::on_action15FPS_toggled(bool enabled) +{ + if(enabled){ + TIMER_PERIOD = 67; + ui->controller_iso->startTimer(); + } +} +void MainWindow::on_action10FPS_toggled(bool enabled) +{ + if(enabled){ + TIMER_PERIOD = 100; + ui->controller_iso->startTimer(); + } +} +void MainWindow::on_action5FPS_toggled(bool enabled) +{ + qDebug() << "5FPS"; + if(enabled){ + qDebug() << "5FPS is enabled!"; + TIMER_PERIOD = 200; + ui->controller_iso->startTimer(); + } +} + + +void MainWindow::on_actionAuto_Lock_toggled(bool arg1) +{ + ui->lockPsuCheckBox->enableTimer(arg1); + ui->lockPsuCheckBox->timer->start(ui->lockPsuCheckBox->timerLength); +} + +void MainWindow::on_actionSnap_to_Cursors_triggered() +{ + double xLeft, xRight, yBot, yTop; + + yTop = ui->controller_iso->y1 > ui->controller_iso->y0 ? ui->controller_iso->y1 : ui->controller_iso->y0; + yBot = ui->controller_iso->y1 > ui->controller_iso->y0 ? ui->controller_iso->y0 : ui->controller_iso->y1; + + xRight = ui->controller_iso->x1 > ui->controller_iso->x0 ? ui->controller_iso->x1 : ui->controller_iso->x0; + xLeft = ui->controller_iso->x1 > ui->controller_iso->x0 ? ui->controller_iso->x0 : ui->controller_iso->x1; + + if((yBot-yTop) != 0){ + ui->controller_iso->topRange = yTop; + ui->controller_iso->botRange = yBot; + } + + if((xLeft - xRight) != 0){ + ui->controller_iso->delay = - xRight; + ui->controller_iso->window = xRight - xLeft; + } +} + +void MainWindow::on_actionEnter_Manually_triggered() +{ + ui->controller_iso->delay = 0; + scopeRangeEnterDialog dialog(this, ui->controller_iso->topRange, ui->controller_iso->botRange, ui->controller_iso->window, ui->controller_iso->delay); + dialog.setModal(true); + connect(&dialog, SIGNAL(yTopUpdated(double)), ui->controller_iso, SLOT(setTopRange(double))); + connect(&dialog, SIGNAL(yBotUpdated(double)), ui->controller_iso, SLOT(setBotRange(double))); + connect(&dialog, SIGNAL(windowUpdated(double)), ui->controller_iso, SLOT(setTimeWindow(double))); + dialog.exec(); +} + +void MainWindow::helloWorld(){ + qDebug() << "Hello World!"; +} + +#define QSETTINGS_DEFAULT_RETURN 42069 +void MainWindow::readSettingsFile(){ + settings = new QSettings("settings.ini", QSettings::IniFormat); + int connectionType = settings->value("ConnectionType", QSETTINGS_DEFAULT_RETURN).toInt(); + double calibrate_vref_ch1 = settings->value("CalibrateVrefCH1", 1.65).toDouble(); + double calibrate_vref_ch2 = settings->value("CalibrateVrefCH2", 1.65).toDouble(); + double calibrate_gain_ch1 = settings->value("CalibrateGainCH1", R4/(R3+R4)).toDouble(); + double calibrate_gain_ch2 = settings->value("CalibrateGainCH2", R4/(R3+R4)).toDouble(); + + //Change connection Type + switch(connectionType){ + case 0: + ui->actionLo_bw->setChecked(1); + on_actionLo_bw_triggered(); + break; + case 1: + ui->actionSingle_ep_msync->setChecked(1); + on_actionSingle_ep_msync_triggered(); + break; + case 2: + ui->actionSingle_ep_async->setChecked(1); + on_actionSingle_ep_async_triggered(); + break; + } + + //Fill in calibration data + ui->controller_iso->ch1_ref = 3.3 - calibrate_vref_ch1; + ui->controller_iso->ch2_ref = 3.3 - calibrate_vref_ch2; + ui->controller_iso->frontendGain_CH1 = calibrate_gain_ch1; + ui->controller_iso->frontendGain_CH2 = calibrate_gain_ch2; + ui->controller_iso->internalBuffer375_CH1->voltage_ref = 3.3 - calibrate_vref_ch1; + ui->controller_iso->internalBuffer750->voltage_ref = 3.3 - calibrate_vref_ch1; + ui->controller_iso->internalBuffer375_CH2->voltage_ref = 3.3 - calibrate_vref_ch2; + ui->controller_iso->internalBuffer375_CH1->frontendGain = calibrate_gain_ch1; + ui->controller_iso->internalBuffer750->frontendGain = calibrate_gain_ch1; + ui->controller_iso->internalBuffer375_CH2->frontendGain = calibrate_gain_ch2; +} + +void MainWindow::on_actionRecord_triggered(bool checked) +{ + if(!checked){ + ui->controller_iso->internalBuffer375_CH1->disableFileIO(); + ui->controller_iso->internalBuffer375_CH2->disableFileIO(); + ui->controller_iso->internalBuffer750->disableFileIO(); + + delete(output375_CH1); + delete(output375_CH2); + delete(output750); + return; + } + QDateTime now = QDateTime::currentDateTime(); + QString dateString = now.toString("yyyyMMddhhmmsszzz"); + qDebug() << dateString; + + qDebug() << "QStandardPaths::DocumentsLocation" << QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); + outputDir = new QDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)); + outputDir->mkdir("EspoTek"); + outputDir->cd("EspoTek"); + outputDir->mkdir("recordings"); + outputDir->cd("recordings"); + outputDir->mkdir(dateString); + outputDir->cd(dateString); + + qDebug() << outputDir->absolutePath(); + + output375_CH1 = new QFile(outputDir->filePath("375_CH1.csv")); + output375_CH2 = new QFile(outputDir->filePath("375_CH2.csv")); + output750 = new QFile(outputDir->filePath("750.csv")); + + ui->controller_iso->internalBuffer375_CH1->enableFileIO(output375_CH1); + ui->controller_iso->internalBuffer375_CH2->enableFileIO(output375_CH2); + ui->controller_iso->internalBuffer750->enableFileIO(output750); + + delete(outputDir); + return; +} + +void MainWindow::on_actionTake_Snapshot_triggered() +{ + ui->controller_iso->takeSnapshot(); +} + +void MainWindow::reinitUsb(void){ + ui->controller_iso->doNotTouchGraph = true; + ui->controller_iso->driver->saveState(&reinitdeviceMode, &reinitScopeGain, &reinitCurrentPsuVoltage, &reinitDigitalPinState); + +#ifdef PLATFORM_WINDOWS + reinitUsbStage2(); +#else + if(!(ui->controller_iso->driver->connected)){ + reinitUsbStage2(); + } else{ + ui->controller_iso->driver->shutdownProcedure(); + QTimer::singleShot(3500, this, SLOT(reinitUsbStage2())); + } +#endif + qDebug() << "ReinitUsb Stage 1 complete"; +} + +void MainWindow::reinitUsbStage2(void){ + qDebug() << "ReinitUsb entering stage 2"; + delete(ui->controller_iso->driver); + qDebug() << "Reinitialising USB driver!"; + ui->controller_iso->driver = new _PLATFORM_DEPENDENT_USB_OBJECT(); + + //Reconnect the other objects. + ui->controller_iso->driver->setBufferPtr(ui->bufferDisplay); + connect(ui->debugButton1, SIGNAL(clicked()), ui->controller_iso->driver, SLOT(avrDebug())); + connect(ui->debugButton3, SIGNAL(clicked()), ui->controller_iso->driver, SLOT(bootloaderJump())); + connect(ui->psuSlider, SIGNAL(voltageChanged(double)), ui->controller_iso->driver, SLOT(setPsu(double))); + connect(ui->controller_iso, SIGNAL(setGain(double)), ui->controller_iso->driver, SLOT(setGain(double))); + connect(ui->controller_fg, SIGNAL(functionGenToUpdate(int,functionGenControl*)), ui->controller_iso->driver, SLOT(setFunctionGen(int,functionGenControl*))); + connect(ui->bufferDisplay, SIGNAL(modeChange(int)), ui->controller_iso->driver, SLOT(setDeviceMode(int))); + connect(ui->bufferDisplay, SIGNAL(updateDig(int)), ui->controller_iso->driver, SLOT(newDig(int))); + + //Set the settings again! + connect(ui->controller_iso->driver, SIGNAL(gainBuffers(double)), ui->controller_iso, SLOT(gainBuffers(double))); + connect(ui->controller_iso->driver, SIGNAL(disableWindow(bool)), this, SLOT(setEnabled(bool))); + connect(ui->controller_iso->driver, SIGNAL(sendClearBuffer(bool,bool,bool)), ui->controller_iso, SLOT(clearBuffers(bool,bool,bool))); + //connect(ui->controller_iso->driver, SIGNAL(startIsoTimer()), ui->controller_iso, SLOT(startTimer())); + connect(ui->controller_iso->driver, SIGNAL(setVisible_CH2(bool)), ui->controller_iso, SLOT(setVisible_CH2(bool))); + //connect(ui->controller_iso->driver, SIGNAL(enableMMTimer()), ui->controller_iso, SLOT(enableMM())); + connect(ui->controller_iso->driver, SIGNAL(checkXY(bool)), ui->xyDisplayLabel, SLOT(setChecked(bool))); + connect(ui->controller_iso->driver, SIGNAL(disableWindow(bool)), ui->deviceConnected, SLOT(connectedStatusChanged(bool))); + connect(ui->controller_iso->driver, SIGNAL(upTick()), ui->controller_iso, SLOT(timerTick())); + connect(ui->controller_iso->driver, SIGNAL(killMe()), this, SLOT(reinitUsb())); + connect(ui->controller_iso->driver, SIGNAL(connectedStatus(bool)), ui->deviceConnected, SLOT(connectedStatusChanged(bool))); + connect(ui->controller_iso->driver, SIGNAL(initialConnectComplete()), this, SLOT(resetUsbState())); + ui->controller_iso->driver->setGain(reinitScopeGain); + + readSettingsFile(); + + qDebug() << "ReinitUsbStage2 is returning"; +} + +void MainWindow::resetUsbState(void){ + //ui->controller_iso->driver->setDeviceMode(deviceMode); + //ui->controller_iso->driver->setPsu(currentPsuVoltage); + ui->psuSlider->poke(); + //ui->controller_iso->driver->newDig(digitalPinState); + ui->bufferDisplay->poke(); + ui->controller_iso->driver->setFunctionGen(0,ui->controller_fg); + ui->controller_iso->driver->setFunctionGen(1,ui->controller_fg); + + ui->controller_iso->clearBuffers(1,1,1); + ui->controller_iso->doNotTouchGraph = false; +} + + +#ifdef PLATFORM_ANDROID + +void MainWindow::on_actionOld_Person_Mode_triggered(bool checked) +{ + qDebug() << "Old Person Mode" << checked; + if(checked){ + QFont font = qApp->font(); + font.setPointSize(8); + qApp->setFont(font); + return; + }else{ + QFont font = qApp->font(); + font.setPointSize(6); + qApp->setFont(font); + } +} + +void MainWindow::screenRotateEvent(Qt::ScreenOrientation orientation) +{ + qDebug() << "Orientation:" << orientation; + + QWidget *oldCentralWidget = centralWidget(); + QLayout *oldLayout = oldCentralWidget->layout(); + oldLayout->removeWidget(ui->scopeAxes); + oldLayout->removeWidget(ui->stackedWidget); + oldLayout->removeWidget(ui->deviceConnected); + + QLayout *newLayout; + if((orientation == Qt::LandscapeOrientation) || (orientation == Qt::InvertedLandscapeOrientation)){ + newLayout = new QHBoxLayout(this); + ui->stackedWidget->setVisible(0); + } else { + newLayout = new QVBoxLayout(this); + ui->stackedWidget->setVisible(1); + } + newLayout->addWidget(ui->scopeAxes); + newLayout->addWidget(ui->stackedWidget); + newLayout->addWidget(ui->deviceConnected); + newLayout->setContentsMargins(0,0,0,0); + newLayout->setSpacing(0); + + QWidget* newCentralWidget = new QWidget(); + newCentralWidget->setLayout(newLayout); + setCentralWidget(newCentralWidget); + delete(oldCentralWidget); +} + +bool MainWindow::eventFilter(QObject *obj, QEvent *event){ + //qDebug() << event; + if(event->type() == QEvent::Gesture){ + qDebug() << "gesture!!"; + return gestureFilter(static_cast(event)); + } else { + return false; + } + + + //return QMainWindow::eventFilter(obj, event); +} + +bool MainWindow::gestureFilter(QGestureEvent *event){ + QGesture *capturedGesture = event->gesture(Qt::PinchGesture); + if(capturedGesture->gestureType() == Qt::PinchGesture){ + qDebug() << "pinch!"; + QPinchGesture *pinchGesture = static_cast(capturedGesture); + qDebug() << "Last Centre Point" << pinchGesture->lastCenterPoint(); + qDebug() << "Last Scale Factor" << pinchGesture->lastScaleFactor(); + qDebug() << "Start Centre Point" << pinchGesture->startCenterPoint(); + qDebug() << "Total Scale Factor" << pinchGesture->totalScaleFactor(); + qDebug() << "Angle" << pinchGesture->rotationAngle(); + + qreal totalScaleFactor = pinchGesture->totalScaleFactor(); + + bool embiggen; + if(totalScaleFactor >= ANDROID_SCALE_INSENSITIVITY){ + embiggen = true; + pinchGesture->setTotalScaleFactor(totalScaleFactor/ANDROID_SCALE_INSENSITIVITY); + } else if(totalScaleFactor < (1/ANDROID_SCALE_INSENSITIVITY)){ + embiggen = false; + pinchGesture->setTotalScaleFactor(totalScaleFactor*ANDROID_SCALE_INSENSITIVITY); + } else { + return true; + } + + QPoint point = pinchGesture->centerPoint().toPoint(); + qDebug() << point; + if(scalingInTimeAxis){ + wheelEmu = new QWheelEvent(point, (embiggen ? 120 : -120), 0, Qt::ControlModifier, Qt::Vertical); + } else{ + wheelEmu = new QWheelEvent(point, (embiggen ? 120 : -120), 0, 0, Qt::Vertical); + } + ui->controller_iso->setVoltageRange(wheelEmu); + + return true; + } else { + return false; + } +} + +void MainWindow::horiScaleEvent(bool enabled){ + if(enabled){ + ui->scaleHoriCheck->setChecked(true); + } + qDebug() << "Hori Scale"; + scalingInTimeAxis = true; + ui->scaleVertCheck->setChecked(false); +} + +void MainWindow::vertScaleEvent(bool enabled){ + if(enabled){ + ui->scaleVertCheck->setChecked(true); + } + qDebug() << "Vert Scale"; + scalingInTimeAxis = false; + ui->scaleHoriCheck->setChecked(false); +} + +#endif + +void MainWindow::on_actionCalibrate_triggered() +{ + //Must be mode 4 + //Must be DC coupled + //Voltage must be disconnected + caibrateStage = 0; + + if(!ui->controller_iso->driver->connected){ + calibrationMessages->setText("You need to connect the board before calibrating it!"); + calibrationMessages->exec(); + return; + } + if(ui->controller_iso->driver->deviceMode!=4){ + calibrationMessages->setStandardButtons(QMessageBox::Ok|QMessageBox::Cancel); + calibrationMessages->setText("The calibration sequence requires all devices to be turned off, except for the oscilloscope CH1 and CH2. Is it OK for me to change your workspace?"); + int choice = calibrationMessages->exec(); + calibrationMessages->setStandardButtons(QMessageBox::Ok); + if(choice == QMessageBox::Ok){ + qDebug() << "Changing workspace..."; + ui->psuSlider->setValue(0); + ui->busSifferGroup_CH1->setChecked(false); + ui->busSnifferGroup_CH2->setChecked(false); + ui->multimeterGroup->setChecked(false); + ui->triggerGroup->setChecked(false); + ui->scopeGroup_CH1->setChecked(true); + ui->scopeGroup_CH2->setChecked(true); + ui->pausedLabeL_CH1->setChecked(false); + ui->pausedLabel_CH2->setChecked(false); + ui->doubleSampleLabel->setChecked(false); + ui->acCoupledLabel_CH1->setChecked(false); + ui->acCoupledLabel_CH2->setChecked(false); + ui->pause_LA->setChecked(false); + ui->multimeterPauseCheckBox->setChecked(false); + } + else{ + return; + } + } + + //Throw out old calibration data in case of bad cali + ui->controller_iso->ch1_ref = 1.65; + ui->controller_iso->ch2_ref = 1.65; + ui->controller_iso->frontendGain_CH1 = (R4/(R3+R4)); + ui->controller_iso->frontendGain_CH2 = (R4/(R3+R4)); + ui->controller_iso->internalBuffer375_CH1->voltage_ref = 1.65; + ui->controller_iso->internalBuffer750->voltage_ref = 1.65; + ui->controller_iso->internalBuffer375_CH2->voltage_ref = 1.65; + ui->controller_iso->internalBuffer375_CH1->frontendGain = R4/(R3+R4); + ui->controller_iso->internalBuffer750->frontendGain = R4/(R3+R4); + ui->controller_iso->internalBuffer375_CH2->frontendGain = R4/(R3+R4); + + settings->setValue("CalibrateVrefCH1", 1.65); + settings->setValue("CalibrateVrefCH2", 1.65); + settings->setValue("CalibrateGainCH1", R4/(R3+R4)); + settings->setValue("CalibrateGainCH2", R4/(R3+R4)); + + qDebug() << "Calibration routine beginning!"; + calibrationMessages->setText("Please disconnect all wires from your Labrador board then press OK to continue."); + calibrationMessages->exec(); + + ui->controller_iso->clearBuffers(1,1,1); + QTimer::singleShot(1200, this, SLOT(calibrateStage2())); +} + +void MainWindow::calibrateStage2(){ + double vref_CH1 = ui->controller_iso->meanVoltageLast(1, 1, 128); + double vref_CH2 = ui->controller_iso->meanVoltageLast(1, 2, 128); + qDebug() << "VRef (CH1) = " << vref_CH1; + qDebug() << "VRef (CH2) = " << vref_CH2; + + if((vref_CH1 > 1.9) | (vref_CH1 < 1.4) | (vref_CH2 > 1.9) | (vref_CH2 < 1.4)){ + calibrationMessages->setText("Calibration has been abandoned due to out-of-range values. Both channels should show approximately 1.6V. Please disconnect all wires from your Labrador board and try again."); + calibrationMessages->exec(); + return; + } + + ui->controller_iso->ch1_ref = 3.3 - vref_CH1; + ui->controller_iso->ch2_ref = 3.3 - vref_CH2; + + ui->controller_iso->internalBuffer375_CH1->voltage_ref = 3.3 - vref_CH1; + ui->controller_iso->internalBuffer750->voltage_ref = 3.3 - vref_CH1; + ui->controller_iso->internalBuffer375_CH2->voltage_ref = 3.3 - vref_CH2; + + settings->setValue("CalibrateVrefCH1", vref_CH1); + settings->setValue("CalibrateVrefCH2", vref_CH2); + + calibrationMessages->setText("Please connect both oscilloscope channels to the outer shield of the USB connector then press OK to continue."); + calibrationMessages->exec(); + + ui->controller_iso->clearBuffers(1,1,1); + QTimer::singleShot(1200, this, SLOT(calibrateStage3())); +} + +void MainWindow::calibrateStage3(){ + double vMeasured_CH1 = ui->controller_iso->meanVoltageLast(1, 1, 128); + double vMeasured_CH2 = ui->controller_iso->meanVoltageLast(1, 2, 128); + + qDebug() << "VMeasured (CH1) = " << vMeasured_CH1; + qDebug() << "VMeasured (CH2) = " << vMeasured_CH2; + + if((vMeasured_CH1 > 0.3) | (vMeasured_CH1 < -0.3) | (vMeasured_CH2 > 0.3) | (vMeasured_CH2 < -0.3)){ + calibrationMessages->setText("Calibration has been abandoned due to out-of-range values. Both channels should show approximately 0V. Please try again."); + calibrationMessages->exec(); + return; + } + + double vref_CH1 = ui->controller_iso->ch1_ref; + double vref_CH2 = ui->controller_iso->ch2_ref; + + //G^ <= G + qDebug() << "Old gain (CH1) = " << ui->controller_iso->frontendGain_CH1; + ui->controller_iso->frontendGain_CH1 = (vref_CH1 - vMeasured_CH1)*(ui->controller_iso->frontendGain_CH1)/vref_CH1; + ui->controller_iso->frontendGain_CH2 = (vref_CH2 - vMeasured_CH2)*(ui->controller_iso->frontendGain_CH2)/vref_CH2; + qDebug() << "New gain (CH1) = " << ui->controller_iso->frontendGain_CH1; + + ui->controller_iso->internalBuffer375_CH1->frontendGain = (vref_CH1 - vMeasured_CH1)*(ui->controller_iso->frontendGain_CH1)/vref_CH1; + ui->controller_iso->internalBuffer750->frontendGain = (vref_CH1 - vMeasured_CH1)*(ui->controller_iso->frontendGain_CH1)/vref_CH1; + ui->controller_iso->internalBuffer375_CH2->frontendGain = (vref_CH2 - vMeasured_CH2)*(ui->controller_iso->frontendGain_CH2)/vref_CH2; + settings->setValue("CalibrateGainCH1", ui->controller_iso->frontendGain_CH1); + settings->setValue("CalibrateGainCH2", ui->controller_iso->frontendGain_CH2); + calibrationMessages->setText("Calibration complete."); + calibrationMessages->exec(); +} + +void MainWindow::rSourceIndexChanged(int newSource){ + if(newSource == 0){ +#ifndef PLATFORM_ANDROID + ui->multimeterRLabel->setVisible(true); + ui->multimeterRComboBox->setVisible(true); +#endif + ui->signalGenGroup_CH2->setEnabled(false); + ui->psuGroup->setEnabled(true); + ui->waveformSelect_CH2->setCurrentText("DC"); + ui->dcOffsetValue_CH2->setValue(0); + ui->amplitudeValue_CH2->setValue(3); + } + if(newSource == 1){ +#ifndef PLATFORM_ANDROID + ui->multimeterRLabel->setVisible(true); + ui->multimeterRComboBox->setVisible(true); +#endif + ui->psuGroup->setEnabled(false); + ui->signalGenGroup_CH2->setEnabled(true); + ui->psuSlider->setValue(100); + } + + if(newSource == 254){ + ui->signalGenGroup_CH2->setEnabled(false); + ui->psuGroup->setEnabled(true); +#ifndef PLATFORM_ANDROID + ui->multimeterRLabel->setVisible(false); + ui->multimeterRComboBox->setVisible(false); +#endif + ui->waveformSelect_CH2->setCurrentText("Square"); + ui->frequencyValue_CH2->setValue(4); + ui->dcOffsetValue_CH2->setValue(0); + ui->amplitudeValue_CH2->setValue(3); + } + + if(newSource == 255){ + ui->signalGenGroup_CH2->setEnabled(true); + ui->psuGroup->setEnabled(true); +#ifndef PLATFORM_ANDROID + ui->multimeterRLabel->setVisible(false); + ui->multimeterRComboBox->setVisible(false); +#endif + } +} + +void MainWindow::multimeterStateChange(bool enabled){ + if(enabled){ + int cIdx = ui->multimeterModeSelect->currentIndex(); + ui->controller_iso->setMultimeterType(cIdx); + } else rSourceIndexChanged(255); +} + +void MainWindow::on_actionLo_bw_triggered() +{ + expected_variant = 1; + settings->setValue("ConnectionType", 0); + if(ui->controller_iso->driver->connected) reinitUsb(); +} + +void MainWindow::on_actionSingle_ep_msync_triggered() +{ + expected_variant = 2; + settings->setValue("ConnectionType", 1); + if(ui->controller_iso->driver->connected) reinitUsb(); +} + +void MainWindow::on_actionSingle_ep_async_triggered() +{ + expected_variant = 2; + settings->setValue("ConnectionType", 2); + if(ui->controller_iso->driver->connected) reinitUsb(); +} diff --git a/Desktop_Interface/mainwindow.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/mainwindow.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index f8f416ca..00000000 --- a/Desktop_Interface/mainwindow.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bc4bed8592e50afd827ab64e8b9d480b2f1e85c1 \ No newline at end of file diff --git a/Desktop_Interface/mainwindow.h b/Desktop_Interface/mainwindow.h new file mode 100644 index 00000000..8a34f3fb --- /dev/null +++ b/Desktop_Interface/mainwindow.h @@ -0,0 +1,211 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "qcustomplot.h" + +#include "platformspecific.h" +#include "qcustomplot.h" +#include "ui_mainwindow.h" +#include "scoperangeenterdialog.h" +#include "isobuffer.h" +#include "q_debugstream.h" +#include "pinchcatcher.h" + + +//The Main Window object. This has a lot of control information too (keyboard shortcuts etc.)! + + + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + void resizeEvent(QResizeEvent *event); +private slots: + //Oscilloscope + void on_actionGain0_5_triggered(); + void on_actionGain1_triggered(); + void on_actionGain2_triggered(); + void on_actionGain4_triggered(); + void on_actionGain8_triggered(); + void on_actionGain16_triggered(); + void on_actionGain32_triggered(); + void on_actionGain64_triggered(); + void on_actionGainAuto_triggered(); + void on_actionCursor_Stats_triggered(bool checked); + void on_actionAutomatically_Enable_Cursors_toggled(bool arg1); + void on_action60FPS_toggled(bool enabled); + void on_action30FPS_toggled(bool enabled); + void on_action20FPS_toggled(bool enabled); + void on_action15FPS_toggled(bool enabled); + void on_action10FPS_toggled(bool enabled); + void on_action5FPS_toggled(bool enabled); + void on_actionSnap_to_Cursors_triggered(); + void on_actionEnter_Manually_triggered(); + + void connectDisplaySignals(); + void calibrateStage2(); + void calibrateStage3(); + + + //Logic Analyzer + void on_action300_toggled(bool arg1); + void on_action600_toggled(bool arg1); + void on_action1200_toggled(bool arg1); + void on_action2400_toggled(bool arg1); + void on_action4800_toggled(bool arg1); + void on_action9600_toggled(bool arg1); + void on_action14400_toggled(bool arg1); + void on_action19200_toggled(bool arg1); + void on_action28800_toggled(bool arg1); + void on_action38400_toggled(bool arg1); + void on_action57600_toggled(bool arg1); + void on_action115200_toggled(bool arg1); + + void on_action300_2_toggled(bool arg1); + void on_action600_2_toggled(bool arg1); + void on_action1200_2_toggled(bool arg1); + void on_action2400_2_toggled(bool arg1); + void on_action4800_2_toggled(bool arg1); + void on_action9600_2_toggled(bool arg1); + void on_action14400_2_toggled(bool arg1); + void on_action19200_2_toggled(bool arg1); + void on_action28800_2_toggled(bool arg1); + void on_action38400_2_toggled(bool arg1); + void on_action57600_2_toggled(bool arg1); + void on_action115200_2_toggled(bool arg1); + void cycleBaudRate_CH1(); + void cycleBaudRateBackwards_CH1(); + void cycleBaudRate_CH2(); + void cycleBaudRateBackwards_CH2(); + + //Deprecated/Unsupported + void timeBaseNeedsChanging(bool positive); + void on_actionForce_Square_triggered(bool checked); + void helloWorld(); + + //Keyboard Shortcuts + void arrowUpTriggered(); + void arrowDownTriggered(); + void ctrlArrowUpTriggered(); + void ctrlArrowDownTriggered(); + void cycleDelayLeft(); + void cycleDelayRight(); + void enableLabradorDebugging(); + + //Power Supply + void on_actionAuto_Lock_toggled(bool arg1); + + //File/other + void on_actionRecord_triggered(bool checked); + void on_actionTake_Snapshot_triggered(); + void reinitUsb(void); + void reinitUsbStage2(void); + void resetUsbState(void); + void rSourceIndexChanged(int newSource); + void multimeterStateChange(bool state); + +#ifdef PLATFORM_ANDROID + //Android Special + void on_actionOld_Person_Mode_triggered(bool checked); + void screenRotateEvent(Qt::ScreenOrientation orientation); + bool eventFilter(QObject *obj, QEvent *event); + bool gestureFilter(QGestureEvent *event); + void horiScaleEvent(bool enabled); + void vertScaleEvent(bool enabled); +#endif + + void on_actionCalibrate_triggered(); + void on_actionLo_bw_triggered(); + + void on_actionSingle_ep_msync_triggered(); + + void on_actionSingle_ep_async_triggered(); + +private: + //Generic Vars + Ui::MainWindow *ui; + QWheelEvent *wheelEmu; + bool forceSquare = false; + QCPItemText *textLabel; + QDir *outputDir; + QFile *output375_CH1, *output375_CH2, *output750; + unsigned char caibrateStage; + QMessageBox *calibrationMessages; + + int reinitdeviceMode; + double reinitScopeGain; + double reinitCurrentPsuVoltage; + int reinitDigitalPinState; + + QSettings *settings; + + //Generic Functions + void initialisePlot(); + void labelPsu(); + void menuSetup(); + void initShortcuts(); + void readSettingsFile(); + + //Shortcut pointers + QActionGroup *gainGroup; + QActionGroup *rangeGroupV; + QActionGroup *rangeGroupI; + QActionGroup *rangeGroupR; + QActionGroup *rangeGroupC; + QActionGroup *uartBaudGroup_CH1; + QActionGroup *uartBaudGroup_CH2; + QActionGroup *fpsGroup; + QActionGroup *connectionTypeGroup; + QShortcut *shortcut_cycleBaudRate_CH1; + QShortcut *shortcut_cycleBaudRateBackwards_CH1; + QShortcut *shortcut_cycleBaudRate_CH2; + QShortcut *shortcut_cycleBaudRateBackwards_CH2; + QShortcut *shortcut_ArrowUp; + QShortcut *shortcut_ArrowDown; + QShortcut *shortcut_CtrlArrowUp; + QShortcut *shortcut_CtrlArrowDown; + QShortcut *shortcut_w; + QShortcut *shortcut_ctrlW; + QShortcut *shortcut_s; + QShortcut *shortcut_ctrlS; + QShortcut *shortcut_a; + QShortcut *shortcut_d; + QShortcut *shortcut_ArrowLeft; + QShortcut *shortcut_ArrowRight; + QShortcut *shortcut_snapScopeToCursors;\ + QShortcut *shortcut_manualRange; + QShortcut *shortcut_snapshot; + QShortcut *shortcut_Debug; + QShortcut *shortcut_Esc; + +#ifdef PLATFORM_ANDROID + //Android Special + QScreen *screenPtr; + bool scalingInTimeAxis = false; +#endif +}; + +#endif // MAINWINDOW_H diff --git a/Desktop_Interface/mainwindow.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/mainwindow.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 68a6b44d..00000000 --- a/Desktop_Interface/mainwindow.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7a1f46d66232974dd5a500e22c0a7d99e3c21902 \ No newline at end of file diff --git a/Desktop_Interface/mainwindow.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/mainwindow.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 4b0c3592..00000000 --- a/Desktop_Interface/mainwindow.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0624bc9e0888000448e56e1b4292b1373b28f5dc \ No newline at end of file diff --git a/Desktop_Interface/mainwindow.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/mainwindow.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 6d7acb1c..00000000 --- a/Desktop_Interface/mainwindow.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3e083b91e89a15627e0750a41799051658f025fa \ No newline at end of file diff --git a/Desktop_Interface/moc/moc_androidusbdriver.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc/moc_androidusbdriver.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 8b9dd1f2..00000000 --- a/Desktop_Interface/moc/moc_androidusbdriver.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f5d30ea54253295094ef065f3a8dbd75dd3881a3 \ No newline at end of file diff --git a/Desktop_Interface/moc/moc_unixusbdriver.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc/moc_unixusbdriver.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 9ff24fa9..00000000 --- a/Desktop_Interface/moc/moc_unixusbdriver.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1948ba9d9216c4bb02b807234074e520a94a31cf \ No newline at end of file diff --git a/Desktop_Interface/moc_androidusbdriver.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_androidusbdriver.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index ce039a1e..00000000 --- a/Desktop_Interface/moc_androidusbdriver.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -52c1932b5b9d275cfb6bbecb9fedc9dc47fa1940 \ No newline at end of file diff --git a/Desktop_Interface/moc_buffercontrol.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_buffercontrol.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index e5683b35..00000000 --- a/Desktop_Interface/moc_buffercontrol.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4162c855ce0357530f19f63565ba449a1de0097f \ No newline at end of file diff --git a/Desktop_Interface/moc_buffercontrol.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_buffercontrol.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 2965e106..00000000 --- a/Desktop_Interface/moc_buffercontrol.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f7640480d09e6f8472bb015e794a923c73709f3b \ No newline at end of file diff --git a/Desktop_Interface/moc_cursorenabler.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_cursorenabler.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index b4abc47a..00000000 --- a/Desktop_Interface/moc_cursorenabler.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2100c338e452307dfba9f38737b2b95db873809d \ No newline at end of file diff --git a/Desktop_Interface/moc_cursorenabler.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_cursorenabler.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index dd147a34..00000000 --- a/Desktop_Interface/moc_cursorenabler.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -26816d00935b9959232ddf685f64740d3fa47ad8 \ No newline at end of file diff --git a/Desktop_Interface/moc_deviceconnecteddisplay.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_deviceconnecteddisplay.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index ec6174cd..00000000 --- a/Desktop_Interface/moc_deviceconnecteddisplay.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6ed11078094ab98268ac88b4bb2a7a6c19b5495c \ No newline at end of file diff --git a/Desktop_Interface/moc_deviceconnecteddisplay.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_deviceconnecteddisplay.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index b9a51aaa..00000000 --- a/Desktop_Interface/moc_deviceconnecteddisplay.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c3189a84313942c0584c6942b27f492462cdd77e \ No newline at end of file diff --git a/Desktop_Interface/moc_espocombobox.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_espocombobox.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index a4b67ec9..00000000 --- a/Desktop_Interface/moc_espocombobox.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a6aa18cdcdb98932df3ea6ee648c2dba48fcaecc \ No newline at end of file diff --git a/Desktop_Interface/moc_espocombobox.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_espocombobox.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index e87d60c5..00000000 --- a/Desktop_Interface/moc_espocombobox.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b719e11e83ba35e47c7a7b0b0e09d459dfb965dd \ No newline at end of file diff --git a/Desktop_Interface/moc_esposlider.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_esposlider.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 72c6f1de..00000000 --- a/Desktop_Interface/moc_esposlider.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8501f39f646bb26bab63f3803aa9b36bbff13172 \ No newline at end of file diff --git a/Desktop_Interface/moc_esposlider.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_esposlider.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 327bcb82..00000000 --- a/Desktop_Interface/moc_esposlider.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -129371df540393352a6efc3faae5fadca90a7d48 \ No newline at end of file diff --git a/Desktop_Interface/moc_espospinbox.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_espospinbox.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 05ab68ee..00000000 --- a/Desktop_Interface/moc_espospinbox.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1583720e753762c61fc13714a6a675d00ec3d448 \ No newline at end of file diff --git a/Desktop_Interface/moc_espospinbox.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_espospinbox.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index eaeb1b2b..00000000 --- a/Desktop_Interface/moc_espospinbox.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -be1152a8d59ed6d5d81ab4c6d499802755dcab27 \ No newline at end of file diff --git a/Desktop_Interface/moc_functiongencontrol.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_functiongencontrol.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index d96a00f4..00000000 --- a/Desktop_Interface/moc_functiongencontrol.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -36fb9021060a924065fe1207a8d79c6e6ae29430 \ No newline at end of file diff --git a/Desktop_Interface/moc_genericusbdriver.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_genericusbdriver.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 46026f88..00000000 --- a/Desktop_Interface/moc_genericusbdriver.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -95965e07aafc4b6b02b3f03f6d9db91aac880c0a \ No newline at end of file diff --git a/Desktop_Interface/moc_isobuffer.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_isobuffer.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 09f1305d..00000000 --- a/Desktop_Interface/moc_isobuffer.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -410e681d0184c2e9e788eaf29882e88baa9fbb54 \ No newline at end of file diff --git a/Desktop_Interface/moc_isodriver.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_isodriver.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 1ea23a8b..00000000 --- a/Desktop_Interface/moc_isodriver.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f2f16700e906e221af54116dc654e1f97d9c686f \ No newline at end of file diff --git a/Desktop_Interface/moc_mainwindow.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_mainwindow.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 18817c42..00000000 --- a/Desktop_Interface/moc_mainwindow.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bfb079bf7b27806c18e954336e7e71ed41178640 \ No newline at end of file diff --git a/Desktop_Interface/moc_noclosemenu.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_noclosemenu.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 0d37361a..00000000 --- a/Desktop_Interface/moc_noclosemenu.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2fc9923d1b1c44d6ac10e15d3435108c0ec35125 \ No newline at end of file diff --git a/Desktop_Interface/moc_noclosemenu.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_noclosemenu.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index bb42f792..00000000 --- a/Desktop_Interface/moc_noclosemenu.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a7c9a2dbd29bc0cba4ed5ccfed0d40dd6ebdd624 \ No newline at end of file diff --git a/Desktop_Interface/moc_qcustomplot.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_qcustomplot.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index a6004dd2..00000000 --- a/Desktop_Interface/moc_qcustomplot.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f789d9bbe4089e6ded235d4c26eb7198453a54e4 \ No newline at end of file diff --git a/Desktop_Interface/moc_qcustomplot.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_qcustomplot.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 9aa411d6..00000000 --- a/Desktop_Interface/moc_qcustomplot.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7d8fdca9ffe1f9ae87c11e46a9684e3e876773e0 \ No newline at end of file diff --git a/Desktop_Interface/moc_scoperangeenterdialog.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_scoperangeenterdialog.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index d05fe759..00000000 --- a/Desktop_Interface/moc_scoperangeenterdialog.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -efa01cd6752ef2873382a735a97fdaa39e69aabe \ No newline at end of file diff --git a/Desktop_Interface/moc_swipeystack.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_swipeystack.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index d81d34f4..00000000 --- a/Desktop_Interface/moc_swipeystack.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7ec22305015d693dfa55d33179abb8381179d72f \ No newline at end of file diff --git a/Desktop_Interface/moc_timedtickbox.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_timedtickbox.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index c5d8d4bf..00000000 --- a/Desktop_Interface/moc_timedtickbox.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -20ec41e109a3a6dfaf73fd57f6ecc454e31104f1 \ No newline at end of file diff --git a/Desktop_Interface/moc_timedtickbox.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_timedtickbox.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 9ec1156f..00000000 --- a/Desktop_Interface/moc_timedtickbox.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cc28056af9255cace6b57626899205c1a1e1695c \ No newline at end of file diff --git a/Desktop_Interface/moc_unixusbdriver.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_unixusbdriver.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index f54d5278..00000000 --- a/Desktop_Interface/moc_unixusbdriver.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -088e5d75e0013c8c44607f30d99e960ac6cda772 \ No newline at end of file diff --git a/Desktop_Interface/moc_voltagespinbox.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/moc_voltagespinbox.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 8e4e6b1b..00000000 --- a/Desktop_Interface/moc_voltagespinbox.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -53e1f0ed88bb27496686b34a31bce5a6b4b69e95 \ No newline at end of file diff --git a/Desktop_Interface/noclosemenu.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/noclosemenu.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 84ab51fd..00000000 --- a/Desktop_Interface/noclosemenu.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -73865b38e40955207f07658f6df3f483871d26a2 \ No newline at end of file diff --git a/Desktop_Interface/noclosemenu.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/noclosemenu.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index a75a6db3..00000000 --- a/Desktop_Interface/noclosemenu.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e24667fd67004241ce725e9a1074d7e3434a551b \ No newline at end of file diff --git a/Desktop_Interface/pinchcatcher.cpp b/Desktop_Interface/pinchcatcher.cpp new file mode 100644 index 00000000..937dd3a3 --- /dev/null +++ b/Desktop_Interface/pinchcatcher.cpp @@ -0,0 +1,6 @@ +#include "pinchcatcher.h" + +pinchCatcher::pinchCatcher(QObject *parent) : QObject(parent) +{ + grabGesture(Qt::PinchGesture); +} diff --git a/Desktop_Interface/pinchcatcher.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/pinchcatcher.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index f37fc304..00000000 --- a/Desktop_Interface/pinchcatcher.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e225058e6d15389a9bf603edf376d5eebe30361e \ No newline at end of file diff --git a/Desktop_Interface/pinchcatcher.h b/Desktop_Interface/pinchcatcher.h new file mode 100644 index 00000000..64a8fe2e --- /dev/null +++ b/Desktop_Interface/pinchcatcher.h @@ -0,0 +1,17 @@ +#ifndef PINCHCATCHER_H +#define PINCHCATCHER_H + +#include + +class pinchCatcher : public QObject +{ + Q_OBJECT +public: + explicit pinchCatcher(QObject *parent = 0); + +signals: + +public slots: +}; + +#endif // PINCHCATCHER_H \ No newline at end of file diff --git a/Desktop_Interface/pinchcatcher.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/pinchcatcher.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index caf9f7b8..00000000 --- a/Desktop_Interface/pinchcatcher.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fe2b4d31ee749643a9740aa0e1421268abf17d9c \ No newline at end of file diff --git a/Desktop_Interface/q_debugstream.h b/Desktop_Interface/q_debugstream.h new file mode 100644 index 00000000..51e37ac3 --- /dev/null +++ b/Desktop_Interface/q_debugstream.h @@ -0,0 +1,82 @@ +//As per forum: +//http://www.qtforum.org/article/39768/redirecting-std-cout-std-cerf-qdebug-to-qtextedit.html +//A couple of lines added to ensure newlines go between each call. +//Thanks, James! + +#ifndef Q_DEBUGSTREAM_H +#define Q_DEBUGSTREAM_H + +#include +#include +#include + +#include + +class Q_DebugStream : public std::basic_streambuf +{ +public: + Q_DebugStream(std::ostream &stream, QTextEdit* text_edit) : m_stream(stream) + { + log_window = text_edit; + m_old_buf = stream.rdbuf(); + stream.rdbuf(this); + } + + ~Q_DebugStream() + { + m_stream.rdbuf(m_old_buf); + } + + static void registerQDebugMessageHandler(){ + qInstallMessageHandler(myQDebugMessageHandler); + } + +private: + + static void myQDebugMessageHandler(QtMsgType, const QMessageLogContext &, const QString &msg) + { + std::cout << msg.toStdString().c_str(); + } + +protected: + + //This is called when a std::endl has been inserted into the stream + virtual int_type overflow(int_type v) + { + if (v == '\n') + { + log_window->append(""); + } + return v; + } + + + virtual std::streamsize xsputn(const char *p, std::streamsize n) + { + QString str(p); + if(str.contains("\n")){ + QStringList strSplitted = str.split("\n"); + + log_window->moveCursor (QTextCursor::End); + log_window->insertPlainText (strSplitted.at(0)); //Index 0 is still on the same old line + + for(int i = 1; i < strSplitted.size(); i++){ + log_window->append(strSplitted.at(i)); + log_window->append("\n"); + } + }else{ + log_window->moveCursor (QTextCursor::End); + log_window->insertPlainText (str); + log_window->insertPlainText ("\n"); + } + return n; + } + +private: + std::ostream &m_stream; + std::streambuf *m_old_buf; + QTextEdit* log_window; +}; + + +#endif // Q_DEBUGSTREAM_H diff --git a/Desktop_Interface/q_debugstream.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/q_debugstream.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index bd8b9dfe..00000000 --- a/Desktop_Interface/q_debugstream.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4029c273a68d8dee3d9163e0ef5a45e1a58ce119 \ No newline at end of file diff --git a/Desktop_Interface/qcustomplot.o b/Desktop_Interface/qcustomplot.o deleted file mode 100644 index e69de29b..00000000 diff --git a/Desktop_Interface/qcustomplot.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/qcustomplot.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 79a1f53f..00000000 --- a/Desktop_Interface/qcustomplot.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -34c6c96cf3bd5ee7bcd8250db482e2d4bd7027d5 \ No newline at end of file diff --git a/Desktop_Interface/qrc_resources.cpp b/Desktop_Interface/qrc_resources.cpp new file mode 100644 index 00000000..3c21c882 --- /dev/null +++ b/Desktop_Interface/qrc_resources.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** Resource object code +** +** Created by: The Resource Compiler for Qt version 5.3.2 +** +** WARNING! All changes made in this file will be lost! +*****************************************************************************/ + +#include + +static const unsigned char qt_resource_data[] = { + // /home/pi/Desktop/Git_Shit/labrador/Desktop_Interface/buffer_0.bmp + 0x0,0x0,0x0,0x8d, + 0x0, + 0x0,0x28,0xb6,0x78,0x9c,0xed,0xd0,0xb1,0xd,0xc2,0x30,0x0,0x45,0xc1,0xb0,0x45, + 0x6,0xa0,0xc8,0x4,0xc,0x90,0x3e,0x3b,0x30,0xa,0x53,0xb1,0x1e,0x98,0x28,0x5, + 0xd5,0xd5,0x2e,0xde,0x49,0x5f,0xb2,0xec,0xc6,0x7a,0xfb,0xf1,0xde,0x96,0xd3,0x63, + 0xec,0x77,0x7c,0x8e,0xdd,0xc7,0x6e,0xcb,0x7a,0xde,0xbf,0xae,0xf7,0x7f,0x9f,0x69, + 0x4c,0xfb,0xb1,0x49,0xd4,0xc7,0xea,0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56, + 0x1f,0xab,0x8f,0xd5,0xc7,0xea,0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,0x1f, + 0xab,0x8f,0xd5,0xc7,0xea,0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,0x1f,0xab, + 0x8f,0xd5,0xc7,0xea,0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,0x1f,0xab,0x8f, + 0xd5,0xc7,0xea,0x63,0x73,0xf6,0xf9,0x2,0xf4,0x4,0x42,0xe7, + // /home/pi/Desktop/Git_Shit/labrador/Desktop_Interface/buffer_2.bmp + 0x0,0x0,0x0,0x7b, + 0x0, + 0x0,0x28,0xb6,0x78,0x9c,0xed,0xd0,0x31,0xd,0x80,0x30,0x14,0x45,0xd1,0xe2,0x82, + 0x81,0xb1,0x3,0xa,0x10,0xc0,0x8e,0x7,0xa4,0xa0,0xa,0x57,0x78,0xa0,0x34,0xc, + 0x95,0xf0,0x86,0xf3,0x73,0x7f,0xd2,0xb4,0x4b,0x73,0xf6,0xe3,0x5e,0x4b,0x9f,0xad, + 0xed,0x77,0x3c,0xdb,0xd6,0xb6,0x53,0x99,0xfb,0xfd,0xf5,0xbf,0x8f,0x53,0x97,0x27, + 0xa4,0xd8,0x8f,0x85,0xc4,0x87,0xf,0x1f,0x3e,0x7c,0x32,0xe3,0xc3,0x87,0xf,0x1f, + 0x3e,0x99,0xf1,0xe1,0xc3,0x87,0xf,0x9f,0xcc,0xf8,0xf0,0xe1,0xc3,0x87,0x4f,0x66, + 0x7c,0xf8,0xf0,0xe1,0xc3,0x27,0x33,0x3e,0x7c,0xf8,0xf0,0xe1,0x93,0x19,0x1f,0x3e, + 0x7c,0xf8,0xf0,0x19,0x7b,0x1,0x6d,0x5a,0xf,0xce, + // /home/pi/Desktop/Git_Shit/labrador/Desktop_Interface/buffer_1.bmp + 0x0,0x0,0x0,0x97, + 0x0, + 0x0,0x28,0xb6,0x78,0x9c,0xed,0xd0,0xb1,0xd,0xc2,0x30,0x10,0x40,0xd1,0xb0,0x5, + 0x5,0x65,0xa,0x26,0x60,0x0,0x7a,0x76,0x60,0x14,0xa6,0x62,0x2b,0x66,0x0,0x27, + 0x42,0x2,0x51,0xbc,0x96,0x14,0xff,0xc9,0x27,0x9d,0xec,0xc6,0xfa,0xe7,0xcb,0xfd, + 0x38,0xad,0x4e,0x63,0x96,0xf5,0x3a,0x66,0x1e,0xb3,0x9b,0xf6,0xeb,0xfd,0xed,0xfd, + 0xfe,0xed,0xb9,0x19,0x3f,0x1f,0x9b,0xf,0x8f,0x2d,0x9c,0x7f,0x57,0xf9,0xa8,0x8f, + 0xd5,0xc7,0xea,0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,0x1f,0xab,0x8f,0xd5, + 0xc7,0xea,0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,0x1f,0xab,0x8f,0xd5,0xc7, + 0xea,0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,0x1f,0xab,0x8f,0xd5,0xc7,0xea, + 0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,0x1f,0xab,0x8f,0xd5,0xc7,0xb6,0xd9, + 0xe7,0x5,0x35,0x2d,0xc9,0xf3, + +}; + +static const unsigned char qt_resource_name[] = { + // bitmap + 0x0,0x6, + 0x6,0x90,0xb3,0x80, + 0x0,0x62, + 0x0,0x69,0x0,0x74,0x0,0x6d,0x0,0x61,0x0,0x70, + // buffer_0.bmp + 0x0,0xc, + 0xd,0x14,0xd0,0xc0, + 0x0,0x62, + 0x0,0x75,0x0,0x66,0x0,0x66,0x0,0x65,0x0,0x72,0x0,0x5f,0x0,0x30,0x0,0x2e,0x0,0x62,0x0,0x6d,0x0,0x70, + // buffer_2.bmp + 0x0,0xc, + 0xd,0x12,0xd0,0xc0, + 0x0,0x62, + 0x0,0x75,0x0,0x66,0x0,0x66,0x0,0x65,0x0,0x72,0x0,0x5f,0x0,0x32,0x0,0x2e,0x0,0x62,0x0,0x6d,0x0,0x70, + // buffer_1.bmp + 0x0,0xc, + 0xd,0x17,0xd0,0xc0, + 0x0,0x62, + 0x0,0x75,0x0,0x66,0x0,0x66,0x0,0x65,0x0,0x72,0x0,0x5f,0x0,0x31,0x0,0x2e,0x0,0x62,0x0,0x6d,0x0,0x70, + +}; + +static const unsigned char qt_resource_struct[] = { + // : + 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1, + // :/bitmap + 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x2, + // :/bitmap/buffer_2.bmp + 0x0,0x0,0x0,0x30,0x0,0x1,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x91, + // :/bitmap/buffer_0.bmp + 0x0,0x0,0x0,0x12,0x0,0x1,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0, + // :/bitmap/buffer_1.bmp + 0x0,0x0,0x0,0x4e,0x0,0x1,0x0,0x0,0x0,0x1,0x0,0x0,0x1,0x10, + +}; + +QT_BEGIN_NAMESPACE + +extern Q_CORE_EXPORT bool qRegisterResourceData + (int, const unsigned char *, const unsigned char *, const unsigned char *); + +extern Q_CORE_EXPORT bool qUnregisterResourceData + (int, const unsigned char *, const unsigned char *, const unsigned char *); + +QT_END_NAMESPACE + + +int QT_MANGLE_NAMESPACE(qInitResources_resources)() +{ + QT_PREPEND_NAMESPACE(qRegisterResourceData) + (0x01, qt_resource_struct, qt_resource_name, qt_resource_data); + return 1; +} + +Q_CONSTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qInitResources_resources)) + +int QT_MANGLE_NAMESPACE(qCleanupResources_resources)() +{ + QT_PREPEND_NAMESPACE(qUnregisterResourceData) + (0x01, qt_resource_struct, qt_resource_name, qt_resource_data); + return 1; +} + +Q_DESTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qCleanupResources_resources)) + diff --git a/Desktop_Interface/qrc_resources.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/qrc_resources.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 24a5b452..00000000 --- a/Desktop_Interface/qrc_resources.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a819fd4cb1c85628c7af64a27dedc982947ffc06 \ No newline at end of file diff --git a/Desktop_Interface/qrc_resources.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/qrc_resources.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 7fdf2ead..00000000 --- a/Desktop_Interface/qrc_resources.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -96fd7195f150ac738a241bb95185c4b178dd2346 \ No newline at end of file diff --git a/Desktop_Interface/qrc_resources.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/qrc_resources.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 8d7ad38d..00000000 --- a/Desktop_Interface/qrc_resources.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -db5f90224b7b1667bffb27a83f2d3b5985c036f0 \ No newline at end of file diff --git a/Desktop_Interface/resources.qrc b/Desktop_Interface/resources.qrc new file mode 100644 index 00000000..67eec860 --- /dev/null +++ b/Desktop_Interface/resources.qrc @@ -0,0 +1,7 @@ + + + buffer_0.bmp + buffer_1.bmp + buffer_2.bmp + + diff --git a/Desktop_Interface/resources.qrc.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/resources.qrc.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 9879cce9..00000000 --- a/Desktop_Interface/resources.qrc.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a26924f4dd3b3be0800a30e075e52ca25ffe41de \ No newline at end of file diff --git a/Desktop_Interface/scoperangeenterdialog.cpp b/Desktop_Interface/scoperangeenterdialog.cpp new file mode 100644 index 00000000..496299ba --- /dev/null +++ b/Desktop_Interface/scoperangeenterdialog.cpp @@ -0,0 +1,37 @@ +#include "scoperangeenterdialog.h" +#include "ui_scoperangeenterdialog.h" + +scopeRangeEnterDialog::scopeRangeEnterDialog(QWidget *parent, double yTop, double yBot, double window, double delay) : + QDialog(parent), + ui(new Ui::scopeRangeEnterDialog) +{ + ui->setupUi(this); + + ui->vMaxBox->setMinimum(yBot); + ui->vMinBox->setMaximum(yTop); + + ui->vMaxBox->setValue(yTop); + ui->vMinBox->setValue(yBot); + ui->timeWindowBox->setValue(window); +} + +scopeRangeEnterDialog::~scopeRangeEnterDialog() +{ + delete ui; +} + +void scopeRangeEnterDialog::toUpdateYTop(double val){ + qDebug() << val; + yTopUpdated(val); +} + +void scopeRangeEnterDialog::toUpdateYBot(double val){ + qDebug() << val; + yBotUpdated(val); +} + +void scopeRangeEnterDialog::toUpdateWindow(double val){ + qDebug() << val; + windowUpdated(val); +} + diff --git a/Desktop_Interface/scoperangeenterdialog.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/scoperangeenterdialog.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 1566b83f..00000000 --- a/Desktop_Interface/scoperangeenterdialog.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a581594b42d865c43ec53393671b87ef599f6cf7 \ No newline at end of file diff --git a/Desktop_Interface/scoperangeenterdialog.h b/Desktop_Interface/scoperangeenterdialog.h new file mode 100644 index 00000000..829d15c1 --- /dev/null +++ b/Desktop_Interface/scoperangeenterdialog.h @@ -0,0 +1,35 @@ +#ifndef SCOPERANGEENTERDIALOG_H +#define SCOPERANGEENTERDIALOG_H + +#include +#include + +//ScopeRangeEnterDialog is the class for the "Enter Scope Range" dialog (Oscilloscope->Range->Enter Manually; shortcut is "M"). +//This code in particular controls the voltageSpinBoxes in the dialog, to ensure they don't go out of range. + +namespace Ui { +class scopeRangeEnterDialog; +} + +class scopeRangeEnterDialog : public QDialog +{ + Q_OBJECT + +public: + explicit scopeRangeEnterDialog(QWidget *parent = 0, double yTop = 20, double yBot = -20, double window = -10, double delay = 0); + ~scopeRangeEnterDialog(); + +private: + Ui::scopeRangeEnterDialog *ui; + +signals: + void yTopUpdated(double val); + void yBotUpdated(double val); + void windowUpdated(double val); +private slots: + void toUpdateYTop(double val); + void toUpdateYBot(double val); + void toUpdateWindow(double val); +}; + +#endif // SCOPERANGEENTERDIALOG_H diff --git a/Desktop_Interface/scoperangeenterdialog.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/scoperangeenterdialog.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 82aaefd9..00000000 --- a/Desktop_Interface/scoperangeenterdialog.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -56ecbb1753bcde6f3d8812405681b02be7981623 \ No newline at end of file diff --git a/Desktop_Interface/scoperangeenterdialog.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/scoperangeenterdialog.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 2c4fa092..00000000 --- a/Desktop_Interface/scoperangeenterdialog.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8b8c10b87d3c4b4044587b39f26f8beb77fe2838 \ No newline at end of file diff --git a/Desktop_Interface/scoperangeenterdialog.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/scoperangeenterdialog.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 2250d422..00000000 --- a/Desktop_Interface/scoperangeenterdialog.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -80379e3bf7ab6728d3c2419b18f409b8bd95a7b5 \ No newline at end of file diff --git a/Desktop_Interface/siPrint.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/siPrint.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 31193a70..00000000 --- a/Desktop_Interface/siPrint.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -826e17e2a26bc2c94bb58e2faf02c0528539d047 \ No newline at end of file diff --git a/Desktop_Interface/siprint.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/siprint.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 3cf0edca..00000000 --- a/Desktop_Interface/siprint.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7beabd3cad3dc4ed3c0aeee3c4d356c5c350f905 \ No newline at end of file diff --git a/Desktop_Interface/swipeystack.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/swipeystack.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 3ed0a5ee..00000000 --- a/Desktop_Interface/swipeystack.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c6412a963794b60c745a7a5f9799650eed19722c \ No newline at end of file diff --git a/Desktop_Interface/swipeystack.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/swipeystack.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index cad15900..00000000 --- a/Desktop_Interface/swipeystack.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d3b7f99479c9028245fd955ebb33060369c4eac6 \ No newline at end of file diff --git a/Desktop_Interface/timedtickbox.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/timedtickbox.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 3b620482..00000000 --- a/Desktop_Interface/timedtickbox.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -58aa5623f981b5c5d0507fa7e1d610fb72cd06fe \ No newline at end of file diff --git a/Desktop_Interface/timedtickbox.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/timedtickbox.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index b2b679b6..00000000 --- a/Desktop_Interface/timedtickbox.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -61d7f8c279f0ed3961f62039190969e48966daff \ No newline at end of file diff --git a/Desktop_Interface/ui_elements.pri b/Desktop_Interface/ui_elements.pri new file mode 100644 index 00000000..c515cb67 --- /dev/null +++ b/Desktop_Interface/ui_elements.pri @@ -0,0 +1,33 @@ +@INCLUDEPATH += $$PWD/ui_elements +@DEPENDPATH += $$PWD/ui_elements + +INCLUDEPATH += $$PWD/ui_elements/qcp$${QCP_VER} +DEPENDPATH += $$PWD/ui_elements/qcp$${QCP_VER} + + +SOURCES += ui_elements/buffercontrol.cpp \ + ui_elements/cursorenabler.cpp \ + ui_elements/deviceconnecteddisplay.cpp \ + ui_elements/espocombobox.cpp \ + ui_elements/esposlider.cpp \ + ui_elements/espospinbox.cpp \ + ui_elements/noclosemenu.cpp \ + ui_elements/qcp$${QCP_VER}/qcustomplot.cpp \ + ui_elements/siprint.cpp \ + ui_elements/timedtickbox.cpp \ + ui_elements/voltagespinbox.cpp \ + ui_elements/swipeystack.cpp + + +HEADERS += ui_elements/buffercontrol.h \ + ui_elements/cursorenabler.h \ + ui_elements/deviceconnecteddisplay.h \ + ui_elements/espocombobox.h \ + ui_elements/esposlider.h \ + ui_elements/espospinbox.h \ + ui_elements/noclosemenu.h \ + ui_elements/qcp$${QCP_VER}/qcustomplot.h \ + ui_elements/siprint.h \ + ui_elements/timedtickbox.h \ + ui_elements/voltagespinbox.h \ + ui_elements/swipeystack.h diff --git a/Desktop_Interface/ui_elements.pri.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/ui_elements.pri.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 50e2b642..00000000 --- a/Desktop_Interface/ui_elements.pri.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -54b12280b845890ab15069a6c71a9d7a6e522ad6 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/buffercontrol.cpp b/Desktop_Interface/ui_elements/buffercontrol.cpp new file mode 100644 index 00000000..3542aaf6 --- /dev/null +++ b/Desktop_Interface/ui_elements/buffercontrol.cpp @@ -0,0 +1,253 @@ +#include "buffercontrol.h" + +bufferControl::bufferControl(QWidget *parent) : QLabel(parent) +{ + //refreshImage(); +} + +void bufferControl::refreshImage(void){ + //qDebug() << "Trying to show bitmap " << numBuffers; + + switch(numBuffers){ + case 0: + bufferImage = QPixmap(":/bitmap/buffer_0.bmp"); + break; + case 1: + bufferImage = QPixmap(":/bitmap/buffer_1.bmp"); + break; + case 2: + bufferImage = QPixmap(":/bitmap/buffer_2.bmp"); + break; + } + + if(bufferImage.isNull()) qFatal("Resource not found\n"); + + this->setPixmap(bufferImage); + //qDebug() << this->text(); + this->show(); + return; +} + +void bufferControl::scopeIn_CH1(bool state){ //What about DSR!? + scopeState_CH1 = state; + + if (scopeState_CH2){ //Implicitly state is false + scopeState_CH2 = false; + //updateBuffer(0); - Causes issues because the uncheck below called scopeIn_CH2 (but only when toggle)!!! + scopeUncheck(0); + } + + //Turn off the DSR when CH1 is disabled. + if(!state){ + scopeDsrUncheck(0); + } + + scopeDsrOut(state); + scopeOut_CH2(state); + + updateBuffer(state,1); // Do this last to ensure anything accidentally enabled is immediately switched off + qDebug() << "scopeIn_CH1" << state; + updateMode(); +} + +void bufferControl::scopeIn_CH2(bool state){ + scopeState_CH2 = state; + + updateBuffer(state,1); + qDebug() << "scopeIn_CH2" << state; + updateMode(); +} + +void bufferControl::scopeDsrIn(bool state){ + scopeDsrState = state; + + updateBuffer(state,1); + qDebug() << "scopeDsrIn" << state; + updateMode(); +} + +/*void bufferControl::signalGenIn(bool state){ + signalGenState = state; + + updateBuffer(state,1); + qDebug() << "signalGenIn" << state; + updateMode(); +}*/ + +void bufferControl::busSnifferIn_CH1(bool state){ + busSnifferState_CH1 = state; + + if (busSnifferState_CH2){ //Implicitly state is false + busSnifferState_CH2 = false; + //updateBuffer(0); - Causes issues because the uncheck below called scopeIn_CH2 (but only when toggle)!!! + busSnifferUncheck(0); + } + + //Signal Gen CH2 doesn't work with bus sniffer. + signalGenOut(!state); + + busSnifferOut_CH2(state); + + updateBuffer(state,1); + qDebug() << "busSnifferIn_CH1" << state; + updateMode(); +} + +void bufferControl::busSnifferIn_CH2(bool state){ + busSnifferState_CH2 = state; + + updateBuffer(state,1); + qDebug() << "busSnifferIn_CH2" << state; + updateMode(); +} + +void bufferControl::multimeterIn(bool state){ + multimeterState = state; + + updateBuffer(state,2); + qDebug() << "multimeterIn" << state; + updateMode(); +} + + + +void bufferControl::updateBuffer(bool decrement, int amount){ + if(decrement){ + numBuffers-=amount; + } + else{ + numBuffers+=amount; + } + refreshImage(); + + //Write new state + switch(numBuffers){ + case 0: + if(scopeState_CH1 == false) scopeOut_CH1(0); + if(scopeState_CH2 == false) scopeOut_CH2(0); + if(scopeDsrState == false) scopeDsrOut(0); + //if(signalGenState == false) signalGenOut(0); + if(busSnifferState_CH1 == false) busSnifferOut_CH1(0); + if(busSnifferState_CH2 == false) busSnifferOut_CH2(0); + if(multimeterState == false) multimeterOut(0); + break; + case 1: + scopeOut_CH1(1); + if(scopeState_CH1 == true){ + scopeDsrOut(1); + scopeOut_CH2(1); + } + //signalGenOut(1); + busSnifferOut_CH1(1); + if(busSnifferState_CH1 == true){ + busSnifferOut_CH2(1); + } + + //busSnifferOut_CH2(1); + multimeterOut(0); + break; + case 2: + scopeOut_CH1(1); + //scopeOut_CH2(1); + if(scopeState_CH1 == true) scopeDsrOut(1); + //signalGenOut(1); + busSnifferOut_CH1(1); + //busSnifferOut_CH2(1); + multimeterOut(1); + break; + default: + qFatal("numBuffers is not equal to 0, 1 or 2"); + } + +} + +void bufferControl::digIn_CH1(bool state){ + unsigned char mask = 0x01; + if(state){ + digState |= mask; + } + else{ + digState &= (unsigned char) 0xff - mask; + } + updateDig(digState); +} + +void bufferControl::digIn_CH2(bool state){ + unsigned char mask = 0x02; + if(state){ + digState |= mask; + } + else{ + digState &= (unsigned char) 0xff - mask; + } updateDig(digState); +} + +void bufferControl::digIn_CH3(bool state){ + unsigned char mask = 0x04; + if(state){ + digState |= mask; + } + else{ + digState &= (unsigned char) 0xff - mask; + } updateDig(digState); +} + +void bufferControl::digIn_CH4(bool state){ + unsigned char mask = 0x08; + if(state){ + digState |= mask; + } + else{ + digState &= (unsigned char) 0xff - mask; + } updateDig(digState); +} + +void bufferControl::updateMode(void){ + if(multimeterState){ + modeChange(7); + qDebug() << "Changed to mode 7"; + return; + } + if(scopeDsrState){ + modeChange(6); + qDebug() << "Changed to mode 6"; + return; + } + + if (busSnifferState_CH2){ + modeChange(4); + qDebug() << "Changed to mode 4"; + return; + } + if(busSnifferState_CH1 && scopeState_CH1){ + modeChange(1); + qDebug() << "Changed to mode 1"; + return; + } + if (scopeState_CH2){ + modeChange(2); + qDebug() << "Changed to mode 2"; + return; + } + if(busSnifferState_CH1){ + modeChange(3); + qDebug() << "Changed to mode 3"; + return; + } + if(scopeState_CH1){ + modeChange(0); + qDebug() << "Changed to mode 0"; + return; + } + + modeChange(5); + qDebug() << "Changed to mode 5"; + return; + +} + +void bufferControl::poke(void){ + updateDig(digState); + updateMode(); +} + diff --git a/Desktop_Interface/ui_elements/buffercontrol.cpp.REMOVED.git-id b/Desktop_Interface/ui_elements/buffercontrol.cpp.REMOVED.git-id deleted file mode 100644 index 20b226ee..00000000 --- a/Desktop_Interface/ui_elements/buffercontrol.cpp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3542aaf6df9c6eadd3654332b8d394b4066b2611 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/buffercontrol.h b/Desktop_Interface/ui_elements/buffercontrol.h new file mode 100644 index 00000000..c67e908d --- /dev/null +++ b/Desktop_Interface/ui_elements/buffercontrol.h @@ -0,0 +1,59 @@ +#ifndef BUFFERCONTROL_H +#define BUFFERCONTROL_H + +#include +#include +#include + +//bufferControl is a controller object that allocates and deallocates bandwidth depending on what devices are active. + +class bufferControl : public QLabel +{ + Q_OBJECT +public: + explicit bufferControl(QWidget *parent = 0); + void refreshImage(void); + bool busSnifferState_CH1 = false; +private: + QPixmap bufferImage; + int numBuffers = 1; + bool scopeState_CH1 = true; + bool scopeState_CH2 = false; + bool scopeDsrState = false; + //bool signalGenState = false; + bool busSnifferState_CH2 = false; + bool multimeterState = false; + unsigned char digState = 0x00; + + void updateBuffer(bool increment, int amount); + void updateMode(void); + +signals: + void scopeOut_CH1(bool state); + void scopeOut_CH2(bool state); + void scopeUncheck(bool state); + void scopeDsrOut(bool state); + void scopeDsrUncheck(bool state); + void signalGenOut(bool state); + void busSnifferOut_CH1(bool state); + void busSnifferOut_CH2(bool state); + void busSnifferUncheck(bool state); + void multimeterOut(bool state); + void updateDig(int digMask); + void modeChange(int newMode); +public slots: + void scopeIn_CH1(bool state); + void scopeIn_CH2(bool state); + void scopeDsrIn(bool state); + //void signalGenIn(bool state); + void busSnifferIn_CH1(bool state); + void busSnifferIn_CH2(bool state); + void multimeterIn(bool state); + void digIn_CH1(bool state); + void digIn_CH2(bool state); + void digIn_CH3(bool state); + void digIn_CH4(bool state); + void poke(void); +}; + +#endif // BUFFERCONTROL_H diff --git a/Desktop_Interface/ui_elements/buffercontrol.h.REMOVED.git-id b/Desktop_Interface/ui_elements/buffercontrol.h.REMOVED.git-id deleted file mode 100644 index 1ae74ec6..00000000 --- a/Desktop_Interface/ui_elements/buffercontrol.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c67e908d845310a19b493bc728686c21e20e64e9 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/cursorenabler.cpp b/Desktop_Interface/ui_elements/cursorenabler.cpp new file mode 100644 index 00000000..e2a2fa48 --- /dev/null +++ b/Desktop_Interface/ui_elements/cursorenabler.cpp @@ -0,0 +1,29 @@ +#include "cursorenabler.h" +#include "platformspecific.h" + +cursorEnabler::cursorEnabler(QWidget *parent) : QLabel(parent) +{ + this->setVisible(0); +#ifdef PLATFORM_ANDROID + this->turnedOn = false; +#endif +} + +void cursorEnabler::setTurnedOn(bool enabled){ + turnedOn = enabled; + #ifdef PLATFORM_ANDROID + this->turnedOn = false; + #endif +} + +void cursorEnabler::clickDetected(QMouseEvent* event){ + if(turnedOn){ + if (event->button() == Qt::LeftButton){ + tickHori(1); + } + if (event->button() == Qt::RightButton){ + tickVert(1); + } + } + passOnSignal(event); +} diff --git a/Desktop_Interface/ui_elements/cursorenabler.cpp.REMOVED.git-id b/Desktop_Interface/ui_elements/cursorenabler.cpp.REMOVED.git-id deleted file mode 100644 index 522d5b9a..00000000 --- a/Desktop_Interface/ui_elements/cursorenabler.cpp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e2a2fa4889e9b62d5546a2c71f800170323e42b7 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/cursorenabler.h b/Desktop_Interface/ui_elements/cursorenabler.h new file mode 100644 index 00000000..a7f6deac --- /dev/null +++ b/Desktop_Interface/ui_elements/cursorenabler.h @@ -0,0 +1,26 @@ +#ifndef CURSORENABLER_H +#define CURSORENABLER_H + +#include +#include +#include + +//cursorEnabler intercepts click events from the chart and allows automatic cursor drops to take place. + +class cursorEnabler : public QLabel +{ + Q_OBJECT +public: + explicit cursorEnabler(QWidget *parent = 0); +private: + bool turnedOn = true; +signals: + void tickHori(bool); + void tickVert(bool); + void passOnSignal(QMouseEvent* event); +public slots: + void setTurnedOn(bool enabled); + void clickDetected(QMouseEvent* event); +}; + +#endif // CURSORENABLER_H diff --git a/Desktop_Interface/ui_elements/cursorenabler.h.REMOVED.git-id b/Desktop_Interface/ui_elements/cursorenabler.h.REMOVED.git-id deleted file mode 100644 index e89a627e..00000000 --- a/Desktop_Interface/ui_elements/cursorenabler.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a7f6deac5053cb8a9cf74b7e31b4328270ac29c0 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/deviceconnecteddisplay.cpp b/Desktop_Interface/ui_elements/deviceconnecteddisplay.cpp new file mode 100644 index 00000000..27353eda --- /dev/null +++ b/Desktop_Interface/ui_elements/deviceconnecteddisplay.cpp @@ -0,0 +1,23 @@ +#include "deviceconnecteddisplay.h" +#include "platformspecific.h" + +deviceConnectedDisplay::deviceConnectedDisplay(QWidget *parent) : QLabel(parent) +{ + this->setText("Device Not Connected!"); + this->setStyleSheet("QLabel { color:red; }"); +} + +void deviceConnectedDisplay::connectedStatusChanged(bool status){ + qDebug() << "deviceConnectedDisplay::connectedStatusChanged running!"; + if(status){ + this->setText("Device Connected"); + this->setStyleSheet("QLabel { color:black; }"); + } + else{ + this->setText("Device Not Connected!"); + this->setStyleSheet("QLabel { color:red; }"); + } + #ifdef PLATFORM_ANDROID + this->setVisible(!status); + #endif +} diff --git a/Desktop_Interface/ui_elements/deviceconnecteddisplay.cpp.REMOVED.git-id b/Desktop_Interface/ui_elements/deviceconnecteddisplay.cpp.REMOVED.git-id deleted file mode 100644 index 3f16af3c..00000000 --- a/Desktop_Interface/ui_elements/deviceconnecteddisplay.cpp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -27353edafc036cdf0d2e30e4c8d267d4366780cb \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/deviceconnecteddisplay.h b/Desktop_Interface/ui_elements/deviceconnecteddisplay.h new file mode 100644 index 00000000..fefd5f14 --- /dev/null +++ b/Desktop_Interface/ui_elements/deviceconnecteddisplay.h @@ -0,0 +1,20 @@ +#ifndef DEVICECONNECTEDDISPLAY_H +#define DEVICECONNECTEDDISPLAY_H + +#include +#include +#include + +//deviceConnectedDisplay simply displays the "device connected" message. + +class deviceConnectedDisplay : public QLabel +{ + Q_OBJECT +public: + explicit deviceConnectedDisplay(QWidget *parent = 0); +signals: +public slots: + void connectedStatusChanged(bool status); +}; + +#endif // DEVICECONNECTEDDISPLAY_H diff --git a/Desktop_Interface/ui_elements/deviceconnecteddisplay.h.REMOVED.git-id b/Desktop_Interface/ui_elements/deviceconnecteddisplay.h.REMOVED.git-id deleted file mode 100644 index f8dc8eb1..00000000 --- a/Desktop_Interface/ui_elements/deviceconnecteddisplay.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fefd5f14e2a941b7bd3acf2fcf5858ef212bedb3 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/espocombobox.cpp b/Desktop_Interface/ui_elements/espocombobox.cpp new file mode 100644 index 00000000..40217ccc --- /dev/null +++ b/Desktop_Interface/ui_elements/espocombobox.cpp @@ -0,0 +1,63 @@ +#include "espocombobox.h" + +espoComboBox::espoComboBox(QWidget *parent) : QComboBox(parent) +{ + +} + + +void espoComboBox::readWaveformList(void) +{ + //This code gets the name of the current directory, regardless of platform. + //This is so the interface knows where to find the waveform data + //QDir *dir = new QDir(); + //qDebug() << dir->currentPath(); +#ifdef PLATFORM_ANDROID + QFile qt_list("assets:/waveforms/_list.wfl"); + bool success = qt_list.open(QIODevice::ReadOnly | QIODevice::Text); + if(!success){ + qFatal("Could not load _list.wfl"); + } + + char nameBuffer[255]; + QStringList *newNames = new QStringList(); + + while (!qt_list.atEnd()) { + QByteArray line = qt_list.readLine(); + strcpy(nameBuffer, line.data()); + strtok(nameBuffer, "\n\r"); + newNames->append(nameBuffer); + qDebug() << nameBuffer; + } + this->addItems(*(newNames)); + delete newNames; + qt_list.close(); +#else + QString dirString = QCoreApplication::applicationDirPath(); + dirString.append("/waveforms/_list.wfl"); + QByteArray array = dirString.toLocal8Bit(); + char* buffer = array.data(); + //qDebug() << buffer; + + qDebug() << "Attempting to open" << dirString; + + FILE *listPtr = fopen(buffer, "r"); + QStringList *newNames = new QStringList(); + char nameBuffer[255]; + + if(listPtr == NULL){ + qFatal("Could not load _list.wfl"); + } + + while (fgets(nameBuffer,256,listPtr) !=NULL){ + qDebug() << "nameBuffer = " << nameBuffer; + strtok(nameBuffer, "\n\r"); + newNames->append(nameBuffer); + } + this->addItems(*(newNames)); + delete newNames; + + fclose(listPtr); +#endif + qDebug() << "List loaded!!"; +} diff --git a/Desktop_Interface/ui_elements/espocombobox.cpp.REMOVED.git-id b/Desktop_Interface/ui_elements/espocombobox.cpp.REMOVED.git-id deleted file mode 100644 index b585aac2..00000000 --- a/Desktop_Interface/ui_elements/espocombobox.cpp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -40217ccc907a2703fc330220d6d604e55e0efb6d \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/espocombobox.h b/Desktop_Interface/ui_elements/espocombobox.h new file mode 100644 index 00000000..ff3cba27 --- /dev/null +++ b/Desktop_Interface/ui_elements/espocombobox.h @@ -0,0 +1,25 @@ +#ifndef ESPOCOMBOBOX_H +#define ESPOCOMBOBOX_H + +#include +#include +#include +#include +#include +#include "platformspecific.h" + +//espoComboBox is a combo box that reads its contents externally from the waveforms file. + +class espoComboBox : public QComboBox +{ + Q_OBJECT +public: + explicit espoComboBox(QWidget *parent = 0); + void readWaveformList(void); +private: +signals: + +public slots: +}; + +#endif // ESPOCOMBOBOX_H diff --git a/Desktop_Interface/ui_elements/espocombobox.h.REMOVED.git-id b/Desktop_Interface/ui_elements/espocombobox.h.REMOVED.git-id deleted file mode 100644 index abd7f2f7..00000000 --- a/Desktop_Interface/ui_elements/espocombobox.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ff3cba2718be5fd05940ccbd0b95d707c883231b \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/esposlider.cpp b/Desktop_Interface/ui_elements/esposlider.cpp new file mode 100644 index 00000000..a20fb209 --- /dev/null +++ b/Desktop_Interface/ui_elements/esposlider.cpp @@ -0,0 +1,106 @@ +//Known issues: +//Memory leak +//Must be called by main window or labels can disappear. + +#include "esposlider.h" + +#define MIN(a,b) (((a)<(b))?(a):(b)) + + +espoSlider::espoSlider(QWidget *parent) : QSlider(parent) +{ + windowPointer = parent; + labelMargin = 3; +} + +bool espoSlider::setTickLabel(QString label, int position) +{ + if (position > maxTick()){ + //qDebug() << "Tried to label tick at position " << position << "but ticks range from 0 to " << maxTick(); + return true; + } + QLabel * working = addressBook.at(position); + working->setText(label); + working->setGeometry(QRect(0, 0, 100, 12)); + //qDebug() << "Set Geometry of QLabel" << working; + working->show(); + + return false; +} + +void espoSlider::resizeEvent(QResizeEvent *event){ + this->debug_var++; + //qDebug() << "move/resize event" << debug_var; + rearrange(); +} + +void espoSlider::moveEvent(QMoveEvent *event){ + this->debug_var++; + //qDebug() << "move/resize event" << debug_var; + rearrange(); +} + + +void espoSlider::setTickInterval(int ti){ + addressBook.resize(maxTick(ti) + 1, NULL); //Leaky, but not significantly. Old qlabels never deleted. + for (int i=0; itickInterval() == 0){ + return 0; + } + return (this->maximum() - this-> minimum() + 1) / (this->tickInterval()); +} + +int espoSlider::maxTick(int ti){ + if (ti == 0){ + return 0; + } + return (this->maximum() - this-> minimum() + 1) / ti; +} + +void espoSlider::rearrange(){ + QLabel *working; + int k = 5; + int c = 5; + + int left = this->geometry().left(); + int right = this->geometry().right(); + int top = this->geometry().top(); + int bottom = this->geometry().bottom(); + int height = bottom - top; + int internalHeight = height-c-k; + int margin = (width()/3) - 6; + + //qDebug() << "left = " << left << "right = " << right << "top = " << top << "bottom = " << bottom << "height = " << height << "internalHeight = " << internalHeight << "margin = " << margin; + //qDebug() << "maxTick() =" << maxTick(); + if (addressBook.size() > 1) + for (int i=addressBook.size()-1; i>0; i--){ + working = addressBook.at(i); + working->setGeometry(QRect(right-margin+labelMargin, top + c + (internalHeight * i * this->tickInterval()) / (this->maximum() - this->minimum()) - 5, 100, 9)); + } + working = addressBook.at(0); + working->setGeometry(QRect(right-margin+labelMargin, top + c - 5, 100, 9)); +} + +void espoSlider::selfMoved(int newval) +{ + QString newstring; + newstring.setNum((double) newval/20, 'f', 2); + //qDebug() << newstring; + voltageChanged(((double) newval) / 20); + lcdOut(newstring); + return; +} + +void espoSlider::poke(void){ + //qDebug() << "Refreshing to voltage" << ((double) (this->value())) / 20; + voltageChanged(((double) (this->value())) / 20); +} + diff --git a/Desktop_Interface/ui_elements/esposlider.cpp.REMOVED.git-id b/Desktop_Interface/ui_elements/esposlider.cpp.REMOVED.git-id deleted file mode 100644 index 5d523163..00000000 --- a/Desktop_Interface/ui_elements/esposlider.cpp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a20fb209198d02dcb7c1459005936238c7f2b6a1 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/esposlider.h b/Desktop_Interface/ui_elements/esposlider.h new file mode 100644 index 00000000..aeed7aac --- /dev/null +++ b/Desktop_Interface/ui_elements/esposlider.h @@ -0,0 +1,38 @@ +#ifndef ESPOSLIDER_H +#define ESPOSLIDER_H + +#include +#include +#include +#include +#include +#include + +//espoSlider is a slider but with the ticks placed at the same position as the numbers. Nothing more, nothing less. + +class espoSlider : public QSlider +{ + Q_OBJECT +public: + explicit espoSlider(QWidget *parent = 0); + bool setTickLabel(QString label, int position); + void resizeEvent(QResizeEvent *event); + void moveEvent(QMoveEvent *event); + void setTickInterval(int ti); + int maxTick(); + int maxTick(int ti); +private: + int debug_var = 0; + void rearrange(); + std::vector addressBook; + QWidget* windowPointer; + int labelMargin; +signals: + void lcdOut(QString values); + void voltageChanged(double newVoltage); +public slots: + void selfMoved(int newval); + void poke(void); +}; + +#endif // ESPOSLIDER_H diff --git a/Desktop_Interface/ui_elements/esposlider.h.REMOVED.git-id b/Desktop_Interface/ui_elements/esposlider.h.REMOVED.git-id deleted file mode 100644 index 7fa0d751..00000000 --- a/Desktop_Interface/ui_elements/esposlider.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aeed7aac7fa512e7795b878a35e949d06af43c78 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/espospinbox.cpp b/Desktop_Interface/ui_elements/espospinbox.cpp new file mode 100644 index 00000000..4cc73ea9 --- /dev/null +++ b/Desktop_Interface/ui_elements/espospinbox.cpp @@ -0,0 +1,53 @@ +#include "espospinbox.h" + +espoSpinBox::espoSpinBox(QWidget *parent) : QDoubleSpinBox(parent) +{ + //connect(this, SIGNAL(valueChanged(double)), this, SLOT(changeStepping(double))); +} + +QString espoSpinBox::textFromValue(double value) const{ + QString windowText; + if (value == 0){ + QTextStream(&windowText) << value; + return windowText; + } + if (value >= 1000000){ + QTextStream(&windowText) << value/1000000 << "M"; + return windowText; + } + if (value >= 1000){ + QTextStream(&windowText) << value/1000 << "k"; + return windowText; + } + if (value >= 1){ + QTextStream(&windowText) << value; + return windowText; + } + if (value >= 1/1000){ + QTextStream(&windowText) << value * 1000 << "m"; + return windowText; + } + if (value >= 1/1000000){ + QTextStream(&windowText) << value * 1000000 << "u"; + return windowText; + } + return "invalid"; +} + +void espoSpinBox::maximumChanged(double linked){ + this->setMaximum(9.6-linked); +} + +void espoSpinBox::setMax(double newMax){ + this->setMaximum(newMax); +} + +void espoSpinBox::setMin(double newMin){ + this->setMinimum(newMin); +} + +void espoSpinBox::changeStepping(double value){ + double roundval = pow(10.0, floor(log10(value))); //http://stackoverflow.com/questions/22491505/how-to-round-down-to-the-nearest-power-of-10 + roundval = (roundval == 0) ? 0.1 : roundval/10; + setSingleStep(roundval); +} diff --git a/Desktop_Interface/ui_elements/espospinbox.cpp.REMOVED.git-id b/Desktop_Interface/ui_elements/espospinbox.cpp.REMOVED.git-id deleted file mode 100644 index 434fed04..00000000 --- a/Desktop_Interface/ui_elements/espospinbox.cpp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4cc73ea933df36efbc358f6e917d70229c1c70f7 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/espospinbox.h b/Desktop_Interface/ui_elements/espospinbox.h new file mode 100644 index 00000000..25375df8 --- /dev/null +++ b/Desktop_Interface/ui_elements/espospinbox.h @@ -0,0 +1,29 @@ +#ifndef ESPOSPINBOX_H +#define ESPOSPINBOX_H + +#include +#include +#include +#include +#include +#include + +//espoSpinBox is a subclass of QSpinbox. It can talk to other espoSpinBoxes and change their min/max values. + +class espoSpinBox : public QDoubleSpinBox +{ + Q_OBJECT +public: + explicit espoSpinBox(QWidget *parent = 0); +private: + QString textFromValue(double value) const; +signals: + +public slots: + void maximumChanged(double linked); + void setMax(double newMax); + void setMin(double newMin); + void changeStepping(double value); +}; + +#endif // ESPOSPINBOX_H diff --git a/Desktop_Interface/ui_elements/espospinbox.h.REMOVED.git-id b/Desktop_Interface/ui_elements/espospinbox.h.REMOVED.git-id deleted file mode 100644 index 4580df48..00000000 --- a/Desktop_Interface/ui_elements/espospinbox.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -25375df88100fcaad1daa09218c5e868ef5951ed \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/noclosemenu.cpp b/Desktop_Interface/ui_elements/noclosemenu.cpp new file mode 100644 index 00000000..07cc148d --- /dev/null +++ b/Desktop_Interface/ui_elements/noclosemenu.cpp @@ -0,0 +1,22 @@ +#include "noclosemenu.h" + +noCloseMenu::noCloseMenu(QWidget *parent) : QMenu(parent) +{ + +} + +//Dankon, Jakob Leben +//http://stackoverflow.com/questions/2050462/prevent-a-qmenu-from-closing-when-one-of-its-qaction-is-triggered + +void noCloseMenu::mouseReleaseEvent(QMouseEvent *e) +{ + QAction *action = activeAction(); + if (action && action->isEnabled()) { + action->setEnabled(false); + QMenu::mouseReleaseEvent(e); + action->setEnabled(true); + action->trigger(); + } + else + QMenu::mouseReleaseEvent(e); +} diff --git a/Desktop_Interface/ui_elements/noclosemenu.cpp.REMOVED.git-id b/Desktop_Interface/ui_elements/noclosemenu.cpp.REMOVED.git-id deleted file mode 100644 index 5954a35e..00000000 --- a/Desktop_Interface/ui_elements/noclosemenu.cpp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -07cc148dc3031e4b99e57b052ee2bb1e29eaff55 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/noclosemenu.h b/Desktop_Interface/ui_elements/noclosemenu.h new file mode 100644 index 00000000..ce966a62 --- /dev/null +++ b/Desktop_Interface/ui_elements/noclosemenu.h @@ -0,0 +1,22 @@ +#ifndef NOCLOSEMENU_H +#define NOCLOSEMENU_H + +#include +#include + +//The menubar in Qt closes by default once a box has been checked. +//noCloseMenu is a simple class that keeps the menu open even after a box is checked. + +class noCloseMenu : public QMenu +{ + Q_OBJECT +public: + explicit noCloseMenu(QWidget *parent = 0); +private: + void mouseReleaseEvent(QMouseEvent *e); +signals: + +public slots: +}; + +#endif // NOCLOSEMENU_H diff --git a/Desktop_Interface/ui_elements/noclosemenu.h.REMOVED.git-id b/Desktop_Interface/ui_elements/noclosemenu.h.REMOVED.git-id deleted file mode 100644 index 900980dc..00000000 --- a/Desktop_Interface/ui_elements/noclosemenu.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ce966a6203723e3a459b6e4c4d6569474a53d1f8 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/qcp1/qcustomplot.cpp b/Desktop_Interface/ui_elements/qcp1/qcustomplot.cpp new file mode 100644 index 00000000..30860827 --- /dev/null +++ b/Desktop_Interface/ui_elements/qcp1/qcustomplot.cpp @@ -0,0 +1,23553 @@ +/*************************************************************************** +** ** +** QCustomPlot, an easy to use, modern plotting widget for Qt ** +** Copyright (C) 2011-2015 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.qcustomplot.com/ ** +** Date: 22.12.15 ** +** Version: 1.3.2 ** +****************************************************************************/ + +#include "qcustomplot.h" + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPainter +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPainter + \brief QPainter subclass used internally + + This QPainter subclass is used to provide some extended functionality e.g. for tweaking position + consistency between antialiased and non-antialiased painting. Further it provides workarounds + for QPainter quirks. + + \warning This class intentionally hides non-virtual functions of QPainter, e.g. setPen, save and + restore. So while it is possible to pass a QCPPainter instance to a function that expects a + QPainter pointer, some of the workarounds and tweaks will be unavailable to the function (because + it will call the base class implementations of the functions actually hidden by QCPPainter). +*/ + +/*! + Creates a new QCPPainter instance and sets default values +*/ +QCPPainter::QCPPainter() : + QPainter(), + mModes(pmDefault), + mIsAntialiasing(false) +{ + // don't setRenderHint(QPainter::NonCosmeticDefautPen) here, because painter isn't active yet and + // a call to begin() will follow +} + +/*! + Creates a new QCPPainter instance on the specified paint \a device and sets default values. Just + like the analogous QPainter constructor, begins painting on \a device immediately. + + Like \ref begin, this method sets QPainter::NonCosmeticDefaultPen in Qt versions before Qt5. +*/ +QCPPainter::QCPPainter(QPaintDevice *device) : + QPainter(device), + mModes(pmDefault), + mIsAntialiasing(false) +{ +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. + if (isActive()) + setRenderHint(QPainter::NonCosmeticDefaultPen); +#endif +} + +QCPPainter::~QCPPainter() +{ +} + +/*! + Sets the pen of the painter and applies certain fixes to it, depending on the mode of this + QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(const QPen &pen) +{ + QPainter::setPen(pen); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Sets the pen (by color) of the painter and applies certain fixes to it, depending on the mode of + this QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(const QColor &color) +{ + QPainter::setPen(color); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Sets the pen (by style) of the painter and applies certain fixes to it, depending on the mode of + this QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(Qt::PenStyle penStyle) +{ + QPainter::setPen(penStyle); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Works around a Qt bug introduced with Qt 4.8 which makes drawing QLineF unpredictable when + antialiasing is disabled. Thus when antialiasing is disabled, it rounds the \a line to + integer coordinates and then passes it to the original drawLine. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::drawLine(const QLineF &line) +{ + if (mIsAntialiasing || mModes.testFlag(pmVectorized)) + QPainter::drawLine(line); + else + QPainter::drawLine(line.toLine()); +} + +/*! + Sets whether painting uses antialiasing or not. Use this method instead of using setRenderHint + with QPainter::Antialiasing directly, as it allows QCPPainter to regain pixel exactness between + antialiased and non-antialiased painting (Since Qt < 5.0 uses slightly different coordinate systems for + AA/Non-AA painting). +*/ +void QCPPainter::setAntialiasing(bool enabled) +{ + setRenderHint(QPainter::Antialiasing, enabled); + if (mIsAntialiasing != enabled) + { + mIsAntialiasing = enabled; + if (!mModes.testFlag(pmVectorized)) // antialiasing half-pixel shift only needed for rasterized outputs + { + if (mIsAntialiasing) + translate(0.5, 0.5); + else + translate(-0.5, -0.5); + } + } +} + +/*! + Sets the mode of the painter. This controls whether the painter shall adjust its + fixes/workarounds optimized for certain output devices. +*/ +void QCPPainter::setModes(QCPPainter::PainterModes modes) +{ + mModes = modes; +} + +/*! + Sets the QPainter::NonCosmeticDefaultPen in Qt versions before Qt5 after beginning painting on \a + device. This is necessary to get cosmetic pen consistency across Qt versions, because since Qt5, + all pens are non-cosmetic by default, and in Qt4 this render hint must be set to get that + behaviour. + + The Constructor \ref QCPPainter(QPaintDevice *device) which directly starts painting also sets + the render hint as appropriate. + + \note this function hides the non-virtual base class implementation. +*/ +bool QCPPainter::begin(QPaintDevice *device) +{ + bool result = QPainter::begin(device); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. + if (result) + setRenderHint(QPainter::NonCosmeticDefaultPen); +#endif + return result; +} + +/*! \overload + + Sets the mode of the painter. This controls whether the painter shall adjust its + fixes/workarounds optimized for certain output devices. +*/ +void QCPPainter::setMode(QCPPainter::PainterMode mode, bool enabled) +{ + if (!enabled && mModes.testFlag(mode)) + mModes &= ~mode; + else if (enabled && !mModes.testFlag(mode)) + mModes |= mode; +} + +/*! + Saves the painter (see QPainter::save). Since QCPPainter adds some new internal state to + QPainter, the save/restore functions are reimplemented to also save/restore those members. + + \note this function hides the non-virtual base class implementation. + + \see restore +*/ +void QCPPainter::save() +{ + mAntialiasingStack.push(mIsAntialiasing); + QPainter::save(); +} + +/*! + Restores the painter (see QPainter::restore). Since QCPPainter adds some new internal state to + QPainter, the save/restore functions are reimplemented to also save/restore those members. + + \note this function hides the non-virtual base class implementation. + + \see save +*/ +void QCPPainter::restore() +{ + if (!mAntialiasingStack.isEmpty()) + mIsAntialiasing = mAntialiasingStack.pop(); + else + qDebug() << Q_FUNC_INFO << "Unbalanced save/restore"; + QPainter::restore(); +} + +/*! + Changes the pen width to 1 if it currently is 0. This function is called in the \ref setPen + overrides when the \ref pmNonCosmetic mode is set. +*/ +void QCPPainter::makeNonCosmetic() +{ + if (qFuzzyIsNull(pen().widthF())) + { + QPen p = pen(); + p.setWidth(1); + QPainter::setPen(p); + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPScatterStyle +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPScatterStyle + \brief Represents the visual appearance of scatter points + + This class holds information about shape, color and size of scatter points. In plottables like + QCPGraph it is used to store how scatter points shall be drawn. For example, \ref + QCPGraph::setScatterStyle takes a QCPScatterStyle instance. + + A scatter style consists of a shape (\ref setShape), a line color (\ref setPen) and possibly a + fill (\ref setBrush), if the shape provides a fillable area. Further, the size of the shape can + be controlled with \ref setSize. + + \section QCPScatterStyle-defining Specifying a scatter style + + You can set all these configurations either by calling the respective functions on an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-1 + + Or you can use one of the various constructors that take different parameter combinations, making + it easy to specify a scatter style in a single call, like so: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-2 + + \section QCPScatterStyle-undefinedpen Leaving the color/pen up to the plottable + + There are two constructors which leave the pen undefined: \ref QCPScatterStyle() and \ref + QCPScatterStyle(ScatterShape shape, double size). If those constructors are used, a call to \ref + isPenDefined will return false. It leads to scatter points that inherit the pen from the + plottable that uses the scatter style. Thus, if such a scatter style is passed to QCPGraph, the line + color of the graph (\ref QCPGraph::setPen) will be used by the scatter points. This makes + it very convenient to set up typical scatter settings: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-shortcreation + + Notice that it wasn't even necessary to explicitly call a QCPScatterStyle constructor. This works + because QCPScatterStyle provides a constructor that can transform a \ref ScatterShape directly + into a QCPScatterStyle instance (that's the \ref QCPScatterStyle(ScatterShape shape, double size) + constructor with a default for \a size). In those cases, C++ allows directly supplying a \ref + ScatterShape, where actually a QCPScatterStyle is expected. + + \section QCPScatterStyle-custompath-and-pixmap Custom shapes and pixmaps + + QCPScatterStyle supports drawing custom shapes and arbitrary pixmaps as scatter points. + + For custom shapes, you can provide a QPainterPath with the desired shape to the \ref + setCustomPath function or call the constructor that takes a painter path. The scatter shape will + automatically be set to \ref ssCustom. + + For pixmaps, you call \ref setPixmap with the desired QPixmap. Alternatively you can use the + constructor that takes a QPixmap. The scatter shape will automatically be set to \ref ssPixmap. + Note that \ref setSize does not influence the appearance of the pixmap. +*/ + +/* start documentation of inline functions */ + +/*! \fn bool QCPScatterStyle::isNone() const + + Returns whether the scatter shape is \ref ssNone. + + \see setShape +*/ + +/*! \fn bool QCPScatterStyle::isPenDefined() const + + Returns whether a pen has been defined for this scatter style. + + The pen is undefined if a constructor is called that does not carry \a pen as parameter. Those are + \ref QCPScatterStyle() and \ref QCPScatterStyle(ScatterShape shape, double size). If the pen is + left undefined, the scatter color will be inherited from the plottable that uses this scatter + style. + + \see setPen +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPScatterStyle instance with size set to 6. No shape, pen or brush is defined. + + Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited + from the plottable that uses this scatter style. +*/ +QCPScatterStyle::QCPScatterStyle() : + mSize(6), + mShape(ssNone), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape and size to \a size. No pen or + brush is defined. + + Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited + from the plottable that uses this scatter style. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, double size) : + mSize(size), + mShape(shape), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, + and size to \a size. No brush is defined, i.e. the scatter point will not be filled. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, double size) : + mSize(size), + mShape(shape), + mPen(QPen(color)), + mBrush(Qt::NoBrush), + mPenDefined(true) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, + the brush color to \a fill (with a solid pattern), and size to \a size. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) : + mSize(size), + mShape(shape), + mPen(QPen(color)), + mBrush(QBrush(fill)), + mPenDefined(true) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen set to \a pen, the + brush to \a brush, and size to \a size. + + \warning In some cases it might be tempting to directly use a pen style like Qt::NoPen as \a pen + and a color like Qt::blue as \a brush. Notice however, that the corresponding call\n + QCPScatterStyle(QCPScatterShape::ssCircle, Qt::NoPen, Qt::blue, 5)\n + doesn't necessarily lead C++ to use this constructor in some cases, but might mistake + Qt::NoPen for a QColor and use the + \ref QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) + constructor instead (which will lead to an unexpected look of the scatter points). To prevent + this, be more explicit with the parameter types. For example, use QBrush(Qt::blue) + instead of just Qt::blue, to clearly point out to the compiler that this constructor is + wanted. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size) : + mSize(size), + mShape(shape), + mPen(pen), + mBrush(brush), + mPenDefined(pen.style() != Qt::NoPen) +{ +} + +/*! + Creates a new QCPScatterStyle instance which will show the specified \a pixmap. The scatter shape + is set to \ref ssPixmap. +*/ +QCPScatterStyle::QCPScatterStyle(const QPixmap &pixmap) : + mSize(5), + mShape(ssPixmap), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPixmap(pixmap), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with a custom shape that is defined via \a customPath. The + scatter shape is set to \ref ssCustom. + + The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly + different meaning than for built-in scatter points: The custom path will be drawn scaled by a + factor of \a size/6.0. Since the default \a size is 6, the custom path will appear at a its + natural size by default. To double the size of the path for example, set \a size to 12. +*/ +QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush, double size) : + mSize(size), + mShape(ssCustom), + mPen(pen), + mBrush(brush), + mCustomPath(customPath), + mPenDefined(pen.style() != Qt::NoPen) +{ +} + +/*! + Sets the size (pixel diameter) of the drawn scatter points to \a size. + + \see setShape +*/ +void QCPScatterStyle::setSize(double size) +{ + mSize = size; +} + +/*! + Sets the shape to \a shape. + + Note that the calls \ref setPixmap and \ref setCustomPath automatically set the shape to \ref + ssPixmap and \ref ssCustom, respectively. + + \see setSize +*/ +void QCPScatterStyle::setShape(QCPScatterStyle::ScatterShape shape) +{ + mShape = shape; +} + +/*! + Sets the pen that will be used to draw scatter points to \a pen. + + If the pen was previously undefined (see \ref isPenDefined), the pen is considered defined after + a call to this function, even if \a pen is Qt::NoPen. + + \see setBrush +*/ +void QCPScatterStyle::setPen(const QPen &pen) +{ + mPenDefined = true; + mPen = pen; +} + +/*! + Sets the brush that will be used to fill scatter points to \a brush. Note that not all scatter + shapes have fillable areas. For example, \ref ssPlus does not while \ref ssCircle does. + + \see setPen +*/ +void QCPScatterStyle::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the pixmap that will be drawn as scatter point to \a pixmap. + + Note that \ref setSize does not influence the appearance of the pixmap. + + The scatter shape is automatically set to \ref ssPixmap. +*/ +void QCPScatterStyle::setPixmap(const QPixmap &pixmap) +{ + setShape(ssPixmap); + mPixmap = pixmap; +} + +/*! + Sets the custom shape that will be drawn as scatter point to \a customPath. + + The scatter shape is automatically set to \ref ssCustom. +*/ +void QCPScatterStyle::setCustomPath(const QPainterPath &customPath) +{ + setShape(ssCustom); + mCustomPath = customPath; +} + +/*! + Applies the pen and the brush of this scatter style to \a painter. If this scatter style has an + undefined pen (\ref isPenDefined), sets the pen of \a painter to \a defaultPen instead. + + This function is used by plottables (or any class that wants to draw scatters) just before a + number of scatters with this style shall be drawn with the \a painter. + + \see drawShape +*/ +void QCPScatterStyle::applyTo(QCPPainter *painter, const QPen &defaultPen) const +{ + painter->setPen(mPenDefined ? mPen : defaultPen); + painter->setBrush(mBrush); +} + +/*! + Draws the scatter shape with \a painter at position \a pos. + + This function does not modify the pen or the brush on the painter, as \ref applyTo is meant to be + called before scatter points are drawn with \ref drawShape. + + \see applyTo +*/ +void QCPScatterStyle::drawShape(QCPPainter *painter, QPointF pos) const +{ + drawShape(painter, pos.x(), pos.y()); +} + +/*! \overload + Draws the scatter shape with \a painter at position \a x and \a y. +*/ +void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const +{ + double w = mSize/2.0; + switch (mShape) + { + case ssNone: break; + case ssDot: + { + painter->drawLine(QPointF(x, y), QPointF(x+0.0001, y)); + break; + } + case ssCross: + { + painter->drawLine(QLineF(x-w, y-w, x+w, y+w)); + painter->drawLine(QLineF(x-w, y+w, x+w, y-w)); + break; + } + case ssPlus: + { + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + break; + } + case ssCircle: + { + painter->drawEllipse(QPointF(x , y), w, w); + break; + } + case ssDisc: + { + QBrush b = painter->brush(); + painter->setBrush(painter->pen().color()); + painter->drawEllipse(QPointF(x , y), w, w); + painter->setBrush(b); + break; + } + case ssSquare: + { + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + break; + } + case ssDiamond: + { + painter->drawLine(QLineF(x-w, y, x, y-w)); + painter->drawLine(QLineF( x, y-w, x+w, y)); + painter->drawLine(QLineF(x+w, y, x, y+w)); + painter->drawLine(QLineF( x, y+w, x-w, y)); + break; + } + case ssStar: + { + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.707, y+w*0.707)); + painter->drawLine(QLineF(x-w*0.707, y+w*0.707, x+w*0.707, y-w*0.707)); + break; + } + case ssTriangle: + { + painter->drawLine(QLineF(x-w, y+0.755*w, x+w, y+0.755*w)); + painter->drawLine(QLineF(x+w, y+0.755*w, x, y-0.977*w)); + painter->drawLine(QLineF( x, y-0.977*w, x-w, y+0.755*w)); + break; + } + case ssTriangleInverted: + { + painter->drawLine(QLineF(x-w, y-0.755*w, x+w, y-0.755*w)); + painter->drawLine(QLineF(x+w, y-0.755*w, x, y+0.977*w)); + painter->drawLine(QLineF( x, y+0.977*w, x-w, y-0.755*w)); + break; + } + case ssCrossSquare: + { + painter->drawLine(QLineF(x-w, y-w, x+w*0.95, y+w*0.95)); + painter->drawLine(QLineF(x-w, y+w*0.95, x+w*0.95, y-w)); + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + break; + } + case ssPlusSquare: + { + painter->drawLine(QLineF(x-w, y, x+w*0.95, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + break; + } + case ssCrossCircle: + { + painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.670, y+w*0.670)); + painter->drawLine(QLineF(x-w*0.707, y+w*0.670, x+w*0.670, y-w*0.707)); + painter->drawEllipse(QPointF(x, y), w, w); + break; + } + case ssPlusCircle: + { + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + painter->drawEllipse(QPointF(x, y), w, w); + break; + } + case ssPeace: + { + painter->drawLine(QLineF(x, y-w, x, y+w)); + painter->drawLine(QLineF(x, y, x-w*0.707, y+w*0.707)); + painter->drawLine(QLineF(x, y, x+w*0.707, y+w*0.707)); + painter->drawEllipse(QPointF(x, y), w, w); + break; + } + case ssPixmap: + { + painter->drawPixmap(x-mPixmap.width()*0.5, y-mPixmap.height()*0.5, mPixmap); + break; + } + case ssCustom: + { + QTransform oldTransform = painter->transform(); + painter->translate(x, y); + painter->scale(mSize/6.0, mSize/6.0); + painter->drawPath(mCustomPath); + painter->setTransform(oldTransform); + break; + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayer + \brief A layer that may contain objects, to control the rendering order + + The Layering system of QCustomPlot is the mechanism to control the rendering order of the + elements inside the plot. + + It is based on the two classes QCPLayer and QCPLayerable. QCustomPlot holds an ordered list of + one or more instances of QCPLayer (see QCustomPlot::addLayer, QCustomPlot::layer, + QCustomPlot::moveLayer, etc.). When replotting, QCustomPlot goes through the list of layers + bottom to top and successively draws the layerables of the layers. + + A QCPLayer contains an ordered list of QCPLayerable instances. QCPLayerable is an abstract base + class from which almost all visible objects derive, like axes, grids, graphs, items, etc. + + Initially, QCustomPlot has five layers: "background", "grid", "main", "axes" and "legend" (in + that order). The top two layers "axes" and "legend" contain the default axes and legend, so they + will be drawn on top. In the middle, there is the "main" layer. It is initially empty and set as + the current layer (see QCustomPlot::setCurrentLayer). This means, all new plottables, items etc. + are created on this layer by default. Then comes the "grid" layer which contains the QCPGrid + instances (which belong tightly to QCPAxis, see \ref QCPAxis::grid). The Axis rect background + shall be drawn behind everything else, thus the default QCPAxisRect instance is placed on the + "background" layer. Of course, the layer affiliation of the individual objects can be changed as + required (\ref QCPLayerable::setLayer). + + Controlling the ordering of objects is easy: Create a new layer in the position you want it to + be, e.g. above "main", with QCustomPlot::addLayer. Then set the current layer with + QCustomPlot::setCurrentLayer to that new layer and finally create the objects normally. They will + be placed on the new layer automatically, due to the current layer setting. Alternatively you + could have also ignored the current layer setting and just moved the objects with + QCPLayerable::setLayer to the desired layer after creating them. + + It is also possible to move whole layers. For example, If you want the grid to be shown in front + of all plottables/items on the "main" layer, just move it above "main" with + QCustomPlot::moveLayer. + + The rendering order within one layer is simply by order of creation or insertion. The item + created last (or added last to the layer), is drawn on top of all other objects on that layer. + + When a layer is deleted, the objects on it are not deleted with it, but fall on the layer below + the deleted layer, see QCustomPlot::removeLayer. +*/ + +/* start documentation of inline functions */ + +/*! \fn QList QCPLayer::children() const + + Returns a list of all layerables on this layer. The order corresponds to the rendering order: + layerables with higher indices are drawn above layerables with lower indices. +*/ + +/*! \fn int QCPLayer::index() const + + Returns the index this layer has in the QCustomPlot. The index is the integer number by which this layer can be + accessed via \ref QCustomPlot::layer. + + Layers with higher indices will be drawn above layers with lower indices. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPLayer instance. + + Normally you shouldn't directly instantiate layers, use \ref QCustomPlot::addLayer instead. + + \warning It is not checked that \a layerName is actually a unique layer name in \a parentPlot. + This check is only performed by \ref QCustomPlot::addLayer. +*/ +QCPLayer::QCPLayer(QCustomPlot *parentPlot, const QString &layerName) : + QObject(parentPlot), + mParentPlot(parentPlot), + mName(layerName), + mIndex(-1), // will be set to a proper value by the QCustomPlot layer creation function + mVisible(true) +{ + // Note: no need to make sure layerName is unique, because layer + // management is done with QCustomPlot functions. +} + +QCPLayer::~QCPLayer() +{ + // If child layerables are still on this layer, detach them, so they don't try to reach back to this + // then invalid layer once they get deleted/moved themselves. This only happens when layers are deleted + // directly, like in the QCustomPlot destructor. (The regular layer removal procedure for the user is to + // call QCustomPlot::removeLayer, which moves all layerables off this layer before deleting it.) + + while (!mChildren.isEmpty()) + mChildren.last()->setLayer(0); // removes itself from mChildren via removeChild() + + if (mParentPlot->currentLayer() == this) + qDebug() << Q_FUNC_INFO << "The parent plot's mCurrentLayer will be a dangling pointer. Should have been set to a valid layer or 0 beforehand."; +} + +/*! + Sets whether this layer is visible or not. If \a visible is set to false, all layerables on this + layer will be invisible. + + This function doesn't change the visibility property of the layerables (\ref + QCPLayerable::setVisible), but the \ref QCPLayerable::realVisibility of each layerable takes the + visibility of the parent layer into account. +*/ +void QCPLayer::setVisible(bool visible) +{ + mVisible = visible; +} + +/*! \internal + + Adds the \a layerable to the list of this layer. If \a prepend is set to true, the layerable will + be prepended to the list, i.e. be drawn beneath the other layerables already in the list. + + This function does not change the \a mLayer member of \a layerable to this layer. (Use + QCPLayerable::setLayer to change the layer of an object, not this function.) + + \see removeChild +*/ +void QCPLayer::addChild(QCPLayerable *layerable, bool prepend) +{ + if (!mChildren.contains(layerable)) + { + if (prepend) + mChildren.prepend(layerable); + else + mChildren.append(layerable); + } else + qDebug() << Q_FUNC_INFO << "layerable is already child of this layer" << reinterpret_cast(layerable); +} + +/*! \internal + + Removes the \a layerable from the list of this layer. + + This function does not change the \a mLayer member of \a layerable. (Use QCPLayerable::setLayer + to change the layer of an object, not this function.) + + \see addChild +*/ +void QCPLayer::removeChild(QCPLayerable *layerable) +{ + if (!mChildren.removeOne(layerable)) + qDebug() << Q_FUNC_INFO << "layerable is not child of this layer" << reinterpret_cast(layerable); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayerable +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayerable + \brief Base class for all drawable objects + + This is the abstract base class most visible objects derive from, e.g. plottables, axes, grid + etc. + + Every layerable is on a layer (QCPLayer) which allows controlling the rendering order by stacking + the layers accordingly. + + For details about the layering mechanism, see the QCPLayer documentation. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayerable *QCPLayerable::parentLayerable() const + + Returns the parent layerable of this layerable. The parent layerable is used to provide + visibility hierarchies in conjunction with the method \ref realVisibility. This way, layerables + only get drawn if their parent layerables are visible, too. + + Note that a parent layerable is not necessarily also the QObject parent for memory management. + Further, a layerable doesn't always have a parent layerable, so this function may return 0. + + A parent layerable is set implicitly with when placed inside layout elements and doesn't need to be + set manually by the user. +*/ + +/* end documentation of inline functions */ +/* start documentation of pure virtual functions */ + +/*! \fn virtual void QCPLayerable::applyDefaultAntialiasingHint(QCPPainter *painter) const = 0 + \internal + + This function applies the default antialiasing setting to the specified \a painter, using the + function \ref applyAntialiasingHint. It is the antialiasing state the painter is put in, when + \ref draw is called on the layerable. If the layerable has multiple entities whose antialiasing + setting may be specified individually, this function should set the antialiasing state of the + most prominent entity. In this case however, the \ref draw function usually calls the specialized + versions of this function before drawing each entity, effectively overriding the setting of the + default antialiasing hint. + + First example: QCPGraph has multiple entities that have an antialiasing setting: The graph + line, fills, scatters and error bars. Those can be configured via QCPGraph::setAntialiased, + QCPGraph::setAntialiasedFill, QCPGraph::setAntialiasedScatters etc. Consequently, there isn't + only the QCPGraph::applyDefaultAntialiasingHint function (which corresponds to the graph line's + antialiasing), but specialized ones like QCPGraph::applyFillAntialiasingHint and + QCPGraph::applyScattersAntialiasingHint. So before drawing one of those entities, QCPGraph::draw + calls the respective specialized applyAntialiasingHint function. + + Second example: QCPItemLine consists only of a line so there is only one antialiasing + setting which can be controlled with QCPItemLine::setAntialiased. (This function is inherited by + all layerables. The specialized functions, as seen on QCPGraph, must be added explicitly to the + respective layerable subclass.) Consequently it only has the normal + QCPItemLine::applyDefaultAntialiasingHint. The \ref QCPItemLine::draw function doesn't need to + care about setting any antialiasing states, because the default antialiasing hint is already set + on the painter when the \ref draw function is called, and that's the state it wants to draw the + line with. +*/ + +/*! \fn virtual void QCPLayerable::draw(QCPPainter *painter) const = 0 + \internal + + This function draws the layerable with the specified \a painter. It is only called by + QCustomPlot, if the layerable is visible (\ref setVisible). + + Before this function is called, the painter's antialiasing state is set via \ref + applyDefaultAntialiasingHint, see the documentation there. Further, the clipping rectangle was + set to \ref clipRect. +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of signals */ + +/*! \fn void QCPLayerable::layerChanged(QCPLayer *newLayer); + + This signal is emitted when the layer of this layerable changes, i.e. this layerable is moved to + a different layer. + + \see setLayer +*/ + +/* end documentation of signals */ + +/*! + Creates a new QCPLayerable instance. + + Since QCPLayerable is an abstract base class, it can't be instantiated directly. Use one of the + derived classes. + + If \a plot is provided, it automatically places itself on the layer named \a targetLayer. If \a + targetLayer is an empty string, it places itself on the current layer of the plot (see \ref + QCustomPlot::setCurrentLayer). + + It is possible to provide 0 as \a plot. In that case, you should assign a parent plot at a later + time with \ref initializeParentPlot. + + The layerable's parent layerable is set to \a parentLayerable, if provided. Direct layerable + parents are mainly used to control visibility in a hierarchy of layerables. This means a + layerable is only drawn, if all its ancestor layerables are also visible. Note that \a + parentLayerable does not become the QObject-parent (for memory management) of this layerable, \a + plot does. It is not uncommon to set the QObject-parent to something else in the constructors of + QCPLayerable subclasses, to guarantee a working destruction hierarchy. +*/ +QCPLayerable::QCPLayerable(QCustomPlot *plot, QString targetLayer, QCPLayerable *parentLayerable) : + QObject(plot), + mVisible(true), + mParentPlot(plot), + mParentLayerable(parentLayerable), + mLayer(0), + mAntialiased(true) +{ + if (mParentPlot) + { + if (targetLayer.isEmpty()) + setLayer(mParentPlot->currentLayer()); + else if (!setLayer(targetLayer)) + qDebug() << Q_FUNC_INFO << "setting QCPlayerable initial layer to" << targetLayer << "failed."; + } +} + +QCPLayerable::~QCPLayerable() +{ + if (mLayer) + { + mLayer->removeChild(this); + mLayer = 0; + } +} + +/*! + Sets the visibility of this layerable object. If an object is not visible, it will not be drawn + on the QCustomPlot surface, and user interaction with it (e.g. click and selection) is not + possible. +*/ +void QCPLayerable::setVisible(bool on) +{ + mVisible = on; +} + +/*! + Sets the \a layer of this layerable object. The object will be placed on top of the other objects + already on \a layer. + + If \a layer is 0, this layerable will not be on any layer and thus not appear in the plot (or + interact/receive events). + + Returns true if the layer of this layerable was successfully changed to \a layer. +*/ +bool QCPLayerable::setLayer(QCPLayer *layer) +{ + return moveToLayer(layer, false); +} + +/*! \overload + Sets the layer of this layerable object by name + + Returns true on success, i.e. if \a layerName is a valid layer name. +*/ +bool QCPLayerable::setLayer(const QString &layerName) +{ + if (!mParentPlot) + { + qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; + return false; + } + if (QCPLayer *layer = mParentPlot->layer(layerName)) + { + return setLayer(layer); + } else + { + qDebug() << Q_FUNC_INFO << "there is no layer with name" << layerName; + return false; + } +} + +/*! + Sets whether this object will be drawn antialiased or not. + + Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPLayerable::setAntialiased(bool enabled) +{ + mAntialiased = enabled; +} + +/*! + Returns whether this layerable is visible, taking the visibility of the layerable parent and the + visibility of the layer this layerable is on into account. This is the method that is consulted + to decide whether a layerable shall be drawn or not. + + If this layerable has a direct layerable parent (usually set via hierarchies implemented in + subclasses, like in the case of QCPLayoutElement), this function returns true only if this + layerable has its visibility set to true and the parent layerable's \ref realVisibility returns + true. + + If this layerable doesn't have a direct layerable parent, returns the state of this layerable's + visibility. +*/ +bool QCPLayerable::realVisibility() const +{ + return mVisible && (!mLayer || mLayer->visible()) && (!mParentLayerable || mParentLayerable.data()->realVisibility()); +} + +/*! + This function is used to decide whether a click hits a layerable object or not. + + \a pos is a point in pixel coordinates on the QCustomPlot surface. This function returns the + shortest pixel distance of this point to the object. If the object is either invisible or the + distance couldn't be determined, -1.0 is returned. Further, if \a onlySelectable is true and the + object is not selectable, -1.0 is returned, too. + + If the object is represented not by single lines but by an area like a \ref QCPItemText or the + bars of a \ref QCPBars plottable, a click inside the area should also be considered a hit. In + these cases this function thus returns a constant value greater zero but still below the parent + plot's selection tolerance. (typically the selectionTolerance multiplied by 0.99). + + Providing a constant value for area objects allows selecting line objects even when they are + obscured by such area objects, by clicking close to the lines (i.e. closer than + 0.99*selectionTolerance). + + The actual setting of the selection state is not done by this function. This is handled by the + parent QCustomPlot when the mouseReleaseEvent occurs, and the finally selected object is notified + via the selectEvent/deselectEvent methods. + + \a details is an optional output parameter. Every layerable subclass may place any information + in \a details. This information will be passed to \ref selectEvent when the parent QCustomPlot + decides on the basis of this selectTest call, that the object was successfully selected. The + subsequent call to \ref selectEvent will carry the \a details. This is useful for multi-part + objects (like QCPAxis). This way, a possibly complex calculation to decide which part was clicked + is only done once in \ref selectTest. The result (i.e. the actually clicked part) can then be + placed in \a details. So in the subsequent \ref selectEvent, the decision which part was + selected doesn't have to be done a second time for a single selection operation. + + You may pass 0 as \a details to indicate that you are not interested in those selection details. + + \see selectEvent, deselectEvent, QCustomPlot::setInteractions +*/ +double QCPLayerable::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(pos) + Q_UNUSED(onlySelectable) + Q_UNUSED(details) + return -1.0; +} + +/*! \internal + + Sets the parent plot of this layerable. Use this function once to set the parent plot if you have + passed 0 in the constructor. It can not be used to move a layerable from one QCustomPlot to + another one. + + Note that, unlike when passing a non-null parent plot in the constructor, this function does not + make \a parentPlot the QObject-parent of this layerable. If you want this, call + QObject::setParent(\a parentPlot) in addition to this function. + + Further, you will probably want to set a layer (\ref setLayer) after calling this function, to + make the layerable appear on the QCustomPlot. + + The parent plot change will be propagated to subclasses via a call to \ref parentPlotInitialized + so they can react accordingly (e.g. also initialize the parent plot of child layerables, like + QCPLayout does). +*/ +void QCPLayerable::initializeParentPlot(QCustomPlot *parentPlot) +{ + if (mParentPlot) + { + qDebug() << Q_FUNC_INFO << "called with mParentPlot already initialized"; + return; + } + + if (!parentPlot) + qDebug() << Q_FUNC_INFO << "called with parentPlot zero"; + + mParentPlot = parentPlot; + parentPlotInitialized(mParentPlot); +} + +/*! \internal + + Sets the parent layerable of this layerable to \a parentLayerable. Note that \a parentLayerable does not + become the QObject-parent (for memory management) of this layerable. + + The parent layerable has influence on the return value of the \ref realVisibility method. Only + layerables with a fully visible parent tree will return true for \ref realVisibility, and thus be + drawn. + + \see realVisibility +*/ +void QCPLayerable::setParentLayerable(QCPLayerable *parentLayerable) +{ + mParentLayerable = parentLayerable; +} + +/*! \internal + + Moves this layerable object to \a layer. If \a prepend is true, this object will be prepended to + the new layer's list, i.e. it will be drawn below the objects already on the layer. If it is + false, the object will be appended. + + Returns true on success, i.e. if \a layer is a valid layer. +*/ +bool QCPLayerable::moveToLayer(QCPLayer *layer, bool prepend) +{ + if (layer && !mParentPlot) + { + qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; + return false; + } + if (layer && layer->parentPlot() != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "layer" << layer->name() << "is not in same QCustomPlot as this layerable"; + return false; + } + + QCPLayer *oldLayer = mLayer; + if (mLayer) + mLayer->removeChild(this); + mLayer = layer; + if (mLayer) + mLayer->addChild(this, prepend); + if (mLayer != oldLayer) + emit layerChanged(mLayer); + return true; +} + +/*! \internal + + Sets the QCPainter::setAntialiasing state on the provided \a painter, depending on the \a + localAntialiased value as well as the overrides \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. Which override enum this function takes into account is + controlled via \a overrideElement. +*/ +void QCPLayerable::applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const +{ + if (mParentPlot && mParentPlot->notAntialiasedElements().testFlag(overrideElement)) + painter->setAntialiasing(false); + else if (mParentPlot && mParentPlot->antialiasedElements().testFlag(overrideElement)) + painter->setAntialiasing(true); + else + painter->setAntialiasing(localAntialiased); +} + +/*! \internal + + This function is called by \ref initializeParentPlot, to allow subclasses to react on the setting + of a parent plot. This is the case when 0 was passed as parent plot in the constructor, and the + parent plot is set at a later time. + + For example, QCPLayoutElement/QCPLayout hierarchies may be created independently of any + QCustomPlot at first. When they are then added to a layout inside the QCustomPlot, the top level + element of the hierarchy gets its parent plot initialized with \ref initializeParentPlot. To + propagate the parent plot to all the children of the hierarchy, the top level element then uses + this function to pass the parent plot on to its child elements. + + The default implementation does nothing. + + \see initializeParentPlot +*/ +void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot) +{ + Q_UNUSED(parentPlot) +} + +/*! \internal + + Returns the selection category this layerable shall belong to. The selection category is used in + conjunction with \ref QCustomPlot::setInteractions to control which objects are selectable and + which aren't. + + Subclasses that don't fit any of the normal \ref QCP::Interaction values can use \ref + QCP::iSelectOther. This is what the default implementation returns. + + \see QCustomPlot::setInteractions +*/ +QCP::Interaction QCPLayerable::selectionCategory() const +{ + return QCP::iSelectOther; +} + +/*! \internal + + Returns the clipping rectangle of this layerable object. By default, this is the viewport of the + parent QCustomPlot. Specific subclasses may reimplement this function to provide different + clipping rects. + + The returned clipping rect is set on the painter before the draw function of the respective + object is called. +*/ +QRect QCPLayerable::clipRect() const +{ + if (mParentPlot) + return mParentPlot->viewport(); + else + return QRect(); +} + +/*! \internal + + This event is called when the layerable shall be selected, as a consequence of a click by the + user. Subclasses should react to it by setting their selection state appropriately. The default + implementation does nothing. + + \a event is the mouse event that caused the selection. \a additive indicates, whether the user + was holding the multi-select-modifier while performing the selection (see \ref + QCustomPlot::setMultiSelectModifier). if \a additive is true, the selection state must be toggled + (i.e. become selected when unselected and unselected when selected). + + Every selectEvent is preceded by a call to \ref selectTest, which has returned positively (i.e. + returned a value greater than 0 and less than the selection tolerance of the parent QCustomPlot). + The \a details data you output from \ref selectTest is fed back via \a details here. You may + use it to transport any kind of information from the selectTest to the possibly subsequent + selectEvent. Usually \a details is used to transfer which part was clicked, if it is a layerable + that has multiple individually selectable parts (like QCPAxis). This way selectEvent doesn't need + to do the calculation again to find out which part was actually clicked. + + \a selectionStateChanged is an output parameter. If the pointer is non-null, this function must + set the value either to true or false, depending on whether the selection state of this layerable + was actually changed. For layerables that only are selectable as a whole and not in parts, this + is simple: if \a additive is true, \a selectionStateChanged must also be set to true, because the + selection toggles. If \a additive is false, \a selectionStateChanged is only set to true, if the + layerable was previously unselected and now is switched to the selected state. + + \see selectTest, deselectEvent +*/ +void QCPLayerable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(additive) + Q_UNUSED(details) + Q_UNUSED(selectionStateChanged) +} + +/*! \internal + + This event is called when the layerable shall be deselected, either as consequence of a user + interaction or a call to \ref QCustomPlot::deselectAll. Subclasses should react to it by + unsetting their selection appropriately. + + just as in \ref selectEvent, the output parameter \a selectionStateChanged (if non-null), must + return true or false when the selection state of this layerable has changed or not changed, + respectively. + + \see selectTest, selectEvent +*/ +void QCPLayerable::deselectEvent(bool *selectionStateChanged) +{ + Q_UNUSED(selectionStateChanged) +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPRange +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPRange + \brief Represents the range an axis is encompassing. + + contains a \a lower and \a upper double value and provides convenience input, output and + modification functions. + + \see QCPAxis::setRange +*/ + +/*! + Minimum range size (\a upper - \a lower) the range changing functions will accept. Smaller + intervals would cause errors due to the 11-bit exponent of double precision numbers, + corresponding to a minimum magnitude of roughly 1e-308. + \see validRange, maxRange +*/ +const double QCPRange::minRange = 1e-280; + +/*! + Maximum values (negative and positive) the range will accept in range-changing functions. + Larger absolute values would cause errors due to the 11-bit exponent of double precision numbers, + corresponding to a maximum magnitude of roughly 1e308. + Since the number of planck-volumes in the entire visible universe is only ~1e183, this should + be enough. + \see validRange, minRange +*/ +const double QCPRange::maxRange = 1e250; + +/*! + Constructs a range with \a lower and \a upper set to zero. +*/ +QCPRange::QCPRange() : + lower(0), + upper(0) +{ +} + +/*! \overload + Constructs a range with the specified \a lower and \a upper values. +*/ +QCPRange::QCPRange(double lower, double upper) : + lower(lower), + upper(upper) +{ + normalize(); +} + +/*! + Returns the size of the range, i.e. \a upper-\a lower +*/ +double QCPRange::size() const +{ + return upper-lower; +} + +/*! + Returns the center of the range, i.e. (\a upper+\a lower)*0.5 +*/ +double QCPRange::center() const +{ + return (upper+lower)*0.5; +} + +/*! + Makes sure \a lower is numerically smaller than \a upper. If this is not the case, the values + are swapped. +*/ +void QCPRange::normalize() +{ + if (lower > upper) + qSwap(lower, upper); +} + +/*! + Expands this range such that \a otherRange is contained in the new range. It is assumed that both + this range and \a otherRange are normalized (see \ref normalize). + + If \a otherRange is already inside the current range, this function does nothing. + + \see expanded +*/ +void QCPRange::expand(const QCPRange &otherRange) +{ + if (lower > otherRange.lower) + lower = otherRange.lower; + if (upper < otherRange.upper) + upper = otherRange.upper; +} + + +/*! + Returns an expanded range that contains this and \a otherRange. It is assumed that both this + range and \a otherRange are normalized (see \ref normalize). + + \see expand +*/ +QCPRange QCPRange::expanded(const QCPRange &otherRange) const +{ + QCPRange result = *this; + result.expand(otherRange); + return result; +} + +/*! + Returns a sanitized version of the range. Sanitized means for logarithmic scales, that + the range won't span the positive and negative sign domain, i.e. contain zero. Further + \a lower will always be numerically smaller (or equal) to \a upper. + + If the original range does span positive and negative sign domains or contains zero, + the returned range will try to approximate the original range as good as possible. + If the positive interval of the original range is wider than the negative interval, the + returned range will only contain the positive interval, with lower bound set to \a rangeFac or + \a rangeFac *\a upper, whichever is closer to zero. Same procedure is used if the negative interval + is wider than the positive interval, this time by changing the \a upper bound. +*/ +QCPRange QCPRange::sanitizedForLogScale() const +{ + double rangeFac = 1e-3; + QCPRange sanitizedRange(lower, upper); + sanitizedRange.normalize(); + // can't have range spanning negative and positive values in log plot, so change range to fix it + //if (qFuzzyCompare(sanitizedRange.lower+1, 1) && !qFuzzyCompare(sanitizedRange.upper+1, 1)) + if (sanitizedRange.lower == 0.0 && sanitizedRange.upper != 0.0) + { + // case lower is 0 + if (rangeFac < sanitizedRange.upper*rangeFac) + sanitizedRange.lower = rangeFac; + else + sanitizedRange.lower = sanitizedRange.upper*rangeFac; + } //else if (!qFuzzyCompare(lower+1, 1) && qFuzzyCompare(upper+1, 1)) + else if (sanitizedRange.lower != 0.0 && sanitizedRange.upper == 0.0) + { + // case upper is 0 + if (-rangeFac > sanitizedRange.lower*rangeFac) + sanitizedRange.upper = -rangeFac; + else + sanitizedRange.upper = sanitizedRange.lower*rangeFac; + } else if (sanitizedRange.lower < 0 && sanitizedRange.upper > 0) + { + // find out whether negative or positive interval is wider to decide which sign domain will be chosen + if (-sanitizedRange.lower > sanitizedRange.upper) + { + // negative is wider, do same as in case upper is 0 + if (-rangeFac > sanitizedRange.lower*rangeFac) + sanitizedRange.upper = -rangeFac; + else + sanitizedRange.upper = sanitizedRange.lower*rangeFac; + } else + { + // positive is wider, do same as in case lower is 0 + if (rangeFac < sanitizedRange.upper*rangeFac) + sanitizedRange.lower = rangeFac; + else + sanitizedRange.lower = sanitizedRange.upper*rangeFac; + } + } + // due to normalization, case lower>0 && upper<0 should never occur, because that implies upper= lower && value <= upper; +} + +/*! + Checks, whether the specified range is within valid bounds, which are defined + as QCPRange::maxRange and QCPRange::minRange. + A valid range means: + \li range bounds within -maxRange and maxRange + \li range size above minRange + \li range size below maxRange +*/ +bool QCPRange::validRange(double lower, double upper) +{ + return (lower > -maxRange && + upper < maxRange && + qAbs(lower-upper) > minRange && + qAbs(lower-upper) < maxRange && + !(lower > 0 && qIsInf(upper/lower)) && + !(upper < 0 && qIsInf(lower/upper))); +} + +/*! + \overload + Checks, whether the specified range is within valid bounds, which are defined + as QCPRange::maxRange and QCPRange::minRange. + A valid range means: + \li range bounds within -maxRange and maxRange + \li range size above minRange + \li range size below maxRange +*/ +bool QCPRange::validRange(const QCPRange &range) +{ + return (range.lower > -maxRange && + range.upper < maxRange && + qAbs(range.lower-range.upper) > minRange && + qAbs(range.lower-range.upper) < maxRange && + !(range.lower > 0 && qIsInf(range.upper/range.lower)) && + !(range.upper < 0 && qIsInf(range.lower/range.upper))); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPMarginGroup +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPMarginGroup + \brief A margin group allows synchronization of margin sides if working with multiple layout elements. + + QCPMarginGroup allows you to tie a margin side of two or more layout elements together, such that + they will all have the same size, based on the largest required margin in the group. + + \n + \image html QCPMarginGroup.png "Demonstration of QCPMarginGroup" + \n + + In certain situations it is desirable that margins at specific sides are synchronized across + layout elements. For example, if one QCPAxisRect is below another one in a grid layout, it will + provide a cleaner look to the user if the left and right margins of the two axis rects are of the + same size. The left axis of the top axis rect will then be at the same horizontal position as the + left axis of the lower axis rect, making them appear aligned. The same applies for the right + axes. This is what QCPMarginGroup makes possible. + + To add/remove a specific side of a layout element to/from a margin group, use the \ref + QCPLayoutElement::setMarginGroup method. To completely break apart the margin group, either call + \ref clear, or just delete the margin group. + + \section QCPMarginGroup-example Example + + First create a margin group: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-1 + Then set this group on the layout element sides: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-2 + Here, we've used the first two axis rects of the plot and synchronized their left margins with + each other and their right margins with each other. +*/ + +/* start documentation of inline functions */ + +/*! \fn QList QCPMarginGroup::elements(QCP::MarginSide side) const + + Returns a list of all layout elements that have their margin \a side associated with this margin + group. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPMarginGroup instance in \a parentPlot. +*/ +QCPMarginGroup::QCPMarginGroup(QCustomPlot *parentPlot) : + QObject(parentPlot), + mParentPlot(parentPlot) +{ + mChildren.insert(QCP::msLeft, QList()); + mChildren.insert(QCP::msRight, QList()); + mChildren.insert(QCP::msTop, QList()); + mChildren.insert(QCP::msBottom, QList()); +} + +QCPMarginGroup::~QCPMarginGroup() +{ + clear(); +} + +/*! + Returns whether this margin group is empty. If this function returns true, no layout elements use + this margin group to synchronize margin sides. +*/ +bool QCPMarginGroup::isEmpty() const +{ + QHashIterator > it(mChildren); + while (it.hasNext()) + { + it.next(); + if (!it.value().isEmpty()) + return false; + } + return true; +} + +/*! + Clears this margin group. The synchronization of the margin sides that use this margin group is + lifted and they will use their individual margin sizes again. +*/ +void QCPMarginGroup::clear() +{ + // make all children remove themselves from this margin group: + QHashIterator > it(mChildren); + while (it.hasNext()) + { + it.next(); + const QList elements = it.value(); + for (int i=elements.size()-1; i>=0; --i) + elements.at(i)->setMarginGroup(it.key(), 0); // removes itself from mChildren via removeChild + } +} + +/*! \internal + + Returns the synchronized common margin for \a side. This is the margin value that will be used by + the layout element on the respective side, if it is part of this margin group. + + The common margin is calculated by requesting the automatic margin (\ref + QCPLayoutElement::calculateAutoMargin) of each element associated with \a side in this margin + group, and choosing the largest returned value. (QCPLayoutElement::minimumMargins is taken into + account, too.) +*/ +int QCPMarginGroup::commonMargin(QCP::MarginSide side) const +{ + // query all automatic margins of the layout elements in this margin group side and find maximum: + int result = 0; + const QList elements = mChildren.value(side); + for (int i=0; iautoMargins().testFlag(side)) + continue; + int m = qMax(elements.at(i)->calculateAutoMargin(side), QCP::getMarginValue(elements.at(i)->minimumMargins(), side)); + if (m > result) + result = m; + } + return result; +} + +/*! \internal + + Adds \a element to the internal list of child elements, for the margin \a side. + + This function does not modify the margin group property of \a element. +*/ +void QCPMarginGroup::addChild(QCP::MarginSide side, QCPLayoutElement *element) +{ + if (!mChildren[side].contains(element)) + mChildren[side].append(element); + else + qDebug() << Q_FUNC_INFO << "element is already child of this margin group side" << reinterpret_cast(element); +} + +/*! \internal + + Removes \a element from the internal list of child elements, for the margin \a side. + + This function does not modify the margin group property of \a element. +*/ +void QCPMarginGroup::removeChild(QCP::MarginSide side, QCPLayoutElement *element) +{ + if (!mChildren[side].removeOne(element)) + qDebug() << Q_FUNC_INFO << "element is not child of this margin group side" << reinterpret_cast(element); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutElement +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayoutElement + \brief The abstract base class for all objects that form \ref thelayoutsystem "the layout system". + + This is an abstract base class. As such, it can't be instantiated directly, rather use one of its subclasses. + + A Layout element is a rectangular object which can be placed in layouts. It has an outer rect + (QCPLayoutElement::outerRect) and an inner rect (\ref QCPLayoutElement::rect). The difference + between outer and inner rect is called its margin. The margin can either be set to automatic or + manual (\ref setAutoMargins) on a per-side basis. If a side is set to manual, that margin can be + set explicitly with \ref setMargins and will stay fixed at that value. If it's set to automatic, + the layout element subclass will control the value itself (via \ref calculateAutoMargin). + + Layout elements can be placed in layouts (base class QCPLayout) like QCPLayoutGrid. The top level + layout is reachable via \ref QCustomPlot::plotLayout, and is a \ref QCPLayoutGrid. Since \ref + QCPLayout itself derives from \ref QCPLayoutElement, layouts can be nested. + + Thus in QCustomPlot one can divide layout elements into two categories: The ones that are + invisible by themselves, because they don't draw anything. Their only purpose is to manage the + position and size of other layout elements. This category of layout elements usually use + QCPLayout as base class. Then there is the category of layout elements which actually draw + something. For example, QCPAxisRect, QCPLegend and QCPPlotTitle are of this category. This does + not necessarily mean that the latter category can't have child layout elements. QCPLegend for + instance, actually derives from QCPLayoutGrid and the individual legend items are child layout + elements in the grid layout. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayout *QCPLayoutElement::layout() const + + Returns the parent layout of this layout element. +*/ + +/*! \fn QRect QCPLayoutElement::rect() const + + Returns the inner rect of this layout element. The inner rect is the outer rect (\ref + setOuterRect) shrinked by the margins (\ref setMargins, \ref setAutoMargins). + + In some cases, the area between outer and inner rect is left blank. In other cases the margin + area is used to display peripheral graphics while the main content is in the inner rect. This is + where automatic margin calculation becomes interesting because it allows the layout element to + adapt the margins to the peripheral graphics it wants to draw. For example, \ref QCPAxisRect + draws the axis labels and tick labels in the margin area, thus needs to adjust the margins (if + \ref setAutoMargins is enabled) according to the space required by the labels of the axes. +*/ + +/*! \fn virtual void QCPLayoutElement::mousePressEvent(QMouseEvent *event) + + This event is called, if the mouse was pressed while being inside the outer rect of this layout + element. +*/ + +/*! \fn virtual void QCPLayoutElement::mouseMoveEvent(QMouseEvent *event) + + This event is called, if the mouse is moved inside the outer rect of this layout element. +*/ + +/*! \fn virtual void QCPLayoutElement::mouseReleaseEvent(QMouseEvent *event) + + This event is called, if the mouse was previously pressed inside the outer rect of this layout + element and is now released. +*/ + +/*! \fn virtual void QCPLayoutElement::mouseDoubleClickEvent(QMouseEvent *event) + + This event is called, if the mouse is double-clicked inside the outer rect of this layout + element. +*/ + +/*! \fn virtual void QCPLayoutElement::wheelEvent(QWheelEvent *event) + + This event is called, if the mouse wheel is scrolled while the cursor is inside the rect of this + layout element. +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutElement and sets default values. +*/ +QCPLayoutElement::QCPLayoutElement(QCustomPlot *parentPlot) : + QCPLayerable(parentPlot), // parenthood is changed as soon as layout element gets inserted into a layout (except for top level layout) + mParentLayout(0), + mMinimumSize(), + mMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX), + mRect(0, 0, 0, 0), + mOuterRect(0, 0, 0, 0), + mMargins(0, 0, 0, 0), + mMinimumMargins(0, 0, 0, 0), + mAutoMargins(QCP::msAll) +{ +} + +QCPLayoutElement::~QCPLayoutElement() +{ + setMarginGroup(QCP::msAll, 0); // unregister at margin groups, if there are any + // unregister at layout: + if (qobject_cast(mParentLayout)) // the qobject_cast is just a safeguard in case the layout forgets to call clear() in its dtor and this dtor is called by QObject dtor + mParentLayout->take(this); +} + +/*! + Sets the outer rect of this layout element. If the layout element is inside a layout, the layout + sets the position and size of this layout element using this function. + + Calling this function externally has no effect, since the layout will overwrite any changes to + the outer rect upon the next replot. + + The layout element will adapt its inner \ref rect by applying the margins inward to the outer rect. + + \see rect +*/ +void QCPLayoutElement::setOuterRect(const QRect &rect) +{ + if (mOuterRect != rect) + { + mOuterRect = rect; + mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); + } +} + +/*! + Sets the margins of this layout element. If \ref setAutoMargins is disabled for some or all + sides, this function is used to manually set the margin on those sides. Sides that are still set + to be handled automatically are ignored and may have any value in \a margins. + + The margin is the distance between the outer rect (controlled by the parent layout via \ref + setOuterRect) and the inner \ref rect (which usually contains the main content of this layout + element). + + \see setAutoMargins +*/ +void QCPLayoutElement::setMargins(const QMargins &margins) +{ + if (mMargins != margins) + { + mMargins = margins; + mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); + } +} + +/*! + If \ref setAutoMargins is enabled on some or all margins, this function is used to provide + minimum values for those margins. + + The minimum values are not enforced on margin sides that were set to be under manual control via + \ref setAutoMargins. + + \see setAutoMargins +*/ +void QCPLayoutElement::setMinimumMargins(const QMargins &margins) +{ + if (mMinimumMargins != margins) + { + mMinimumMargins = margins; + } +} + +/*! + Sets on which sides the margin shall be calculated automatically. If a side is calculated + automatically, a minimum margin value may be provided with \ref setMinimumMargins. If a side is + set to be controlled manually, the value may be specified with \ref setMargins. + + Margin sides that are under automatic control may participate in a \ref QCPMarginGroup (see \ref + setMarginGroup), to synchronize (align) it with other layout elements in the plot. + + \see setMinimumMargins, setMargins +*/ +void QCPLayoutElement::setAutoMargins(QCP::MarginSides sides) +{ + mAutoMargins = sides; +} + +/*! + Sets the minimum size for the inner \ref rect of this layout element. A parent layout tries to + respect the \a size here by changing row/column sizes in the layout accordingly. + + If the parent layout size is not sufficient to satisfy all minimum size constraints of its child + layout elements, the layout may set a size that is actually smaller than \a size. QCustomPlot + propagates the layout's size constraints to the outside by setting its own minimum QWidget size + accordingly, so violations of \a size should be exceptions. +*/ +void QCPLayoutElement::setMinimumSize(const QSize &size) +{ + if (mMinimumSize != size) + { + mMinimumSize = size; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! \overload + + Sets the minimum size for the inner \ref rect of this layout element. +*/ +void QCPLayoutElement::setMinimumSize(int width, int height) +{ + setMinimumSize(QSize(width, height)); +} + +/*! + Sets the maximum size for the inner \ref rect of this layout element. A parent layout tries to + respect the \a size here by changing row/column sizes in the layout accordingly. +*/ +void QCPLayoutElement::setMaximumSize(const QSize &size) +{ + if (mMaximumSize != size) + { + mMaximumSize = size; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! \overload + + Sets the maximum size for the inner \ref rect of this layout element. +*/ +void QCPLayoutElement::setMaximumSize(int width, int height) +{ + setMaximumSize(QSize(width, height)); +} + +/*! + Sets the margin \a group of the specified margin \a sides. + + Margin groups allow synchronizing specified margins across layout elements, see the documentation + of \ref QCPMarginGroup. + + To unset the margin group of \a sides, set \a group to 0. + + Note that margin groups only work for margin sides that are set to automatic (\ref + setAutoMargins). +*/ +void QCPLayoutElement::setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group) +{ + QVector sideVector; + if (sides.testFlag(QCP::msLeft)) sideVector.append(QCP::msLeft); + if (sides.testFlag(QCP::msRight)) sideVector.append(QCP::msRight); + if (sides.testFlag(QCP::msTop)) sideVector.append(QCP::msTop); + if (sides.testFlag(QCP::msBottom)) sideVector.append(QCP::msBottom); + + for (int i=0; iremoveChild(side, this); + + if (!group) // if setting to 0, remove hash entry. Else set hash entry to new group and register there + { + mMarginGroups.remove(side); + } else // setting to a new group + { + mMarginGroups[side] = group; + group->addChild(side, this); + } + } + } +} + +/*! + Updates the layout element and sub-elements. This function is automatically called before every + replot by the parent layout element. It is called multiple times, once for every \ref + UpdatePhase. The phases are run through in the order of the enum values. For details about what + happens at the different phases, see the documentation of \ref UpdatePhase. + + Layout elements that have child elements should call the \ref update method of their child + elements, and pass the current \a phase unchanged. + + The default implementation executes the automatic margin mechanism in the \ref upMargins phase. + Subclasses should make sure to call the base class implementation. +*/ +void QCPLayoutElement::update(UpdatePhase phase) +{ + if (phase == upMargins) + { + if (mAutoMargins != QCP::msNone) + { + // set the margins of this layout element according to automatic margin calculation, either directly or via a margin group: + QMargins newMargins = mMargins; + QList allMarginSides = QList() << QCP::msLeft << QCP::msRight << QCP::msTop << QCP::msBottom; + foreach (QCP::MarginSide side, allMarginSides) + { + if (mAutoMargins.testFlag(side)) // this side's margin shall be calculated automatically + { + if (mMarginGroups.contains(side)) + QCP::setMarginValue(newMargins, side, mMarginGroups[side]->commonMargin(side)); // this side is part of a margin group, so get the margin value from that group + else + QCP::setMarginValue(newMargins, side, calculateAutoMargin(side)); // this side is not part of a group, so calculate the value directly + // apply minimum margin restrictions: + if (QCP::getMarginValue(newMargins, side) < QCP::getMarginValue(mMinimumMargins, side)) + QCP::setMarginValue(newMargins, side, QCP::getMarginValue(mMinimumMargins, side)); + } + } + setMargins(newMargins); + } + } +} + +/*! + Returns the minimum size this layout element (the inner \ref rect) may be compressed to. + + if a minimum size (\ref setMinimumSize) was not set manually, parent layouts consult this + function to determine the minimum allowed size of this layout element. (A manual minimum size is + considered set if it is non-zero.) +*/ +QSize QCPLayoutElement::minimumSizeHint() const +{ + return mMinimumSize; +} + +/*! + Returns the maximum size this layout element (the inner \ref rect) may be expanded to. + + if a maximum size (\ref setMaximumSize) was not set manually, parent layouts consult this + function to determine the maximum allowed size of this layout element. (A manual maximum size is + considered set if it is smaller than Qt's QWIDGETSIZE_MAX.) +*/ +QSize QCPLayoutElement::maximumSizeHint() const +{ + return mMaximumSize; +} + +/*! + Returns a list of all child elements in this layout element. If \a recursive is true, all + sub-child elements are included in the list, too. + + \warning There may be entries with value 0 in the returned list. (For example, QCPLayoutGrid may have + empty cells which yield 0 at the respective index.) +*/ +QList QCPLayoutElement::elements(bool recursive) const +{ + Q_UNUSED(recursive) + return QList(); +} + +/*! + Layout elements are sensitive to events inside their outer rect. If \a pos is within the outer + rect, this method returns a value corresponding to 0.99 times the parent plot's selection + tolerance. However, layout elements are not selectable by default. So if \a onlySelectable is + true, -1.0 is returned. + + See \ref QCPLayerable::selectTest for a general explanation of this virtual method. + + QCPLayoutElement subclasses may reimplement this method to provide more specific selection test + behaviour. +*/ +double QCPLayoutElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + + if (onlySelectable) + return -1; + + if (QRectF(mOuterRect).contains(pos)) + { + if (mParentPlot) + return mParentPlot->selectionTolerance()*0.99; + else + { + qDebug() << Q_FUNC_INFO << "parent plot not defined"; + return -1; + } + } else + return -1; +} + +/*! \internal + + propagates the parent plot initialization to all child elements, by calling \ref + QCPLayerable::initializeParentPlot on them. +*/ +void QCPLayoutElement::parentPlotInitialized(QCustomPlot *parentPlot) +{ + foreach (QCPLayoutElement* el, elements(false)) + { + if (!el->parentPlot()) + el->initializeParentPlot(parentPlot); + } +} + +/*! \internal + + Returns the margin size for this \a side. It is used if automatic margins is enabled for this \a + side (see \ref setAutoMargins). If a minimum margin was set with \ref setMinimumMargins, the + returned value will not be smaller than the specified minimum margin. + + The default implementation just returns the respective manual margin (\ref setMargins) or the + minimum margin, whichever is larger. +*/ +int QCPLayoutElement::calculateAutoMargin(QCP::MarginSide side) +{ + return qMax(QCP::getMarginValue(mMargins, side), QCP::getMarginValue(mMinimumMargins, side)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayout +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayout + \brief The abstract base class for layouts + + This is an abstract base class for layout elements whose main purpose is to define the position + and size of other child layout elements. In most cases, layouts don't draw anything themselves + (but there are exceptions to this, e.g. QCPLegend). + + QCPLayout derives from QCPLayoutElement, and thus can itself be nested in other layouts. + + QCPLayout introduces a common interface for accessing and manipulating the child elements. Those + functions are most notably \ref elementCount, \ref elementAt, \ref takeAt, \ref take, \ref + simplify, \ref removeAt, \ref remove and \ref clear. Individual subclasses may add more functions + to this interface which are more specialized to the form of the layout. For example, \ref + QCPLayoutGrid adds functions that take row and column indices to access cells of the layout grid + more conveniently. + + Since this is an abstract base class, you can't instantiate it directly. Rather use one of its + subclasses like QCPLayoutGrid or QCPLayoutInset. + + For a general introduction to the layout system, see the dedicated documentation page \ref + thelayoutsystem "The Layout System". +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual int QCPLayout::elementCount() const = 0 + + Returns the number of elements/cells in the layout. + + \see elements, elementAt +*/ + +/*! \fn virtual QCPLayoutElement* QCPLayout::elementAt(int index) const = 0 + + Returns the element in the cell with the given \a index. If \a index is invalid, returns 0. + + Note that even if \a index is valid, the respective cell may be empty in some layouts (e.g. + QCPLayoutGrid), so this function may return 0 in those cases. You may use this function to check + whether a cell is empty or not. + + \see elements, elementCount, takeAt +*/ + +/*! \fn virtual QCPLayoutElement* QCPLayout::takeAt(int index) = 0 + + Removes the element with the given \a index from the layout and returns it. + + If the \a index is invalid or the cell with that index is empty, returns 0. + + Note that some layouts don't remove the respective cell right away but leave an empty cell after + successful removal of the layout element. To collapse empty cells, use \ref simplify. + + \see elementAt, take +*/ + +/*! \fn virtual bool QCPLayout::take(QCPLayoutElement* element) = 0 + + Removes the specified \a element from the layout and returns true on success. + + If the \a element isn't in this layout, returns false. + + Note that some layouts don't remove the respective cell right away but leave an empty cell after + successful removal of the layout element. To collapse empty cells, use \ref simplify. + + \see takeAt +*/ + +/* end documentation of pure virtual functions */ + +/*! + Creates an instance of QCPLayout and sets default values. Note that since QCPLayout + is an abstract base class, it can't be instantiated directly. +*/ +QCPLayout::QCPLayout() +{ +} + +/*! + First calls the QCPLayoutElement::update base class implementation to update the margins on this + layout. + + Then calls \ref updateLayout which subclasses reimplement to reposition and resize their cells. + + Finally, \ref update is called on all child elements. +*/ +void QCPLayout::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + + // set child element rects according to layout: + if (phase == upLayout) + updateLayout(); + + // propagate update call to child elements: + const int elCount = elementCount(); + for (int i=0; iupdate(phase); + } +} + +/* inherits documentation from base class */ +QList QCPLayout::elements(bool recursive) const +{ + const int c = elementCount(); + QList result; +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + result.reserve(c); +#endif + for (int i=0; ielements(recursive); + } + } + return result; +} + +/*! + Simplifies the layout by collapsing empty cells. The exact behavior depends on subclasses, the + default implementation does nothing. + + Not all layouts need simplification. For example, QCPLayoutInset doesn't use explicit + simplification while QCPLayoutGrid does. +*/ +void QCPLayout::simplify() +{ +} + +/*! + Removes and deletes the element at the provided \a index. Returns true on success. If \a index is + invalid or points to an empty cell, returns false. + + This function internally uses \ref takeAt to remove the element from the layout and then deletes + the returned element. Note that some layouts don't remove the respective cell right away but leave an + empty cell after successful removal of the layout element. To collapse empty cells, use \ref + simplify. + + \see remove, takeAt +*/ +bool QCPLayout::removeAt(int index) +{ + if (QCPLayoutElement *el = takeAt(index)) + { + delete el; + return true; + } else + return false; +} + +/*! + Removes and deletes the provided \a element. Returns true on success. If \a element is not in the + layout, returns false. + + This function internally uses \ref takeAt to remove the element from the layout and then deletes + the element. Note that some layouts don't remove the respective cell right away but leave an + empty cell after successful removal of the layout element. To collapse empty cells, use \ref + simplify. + + \see removeAt, take +*/ +bool QCPLayout::remove(QCPLayoutElement *element) +{ + if (take(element)) + { + delete element; + return true; + } else + return false; +} + +/*! + Removes and deletes all layout elements in this layout. Finally calls \ref simplify to make sure + all empty cells are collapsed. + + \see remove, removeAt +*/ +void QCPLayout::clear() +{ + for (int i=elementCount()-1; i>=0; --i) + { + if (elementAt(i)) + removeAt(i); + } + simplify(); +} + +/*! + Subclasses call this method to report changed (minimum/maximum) size constraints. + + If the parent of this layout is again a QCPLayout, forwards the call to the parent's \ref + sizeConstraintsChanged. If the parent is a QWidget (i.e. is the \ref QCustomPlot::plotLayout of + QCustomPlot), calls QWidget::updateGeometry, so if the QCustomPlot widget is inside a Qt QLayout, + it may update itself and resize cells accordingly. +*/ +void QCPLayout::sizeConstraintsChanged() const +{ + if (QWidget *w = qobject_cast(parent())) + w->updateGeometry(); + else if (QCPLayout *l = qobject_cast(parent())) + l->sizeConstraintsChanged(); +} + +/*! \internal + + Subclasses reimplement this method to update the position and sizes of the child elements/cells + via calling their \ref QCPLayoutElement::setOuterRect. The default implementation does nothing. + + The geometry used as a reference is the inner \ref rect of this layout. Child elements should stay + within that rect. + + \ref getSectionSizes may help with the reimplementation of this function. + + \see update +*/ +void QCPLayout::updateLayout() +{ +} + + +/*! \internal + + Associates \a el with this layout. This is done by setting the \ref QCPLayoutElement::layout, the + \ref QCPLayerable::parentLayerable and the QObject parent to this layout. + + Further, if \a el didn't previously have a parent plot, calls \ref + QCPLayerable::initializeParentPlot on \a el to set the paret plot. + + This method is used by subclass specific methods that add elements to the layout. Note that this + method only changes properties in \a el. The removal from the old layout and the insertion into + the new layout must be done additionally. +*/ +void QCPLayout::adoptElement(QCPLayoutElement *el) +{ + if (el) + { + el->mParentLayout = this; + el->setParentLayerable(this); + el->setParent(this); + if (!el->parentPlot()) + el->initializeParentPlot(mParentPlot); + } else + qDebug() << Q_FUNC_INFO << "Null element passed"; +} + +/*! \internal + + Disassociates \a el from this layout. This is done by setting the \ref QCPLayoutElement::layout + and the \ref QCPLayerable::parentLayerable to zero. The QObject parent is set to the parent + QCustomPlot. + + This method is used by subclass specific methods that remove elements from the layout (e.g. \ref + take or \ref takeAt). Note that this method only changes properties in \a el. The removal from + the old layout must be done additionally. +*/ +void QCPLayout::releaseElement(QCPLayoutElement *el) +{ + if (el) + { + el->mParentLayout = 0; + el->setParentLayerable(0); + el->setParent(mParentPlot); + // Note: Don't initializeParentPlot(0) here, because layout element will stay in same parent plot + } else + qDebug() << Q_FUNC_INFO << "Null element passed"; +} + +/*! \internal + + This is a helper function for the implementation of \ref updateLayout in subclasses. + + It calculates the sizes of one-dimensional sections with provided constraints on maximum section + sizes, minimum section sizes, relative stretch factors and the final total size of all sections. + + The QVector entries refer to the sections. Thus all QVectors must have the same size. + + \a maxSizes gives the maximum allowed size of each section. If there shall be no maximum size + imposed, set all vector values to Qt's QWIDGETSIZE_MAX. + + \a minSizes gives the minimum allowed size of each section. If there shall be no minimum size + imposed, set all vector values to zero. If the \a minSizes entries add up to a value greater than + \a totalSize, sections will be scaled smaller than the proposed minimum sizes. (In other words, + not exceeding the allowed total size is taken to be more important than not going below minimum + section sizes.) + + \a stretchFactors give the relative proportions of the sections to each other. If all sections + shall be scaled equally, set all values equal. If the first section shall be double the size of + each individual other section, set the first number of \a stretchFactors to double the value of + the other individual values (e.g. {2, 1, 1, 1}). + + \a totalSize is the value that the final section sizes will add up to. Due to rounding, the + actual sum may differ slightly. If you want the section sizes to sum up to exactly that value, + you could distribute the remaining difference on the sections. + + The return value is a QVector containing the section sizes. +*/ +QVector QCPLayout::getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const +{ + if (maxSizes.size() != minSizes.size() || minSizes.size() != stretchFactors.size()) + { + qDebug() << Q_FUNC_INFO << "Passed vector sizes aren't equal:" << maxSizes << minSizes << stretchFactors; + return QVector(); + } + if (stretchFactors.isEmpty()) + return QVector(); + int sectionCount = stretchFactors.size(); + QVector sectionSizes(sectionCount); + // if provided total size is forced smaller than total minimum size, ignore minimum sizes (squeeze sections): + int minSizeSum = 0; + for (int i=0; i minimumLockedSections; + QList unfinishedSections; + for (int i=0; i result(sectionCount); + for (int i=0; i= 0 && row < mElements.size()) + { + if (column >= 0 && column < mElements.first().size()) + { + if (QCPLayoutElement *result = mElements.at(row).at(column)) + return result; + else + qDebug() << Q_FUNC_INFO << "Requested cell is empty. Row:" << row << "Column:" << column; + } else + qDebug() << Q_FUNC_INFO << "Invalid column. Row:" << row << "Column:" << column; + } else + qDebug() << Q_FUNC_INFO << "Invalid row. Row:" << row << "Column:" << column; + return 0; +} + +/*! + Returns the number of rows in the layout. + + \see columnCount +*/ +int QCPLayoutGrid::rowCount() const +{ + return mElements.size(); +} + +/*! + Returns the number of columns in the layout. + + \see rowCount +*/ +int QCPLayoutGrid::columnCount() const +{ + if (mElements.size() > 0) + return mElements.first().size(); + else + return 0; +} + +/*! + Adds the \a element to cell with \a row and \a column. If \a element is already in a layout, it + is first removed from there. If \a row or \a column don't exist yet, the layout is expanded + accordingly. + + Returns true if the element was added successfully, i.e. if the cell at \a row and \a column + didn't already have an element. + + \see element, hasElement, take, remove +*/ +bool QCPLayoutGrid::addElement(int row, int column, QCPLayoutElement *element) +{ + if (element) + { + if (!hasElement(row, column)) + { + if (element->layout()) // remove from old layout first + element->layout()->take(element); + expandTo(row+1, column+1); + mElements[row][column] = element; + adoptElement(element); + return true; + } else + qDebug() << Q_FUNC_INFO << "There is already an element in the specified row/column:" << row << column; + } else + qDebug() << Q_FUNC_INFO << "Can't add null element to row/column:" << row << column; + return false; +} + +/*! + Returns whether the cell at \a row and \a column exists and contains a valid element, i.e. isn't + empty. + + \see element +*/ +bool QCPLayoutGrid::hasElement(int row, int column) +{ + if (row >= 0 && row < rowCount() && column >= 0 && column < columnCount()) + return mElements.at(row).at(column); + else + return false; +} + +/*! + Sets the stretch \a factor of \a column. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights (\ref QCPLayoutElement::setMinimumSize, \ref + QCPLayoutElement::setMaximumSize), regardless of the stretch factor. + + The default stretch factor of newly created rows/columns is 1. + + \see setColumnStretchFactors, setRowStretchFactor +*/ +void QCPLayoutGrid::setColumnStretchFactor(int column, double factor) +{ + if (column >= 0 && column < columnCount()) + { + if (factor > 0) + mColumnStretchFactors[column] = factor; + else + qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; + } else + qDebug() << Q_FUNC_INFO << "Invalid column:" << column; +} + +/*! + Sets the stretch \a factors of all columns. \a factors must have the size \ref columnCount. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights (\ref QCPLayoutElement::setMinimumSize, \ref + QCPLayoutElement::setMaximumSize), regardless of the stretch factor. + + The default stretch factor of newly created rows/columns is 1. + + \see setColumnStretchFactor, setRowStretchFactors +*/ +void QCPLayoutGrid::setColumnStretchFactors(const QList &factors) +{ + if (factors.size() == mColumnStretchFactors.size()) + { + mColumnStretchFactors = factors; + for (int i=0; i= 0 && row < rowCount()) + { + if (factor > 0) + mRowStretchFactors[row] = factor; + else + qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; + } else + qDebug() << Q_FUNC_INFO << "Invalid row:" << row; +} + +/*! + Sets the stretch \a factors of all rows. \a factors must have the size \ref rowCount. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights (\ref QCPLayoutElement::setMinimumSize, \ref + QCPLayoutElement::setMaximumSize), regardless of the stretch factor. + + The default stretch factor of newly created rows/columns is 1. + + \see setRowStretchFactor, setColumnStretchFactors +*/ +void QCPLayoutGrid::setRowStretchFactors(const QList &factors) +{ + if (factors.size() == mRowStretchFactors.size()) + { + mRowStretchFactors = factors; + for (int i=0; i()); + mRowStretchFactors.append(1); + } + // go through rows and expand columns as necessary: + int newColCount = qMax(columnCount(), newColumnCount); + for (int i=0; i rowCount()) + newIndex = rowCount(); + + mRowStretchFactors.insert(newIndex, 1); + QList newRow; + for (int col=0; col columnCount()) + newIndex = columnCount(); + + mColumnStretchFactors.insert(newIndex, 1); + for (int row=0; row minColWidths, minRowHeights, maxColWidths, maxRowHeights; + getMinimumRowColSizes(&minColWidths, &minRowHeights); + getMaximumRowColSizes(&maxColWidths, &maxRowHeights); + + int totalRowSpacing = (rowCount()-1) * mRowSpacing; + int totalColSpacing = (columnCount()-1) * mColumnSpacing; + QVector colWidths = getSectionSizes(maxColWidths, minColWidths, mColumnStretchFactors.toVector(), mRect.width()-totalColSpacing); + QVector rowHeights = getSectionSizes(maxRowHeights, minRowHeights, mRowStretchFactors.toVector(), mRect.height()-totalRowSpacing); + + // go through cells and set rects accordingly: + int yOffset = mRect.top(); + for (int row=0; row 0) + yOffset += rowHeights.at(row-1)+mRowSpacing; + int xOffset = mRect.left(); + for (int col=0; col 0) + xOffset += colWidths.at(col-1)+mColumnSpacing; + if (mElements.at(row).at(col)) + mElements.at(row).at(col)->setOuterRect(QRect(xOffset, yOffset, colWidths.at(col), rowHeights.at(row))); + } + } +} + +/* inherits documentation from base class */ +int QCPLayoutGrid::elementCount() const +{ + return rowCount()*columnCount(); +} + +/* inherits documentation from base class */ +QCPLayoutElement *QCPLayoutGrid::elementAt(int index) const +{ + if (index >= 0 && index < elementCount()) + return mElements.at(index / columnCount()).at(index % columnCount()); + else + return 0; +} + +/* inherits documentation from base class */ +QCPLayoutElement *QCPLayoutGrid::takeAt(int index) +{ + if (QCPLayoutElement *el = elementAt(index)) + { + releaseElement(el); + mElements[index / columnCount()][index % columnCount()] = 0; + return el; + } else + { + qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; + return 0; + } +} + +/* inherits documentation from base class */ +bool QCPLayoutGrid::take(QCPLayoutElement *element) +{ + if (element) + { + for (int i=0; i QCPLayoutGrid::elements(bool recursive) const +{ + QList result; + int colC = columnCount(); + int rowC = rowCount(); +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + result.reserve(colC*rowC); +#endif + for (int row=0; rowelements(recursive); + } + } + return result; +} + +/*! + Simplifies the layout by collapsing rows and columns which only contain empty cells. +*/ +void QCPLayoutGrid::simplify() +{ + // remove rows with only empty cells: + for (int row=rowCount()-1; row>=0; --row) + { + bool hasElements = false; + for (int col=0; col=0; --col) + { + bool hasElements = false; + for (int row=0; row minColWidths, minRowHeights; + getMinimumRowColSizes(&minColWidths, &minRowHeights); + QSize result(0, 0); + for (int i=0; i maxColWidths, maxRowHeights; + getMaximumRowColSizes(&maxColWidths, &maxRowHeights); + + QSize result(0, 0); + for (int i=0; i *minColWidths, QVector *minRowHeights) const +{ + *minColWidths = QVector(columnCount(), 0); + *minRowHeights = QVector(rowCount(), 0); + for (int row=0; rowminimumSizeHint(); + QSize min = mElements.at(row).at(col)->minimumSize(); + QSize final(min.width() > 0 ? min.width() : minHint.width(), min.height() > 0 ? min.height() : minHint.height()); + if (minColWidths->at(col) < final.width()) + (*minColWidths)[col] = final.width(); + if (minRowHeights->at(row) < final.height()) + (*minRowHeights)[row] = final.height(); + } + } + } +} + +/*! \internal + + Places the maximum column widths and row heights into \a maxColWidths and \a maxRowHeights + respectively. + + The maximum height of a row is the smallest maximum height of any element in that row. The + maximum width of a column is the smallest maximum width of any element in that column. + + This is a helper function for \ref updateLayout. + + \see getMinimumRowColSizes +*/ +void QCPLayoutGrid::getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const +{ + *maxColWidths = QVector(columnCount(), QWIDGETSIZE_MAX); + *maxRowHeights = QVector(rowCount(), QWIDGETSIZE_MAX); + for (int row=0; rowmaximumSizeHint(); + QSize max = mElements.at(row).at(col)->maximumSize(); + QSize final(max.width() < QWIDGETSIZE_MAX ? max.width() : maxHint.width(), max.height() < QWIDGETSIZE_MAX ? max.height() : maxHint.height()); + if (maxColWidths->at(col) > final.width()) + (*maxColWidths)[col] = final.width(); + if (maxRowHeights->at(row) > final.height()) + (*maxRowHeights)[row] = final.height(); + } + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutInset +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPLayoutInset + \brief A layout that places child elements aligned to the border or arbitrarily positioned + + Elements are placed either aligned to the border or at arbitrary position in the area of the + layout. Which placement applies is controlled with the \ref InsetPlacement (\ref + setInsetPlacement). + + Elements are added via \ref addElement(QCPLayoutElement *element, Qt::Alignment alignment) or + addElement(QCPLayoutElement *element, const QRectF &rect). If the first method is used, the inset + placement will default to \ref ipBorderAligned and the element will be aligned according to the + \a alignment parameter. The second method defaults to \ref ipFree and allows placing elements at + arbitrary position and size, defined by \a rect. + + The alignment or rect can be set via \ref setInsetAlignment or \ref setInsetRect, respectively. + + This is the layout that every QCPAxisRect has as \ref QCPAxisRect::insetLayout. +*/ + +/* start documentation of inline functions */ + +/*! \fn virtual void QCPLayoutInset::simplify() + + The QCPInsetLayout does not need simplification since it can never have empty cells due to its + linear index structure. This method does nothing. +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutInset and sets default values. +*/ +QCPLayoutInset::QCPLayoutInset() +{ +} + +QCPLayoutInset::~QCPLayoutInset() +{ + // clear all child layout elements. This is important because only the specific layouts know how + // to handle removing elements (clear calls virtual removeAt method to do that). + clear(); +} + +/*! + Returns the placement type of the element with the specified \a index. +*/ +QCPLayoutInset::InsetPlacement QCPLayoutInset::insetPlacement(int index) const +{ + if (elementAt(index)) + return mInsetPlacement.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return ipFree; + } +} + +/*! + Returns the alignment of the element with the specified \a index. The alignment only has a + meaning, if the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned. +*/ +Qt::Alignment QCPLayoutInset::insetAlignment(int index) const +{ + if (elementAt(index)) + return mInsetAlignment.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return 0; + } +} + +/*! + Returns the rect of the element with the specified \a index. The rect only has a + meaning, if the inset placement (\ref setInsetPlacement) is \ref ipFree. +*/ +QRectF QCPLayoutInset::insetRect(int index) const +{ + if (elementAt(index)) + return mInsetRect.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return QRectF(); + } +} + +/*! + Sets the inset placement type of the element with the specified \a index to \a placement. + + \see InsetPlacement +*/ +void QCPLayoutInset::setInsetPlacement(int index, QCPLayoutInset::InsetPlacement placement) +{ + if (elementAt(index)) + mInsetPlacement[index] = placement; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/*! + If the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned, this function + is used to set the alignment of the element with the specified \a index to \a alignment. + + \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, + Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other + alignment flags will be ignored. +*/ +void QCPLayoutInset::setInsetAlignment(int index, Qt::Alignment alignment) +{ + if (elementAt(index)) + mInsetAlignment[index] = alignment; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/*! + If the inset placement (\ref setInsetPlacement) is \ref ipFree, this function is used to set the + position and size of the element with the specified \a index to \a rect. + + \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) + will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right + corner of the layout, with 35% width and height of the parent layout. + + Note that the minimum and maximum sizes of the embedded element (\ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize) are enforced. +*/ +void QCPLayoutInset::setInsetRect(int index, const QRectF &rect) +{ + if (elementAt(index)) + mInsetRect[index] = rect; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/* inherits documentation from base class */ +void QCPLayoutInset::updateLayout() +{ + for (int i=0; iminimumSizeHint(); + QSize maxSizeHint = mElements.at(i)->maximumSizeHint(); + finalMinSize.setWidth(mElements.at(i)->minimumSize().width() > 0 ? mElements.at(i)->minimumSize().width() : minSizeHint.width()); + finalMinSize.setHeight(mElements.at(i)->minimumSize().height() > 0 ? mElements.at(i)->minimumSize().height() : minSizeHint.height()); + finalMaxSize.setWidth(mElements.at(i)->maximumSize().width() < QWIDGETSIZE_MAX ? mElements.at(i)->maximumSize().width() : maxSizeHint.width()); + finalMaxSize.setHeight(mElements.at(i)->maximumSize().height() < QWIDGETSIZE_MAX ? mElements.at(i)->maximumSize().height() : maxSizeHint.height()); + if (mInsetPlacement.at(i) == ipFree) + { + insetRect = QRect(rect().x()+rect().width()*mInsetRect.at(i).x(), + rect().y()+rect().height()*mInsetRect.at(i).y(), + rect().width()*mInsetRect.at(i).width(), + rect().height()*mInsetRect.at(i).height()); + if (insetRect.size().width() < finalMinSize.width()) + insetRect.setWidth(finalMinSize.width()); + if (insetRect.size().height() < finalMinSize.height()) + insetRect.setHeight(finalMinSize.height()); + if (insetRect.size().width() > finalMaxSize.width()) + insetRect.setWidth(finalMaxSize.width()); + if (insetRect.size().height() > finalMaxSize.height()) + insetRect.setHeight(finalMaxSize.height()); + } else if (mInsetPlacement.at(i) == ipBorderAligned) + { + insetRect.setSize(finalMinSize); + Qt::Alignment al = mInsetAlignment.at(i); + if (al.testFlag(Qt::AlignLeft)) insetRect.moveLeft(rect().x()); + else if (al.testFlag(Qt::AlignRight)) insetRect.moveRight(rect().x()+rect().width()); + else insetRect.moveLeft(rect().x()+rect().width()*0.5-finalMinSize.width()*0.5); // default to Qt::AlignHCenter + if (al.testFlag(Qt::AlignTop)) insetRect.moveTop(rect().y()); + else if (al.testFlag(Qt::AlignBottom)) insetRect.moveBottom(rect().y()+rect().height()); + else insetRect.moveTop(rect().y()+rect().height()*0.5-finalMinSize.height()*0.5); // default to Qt::AlignVCenter + } + mElements.at(i)->setOuterRect(insetRect); + } +} + +/* inherits documentation from base class */ +int QCPLayoutInset::elementCount() const +{ + return mElements.size(); +} + +/* inherits documentation from base class */ +QCPLayoutElement *QCPLayoutInset::elementAt(int index) const +{ + if (index >= 0 && index < mElements.size()) + return mElements.at(index); + else + return 0; +} + +/* inherits documentation from base class */ +QCPLayoutElement *QCPLayoutInset::takeAt(int index) +{ + if (QCPLayoutElement *el = elementAt(index)) + { + releaseElement(el); + mElements.removeAt(index); + mInsetPlacement.removeAt(index); + mInsetAlignment.removeAt(index); + mInsetRect.removeAt(index); + return el; + } else + { + qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; + return 0; + } +} + +/* inherits documentation from base class */ +bool QCPLayoutInset::take(QCPLayoutElement *element) +{ + if (element) + { + for (int i=0; irealVisibility() && mElements.at(i)->selectTest(pos, onlySelectable) >= 0) + return mParentPlot->selectionTolerance()*0.99; + } + return -1; +} + +/*! + Adds the specified \a element to the layout as an inset aligned at the border (\ref + setInsetAlignment is initialized with \ref ipBorderAligned). The alignment is set to \a + alignment. + + \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, + Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other + alignment flags will be ignored. + + \see addElement(QCPLayoutElement *element, const QRectF &rect) +*/ +void QCPLayoutInset::addElement(QCPLayoutElement *element, Qt::Alignment alignment) +{ + if (element) + { + if (element->layout()) // remove from old layout first + element->layout()->take(element); + mElements.append(element); + mInsetPlacement.append(ipBorderAligned); + mInsetAlignment.append(alignment); + mInsetRect.append(QRectF(0.6, 0.6, 0.4, 0.4)); + adoptElement(element); + } else + qDebug() << Q_FUNC_INFO << "Can't add null element"; +} + +/*! + Adds the specified \a element to the layout as an inset with free positioning/sizing (\ref + setInsetAlignment is initialized with \ref ipFree). The position and size is set to \a + rect. + + \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) + will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right + corner of the layout, with 35% width and height of the parent layout. + + \see addElement(QCPLayoutElement *element, Qt::Alignment alignment) +*/ +void QCPLayoutInset::addElement(QCPLayoutElement *element, const QRectF &rect) +{ + if (element) + { + if (element->layout()) // remove from old layout first + element->layout()->take(element); + mElements.append(element); + mInsetPlacement.append(ipFree); + mInsetAlignment.append(Qt::AlignRight|Qt::AlignTop); + mInsetRect.append(rect); + adoptElement(element); + } else + qDebug() << Q_FUNC_INFO << "Can't add null element"; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLineEnding +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLineEnding + \brief Handles the different ending decorations for line-like items + + \image html QCPLineEnding.png "The various ending styles currently supported" + + For every ending a line-like item has, an instance of this class exists. For example, QCPItemLine + has two endings which can be set with QCPItemLine::setHead and QCPItemLine::setTail. + + The styles themselves are defined via the enum QCPLineEnding::EndingStyle. Most decorations can + be modified regarding width and length, see \ref setWidth and \ref setLength. The direction of + the ending decoration (e.g. direction an arrow is pointing) is controlled by the line-like item. + For example, when both endings of a QCPItemLine are set to be arrows, they will point to opposite + directions, e.g. "outward". This can be changed by \ref setInverted, which would make the + respective arrow point inward. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify a + QCPLineEnding::EndingStyle where actually a QCPLineEnding is expected, e.g. + \snippet documentation/doc-code-snippets/mainwindow.cpp qcplineending-sethead +*/ + +/*! + Creates a QCPLineEnding instance with default values (style \ref esNone). +*/ +QCPLineEnding::QCPLineEnding() : + mStyle(esNone), + mWidth(8), + mLength(10), + mInverted(false) +{ +} + +/*! + Creates a QCPLineEnding instance with the specified values. +*/ +QCPLineEnding::QCPLineEnding(QCPLineEnding::EndingStyle style, double width, double length, bool inverted) : + mStyle(style), + mWidth(width), + mLength(length), + mInverted(inverted) +{ +} + +/*! + Sets the style of the ending decoration. +*/ +void QCPLineEnding::setStyle(QCPLineEnding::EndingStyle style) +{ + mStyle = style; +} + +/*! + Sets the width of the ending decoration, if the style supports it. On arrows, for example, the + width defines the size perpendicular to the arrow's pointing direction. + + \see setLength +*/ +void QCPLineEnding::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets the length of the ending decoration, if the style supports it. On arrows, for example, the + length defines the size in pointing direction. + + \see setWidth +*/ +void QCPLineEnding::setLength(double length) +{ + mLength = length; +} + +/*! + Sets whether the ending decoration shall be inverted. For example, an arrow decoration will point + inward when \a inverted is set to true. + + Note that also the \a width direction is inverted. For symmetrical ending styles like arrows or + discs, this doesn't make a difference. However, asymmetric styles like \ref esHalfBar are + affected by it, which can be used to control to which side the half bar points to. +*/ +void QCPLineEnding::setInverted(bool inverted) +{ + mInverted = inverted; +} + +/*! \internal + + Returns the maximum pixel radius the ending decoration might cover, starting from the position + the decoration is drawn at (typically a line ending/\ref QCPItemPosition of an item). + + This is relevant for clipping. Only omit painting of the decoration when the position where the + decoration is supposed to be drawn is farther away from the clipping rect than the returned + distance. +*/ +double QCPLineEnding::boundingDistance() const +{ + switch (mStyle) + { + case esNone: + return 0; + + case esFlatArrow: + case esSpikeArrow: + case esLineArrow: + case esSkewedBar: + return qSqrt(mWidth*mWidth+mLength*mLength); // items that have width and length + + case esDisc: + case esSquare: + case esDiamond: + case esBar: + case esHalfBar: + return mWidth*1.42; // items that only have a width -> width*sqrt(2) + + } + return 0; +} + +/*! + Starting from the origin of this line ending (which is style specific), returns the length + covered by the line ending symbol, in backward direction. + + For example, the \ref esSpikeArrow has a shorter real length than a \ref esFlatArrow, even if + both have the same \ref setLength value, because the spike arrow has an inward curved back, which + reduces the length along its center axis (the drawing origin for arrows is at the tip). + + This function is used for precise, style specific placement of line endings, for example in + QCPAxes. +*/ +double QCPLineEnding::realLength() const +{ + switch (mStyle) + { + case esNone: + case esLineArrow: + case esSkewedBar: + case esBar: + case esHalfBar: + return 0; + + case esFlatArrow: + return mLength; + + case esDisc: + case esSquare: + case esDiamond: + return mWidth*0.5; + + case esSpikeArrow: + return mLength*0.8; + } + return 0; +} + +/*! \internal + + Draws the line ending with the specified \a painter at the position \a pos. The direction of the + line ending is controlled with \a dir. +*/ +void QCPLineEnding::draw(QCPPainter *painter, const QVector2D &pos, const QVector2D &dir) const +{ + if (mStyle == esNone) + return; + + QVector2D lengthVec(dir.normalized()); + if (lengthVec.isNull()) + lengthVec = QVector2D(1, 0); + QVector2D widthVec(-lengthVec.y(), lengthVec.x()); + lengthVec *= (float)(mLength*(mInverted ? -1 : 1)); + widthVec *= (float)(mWidth*0.5*(mInverted ? -1 : 1)); + + QPen penBackup = painter->pen(); + QBrush brushBackup = painter->brush(); + QPen miterPen = penBackup; + miterPen.setJoinStyle(Qt::MiterJoin); // to make arrow heads spikey + QBrush brush(painter->pen().color(), Qt::SolidPattern); + switch (mStyle) + { + case esNone: break; + case esFlatArrow: + { + QPointF points[3] = {pos.toPointF(), + (pos-lengthVec+widthVec).toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 3); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esSpikeArrow: + { + QPointF points[4] = {pos.toPointF(), + (pos-lengthVec+widthVec).toPointF(), + (pos-lengthVec*0.8f).toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esLineArrow: + { + QPointF points[3] = {(pos-lengthVec+widthVec).toPointF(), + pos.toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->drawPolyline(points, 3); + painter->setPen(penBackup); + break; + } + case esDisc: + { + painter->setBrush(brush); + painter->drawEllipse(pos.toPointF(), mWidth*0.5, mWidth*0.5); + painter->setBrush(brushBackup); + break; + } + case esSquare: + { + QVector2D widthVecPerp(-widthVec.y(), widthVec.x()); + QPointF points[4] = {(pos-widthVecPerp+widthVec).toPointF(), + (pos-widthVecPerp-widthVec).toPointF(), + (pos+widthVecPerp-widthVec).toPointF(), + (pos+widthVecPerp+widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esDiamond: + { + QVector2D widthVecPerp(-widthVec.y(), widthVec.x()); + QPointF points[4] = {(pos-widthVecPerp).toPointF(), + (pos-widthVec).toPointF(), + (pos+widthVecPerp).toPointF(), + (pos+widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esBar: + { + painter->drawLine((pos+widthVec).toPointF(), (pos-widthVec).toPointF()); + break; + } + case esHalfBar: + { + painter->drawLine((pos+widthVec).toPointF(), pos.toPointF()); + break; + } + case esSkewedBar: + { + if (qFuzzyIsNull(painter->pen().widthF()) && !painter->modes().testFlag(QCPPainter::pmNonCosmetic)) + { + // if drawing with cosmetic pen (perfectly thin stroke, happens only in vector exports), draw bar exactly on tip of line + painter->drawLine((pos+widthVec+lengthVec*0.2f*(mInverted?-1:1)).toPointF(), + (pos-widthVec-lengthVec*0.2f*(mInverted?-1:1)).toPointF()); + } else + { + // if drawing with thick (non-cosmetic) pen, shift bar a little in line direction to prevent line from sticking through bar slightly + painter->drawLine((pos+widthVec+lengthVec*0.2f*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF(), + (pos-widthVec-lengthVec*0.2f*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF()); + } + break; + } + } +} + +/*! \internal + \overload + + Draws the line ending. The direction is controlled with the \a angle parameter in radians. +*/ +void QCPLineEnding::draw(QCPPainter *painter, const QVector2D &pos, double angle) const +{ + draw(painter, pos, QVector2D(qCos(angle), qSin(angle))); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGrid +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGrid + \brief Responsible for drawing the grid of a QCPAxis. + + This class is tightly bound to QCPAxis. Every axis owns a grid instance and uses it to draw the + grid lines, sub grid lines and zero-line. You can interact with the grid of an axis via \ref + QCPAxis::grid. Normally, you don't need to create an instance of QCPGrid yourself. + + The axis and grid drawing was split into two classes to allow them to be placed on different + layers (both QCPAxis and QCPGrid inherit from QCPLayerable). Thus it is possible to have the grid + in the background and the axes in the foreground, and any plottables/items in between. This + described situation is the default setup, see the QCPLayer documentation. +*/ + +/*! + Creates a QCPGrid instance and sets default values. + + You shouldn't instantiate grids on their own, since every QCPAxis brings its own QCPGrid. +*/ +QCPGrid::QCPGrid(QCPAxis *parentAxis) : + QCPLayerable(parentAxis->parentPlot(), QString(), parentAxis), + mParentAxis(parentAxis) +{ + // warning: this is called in QCPAxis constructor, so parentAxis members should not be accessed/called + setParent(parentAxis); + setPen(QPen(QColor(200,200,200), 0, Qt::DotLine)); + setSubGridPen(QPen(QColor(220,220,220), 0, Qt::DotLine)); + setZeroLinePen(QPen(QColor(200,200,200), 0, Qt::SolidLine)); + setSubGridVisible(false); + setAntialiased(false); + setAntialiasedSubGrid(false); + setAntialiasedZeroLine(false); +} + +/*! + Sets whether grid lines at sub tick marks are drawn. + + \see setSubGridPen +*/ +void QCPGrid::setSubGridVisible(bool visible) +{ + mSubGridVisible = visible; +} + +/*! + Sets whether sub grid lines are drawn antialiased. +*/ +void QCPGrid::setAntialiasedSubGrid(bool enabled) +{ + mAntialiasedSubGrid = enabled; +} + +/*! + Sets whether zero lines are drawn antialiased. +*/ +void QCPGrid::setAntialiasedZeroLine(bool enabled) +{ + mAntialiasedZeroLine = enabled; +} + +/*! + Sets the pen with which (major) grid lines are drawn. +*/ +void QCPGrid::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen with which sub grid lines are drawn. +*/ +void QCPGrid::setSubGridPen(const QPen &pen) +{ + mSubGridPen = pen; +} + +/*! + Sets the pen with which zero lines are drawn. + + Zero lines are lines at value coordinate 0 which may be drawn with a different pen than other grid + lines. To disable zero lines and just draw normal grid lines at zero, set \a pen to Qt::NoPen. +*/ +void QCPGrid::setZeroLinePen(const QPen &pen) +{ + mZeroLinePen = pen; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing the major grid lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPGrid::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeGrid); +} + +/*! \internal + + Draws grid lines and sub grid lines at the positions of (sub) ticks of the parent axis, spanning + over the complete axis rect. Also draws the zero line, if appropriate (\ref setZeroLinePen). +*/ +void QCPGrid::draw(QCPPainter *painter) +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + if (mSubGridVisible) + drawSubGridLines(painter); + drawGridLines(painter); +} + +/*! \internal + + Draws the main grid lines and possibly a zero line with the specified painter. + + This is a helper function called by \ref draw. +*/ +void QCPGrid::drawGridLines(QCPPainter *painter) const +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + int lowTick = mParentAxis->mLowestVisibleTick; + int highTick = mParentAxis->mHighestVisibleTick; + double t; // helper variable, result of coordinate-to-pixel transforms + if (mParentAxis->orientation() == Qt::Horizontal) + { + // draw zeroline: + int zeroLineIndex = -1; + if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(mZeroLinePen); + double epsilon = mParentAxis->range().size()*1E-6; // for comparing double to zero + for (int i=lowTick; i <= highTick; ++i) + { + if (qAbs(mParentAxis->mTickVector.at(i)) < epsilon) + { + zeroLineIndex = i; + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + break; + } + } + } + // draw grid lines: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + for (int i=lowTick; i <= highTick; ++i) + { + if (i == zeroLineIndex) continue; // don't draw a gridline on top of the zeroline + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + } + } else + { + // draw zeroline: + int zeroLineIndex = -1; + if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(mZeroLinePen); + double epsilon = mParentAxis->mRange.size()*1E-6; // for comparing double to zero + for (int i=lowTick; i <= highTick; ++i) + { + if (qAbs(mParentAxis->mTickVector.at(i)) < epsilon) + { + zeroLineIndex = i; + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + break; + } + } + } + // draw grid lines: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + for (int i=lowTick; i <= highTick; ++i) + { + if (i == zeroLineIndex) continue; // don't draw a gridline on top of the zeroline + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + } + } +} + +/*! \internal + + Draws the sub grid lines with the specified painter. + + This is a helper function called by \ref draw. +*/ +void QCPGrid::drawSubGridLines(QCPPainter *painter) const +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + applyAntialiasingHint(painter, mAntialiasedSubGrid, QCP::aeSubGrid); + double t; // helper variable, result of coordinate-to-pixel transforms + painter->setPen(mSubGridPen); + if (mParentAxis->orientation() == Qt::Horizontal) + { + for (int i=0; imSubTickVector.size(); ++i) + { + t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + } + } else + { + for (int i=0; imSubTickVector.size(); ++i) + { + t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxis +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxis + \brief Manages a single axis inside a QCustomPlot. + + Usually doesn't need to be instantiated externally. Access %QCustomPlot's default four axes via + QCustomPlot::xAxis (bottom), QCustomPlot::yAxis (left), QCustomPlot::xAxis2 (top) and + QCustomPlot::yAxis2 (right). + + Axes are always part of an axis rect, see QCPAxisRect. + \image html AxisNamesOverview.png +
Naming convention of axis parts
+ \n + + \image html AxisRectSpacingOverview.png +
Overview of the spacings and paddings that define the geometry of an axis. The dashed gray line + on the left represents the QCustomPlot widget border.
+ +*/ + +/* start of documentation of inline functions */ + +/*! \fn Qt::Orientation QCPAxis::orientation() const + + Returns the orientation of this axis. The axis orientation (horizontal or vertical) is deduced + from the axis type (left, top, right or bottom). + + \see orientation(AxisType type) +*/ + +/*! \fn QCPGrid *QCPAxis::grid() const + + Returns the \ref QCPGrid instance belonging to this axis. Access it to set details about the way the + grid is displayed. +*/ + +/*! \fn static Qt::Orientation QCPAxis::orientation(AxisType type) + + Returns the orientation of the specified axis type + + \see orientation() +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAxis::ticksRequest() + + This signal is emitted when \ref setAutoTicks is false and the axis is about to generate tick + labels for a replot. + + Modifying the tick positions can be done with \ref setTickVector. If you also want to control the + tick labels, set \ref setAutoTickLabels to false and also provide the labels with \ref + setTickVectorLabels. + + If you only want static ticks you probably don't need this signal, since you can just set the + tick vector (and possibly tick label vector) once. However, if you want to provide ticks (and + maybe labels) dynamically, e.g. depending on the current axis range, connect a slot to this + signal and set the vector/vectors there. +*/ + +/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange) + + This signal is emitted when the range of this axis has changed. You can connect it to the \ref + setRange slot of another axis to communicate the new range to the other axis, in order for it to + be synchronized. + + You may also manipulate/correct the range with \ref setRange in a slot connected to this signal. + This is useful if for example a maximum range span shall not be exceeded, or if the lower/upper + range shouldn't go beyond certain values. For example, the following slot would limit the x axis + to only positive ranges: + \code + if (newRange.lower < 0) + plot->xAxis->setRange(0, newRange.size()); + \endcode +*/ + +/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange, const QCPRange &oldRange) + \overload + + Additionally to the new range, this signal also provides the previous range held by the axis as + \a oldRange. +*/ + +/*! \fn void QCPAxis::scaleTypeChanged(QCPAxis::ScaleType scaleType); + + This signal is emitted when the scale type changes, by calls to \ref setScaleType +*/ + +/*! \fn void QCPAxis::selectionChanged(QCPAxis::SelectableParts selection) + + This signal is emitted when the selection state of this axis has changed, either by user interaction + or by a direct call to \ref setSelectedParts. +*/ + +/*! \fn void QCPAxis::selectableChanged(const QCPAxis::SelectableParts &parts); + + This signal is emitted when the selectability changes, by calls to \ref setSelectableParts +*/ + +/* end of documentation of signals */ + +/*! + Constructs an Axis instance of Type \a type for the axis rect \a parent. + + Usually it isn't necessary to instantiate axes directly, because you can let QCustomPlot create + them for you with \ref QCPAxisRect::addAxis. If you want to use own QCPAxis-subclasses however, + create them manually and then inject them also via \ref QCPAxisRect::addAxis. +*/ +QCPAxis::QCPAxis(QCPAxisRect *parent, AxisType type) : + QCPLayerable(parent->parentPlot(), QString(), parent), + // axis base: + mAxisType(type), + mAxisRect(parent), + mPadding(5), + mOrientation(orientation(type)), + mSelectableParts(spAxis | spTickLabels | spAxisLabel), + mSelectedParts(spNone), + mBasePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedBasePen(QPen(Qt::blue, 2)), + // axis label: + mLabel(), + mLabelFont(mParentPlot->font()), + mSelectedLabelFont(QFont(mLabelFont.family(), mLabelFont.pointSize(), QFont::Bold)), + mLabelColor(Qt::black), + mSelectedLabelColor(Qt::blue), + // tick labels: + mTickLabels(true), + mAutoTickLabels(true), + mTickLabelType(ltNumber), + mTickLabelFont(mParentPlot->font()), + mSelectedTickLabelFont(QFont(mTickLabelFont.family(), mTickLabelFont.pointSize(), QFont::Bold)), + mTickLabelColor(Qt::black), + mSelectedTickLabelColor(Qt::blue), + mDateTimeFormat(QLatin1String("hh:mm:ss\ndd.MM.yy")), + mDateTimeSpec(Qt::LocalTime), + mNumberPrecision(6), + mNumberFormatChar('g'), + mNumberBeautifulPowers(true), + // ticks and subticks: + mTicks(true), + mTickStep(1), + mSubTickCount(4), + mAutoTickCount(6), + mAutoTicks(true), + mAutoTickStep(true), + mAutoSubTicks(true), + mTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedTickPen(QPen(Qt::blue, 2)), + mSubTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedSubTickPen(QPen(Qt::blue, 2)), + // scale and range: + mRange(0, 5), + mRangeReversed(false), + mScaleType(stLinear), + mScaleLogBase(10), + mScaleLogBaseLogInv(1.0/qLn(mScaleLogBase)), + // internal members: + mGrid(new QCPGrid(this)), + mAxisPainter(new QCPAxisPainterPrivate(parent->parentPlot())), + mLowestVisibleTick(0), + mHighestVisibleTick(-1), + mCachedMarginValid(false), + mCachedMargin(0) +{ + setParent(parent); + mGrid->setVisible(false); + setAntialiased(false); + setLayer(mParentPlot->currentLayer()); // it's actually on that layer already, but we want it in front of the grid, so we place it on there again + + if (type == atTop) + { + setTickLabelPadding(3); + setLabelPadding(6); + } else if (type == atRight) + { + setTickLabelPadding(7); + setLabelPadding(12); + } else if (type == atBottom) + { + setTickLabelPadding(3); + setLabelPadding(3); + } else if (type == atLeft) + { + setTickLabelPadding(5); + setLabelPadding(10); + } +} + +QCPAxis::~QCPAxis() +{ + delete mAxisPainter; + delete mGrid; // delete grid here instead of via parent ~QObject for better defined deletion order +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLabelPadding() const +{ + return mAxisPainter->tickLabelPadding; +} + +/* No documentation as it is a property getter */ +double QCPAxis::tickLabelRotation() const +{ + return mAxisPainter->tickLabelRotation; +} + +/* No documentation as it is a property getter */ +QCPAxis::LabelSide QCPAxis::tickLabelSide() const +{ + return mAxisPainter->tickLabelSide; +} + +/* No documentation as it is a property getter */ +QString QCPAxis::numberFormat() const +{ + QString result; + result.append(mNumberFormatChar); + if (mNumberBeautifulPowers) + { + result.append(QLatin1Char('b')); + if (mAxisPainter->numberMultiplyCross) + result.append(QLatin1Char('c')); + } + return result; +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLengthIn() const +{ + return mAxisPainter->tickLengthIn; +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLengthOut() const +{ + return mAxisPainter->tickLengthOut; +} + +/* No documentation as it is a property getter */ +int QCPAxis::subTickLengthIn() const +{ + return mAxisPainter->subTickLengthIn; +} + +/* No documentation as it is a property getter */ +int QCPAxis::subTickLengthOut() const +{ + return mAxisPainter->subTickLengthOut; +} + +/* No documentation as it is a property getter */ +int QCPAxis::labelPadding() const +{ + return mAxisPainter->labelPadding; +} + +/* No documentation as it is a property getter */ +int QCPAxis::offset() const +{ + return mAxisPainter->offset; +} + +/* No documentation as it is a property getter */ +QCPLineEnding QCPAxis::lowerEnding() const +{ + return mAxisPainter->lowerEnding; +} + +/* No documentation as it is a property getter */ +QCPLineEnding QCPAxis::upperEnding() const +{ + return mAxisPainter->upperEnding; +} + +/*! + Sets whether the axis uses a linear scale or a logarithmic scale. If \a type is set to \ref + stLogarithmic, the logarithm base can be set with \ref setScaleLogBase. In logarithmic axis + scaling, major tick marks appear at all powers of the logarithm base. Properties like tick step + (\ref setTickStep) don't apply in logarithmic scaling. If you wish a decimal base but less major + ticks, consider choosing a logarithm base of 100, 1000 or even higher. + + If \a type is \ref stLogarithmic and the number format (\ref setNumberFormat) uses the 'b' option + (beautifully typeset decimal powers), the display usually is "1 [multiplication sign] 10 + [superscript] n", which looks unnatural for logarithmic scaling (the "1 [multiplication sign]" + part). To only display the decimal power, set the number precision to zero with + \ref setNumberPrecision. +*/ +void QCPAxis::setScaleType(QCPAxis::ScaleType type) +{ + if (mScaleType != type) + { + mScaleType = type; + if (mScaleType == stLogarithmic) + setRange(mRange.sanitizedForLogScale()); + mCachedMarginValid = false; + emit scaleTypeChanged(mScaleType); + } +} + +/*! + If \ref setScaleType is set to \ref stLogarithmic, \a base will be the logarithm base of the + scaling. In logarithmic axis scaling, major tick marks appear at all powers of \a base. + + Properties like tick step (\ref setTickStep) don't apply in logarithmic scaling. If you wish a decimal base but + less major ticks, consider choosing \a base 100, 1000 or even higher. +*/ +void QCPAxis::setScaleLogBase(double base) +{ + if (base > 1) + { + mScaleLogBase = base; + mScaleLogBaseLogInv = 1.0/qLn(mScaleLogBase); // buffer for faster baseLog() calculation + mCachedMarginValid = false; + } else + qDebug() << Q_FUNC_INFO << "Invalid logarithmic scale base (must be greater 1):" << base; +} + +/*! + Sets the range of the axis. + + This slot may be connected with the \ref rangeChanged signal of another axis so this axis + is always synchronized with the other axis range, when it changes. + + To invert the direction of an axis, use \ref setRangeReversed. +*/ +void QCPAxis::setRange(const QCPRange &range) +{ + if (range.lower == mRange.lower && range.upper == mRange.upper) + return; + + if (!QCPRange::validRange(range)) return; + QCPRange oldRange = mRange; + if (mScaleType == stLogarithmic) + { + mRange = range.sanitizedForLogScale(); + } else + { + mRange = range.sanitizedForLinScale(); + } + mCachedMarginValid = false; + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains iSelectAxes.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelectedParts + directly. + + \see SelectablePart, setSelectedParts +*/ +void QCPAxis::setSelectableParts(const SelectableParts &selectable) +{ + if (mSelectableParts != selectable) + { + mSelectableParts = selectable; + emit selectableChanged(mSelectableParts); + } +} + +/*! + Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font. + + The entire selection mechanism for axes is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you + wish to change the selection state manually. + + This function can change the selection state of a part, independent of the \ref setSelectableParts setting. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see SelectablePart, setSelectableParts, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, + setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor +*/ +void QCPAxis::setSelectedParts(const SelectableParts &selected) +{ + if (mSelectedParts != selected) + { + mSelectedParts = selected; + emit selectionChanged(mSelectedParts); + } +} + +/*! + \overload + + Sets the lower and upper bound of the axis range. + + To invert the direction of an axis, use \ref setRangeReversed. + + There is also a slot to set a range, see \ref setRange(const QCPRange &range). +*/ +void QCPAxis::setRange(double lower, double upper) +{ + if (lower == mRange.lower && upper == mRange.upper) + return; + + if (!QCPRange::validRange(lower, upper)) return; + QCPRange oldRange = mRange; + mRange.lower = lower; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + mCachedMarginValid = false; + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + \overload + + Sets the range of the axis. + + The \a position coordinate indicates together with the \a alignment parameter, where the new + range will be positioned. \a size defines the size of the new axis range. \a alignment may be + Qt::AlignLeft, Qt::AlignRight or Qt::AlignCenter. This will cause the left border, right border, + or center of the range to be aligned with \a position. Any other values of \a alignment will + default to Qt::AlignCenter. +*/ +void QCPAxis::setRange(double position, double size, Qt::AlignmentFlag alignment) +{ + if (alignment == Qt::AlignLeft) + setRange(position, position+size); + else if (alignment == Qt::AlignRight) + setRange(position-size, position); + else // alignment == Qt::AlignCenter + setRange(position-size/2.0, position+size/2.0); +} + +/*! + Sets the lower bound of the axis range. The upper bound is not changed. + \see setRange +*/ +void QCPAxis::setRangeLower(double lower) +{ + if (mRange.lower == lower) + return; + + QCPRange oldRange = mRange; + mRange.lower = lower; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + mCachedMarginValid = false; + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets the upper bound of the axis range. The lower bound is not changed. + \see setRange +*/ +void QCPAxis::setRangeUpper(double upper) +{ + if (mRange.upper == upper) + return; + + QCPRange oldRange = mRange; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + mCachedMarginValid = false; + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the axis range (direction) is displayed reversed. Normally, the values on horizontal + axes increase left to right, on vertical axes bottom to top. When \a reversed is set to true, the + direction of increasing values is inverted. + + Note that the range and data interface stays the same for reversed axes, e.g. the \a lower part + of the \ref setRange interface will still reference the mathematically smaller number than the \a + upper part. +*/ +void QCPAxis::setRangeReversed(bool reversed) +{ + if (mRangeReversed != reversed) + { + mRangeReversed = reversed; + mCachedMarginValid = false; + } +} + +/*! + Sets whether the tick positions should be calculated automatically (either from an automatically + generated tick step or a tick step provided manually via \ref setTickStep, see \ref setAutoTickStep). + + If \a on is set to false, you must provide the tick positions manually via \ref setTickVector. + For these manual ticks you may let QCPAxis generate the appropriate labels automatically by + leaving \ref setAutoTickLabels set to true. If you also wish to control the displayed labels + manually, set \ref setAutoTickLabels to false and provide the label strings with \ref + setTickVectorLabels. + + If you need dynamically calculated tick vectors (and possibly tick label vectors), set the + vectors in a slot connected to the \ref ticksRequest signal. + + \see setAutoTickLabels, setAutoSubTicks, setAutoTickCount, setAutoTickStep +*/ +void QCPAxis::setAutoTicks(bool on) +{ + if (mAutoTicks != on) + { + mAutoTicks = on; + mCachedMarginValid = false; + } +} + +/*! + When \ref setAutoTickStep is true, \a approximateCount determines how many ticks should be + generated in the visible range, approximately. + + It's not guaranteed that this number of ticks is met exactly, but approximately within a + tolerance of about two. + + Only values greater than zero are accepted as \a approximateCount. + + \see setAutoTickStep, setAutoTicks, setAutoSubTicks +*/ +void QCPAxis::setAutoTickCount(int approximateCount) +{ + if (mAutoTickCount != approximateCount) + { + if (approximateCount > 0) + { + mAutoTickCount = approximateCount; + mCachedMarginValid = false; + } else + qDebug() << Q_FUNC_INFO << "approximateCount must be greater than zero:" << approximateCount; + } +} + +/*! + Sets whether the tick labels are generated automatically. Depending on the tick label type (\ref + ltNumber or \ref ltDateTime), the labels will either show the coordinate as floating point + number (\ref setNumberFormat), or a date/time formatted according to \ref setDateTimeFormat. + + If \a on is set to false, you should provide the tick labels via \ref setTickVectorLabels. This + is usually used in a combination with \ref setAutoTicks set to false for complete control over + tick positions and labels, e.g. when the ticks should be at multiples of pi and show "2pi", "3pi" + etc. as tick labels. + + If you need dynamically calculated tick vectors (and possibly tick label vectors), set the + vectors in a slot connected to the \ref ticksRequest signal. + + \see setAutoTicks +*/ +void QCPAxis::setAutoTickLabels(bool on) +{ + if (mAutoTickLabels != on) + { + mAutoTickLabels = on; + mCachedMarginValid = false; + } +} + +/*! + Sets whether the tick step, i.e. the interval between two (major) ticks, is calculated + automatically. If \a on is set to true, the axis finds a tick step that is reasonable for human + readable plots. + + The number of ticks the algorithm aims for within the visible range can be specified with \ref + setAutoTickCount. + + If \a on is set to false, you may set the tick step manually with \ref setTickStep. + + \see setAutoTicks, setAutoSubTicks, setAutoTickCount +*/ +void QCPAxis::setAutoTickStep(bool on) +{ + if (mAutoTickStep != on) + { + mAutoTickStep = on; + mCachedMarginValid = false; + } +} + +/*! + Sets whether the number of sub ticks in one tick interval is determined automatically. This + works, as long as the tick step mantissa is a multiple of 0.5. When \ref setAutoTickStep is + enabled, this is always the case. + + When \a on is set to false, you may set the sub tick count with \ref setSubTickCount manually. + + \see setAutoTickCount, setAutoTicks, setAutoTickStep +*/ +void QCPAxis::setAutoSubTicks(bool on) +{ + if (mAutoSubTicks != on) + { + mAutoSubTicks = on; + mCachedMarginValid = false; + } +} + +/*! + Sets whether tick marks are displayed. + + Note that setting \a show to false does not imply that tick labels are invisible, too. To achieve + that, see \ref setTickLabels. +*/ +void QCPAxis::setTicks(bool show) +{ + if (mTicks != show) + { + mTicks = show; + mCachedMarginValid = false; + } +} + +/*! + Sets whether tick labels are displayed. Tick labels are the numbers drawn next to tick marks. +*/ +void QCPAxis::setTickLabels(bool show) +{ + if (mTickLabels != show) + { + mTickLabels = show; + mCachedMarginValid = false; + } +} + +/*! + Sets the distance between the axis base line (including any outward ticks) and the tick labels. + \see setLabelPadding, setPadding +*/ +void QCPAxis::setTickLabelPadding(int padding) +{ + if (mAxisPainter->tickLabelPadding != padding) + { + mAxisPainter->tickLabelPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets whether the tick labels display numbers or dates/times. + + If \a type is set to \ref ltNumber, the format specifications of \ref setNumberFormat apply. + + If \a type is set to \ref ltDateTime, the format specifications of \ref setDateTimeFormat apply. + + In QCustomPlot, date/time coordinates are double numbers representing the seconds since + 1970-01-01T00:00:00 UTC. This format can be retrieved from QDateTime objects with the + QDateTime::toTime_t() function. Since this only gives a resolution of one second, there is also + the QDateTime::toMSecsSinceEpoch() function which returns the timespan described above in + milliseconds. Divide its return value by 1000.0 to get a value with the format needed for + date/time plotting, with a resolution of one millisecond. + + Using the toMSecsSinceEpoch function allows dates that go back to 2nd January 4713 B.C. + (represented by a negative number), unlike the toTime_t function, which works with unsigned + integers and thus only goes back to 1st January 1970. So both for range and accuracy, use of + toMSecsSinceEpoch()/1000.0 should be preferred as key coordinate for date/time axes. + + \see setTickLabels +*/ +void QCPAxis::setTickLabelType(LabelType type) +{ + if (mTickLabelType != type) + { + mTickLabelType = type; + mCachedMarginValid = false; + } +} + +/*! + Sets the font of the tick labels. + + \see setTickLabels, setTickLabelColor +*/ +void QCPAxis::setTickLabelFont(const QFont &font) +{ + if (font != mTickLabelFont) + { + mTickLabelFont = font; + mCachedMarginValid = false; + } +} + +/*! + Sets the color of the tick labels. + + \see setTickLabels, setTickLabelFont +*/ +void QCPAxis::setTickLabelColor(const QColor &color) +{ + if (color != mTickLabelColor) + { + mTickLabelColor = color; + mCachedMarginValid = false; + } +} + +/*! + Sets the rotation of the tick labels. If \a degrees is zero, the labels are drawn normally. Else, + the tick labels are drawn rotated by \a degrees clockwise. The specified angle is bound to values + from -90 to 90 degrees. + + If \a degrees is exactly -90, 0 or 90, the tick labels are centered on the tick coordinate. For + other angles, the label is drawn with an offset such that it seems to point toward or away from + the tick mark. +*/ +void QCPAxis::setTickLabelRotation(double degrees) +{ + if (!qFuzzyIsNull(degrees-mAxisPainter->tickLabelRotation)) + { + mAxisPainter->tickLabelRotation = qBound(-90.0, degrees, 90.0); + mCachedMarginValid = false; + } +} + +/*! + Sets whether the tick labels (numbers) shall appear inside or outside the axis rect. + + The usual and default setting is \ref lsOutside. Very compact plots sometimes require tick labels + to be inside the axis rect, to save space. If \a side is set to \ref lsInside, the tick labels + appear on the inside are additionally clipped to the axis rect. +*/ +void QCPAxis::setTickLabelSide(LabelSide side) +{ + mAxisPainter->tickLabelSide = side; + mCachedMarginValid = false; +} + +/*! + Sets the format in which dates and times are displayed as tick labels, if \ref setTickLabelType is \ref ltDateTime. + for details about the \a format string, see the documentation of QDateTime::toString(). + + Newlines can be inserted with "\n". + + \see setDateTimeSpec +*/ +void QCPAxis::setDateTimeFormat(const QString &format) +{ + if (mDateTimeFormat != format) + { + mDateTimeFormat = format; + mCachedMarginValid = false; + } +} + +/*! + Sets the time spec that is used for the date time values when \ref setTickLabelType is \ref + ltDateTime. + + The default value of QDateTime objects (and also QCustomPlot) is Qt::LocalTime. However, + if the date time values passed to QCustomPlot are given in the UTC spec, set \a + timeSpec to Qt::UTC to get the correct axis labels. + + \see setDateTimeFormat +*/ +void QCPAxis::setDateTimeSpec(const Qt::TimeSpec &timeSpec) +{ + mDateTimeSpec = timeSpec; +} + +/*! + Sets the number format for the numbers drawn as tick labels (if tick label type is \ref + ltNumber). This \a formatCode is an extended version of the format code used e.g. by + QString::number() and QLocale::toString(). For reference about that, see the "Argument Formats" + section in the detailed description of the QString class. \a formatCode is a string of one, two + or three characters. The first character is identical to the normal format code used by Qt. In + short, this means: 'e'/'E' scientific format, 'f' fixed format, 'g'/'G' scientific or fixed, + whichever is shorter. + + The second and third characters are optional and specific to QCustomPlot:\n + If the first char was 'e' or 'g', numbers are/might be displayed in the scientific format, e.g. + "5.5e9", which is ugly in a plot. So when the second char of \a formatCode is set to 'b' (for + "beautiful"), those exponential numbers are formatted in a more natural way, i.e. "5.5 + [multiplication sign] 10 [superscript] 9". By default, the multiplication sign is a centered dot. + If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can + be set to 'c'. The inserted multiplication signs are the UTF-8 characters 215 (0xD7) for the + cross and 183 (0xB7) for the dot. + + If the scale type (\ref setScaleType) is \ref stLogarithmic and the \a formatCode uses the 'b' + option (beautifully typeset decimal powers), the display usually is "1 [multiplication sign] 10 + [superscript] n", which looks unnatural for logarithmic scaling (the "1 [multiplication sign]" + part). To only display the decimal power, set the number precision to zero with \ref + setNumberPrecision. + + Examples for \a formatCode: + \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large, + normal scientific format is used + \li \c gb If number is small, fixed format is used, if number is large, scientific format is used with + beautifully typeset decimal powers and a dot as multiplication sign + \li \c ebc All numbers are in scientific format with beautifully typeset decimal power and a cross as + multiplication sign + \li \c fb illegal format code, since fixed format doesn't support (or need) beautifully typeset decimal + powers. Format code will be reduced to 'f'. + \li \c hello illegal format code, since first char is not 'e', 'E', 'f', 'g' or 'G'. Current format + code will not be changed. +*/ +void QCPAxis::setNumberFormat(const QString &formatCode) +{ + if (formatCode.isEmpty()) + { + qDebug() << Q_FUNC_INFO << "Passed formatCode is empty"; + return; + } + mCachedMarginValid = false; + + // interpret first char as number format char: + QString allowedFormatChars(QLatin1String("eEfgG")); + if (allowedFormatChars.contains(formatCode.at(0))) + { + mNumberFormatChar = QLatin1Char(formatCode.at(0).toLatin1()); + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (first char not in 'eEfgG'):" << formatCode; + return; + } + if (formatCode.length() < 2) + { + mNumberBeautifulPowers = false; + mAxisPainter->numberMultiplyCross = false; + return; + } + + // interpret second char as indicator for beautiful decimal powers: + if (formatCode.at(1) == QLatin1Char('b') && (mNumberFormatChar == QLatin1Char('e') || mNumberFormatChar == QLatin1Char('g'))) + { + mNumberBeautifulPowers = true; + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode; + return; + } + if (formatCode.length() < 3) + { + mAxisPainter->numberMultiplyCross = false; + return; + } + + // interpret third char as indicator for dot or cross multiplication symbol: + if (formatCode.at(2) == QLatin1Char('c')) + { + mAxisPainter->numberMultiplyCross = true; + } else if (formatCode.at(2) == QLatin1Char('d')) + { + mAxisPainter->numberMultiplyCross = false; + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (third char neither 'c' nor 'd'):" << formatCode; + return; + } +} + +/*! + Sets the precision of the tick label numbers. See QLocale::toString(double i, char f, int prec) + for details. The effect of precisions are most notably for number Formats starting with 'e', see + \ref setNumberFormat + + If the scale type (\ref setScaleType) is \ref stLogarithmic and the number format (\ref + setNumberFormat) uses the 'b' format code (beautifully typeset decimal powers), the display + usually is "1 [multiplication sign] 10 [superscript] n", which looks unnatural for logarithmic + scaling (the redundant "1 [multiplication sign]" part). To only display the decimal power "10 + [superscript] n", set \a precision to zero. +*/ +void QCPAxis::setNumberPrecision(int precision) +{ + if (mNumberPrecision != precision) + { + mNumberPrecision = precision; + mCachedMarginValid = false; + } +} + +/*! + If \ref setAutoTickStep is set to false, use this function to set the tick step manually. + The tick step is the interval between (major) ticks, in plot coordinates. + \see setSubTickCount +*/ +void QCPAxis::setTickStep(double step) +{ + if (mTickStep != step) + { + mTickStep = step; + mCachedMarginValid = false; + } +} + +/*! + If you want full control over what ticks (and possibly labels) the axes show, this function is + used to set the coordinates at which ticks will appear.\ref setAutoTicks must be disabled, else + the provided tick vector will be overwritten with automatically generated tick coordinates upon + replot. The labels of the ticks can be generated automatically when \ref setAutoTickLabels is + left enabled. If it is disabled, you can set the labels manually with \ref setTickVectorLabels. + + \a vec is a vector containing the positions of the ticks, in plot coordinates. + + \warning \a vec must be sorted in ascending order, no additional checks are made to ensure this. + + \see setTickVectorLabels +*/ +void QCPAxis::setTickVector(const QVector &vec) +{ + // don't check whether mTickVector != vec here, because it takes longer than we would save + mTickVector = vec; + mCachedMarginValid = false; +} + +/*! + If you want full control over what ticks and labels the axes show, this function is used to set a + number of QStrings that will be displayed at the tick positions which you need to provide with + \ref setTickVector. These two vectors should have the same size. (Note that you need to disable + \ref setAutoTicks and \ref setAutoTickLabels first.) + + \a vec is a vector containing the labels of the ticks. The entries correspond to the respective + indices in the tick vector, passed via \ref setTickVector. + + \see setTickVector +*/ +void QCPAxis::setTickVectorLabels(const QVector &vec) +{ + // don't check whether mTickVectorLabels != vec here, because it takes longer than we would save + mTickVectorLabels = vec; + mCachedMarginValid = false; +} + +/*! + Sets the length of the ticks in pixels. \a inside is the length the ticks will reach inside the + plot and \a outside is the length they will reach outside the plot. If \a outside is greater than + zero, the tick labels and axis label will increase their distance to the axis accordingly, so + they won't collide with the ticks. + + \see setSubTickLength, setTickLengthIn, setTickLengthOut +*/ +void QCPAxis::setTickLength(int inside, int outside) +{ + setTickLengthIn(inside); + setTickLengthOut(outside); +} + +/*! + Sets the length of the inward ticks in pixels. \a inside is the length the ticks will reach + inside the plot. + + \see setTickLengthOut, setTickLength, setSubTickLength +*/ +void QCPAxis::setTickLengthIn(int inside) +{ + if (mAxisPainter->tickLengthIn != inside) + { + mAxisPainter->tickLengthIn = inside; + } +} + +/*! + Sets the length of the outward ticks in pixels. \a outside is the length the ticks will reach + outside the plot. If \a outside is greater than zero, the tick labels and axis label will + increase their distance to the axis accordingly, so they won't collide with the ticks. + + \see setTickLengthIn, setTickLength, setSubTickLength +*/ +void QCPAxis::setTickLengthOut(int outside) +{ + if (mAxisPainter->tickLengthOut != outside) + { + mAxisPainter->tickLengthOut = outside; + mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets the number of sub ticks in one (major) tick step. A sub tick count of three for example, + divides the tick intervals in four sub intervals. + + By default, the number of sub ticks is chosen automatically in a reasonable manner as long as the + mantissa of the tick step is a multiple of 0.5. When \ref setAutoTickStep is enabled, this is + always the case. + + If you want to disable automatic sub tick count and use this function to set the count manually, + see \ref setAutoSubTicks. +*/ +void QCPAxis::setSubTickCount(int count) +{ + mSubTickCount = count; +} + +/*! + Sets the length of the subticks in pixels. \a inside is the length the subticks will reach inside + the plot and \a outside is the length they will reach outside the plot. If \a outside is greater + than zero, the tick labels and axis label will increase their distance to the axis accordingly, + so they won't collide with the ticks. + + \see setTickLength, setSubTickLengthIn, setSubTickLengthOut +*/ +void QCPAxis::setSubTickLength(int inside, int outside) +{ + setSubTickLengthIn(inside); + setSubTickLengthOut(outside); +} + +/*! + Sets the length of the inward subticks in pixels. \a inside is the length the subticks will reach inside + the plot. + + \see setSubTickLengthOut, setSubTickLength, setTickLength +*/ +void QCPAxis::setSubTickLengthIn(int inside) +{ + if (mAxisPainter->subTickLengthIn != inside) + { + mAxisPainter->subTickLengthIn = inside; + } +} + +/*! + Sets the length of the outward subticks in pixels. \a outside is the length the subticks will reach + outside the plot. If \a outside is greater than zero, the tick labels will increase their + distance to the axis accordingly, so they won't collide with the ticks. + + \see setSubTickLengthIn, setSubTickLength, setTickLength +*/ +void QCPAxis::setSubTickLengthOut(int outside) +{ + if (mAxisPainter->subTickLengthOut != outside) + { + mAxisPainter->subTickLengthOut = outside; + mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets the pen, the axis base line is drawn with. + + \see setTickPen, setSubTickPen +*/ +void QCPAxis::setBasePen(const QPen &pen) +{ + mBasePen = pen; +} + +/*! + Sets the pen, tick marks will be drawn with. + + \see setTickLength, setBasePen +*/ +void QCPAxis::setTickPen(const QPen &pen) +{ + mTickPen = pen; +} + +/*! + Sets the pen, subtick marks will be drawn with. + + \see setSubTickCount, setSubTickLength, setBasePen +*/ +void QCPAxis::setSubTickPen(const QPen &pen) +{ + mSubTickPen = pen; +} + +/*! + Sets the font of the axis label. + + \see setLabelColor +*/ +void QCPAxis::setLabelFont(const QFont &font) +{ + if (mLabelFont != font) + { + mLabelFont = font; + mCachedMarginValid = false; + } +} + +/*! + Sets the color of the axis label. + + \see setLabelFont +*/ +void QCPAxis::setLabelColor(const QColor &color) +{ + mLabelColor = color; +} + +/*! + Sets the text of the axis label that will be shown below/above or next to the axis, depending on + its orientation. To disable axis labels, pass an empty string as \a str. +*/ +void QCPAxis::setLabel(const QString &str) +{ + if (mLabel != str) + { + mLabel = str; + mCachedMarginValid = false; + } +} + +/*! + Sets the distance between the tick labels and the axis label. + + \see setTickLabelPadding, setPadding +*/ +void QCPAxis::setLabelPadding(int padding) +{ + if (mAxisPainter->labelPadding != padding) + { + mAxisPainter->labelPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the padding of the axis. + + When \ref QCPAxisRect::setAutoMargins is enabled, the padding is the additional outer most space, + that is left blank. + + The axis padding has no meaning if \ref QCPAxisRect::setAutoMargins is disabled. + + \see setLabelPadding, setTickLabelPadding +*/ +void QCPAxis::setPadding(int padding) +{ + if (mPadding != padding) + { + mPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the offset the axis has to its axis rect side. + + If an axis rect side has multiple axes and automatic margin calculation is enabled for that side, + only the offset of the inner most axis has meaning (even if it is set to be invisible). The + offset of the other, outer axes is controlled automatically, to place them at appropriate + positions. +*/ +void QCPAxis::setOffset(int offset) +{ + mAxisPainter->offset = offset; +} + +/*! + Sets the font that is used for tick labels when they are selected. + + \see setTickLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickLabelFont(const QFont &font) +{ + if (font != mSelectedTickLabelFont) + { + mSelectedTickLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts + } +} + +/*! + Sets the font that is used for the axis label when it is selected. + + \see setLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedLabelFont(const QFont &font) +{ + mSelectedLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts +} + +/*! + Sets the color that is used for tick labels when they are selected. + + \see setTickLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickLabelColor(const QColor &color) +{ + if (color != mSelectedTickLabelColor) + { + mSelectedTickLabelColor = color; + } +} + +/*! + Sets the color that is used for the axis label when it is selected. + + \see setLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedLabelColor(const QColor &color) +{ + mSelectedLabelColor = color; +} + +/*! + Sets the pen that is used to draw the axis base line when selected. + + \see setBasePen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedBasePen(const QPen &pen) +{ + mSelectedBasePen = pen; +} + +/*! + Sets the pen that is used to draw the (major) ticks when selected. + + \see setTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickPen(const QPen &pen) +{ + mSelectedTickPen = pen; +} + +/*! + Sets the pen that is used to draw the subticks when selected. + + \see setSubTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedSubTickPen(const QPen &pen) +{ + mSelectedSubTickPen = pen; +} + +/*! + Sets the style for the lower axis ending. See the documentation of QCPLineEnding for available + styles. + + For horizontal axes, this method refers to the left ending, for vertical axes the bottom ending. + Note that this meaning does not change when the axis range is reversed with \ref + setRangeReversed. + + \see setUpperEnding +*/ +void QCPAxis::setLowerEnding(const QCPLineEnding &ending) +{ + mAxisPainter->lowerEnding = ending; +} + +/*! + Sets the style for the upper axis ending. See the documentation of QCPLineEnding for available + styles. + + For horizontal axes, this method refers to the right ending, for vertical axes the top ending. + Note that this meaning does not change when the axis range is reversed with \ref + setRangeReversed. + + \see setLowerEnding +*/ +void QCPAxis::setUpperEnding(const QCPLineEnding &ending) +{ + mAxisPainter->upperEnding = ending; +} + +/*! + If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper + bounds of the range. The range is simply moved by \a diff. + + If the scale type is \ref stLogarithmic, the range bounds are multiplied by \a diff. This + corresponds to an apparent "linear" move in logarithmic scaling by a distance of log(diff). +*/ +void QCPAxis::moveRange(double diff) +{ + QCPRange oldRange = mRange; + if (mScaleType == stLinear) + { + mRange.lower += diff; + mRange.upper += diff; + } else // mScaleType == stLogarithmic + { + mRange.lower *= diff; + mRange.upper *= diff; + } + mCachedMarginValid = false; + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Scales the range of this axis by \a factor around the coordinate \a center. For example, if \a + factor is 2.0, \a center is 1.0, then the axis range will double its size, and the point at + coordinate 1.0 won't have changed its position in the QCustomPlot widget (i.e. coordinates + around 1.0 will have moved symmetrically closer to 1.0). +*/ +void QCPAxis::scaleRange(double factor, double center) +{ + QCPRange oldRange = mRange; + if (mScaleType == stLinear) + { + QCPRange newRange; + newRange.lower = (mRange.lower-center)*factor + center; + newRange.upper = (mRange.upper-center)*factor + center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLinScale(); + } else // mScaleType == stLogarithmic + { + if ((mRange.upper < 0 && center < 0) || (mRange.upper > 0 && center > 0)) // make sure center has same sign as range + { + QCPRange newRange; + newRange.lower = qPow(mRange.lower/center, factor)*center; + newRange.upper = qPow(mRange.upper/center, factor)*center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLogScale(); + } else + qDebug() << Q_FUNC_INFO << "Center of scaling operation doesn't lie in same logarithmic sign domain as range:" << center; + } + mCachedMarginValid = false; + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Scales the range of this axis to have a certain scale \a ratio to \a otherAxis. The scaling will + be done around the center of the current axis range. + + For example, if \a ratio is 1, this axis is the \a yAxis and \a otherAxis is \a xAxis, graphs + plotted with those axes will appear in a 1:1 aspect ratio, independent of the aspect ratio the + axis rect has. + + This is an operation that changes the range of this axis once, it doesn't fix the scale ratio + indefinitely. Note that calling this function in the constructor of the QCustomPlot's parent + won't have the desired effect, since the widget dimensions aren't defined yet, and a resizeEvent + will follow. +*/ +void QCPAxis::setScaleRatio(const QCPAxis *otherAxis, double ratio) +{ + int otherPixelSize, ownPixelSize; + + if (otherAxis->orientation() == Qt::Horizontal) + otherPixelSize = otherAxis->axisRect()->width(); + else + otherPixelSize = otherAxis->axisRect()->height(); + + if (orientation() == Qt::Horizontal) + ownPixelSize = axisRect()->width(); + else + ownPixelSize = axisRect()->height(); + + double newRangeSize = ratio*otherAxis->range().size()*ownPixelSize/(double)otherPixelSize; + setRange(range().center(), newRangeSize, Qt::AlignCenter); +} + +/*! + Changes the axis range such that all plottables associated with this axis are fully visible in + that dimension. + + \see QCPAbstractPlottable::rescaleAxes, QCustomPlot::rescaleAxes +*/ +void QCPAxis::rescale(bool onlyVisiblePlottables) +{ + QList p = plottables(); + QCPRange newRange; + bool haveRange = false; + for (int i=0; irealVisibility() && onlyVisiblePlottables) + continue; + QCPRange plottableRange; + bool currentFoundRange; + QCPAbstractPlottable::SignDomain signDomain = QCPAbstractPlottable::sdBoth; + if (mScaleType == stLogarithmic) + signDomain = (mRange.upper < 0 ? QCPAbstractPlottable::sdNegative : QCPAbstractPlottable::sdPositive); + if (p.at(i)->keyAxis() == this) + plottableRange = p.at(i)->getKeyRange(currentFoundRange, signDomain); + else + plottableRange = p.at(i)->getValueRange(currentFoundRange, signDomain); + if (currentFoundRange) + { + if (!haveRange) + newRange = plottableRange; + else + newRange.expand(plottableRange); + haveRange = true; + } + } + if (haveRange) + { + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (mScaleType == stLinear) + { + newRange.lower = center-mRange.size()/2.0; + newRange.upper = center+mRange.size()/2.0; + } else // mScaleType == stLogarithmic + { + newRange.lower = center/qSqrt(mRange.upper/mRange.lower); + newRange.upper = center*qSqrt(mRange.upper/mRange.lower); + } + } + setRange(newRange); + } +} + +/*! + Transforms \a value, in pixel coordinates of the QCustomPlot widget, to axis coordinates. +*/ +double QCPAxis::pixelToCoord(double value) const +{ + if (orientation() == Qt::Horizontal) + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (value-mAxisRect->left())/(double)mAxisRect->width()*mRange.size()+mRange.lower; + else + return -(value-mAxisRect->left())/(double)mAxisRect->width()*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return qPow(mRange.upper/mRange.lower, (value-mAxisRect->left())/(double)mAxisRect->width())*mRange.lower; + else + return qPow(mRange.upper/mRange.lower, (mAxisRect->left()-value)/(double)mAxisRect->width())*mRange.upper; + } + } else // orientation() == Qt::Vertical + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (mAxisRect->bottom()-value)/(double)mAxisRect->height()*mRange.size()+mRange.lower; + else + return -(mAxisRect->bottom()-value)/(double)mAxisRect->height()*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return qPow(mRange.upper/mRange.lower, (mAxisRect->bottom()-value)/(double)mAxisRect->height())*mRange.lower; + else + return qPow(mRange.upper/mRange.lower, (value-mAxisRect->bottom())/(double)mAxisRect->height())*mRange.upper; + } + } +} + +/*! + Transforms \a value, in coordinates of the axis, to pixel coordinates of the QCustomPlot widget. +*/ +double QCPAxis::coordToPixel(double value) const +{ + if (orientation() == Qt::Horizontal) + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (value-mRange.lower)/mRange.size()*mAxisRect->width()+mAxisRect->left(); + else + return (mRange.upper-value)/mRange.size()*mAxisRect->width()+mAxisRect->left(); + } else // mScaleType == stLogarithmic + { + if (value >= 0 && mRange.upper < 0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->right()+200 : mAxisRect->left()-200; + else if (value <= 0 && mRange.upper > 0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->left()-200 : mAxisRect->right()+200; + else + { + if (!mRangeReversed) + return baseLog(value/mRange.lower)/baseLog(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); + else + return baseLog(mRange.upper/value)/baseLog(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); + } + } + } else // orientation() == Qt::Vertical + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return mAxisRect->bottom()-(value-mRange.lower)/mRange.size()*mAxisRect->height(); + else + return mAxisRect->bottom()-(mRange.upper-value)/mRange.size()*mAxisRect->height(); + } else // mScaleType == stLogarithmic + { + if (value >= 0 && mRange.upper < 0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->top()-200 : mAxisRect->bottom()+200; + else if (value <= 0 && mRange.upper > 0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->bottom()+200 : mAxisRect->top()-200; + else + { + if (!mRangeReversed) + return mAxisRect->bottom()-baseLog(value/mRange.lower)/baseLog(mRange.upper/mRange.lower)*mAxisRect->height(); + else + return mAxisRect->bottom()-baseLog(mRange.upper/value)/baseLog(mRange.upper/mRange.lower)*mAxisRect->height(); + } + } + } +} + +/*! + Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function + is independent of the user-selectable parts defined with \ref setSelectableParts. Further, this + function does not change the current selection state of the axis. + + If the axis is not visible (\ref setVisible), this function always returns \ref spNone. + + \see setSelectedParts, setSelectableParts, QCustomPlot::setInteractions +*/ +QCPAxis::SelectablePart QCPAxis::getPartAt(const QPointF &pos) const +{ + if (!mVisible) + return spNone; + + if (mAxisPainter->axisSelectionBox().contains(pos.toPoint())) + return spAxis; + else if (mAxisPainter->tickLabelsSelectionBox().contains(pos.toPoint())) + return spTickLabels; + else if (mAxisPainter->labelSelectionBox().contains(pos.toPoint())) + return spAxisLabel; + else + return spNone; +} + +/* inherits documentation from base class */ +double QCPAxis::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mParentPlot) return -1; + SelectablePart part = getPartAt(pos); + if ((onlySelectable && !mSelectableParts.testFlag(part)) || part == spNone) + return -1; + + if (details) + details->setValue(part); + return mParentPlot->selectionTolerance()*0.99; +} + +/*! + Returns a list of all the plottables that have this axis as key or value axis. + + If you are only interested in plottables of type QCPGraph, see \ref graphs. + + \see graphs, items +*/ +QList QCPAxis::plottables() const +{ + QList result; + if (!mParentPlot) return result; + + for (int i=0; imPlottables.size(); ++i) + { + if (mParentPlot->mPlottables.at(i)->keyAxis() == this ||mParentPlot->mPlottables.at(i)->valueAxis() == this) + result.append(mParentPlot->mPlottables.at(i)); + } + return result; +} + +/*! + Returns a list of all the graphs that have this axis as key or value axis. + + \see plottables, items +*/ +QList QCPAxis::graphs() const +{ + QList result; + if (!mParentPlot) return result; + + for (int i=0; imGraphs.size(); ++i) + { + if (mParentPlot->mGraphs.at(i)->keyAxis() == this || mParentPlot->mGraphs.at(i)->valueAxis() == this) + result.append(mParentPlot->mGraphs.at(i)); + } + return result; +} + +/*! + Returns a list of all the items that are associated with this axis. An item is considered + associated with an axis if at least one of its positions uses the axis as key or value axis. + + \see plottables, graphs +*/ +QList QCPAxis::items() const +{ + QList result; + if (!mParentPlot) return result; + + for (int itemId=0; itemIdmItems.size(); ++itemId) + { + QList positions = mParentPlot->mItems.at(itemId)->positions(); + for (int posId=0; posIdkeyAxis() == this || positions.at(posId)->valueAxis() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + break; + } + } + } + return result; +} + +/*! + Transforms a margin side to the logically corresponding axis type. (QCP::msLeft to + QCPAxis::atLeft, QCP::msRight to QCPAxis::atRight, etc.) +*/ +QCPAxis::AxisType QCPAxis::marginSideToAxisType(QCP::MarginSide side) +{ + switch (side) + { + case QCP::msLeft: return atLeft; + case QCP::msRight: return atRight; + case QCP::msTop: return atTop; + case QCP::msBottom: return atBottom; + default: break; + } + qDebug() << Q_FUNC_INFO << "Invalid margin side passed:" << (int)side; + return atLeft; +} + +/*! + Returns the axis type that describes the opposite axis of an axis with the specified \a type. +*/ +QCPAxis::AxisType QCPAxis::opposite(QCPAxis::AxisType type) +{ + switch (type) + { + case atLeft: return atRight; break; + case atRight: return atLeft; break; + case atBottom: return atTop; break; + case atTop: return atBottom; break; + default: qDebug() << Q_FUNC_INFO << "invalid axis type"; return atLeft; break; + } +} + +/*! \internal + + This function is called to prepare the tick vector, sub tick vector and tick label vector. If + \ref setAutoTicks is set to true, appropriate tick values are determined automatically via \ref + generateAutoTicks. If it's set to false, the signal ticksRequest is emitted, which can be used to + provide external tick positions. Then the sub tick vectors and tick label vectors are created. +*/ +void QCPAxis::setupTickVectors() +{ + if (!mParentPlot) return; + if ((!mTicks && !mTickLabels && !mGrid->visible()) || mRange.size() <= 0) return; + + // fill tick vectors, either by auto generating or by notifying user to fill the vectors himself + if (mAutoTicks) + { + generateAutoTicks(); + } else + { + emit ticksRequest(); + } + + visibleTickBounds(mLowestVisibleTick, mHighestVisibleTick); + if (mTickVector.isEmpty()) + { + mSubTickVector.clear(); + return; + } + + // generate subticks between ticks: + mSubTickVector.resize((mTickVector.size()-1)*mSubTickCount); + if (mSubTickCount > 0) + { + double subTickStep = 0; + double subTickPosition = 0; + int subTickIndex = 0; + bool done = false; + int lowTick = mLowestVisibleTick > 0 ? mLowestVisibleTick-1 : mLowestVisibleTick; + int highTick = mHighestVisibleTick < mTickVector.size()-1 ? mHighestVisibleTick+1 : mHighestVisibleTick; + for (int i=lowTick+1; i<=highTick; ++i) + { + subTickStep = (mTickVector.at(i)-mTickVector.at(i-1))/(double)(mSubTickCount+1); + for (int k=1; k<=mSubTickCount; ++k) + { + subTickPosition = mTickVector.at(i-1) + k*subTickStep; + if (subTickPosition < mRange.lower) + continue; + if (subTickPosition > mRange.upper) + { + done = true; + break; + } + mSubTickVector[subTickIndex] = subTickPosition; + subTickIndex++; + } + if (done) break; + } + mSubTickVector.resize(subTickIndex); + } + + // generate tick labels according to tick positions: + if (mAutoTickLabels) + { + int vecsize = mTickVector.size(); + mTickVectorLabels.resize(vecsize); + if (mTickLabelType == ltNumber) + { + for (int i=mLowestVisibleTick; i<=mHighestVisibleTick; ++i) + mTickVectorLabels[i] = mParentPlot->locale().toString(mTickVector.at(i), mNumberFormatChar.toLatin1(), mNumberPrecision); + } else if (mTickLabelType == ltDateTime) + { + for (int i=mLowestVisibleTick; i<=mHighestVisibleTick; ++i) + { +#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0) // use fromMSecsSinceEpoch function if available, to gain sub-second accuracy on tick labels (e.g. for format "hh:mm:ss:zzz") + mTickVectorLabels[i] = mParentPlot->locale().toString(QDateTime::fromTime_t(mTickVector.at(i)).toTimeSpec(mDateTimeSpec), mDateTimeFormat); +#else + mTickVectorLabels[i] = mParentPlot->locale().toString(QDateTime::fromMSecsSinceEpoch(mTickVector.at(i)*1000).toTimeSpec(mDateTimeSpec), mDateTimeFormat); +#endif + } + } + } else // mAutoTickLabels == false + { + if (mAutoTicks) // ticks generated automatically, but not ticklabels, so emit ticksRequest here for labels + { + emit ticksRequest(); + } + // make sure provided tick label vector has correct (minimal) length: + if (mTickVectorLabels.size() < mTickVector.size()) + mTickVectorLabels.resize(mTickVector.size()); + } +} + +/*! \internal + + If \ref setAutoTicks is set to true, this function is called by \ref setupTickVectors to + generate reasonable tick positions (and subtick count). The algorithm tries to create + approximately mAutoTickCount ticks (set via \ref setAutoTickCount). + + If the scale is logarithmic, \ref setAutoTickCount is ignored, and one tick is generated at every + power of the current logarithm base, set via \ref setScaleLogBase. +*/ +void QCPAxis::generateAutoTicks() +{ + if (mScaleType == stLinear) + { + if (mAutoTickStep) + { + // Generate tick positions according to linear scaling: + mTickStep = mRange.size()/(double)(mAutoTickCount+1e-10); // mAutoTickCount ticks on average, the small addition is to prevent jitter on exact integers + double magnitudeFactor = qPow(10.0, qFloor(qLn(mTickStep)/qLn(10.0))); // get magnitude factor e.g. 0.01, 1, 10, 1000 etc. + double tickStepMantissa = mTickStep/magnitudeFactor; + if (tickStepMantissa < 5) + { + // round digit after decimal point to 0.5 + mTickStep = (int)(tickStepMantissa*2)/2.0*magnitudeFactor; + } else + { + // round to first digit in multiples of 2 + mTickStep = (int)(tickStepMantissa/2.0)*2.0*magnitudeFactor; + } + } + if (mAutoSubTicks) + mSubTickCount = calculateAutoSubTickCount(mTickStep); + // Generate tick positions according to mTickStep: + qint64 firstStep = floor(mRange.lower/mTickStep); // do not use qFloor here, or we'll lose 64 bit precision + qint64 lastStep = ceil(mRange.upper/mTickStep); // do not use qCeil here, or we'll lose 64 bit precision + int tickcount = lastStep-firstStep+1; + if (tickcount < 0) tickcount = 0; + mTickVector.resize(tickcount); + for (int i=0; i 0 && mRange.upper > 0) // positive range + { + double lowerMag = basePow(qFloor(baseLog(mRange.lower))); + double currentMag = lowerMag; + mTickVector.clear(); + mTickVector.append(currentMag); + while (currentMag < mRange.upper && currentMag > 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case + { + currentMag *= mScaleLogBase; + mTickVector.append(currentMag); + } + } else if (mRange.lower < 0 && mRange.upper < 0) // negative range + { + double lowerMag = -basePow(qCeil(baseLog(-mRange.lower))); + double currentMag = lowerMag; + mTickVector.clear(); + mTickVector.append(currentMag); + while (currentMag < mRange.upper && currentMag < 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case + { + currentMag /= mScaleLogBase; + mTickVector.append(currentMag); + } + } else // invalid range for logarithmic scale, because lower and upper have different sign + { + mTickVector.clear(); + qDebug() << Q_FUNC_INFO << "Invalid range for logarithmic plot: " << mRange.lower << "-" << mRange.upper; + } + } +} + +/*! \internal + + Called by generateAutoTicks when \ref setAutoSubTicks is set to true. Depending on the \a + tickStep between two major ticks on the axis, a different number of sub ticks is appropriate. For + Example taking 4 sub ticks for a \a tickStep of 1 makes more sense than taking 5 sub ticks, + because this corresponds to a sub tick step of 0.2, instead of the less intuitive 0.16667. Note + that a subtick count of 4 means dividing the major tick step into 5 sections. + + This is implemented by a hand made lookup for integer tick steps as well as fractional tick steps + with a fractional part of (approximately) 0.5. If a tick step is different (i.e. has no + fractional part close to 0.5), the currently set sub tick count (\ref setSubTickCount) is + returned. +*/ +int QCPAxis::calculateAutoSubTickCount(double tickStep) const +{ + int result = mSubTickCount; // default to current setting, if no proper value can be found + + // get mantissa of tickstep: + double magnitudeFactor = qPow(10.0, qFloor(qLn(tickStep)/qLn(10.0))); // get magnitude factor e.g. 0.01, 1, 10, 1000 etc. + double tickStepMantissa = tickStep/magnitudeFactor; + + // separate integer and fractional part of mantissa: + double epsilon = 0.01; + double intPartf; + int intPart; + double fracPart = modf(tickStepMantissa, &intPartf); + intPart = intPartf; + + // handle cases with (almost) integer mantissa: + if (fracPart < epsilon || 1.0-fracPart < epsilon) + { + if (1.0-fracPart < epsilon) + ++intPart; + switch (intPart) + { + case 1: result = 4; break; // 1.0 -> 0.2 substep + case 2: result = 3; break; // 2.0 -> 0.5 substep + case 3: result = 2; break; // 3.0 -> 1.0 substep + case 4: result = 3; break; // 4.0 -> 1.0 substep + case 5: result = 4; break; // 5.0 -> 1.0 substep + case 6: result = 2; break; // 6.0 -> 2.0 substep + case 7: result = 6; break; // 7.0 -> 1.0 substep + case 8: result = 3; break; // 8.0 -> 2.0 substep + case 9: result = 2; break; // 9.0 -> 3.0 substep + } + } else + { + // handle cases with significantly fractional mantissa: + if (qAbs(fracPart-0.5) < epsilon) // *.5 mantissa + { + switch (intPart) + { + case 1: result = 2; break; // 1.5 -> 0.5 substep + case 2: result = 4; break; // 2.5 -> 0.5 substep + case 3: result = 4; break; // 3.5 -> 0.7 substep + case 4: result = 2; break; // 4.5 -> 1.5 substep + case 5: result = 4; break; // 5.5 -> 1.1 substep (won't occur with autoTickStep from here on) + case 6: result = 4; break; // 6.5 -> 1.3 substep + case 7: result = 2; break; // 7.5 -> 2.5 substep + case 8: result = 4; break; // 8.5 -> 1.7 substep + case 9: result = 4; break; // 9.5 -> 1.9 substep + } + } + // if mantissa fraction isnt 0.0 or 0.5, don't bother finding good sub tick marks, leave default + } + + return result; +} + +/* inherits documentation from base class */ +void QCPAxis::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + SelectablePart part = details.value(); + if (mSelectableParts.testFlag(part)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(additive ? mSelectedParts^part : part); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAxis::deselectEvent(bool *selectionStateChanged) +{ + SelectableParts selBefore = mSelectedParts; + setSelectedParts(mSelectedParts & ~mSelectableParts); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing axis lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPAxis::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeAxes); +} + +/*! \internal + + Draws the axis with the specified \a painter, using the internal QCPAxisPainterPrivate instance. + +*/ +void QCPAxis::draw(QCPPainter *painter) +{ + const int lowTick = mLowestVisibleTick; + const int highTick = mHighestVisibleTick; + QVector subTickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickLabels; // the final vector passed to QCPAxisPainter + tickPositions.reserve(highTick-lowTick+1); + tickLabels.reserve(highTick-lowTick+1); + subTickPositions.reserve(mSubTickVector.size()); + + if (mTicks) + { + for (int i=lowTick; i<=highTick; ++i) + { + tickPositions.append(coordToPixel(mTickVector.at(i))); + if (mTickLabels) + tickLabels.append(mTickVectorLabels.at(i)); + } + + if (mSubTickCount > 0) + { + const int subTickCount = mSubTickVector.size(); + for (int i=0; itype = mAxisType; + mAxisPainter->basePen = getBasePen(); + mAxisPainter->labelFont = getLabelFont(); + mAxisPainter->labelColor = getLabelColor(); + mAxisPainter->label = mLabel; + mAxisPainter->substituteExponent = mAutoTickLabels && mNumberBeautifulPowers && mTickLabelType == ltNumber; + mAxisPainter->tickPen = getTickPen(); + mAxisPainter->subTickPen = getSubTickPen(); + mAxisPainter->tickLabelFont = getTickLabelFont(); + mAxisPainter->tickLabelColor = getTickLabelColor(); + mAxisPainter->axisRect = mAxisRect->rect(); + mAxisPainter->viewportRect = mParentPlot->viewport(); + mAxisPainter->abbreviateDecimalPowers = mScaleType == stLogarithmic; + mAxisPainter->reversedEndings = mRangeReversed; + mAxisPainter->tickPositions = tickPositions; + mAxisPainter->tickLabels = tickLabels; + mAxisPainter->subTickPositions = subTickPositions; + mAxisPainter->draw(painter); +} + +/*! \internal + + Returns via \a lowIndex and \a highIndex, which ticks in the current tick vector are visible in + the current range. The return values are indices of the tick vector, not the positions of the + ticks themselves. + + The actual use of this function is when an external tick vector is provided, since it might + exceed far beyond the currently displayed range, and would cause unnecessary calculations e.g. of + subticks. + + If all ticks are outside the axis range, an inverted range is returned, i.e. highIndex will be + smaller than lowIndex. There is one case, where this function returns indices that are not really + visible in the current axis range: When the tick spacing is larger than the axis range size and + one tick is below the axis range and the next tick is already above the axis range. Because in + such cases it is usually desirable to know the tick pair, to draw proper subticks. +*/ +void QCPAxis::visibleTickBounds(int &lowIndex, int &highIndex) const +{ + bool lowFound = false; + bool highFound = false; + lowIndex = 0; + highIndex = -1; + + for (int i=0; i < mTickVector.size(); ++i) + { + if (mTickVector.at(i) >= mRange.lower) + { + lowFound = true; + lowIndex = i; + break; + } + } + for (int i=mTickVector.size()-1; i >= 0; --i) + { + if (mTickVector.at(i) <= mRange.upper) + { + highFound = true; + highIndex = i; + break; + } + } + + if (!lowFound && highFound) + lowIndex = highIndex+1; + else if (lowFound && !highFound) + highIndex = lowIndex-1; +} + +/*! \internal + + A log function with the base mScaleLogBase, used mostly for coordinate transforms in logarithmic + scales with arbitrary log base. Uses the buffered mScaleLogBaseLogInv for faster calculation. + This is set to 1.0/qLn(mScaleLogBase) in \ref setScaleLogBase. + + \see basePow, setScaleLogBase, setScaleType +*/ +double QCPAxis::baseLog(double value) const +{ + return qLn(value)*mScaleLogBaseLogInv; +} + +/*! \internal + + A power function with the base mScaleLogBase, used mostly for coordinate transforms in + logarithmic scales with arbitrary log base. + + \see baseLog, setScaleLogBase, setScaleType +*/ +double QCPAxis::basePow(double value) const +{ + return qPow(mScaleLogBase, value); +} + +/*! \internal + + Returns the pen that is used to draw the axis base line. Depending on the selection state, this + is either mSelectedBasePen or mBasePen. +*/ +QPen QCPAxis::getBasePen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedBasePen : mBasePen; +} + +/*! \internal + + Returns the pen that is used to draw the (major) ticks. Depending on the selection state, this + is either mSelectedTickPen or mTickPen. +*/ +QPen QCPAxis::getTickPen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedTickPen : mTickPen; +} + +/*! \internal + + Returns the pen that is used to draw the subticks. Depending on the selection state, this + is either mSelectedSubTickPen or mSubTickPen. +*/ +QPen QCPAxis::getSubTickPen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedSubTickPen : mSubTickPen; +} + +/*! \internal + + Returns the font that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelFont or mTickLabelFont. +*/ +QFont QCPAxis::getTickLabelFont() const +{ + return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelFont : mTickLabelFont; +} + +/*! \internal + + Returns the font that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelFont or mLabelFont. +*/ +QFont QCPAxis::getLabelFont() const +{ + return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelFont : mLabelFont; +} + +/*! \internal + + Returns the color that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelColor or mTickLabelColor. +*/ +QColor QCPAxis::getTickLabelColor() const +{ + return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelColor : mTickLabelColor; +} + +/*! \internal + + Returns the color that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelColor or mLabelColor. +*/ +QColor QCPAxis::getLabelColor() const +{ + return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelColor : mLabelColor; +} + +/*! \internal + + Returns the appropriate outward margin for this axis. It is needed if \ref + QCPAxisRect::setAutoMargins is set to true on the parent axis rect. An axis with axis type \ref + atLeft will return an appropriate left margin, \ref atBottom will return an appropriate bottom + margin and so forth. For the calculation, this function goes through similar steps as \ref draw, + so changing one function likely requires the modification of the other one as well. + + The margin consists of the outward tick length, tick label padding, tick label size, label + padding, label size, and padding. + + The margin is cached internally, so repeated calls while leaving the axis range, fonts, etc. + unchanged are very fast. +*/ +int QCPAxis::calculateMargin() +{ + if (!mVisible) // if not visible, directly return 0, don't cache 0 because we can't react to setVisible in QCPAxis + return 0; + + if (mCachedMarginValid) + return mCachedMargin; + + // run through similar steps as QCPAxis::draw, and caluclate margin needed to fit axis and its labels + int margin = 0; + + int lowTick, highTick; + visibleTickBounds(lowTick, highTick); + QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickLabels; // the final vector passed to QCPAxisPainter + tickPositions.reserve(highTick-lowTick+1); + tickLabels.reserve(highTick-lowTick+1); + if (mTicks) + { + for (int i=lowTick; i<=highTick; ++i) + { + tickPositions.append(coordToPixel(mTickVector.at(i))); + if (mTickLabels) + tickLabels.append(mTickVectorLabels.at(i)); + } + } + // transfer all properties of this axis to QCPAxisPainterPrivate which it needs to calculate the size. + // Note that some axis painter properties are already set by direct feed-through with QCPAxis setters + mAxisPainter->type = mAxisType; + mAxisPainter->labelFont = getLabelFont(); + mAxisPainter->label = mLabel; + mAxisPainter->tickLabelFont = mTickLabelFont; + mAxisPainter->axisRect = mAxisRect->rect(); + mAxisPainter->viewportRect = mParentPlot->viewport(); + mAxisPainter->tickPositions = tickPositions; + mAxisPainter->tickLabels = tickLabels; + margin += mAxisPainter->size(); + margin += mPadding; + + mCachedMargin = margin; + mCachedMarginValid = true; + return margin; +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAxis::selectionCategory() const +{ + return QCP::iSelectAxes; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisPainterPrivate +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxisPainterPrivate + + \internal + \brief (Private) + + This is a private class and not part of the public QCustomPlot interface. + + It is used by QCPAxis to do the low-level drawing of axis backbone, tick marks, tick labels and + axis label. It also buffers the labels to reduce replot times. The parameters are configured by + directly accessing the public member variables. +*/ + +/*! + Constructs a QCPAxisPainterPrivate instance. Make sure to not create a new instance on every + redraw, to utilize the caching mechanisms. +*/ +QCPAxisPainterPrivate::QCPAxisPainterPrivate(QCustomPlot *parentPlot) : + type(QCPAxis::atLeft), + basePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + lowerEnding(QCPLineEnding::esNone), + upperEnding(QCPLineEnding::esNone), + labelPadding(0), + tickLabelPadding(0), + tickLabelRotation(0), + tickLabelSide(QCPAxis::lsOutside), + substituteExponent(true), + numberMultiplyCross(false), + tickLengthIn(5), + tickLengthOut(0), + subTickLengthIn(2), + subTickLengthOut(0), + tickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + subTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + offset(0), + abbreviateDecimalPowers(false), + reversedEndings(false), + mParentPlot(parentPlot), + mLabelCache(16) // cache at most 16 (tick) labels +{ +} + +QCPAxisPainterPrivate::~QCPAxisPainterPrivate() +{ +} + +/*! \internal + + Draws the axis with the specified \a painter. + + The selection boxes (mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox) are set + here, too. +*/ +void QCPAxisPainterPrivate::draw(QCPPainter *painter) +{ + QByteArray newHash = generateLabelParameterHash(); + if (newHash != mLabelParameterHash) + { + mLabelCache.clear(); + mLabelParameterHash = newHash; + } + + QPoint origin; + switch (type) + { + case QCPAxis::atLeft: origin = axisRect.bottomLeft() +QPoint(-offset, 0); break; + case QCPAxis::atRight: origin = axisRect.bottomRight()+QPoint(+offset, 0); break; + case QCPAxis::atTop: origin = axisRect.topLeft() +QPoint(0, -offset); break; + case QCPAxis::atBottom: origin = axisRect.bottomLeft() +QPoint(0, +offset); break; + } + + double xCor = 0, yCor = 0; // paint system correction, for pixel exact matches (affects baselines and ticks of top/right axes) + switch (type) + { + case QCPAxis::atTop: yCor = -1; break; + case QCPAxis::atRight: xCor = 1; break; + default: break; + } + int margin = 0; + // draw baseline: + QLineF baseLine; + painter->setPen(basePen); + if (QCPAxis::orientation(type) == Qt::Horizontal) + baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(axisRect.width()+xCor, yCor)); + else + baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(xCor, -axisRect.height()+yCor)); + if (reversedEndings) + baseLine = QLineF(baseLine.p2(), baseLine.p1()); // won't make a difference for line itself, but for line endings later + painter->drawLine(baseLine); + + // draw ticks: + if (!tickPositions.isEmpty()) + { + painter->setPen(tickPen); + int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; // direction of ticks ("inward" is right for left axis and left for right axis) + if (QCPAxis::orientation(type) == Qt::Horizontal) + { + for (int i=0; idrawLine(QLineF(tickPositions.at(i)+xCor, origin.y()-tickLengthOut*tickDir+yCor, tickPositions.at(i)+xCor, origin.y()+tickLengthIn*tickDir+yCor)); + } else + { + for (int i=0; idrawLine(QLineF(origin.x()-tickLengthOut*tickDir+xCor, tickPositions.at(i)+yCor, origin.x()+tickLengthIn*tickDir+xCor, tickPositions.at(i)+yCor)); + } + } + + // draw subticks: + if (!subTickPositions.isEmpty()) + { + painter->setPen(subTickPen); + // direction of ticks ("inward" is right for left axis and left for right axis) + int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; + if (QCPAxis::orientation(type) == Qt::Horizontal) + { + for (int i=0; idrawLine(QLineF(subTickPositions.at(i)+xCor, origin.y()-subTickLengthOut*tickDir+yCor, subTickPositions.at(i)+xCor, origin.y()+subTickLengthIn*tickDir+yCor)); + } else + { + for (int i=0; idrawLine(QLineF(origin.x()-subTickLengthOut*tickDir+xCor, subTickPositions.at(i)+yCor, origin.x()+subTickLengthIn*tickDir+xCor, subTickPositions.at(i)+yCor)); + } + } + margin += qMax(0, qMax(tickLengthOut, subTickLengthOut)); + + // draw axis base endings: + bool antialiasingBackup = painter->antialiasing(); + painter->setAntialiasing(true); // always want endings to be antialiased, even if base and ticks themselves aren't + painter->setBrush(QBrush(basePen.color())); + QVector2D baseLineVector(baseLine.dx(), baseLine.dy()); + if (lowerEnding.style() != QCPLineEnding::esNone) + lowerEnding.draw(painter, QVector2D(baseLine.p1())-baseLineVector.normalized()*lowerEnding.realLength()*(lowerEnding.inverted()?-1:1), -baseLineVector); + if (upperEnding.style() != QCPLineEnding::esNone) + upperEnding.draw(painter, QVector2D(baseLine.p2())+baseLineVector.normalized()*upperEnding.realLength()*(upperEnding.inverted()?-1:1), baseLineVector); + painter->setAntialiasing(antialiasingBackup); + + // tick labels: + QRect oldClipRect; + if (tickLabelSide == QCPAxis::lsInside) // if using inside labels, clip them to the axis rect + { + oldClipRect = painter->clipRegion().boundingRect(); + painter->setClipRect(axisRect); + } + QSize tickLabelsSize(0, 0); // size of largest tick label, for offset calculation of axis label + if (!tickLabels.isEmpty()) + { + if (tickLabelSide == QCPAxis::lsOutside) + margin += tickLabelPadding; + painter->setFont(tickLabelFont); + painter->setPen(QPen(tickLabelColor)); + const int maxLabelIndex = qMin(tickPositions.size(), tickLabels.size()); + int distanceToAxis = margin; + if (tickLabelSide == QCPAxis::lsInside) + distanceToAxis = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); + for (int i=0; isetClipRect(oldClipRect); + + // axis label: + QRect labelBounds; + if (!label.isEmpty()) + { + margin += labelPadding; + painter->setFont(labelFont); + painter->setPen(QPen(labelColor)); + labelBounds = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip, label); + if (type == QCPAxis::atLeft) + { + QTransform oldTransform = painter->transform(); + painter->translate((origin.x()-margin-labelBounds.height()), origin.y()); + painter->rotate(-90); + painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + painter->setTransform(oldTransform); + } + else if (type == QCPAxis::atRight) + { + QTransform oldTransform = painter->transform(); + painter->translate((origin.x()+margin+labelBounds.height()), origin.y()-axisRect.height()); + painter->rotate(90); + painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + painter->setTransform(oldTransform); + } + else if (type == QCPAxis::atTop) + painter->drawText(origin.x(), origin.y()-margin-labelBounds.height(), axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + else if (type == QCPAxis::atBottom) + painter->drawText(origin.x(), origin.y()+margin, axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + } + + // set selection boxes: + int selectionTolerance = 0; + if (mParentPlot) + selectionTolerance = mParentPlot->selectionTolerance(); + else + qDebug() << Q_FUNC_INFO << "mParentPlot is null"; + int selAxisOutSize = qMax(qMax(tickLengthOut, subTickLengthOut), selectionTolerance); + int selAxisInSize = selectionTolerance; + int selTickLabelSize; + int selTickLabelOffset; + if (tickLabelSide == QCPAxis::lsOutside) + { + selTickLabelSize = (QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); + selTickLabelOffset = qMax(tickLengthOut, subTickLengthOut)+tickLabelPadding; + } else + { + selTickLabelSize = -(QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); + selTickLabelOffset = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); + } + int selLabelSize = labelBounds.height(); + int selLabelOffset = qMax(tickLengthOut, subTickLengthOut)+(!tickLabels.isEmpty() && tickLabelSide == QCPAxis::lsOutside ? tickLabelPadding+selTickLabelSize : 0)+labelPadding; + if (type == QCPAxis::atLeft) + { + mAxisSelectionBox.setCoords(origin.x()-selAxisOutSize, axisRect.top(), origin.x()+selAxisInSize, axisRect.bottom()); + mTickLabelsSelectionBox.setCoords(origin.x()-selTickLabelOffset-selTickLabelSize, axisRect.top(), origin.x()-selTickLabelOffset, axisRect.bottom()); + mLabelSelectionBox.setCoords(origin.x()-selLabelOffset-selLabelSize, axisRect.top(), origin.x()-selLabelOffset, axisRect.bottom()); + } else if (type == QCPAxis::atRight) + { + mAxisSelectionBox.setCoords(origin.x()-selAxisInSize, axisRect.top(), origin.x()+selAxisOutSize, axisRect.bottom()); + mTickLabelsSelectionBox.setCoords(origin.x()+selTickLabelOffset+selTickLabelSize, axisRect.top(), origin.x()+selTickLabelOffset, axisRect.bottom()); + mLabelSelectionBox.setCoords(origin.x()+selLabelOffset+selLabelSize, axisRect.top(), origin.x()+selLabelOffset, axisRect.bottom()); + } else if (type == QCPAxis::atTop) + { + mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisOutSize, axisRect.right(), origin.y()+selAxisInSize); + mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()-selTickLabelOffset-selTickLabelSize, axisRect.right(), origin.y()-selTickLabelOffset); + mLabelSelectionBox.setCoords(axisRect.left(), origin.y()-selLabelOffset-selLabelSize, axisRect.right(), origin.y()-selLabelOffset); + } else if (type == QCPAxis::atBottom) + { + mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisInSize, axisRect.right(), origin.y()+selAxisOutSize); + mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()+selTickLabelOffset+selTickLabelSize, axisRect.right(), origin.y()+selTickLabelOffset); + mLabelSelectionBox.setCoords(axisRect.left(), origin.y()+selLabelOffset+selLabelSize, axisRect.right(), origin.y()+selLabelOffset); + } + mAxisSelectionBox = mAxisSelectionBox.normalized(); + mTickLabelsSelectionBox = mTickLabelsSelectionBox.normalized(); + mLabelSelectionBox = mLabelSelectionBox.normalized(); + // draw hitboxes for debug purposes: + //painter->setBrush(Qt::NoBrush); + //painter->drawRects(QVector() << mAxisSelectionBox << mTickLabelsSelectionBox << mLabelSelectionBox); +} + +/*! \internal + + Returns the size ("margin" in QCPAxisRect context, so measured perpendicular to the axis backbone + direction) needed to fit the axis. +*/ +int QCPAxisPainterPrivate::size() const +{ + int result = 0; + + // get length of tick marks pointing outwards: + if (!tickPositions.isEmpty()) + result += qMax(0, qMax(tickLengthOut, subTickLengthOut)); + + // calculate size of tick labels: + if (tickLabelSide == QCPAxis::lsOutside) + { + QSize tickLabelsSize(0, 0); + if (!tickLabels.isEmpty()) + { + for (int i=0; iplottingHints().testFlag(QCP::phCacheLabels) && !painter->modes().testFlag(QCPPainter::pmNoCaching)) // label caching enabled + { + CachedLabel *cachedLabel = mLabelCache.take(text); // attempt to get label from cache + if (!cachedLabel) // no cached label existed, create it + { + cachedLabel = new CachedLabel; + TickLabelData labelData = getTickLabelData(painter->font(), text); + cachedLabel->offset = getTickLabelDrawOffset(labelData)+labelData.rotatedTotalBounds.topLeft(); + cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()); + cachedLabel->pixmap.fill(Qt::transparent); + QCPPainter cachePainter(&cachedLabel->pixmap); + cachePainter.setPen(painter->pen()); + drawTickLabel(&cachePainter, -labelData.rotatedTotalBounds.topLeft().x(), -labelData.rotatedTotalBounds.topLeft().y(), labelData); + } + // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): + bool labelClippedByBorder = false; + if (tickLabelSide == QCPAxis::lsOutside) + { + if (QCPAxis::orientation(type) == Qt::Horizontal) + labelClippedByBorder = labelAnchor.x()+cachedLabel->offset.x()+cachedLabel->pixmap.width() > viewportRect.right() || labelAnchor.x()+cachedLabel->offset.x() < viewportRect.left(); + else + labelClippedByBorder = labelAnchor.y()+cachedLabel->offset.y()+cachedLabel->pixmap.height() > viewportRect.bottom() || labelAnchor.y()+cachedLabel->offset.y() < viewportRect.top(); + } + if (!labelClippedByBorder) + { + painter->drawPixmap(labelAnchor+cachedLabel->offset, cachedLabel->pixmap); + finalSize = cachedLabel->pixmap.size(); + } + mLabelCache.insert(text, cachedLabel); // return label to cache or insert for the first time if newly created + } else // label caching disabled, draw text directly on surface: + { + TickLabelData labelData = getTickLabelData(painter->font(), text); + QPointF finalPosition = labelAnchor + getTickLabelDrawOffset(labelData); + // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): + bool labelClippedByBorder = false; + if (tickLabelSide == QCPAxis::lsOutside) + { + if (QCPAxis::orientation(type) == Qt::Horizontal) + labelClippedByBorder = finalPosition.x()+(labelData.rotatedTotalBounds.width()+labelData.rotatedTotalBounds.left()) > viewportRect.right() || finalPosition.x()+labelData.rotatedTotalBounds.left() < viewportRect.left(); + else + labelClippedByBorder = finalPosition.y()+(labelData.rotatedTotalBounds.height()+labelData.rotatedTotalBounds.top()) > viewportRect.bottom() || finalPosition.y()+labelData.rotatedTotalBounds.top() < viewportRect.top(); + } + if (!labelClippedByBorder) + { + drawTickLabel(painter, finalPosition.x(), finalPosition.y(), labelData); + finalSize = labelData.rotatedTotalBounds.size(); + } + } + + // expand passed tickLabelsSize if current tick label is larger: + if (finalSize.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(finalSize.width()); + if (finalSize.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(finalSize.height()); +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Draws the tick label specified in \a labelData with \a painter at the pixel positions \a x and \a + y. This function is used by \ref placeTickLabel to create new tick labels for the cache, or to + directly draw the labels on the QCustomPlot surface when label caching is disabled, i.e. when + QCP::phCacheLabels plotting hint is not set. +*/ +void QCPAxisPainterPrivate::drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const +{ + // backup painter settings that we're about to change: + QTransform oldTransform = painter->transform(); + QFont oldFont = painter->font(); + + // transform painter to position/rotation: + painter->translate(x, y); + if (!qFuzzyIsNull(tickLabelRotation)) + painter->rotate(tickLabelRotation); + + // draw text: + if (!labelData.expPart.isEmpty()) // indicator that beautiful powers must be used + { + painter->setFont(labelData.baseFont); + painter->drawText(0, 0, 0, 0, Qt::TextDontClip, labelData.basePart); + painter->setFont(labelData.expFont); + painter->drawText(labelData.baseBounds.width()+1, 0, labelData.expBounds.width(), labelData.expBounds.height(), Qt::TextDontClip, labelData.expPart); + } else + { + painter->setFont(labelData.baseFont); + painter->drawText(0, 0, labelData.totalBounds.width(), labelData.totalBounds.height(), Qt::TextDontClip | Qt::AlignHCenter, labelData.basePart); + } + + // reset painter settings to what it was before: + painter->setTransform(oldTransform); + painter->setFont(oldFont); +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Transforms the passed \a text and \a font to a tickLabelData structure that can then be further + processed by \ref getTickLabelDrawOffset and \ref drawTickLabel. It splits the text into base and + exponent if necessary (member substituteExponent) and calculates appropriate bounding boxes. +*/ +QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(const QFont &font, const QString &text) const +{ + TickLabelData result; + + // determine whether beautiful decimal powers should be used + bool useBeautifulPowers = false; + int ePos = -1; // first index of exponent part, text before that will be basePart, text until eLast will be expPart + int eLast = -1; // last index of exponent part, rest of text after this will be suffixPart + if (substituteExponent) + { + ePos = text.indexOf(QLatin1Char('e')); + if (ePos > 0 && text.at(ePos-1).isDigit()) + { + eLast = ePos; + while (eLast+1 < text.size() && (text.at(eLast+1) == QLatin1Char('+') || text.at(eLast+1) == QLatin1Char('-') || text.at(eLast+1).isDigit())) + ++eLast; + if (eLast > ePos) // only if also to right of 'e' is a digit/+/- interpret it as beautifiable power + useBeautifulPowers = true; + } + } + + // calculate text bounding rects and do string preparation for beautiful decimal powers: + result.baseFont = font; + if (result.baseFont.pointSizeF() > 0) // might return -1 if specified with setPixelSize, in that case we can't do correction in next line + result.baseFont.setPointSizeF(result.baseFont.pointSizeF()+0.05); // QFontMetrics.boundingRect has a bug for exact point sizes that make the results oscillate due to internal rounding + if (useBeautifulPowers) + { + // split text into parts of number/symbol that will be drawn normally and part that will be drawn as exponent: + result.basePart = text.left(ePos); + // in log scaling, we want to turn "1*10^n" into "10^n", else add multiplication sign and decimal base: + if (abbreviateDecimalPowers && result.basePart == QLatin1String("1")) + result.basePart = QLatin1String("10"); + else + result.basePart += (numberMultiplyCross ? QString(QChar(215)) : QString(QChar(183))) + QLatin1String("10"); + result.expPart = text.mid(ePos+1); + // clip "+" and leading zeros off expPart: + while (result.expPart.length() > 2 && result.expPart.at(1) == QLatin1Char('0')) // length > 2 so we leave one zero when numberFormatChar is 'e' + result.expPart.remove(1, 1); + if (!result.expPart.isEmpty() && result.expPart.at(0) == QLatin1Char('+')) + result.expPart.remove(0, 1); + // prepare smaller font for exponent: + result.expFont = font; + if (result.expFont.pointSize() > 0) + result.expFont.setPointSize(result.expFont.pointSize()*0.75); + else + result.expFont.setPixelSize(result.expFont.pixelSize()*0.75); + // calculate bounding rects of base part, exponent part and total one: + result.baseBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.basePart); + result.expBounds = QFontMetrics(result.expFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.expPart); + result.totalBounds = result.baseBounds.adjusted(0, 0, result.expBounds.width()+2, 0); // +2 consists of the 1 pixel spacing between base and exponent (see drawTickLabel) and an extra pixel to include AA + } else // useBeautifulPowers == false + { + result.basePart = text; + result.totalBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, result.basePart); + } + result.totalBounds.moveTopLeft(QPoint(0, 0)); // want bounding box aligned top left at origin, independent of how it was created, to make further processing simpler + + // calculate possibly different bounding rect after rotation: + result.rotatedTotalBounds = result.totalBounds; + if (!qFuzzyIsNull(tickLabelRotation)) + { + QTransform transform; + transform.rotate(tickLabelRotation); + result.rotatedTotalBounds = transform.mapRect(result.rotatedTotalBounds); + } + + return result; +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Calculates the offset at which the top left corner of the specified tick label shall be drawn. + The offset is relative to a point right next to the tick the label belongs to. + + This function is thus responsible for e.g. centering tick labels under ticks and positioning them + appropriately when they are rotated. +*/ +QPointF QCPAxisPainterPrivate::getTickLabelDrawOffset(const TickLabelData &labelData) const +{ + /* + calculate label offset from base point at tick (non-trivial, for best visual appearance): short + explanation for bottom axis: The anchor, i.e. the point in the label that is placed + horizontally under the corresponding tick is always on the label side that is closer to the + axis (e.g. the left side of the text when we're rotating clockwise). On that side, the height + is halved and the resulting point is defined the anchor. This way, a 90 degree rotated text + will be centered under the tick (i.e. displaced horizontally by half its height). At the same + time, a 45 degree rotated text will "point toward" its tick, as is typical for rotated tick + labels. + */ + bool doRotation = !qFuzzyIsNull(tickLabelRotation); + bool flip = qFuzzyCompare(qAbs(tickLabelRotation), 90.0); // perfect +/-90 degree flip. Indicates vertical label centering on vertical axes. + double radians = tickLabelRotation/180.0*M_PI; + int x=0, y=0; + if ((type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsInside)) // Anchor at right side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = -qCos(radians)*labelData.totalBounds.width(); + y = flip ? -labelData.totalBounds.width()/2.0 : -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height()/2.0; + } else + { + x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height(); + y = flip ? +labelData.totalBounds.width()/2.0 : +qSin(-radians)*labelData.totalBounds.width()-qCos(-radians)*labelData.totalBounds.height()/2.0; + } + } else + { + x = -labelData.totalBounds.width(); + y = -labelData.totalBounds.height()/2.0; + } + } else if ((type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsInside)) // Anchor at left side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = +qSin(radians)*labelData.totalBounds.height(); + y = flip ? -labelData.totalBounds.width()/2.0 : -qCos(radians)*labelData.totalBounds.height()/2.0; + } else + { + x = 0; + y = flip ? +labelData.totalBounds.width()/2.0 : -qCos(-radians)*labelData.totalBounds.height()/2.0; + } + } else + { + x = 0; + y = -labelData.totalBounds.height()/2.0; + } + } else if ((type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsInside)) // Anchor at bottom side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = -qCos(radians)*labelData.totalBounds.width()+qSin(radians)*labelData.totalBounds.height()/2.0; + y = -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height(); + } else + { + x = -qSin(-radians)*labelData.totalBounds.height()/2.0; + y = -qCos(-radians)*labelData.totalBounds.height(); + } + } else + { + x = -labelData.totalBounds.width()/2.0; + y = -labelData.totalBounds.height(); + } + } else if ((type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsInside)) // Anchor at top side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = +qSin(radians)*labelData.totalBounds.height()/2.0; + y = 0; + } else + { + x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height()/2.0; + y = +qSin(-radians)*labelData.totalBounds.width(); + } + } else + { + x = -labelData.totalBounds.width()/2.0; + y = 0; + } + } + + return QPointF(x, y); +} + +/*! \internal + + Simulates the steps done by \ref placeTickLabel by calculating bounding boxes of the text label + to be drawn, depending on number format etc. Since only the largest tick label is wanted for the + margin calculation, the passed \a tickLabelsSize is only expanded, if it's currently set to a + smaller width/height. +*/ +void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const +{ + // note: this function must return the same tick label sizes as the placeTickLabel function. + QSize finalSize; + if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && mLabelCache.contains(text)) // label caching enabled and have cached label + { + const CachedLabel *cachedLabel = mLabelCache.object(text); + finalSize = cachedLabel->pixmap.size(); + } else // label caching disabled or no label with this text cached: + { + TickLabelData labelData = getTickLabelData(font, text); + finalSize = labelData.rotatedTotalBounds.size(); + } + + // expand passed tickLabelsSize if current tick label is larger: + if (finalSize.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(finalSize.width()); + if (finalSize.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(finalSize.height()); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPlottable +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPlottable + \brief The abstract base class for all data representing objects in a plot. + + It defines a very basic interface like name, pen, brush, visibility etc. Since this class is + abstract, it can't be instantiated. Use one of the subclasses or create a subclass yourself to + create new ways of displaying data (see "Creating own plottables" below). + + All further specifics are in the subclasses, for example: + \li A normal graph with possibly a line, scatter points and error bars: \ref QCPGraph + (typically created with \ref QCustomPlot::addGraph) + \li A parametric curve: \ref QCPCurve + \li A bar chart: \ref QCPBars + \li A statistical box plot: \ref QCPStatisticalBox + \li A color encoded two-dimensional map: \ref QCPColorMap + \li An OHLC/Candlestick chart: \ref QCPFinancial + + \section plottables-subclassing Creating own plottables + + To create an own plottable, you implement a subclass of QCPAbstractPlottable. These are the pure + virtual functions, you must implement: + \li \ref clearData + \li \ref selectTest + \li \ref draw + \li \ref drawLegendIcon + \li \ref getKeyRange + \li \ref getValueRange + + See the documentation of those functions for what they need to do. + + For drawing your plot, you can use the \ref coordsToPixels functions to translate a point in plot + coordinates to pixel coordinates. This function is quite convenient, because it takes the + orientation of the key and value axes into account for you (x and y are swapped when the key axis + is vertical and the value axis horizontal). If you are worried about performance (i.e. you need + to translate many points in a loop like QCPGraph), you can directly use \ref + QCPAxis::coordToPixel. However, you must then take care about the orientation of the axis + yourself. + + Here are some important members you inherit from QCPAbstractPlottable: + + + + + + + + + + + + + + + + + + + + + + + + + + +
QCustomPlot *\b mParentPlotA pointer to the parent QCustomPlot instance. The parent plot is inferred from the axes that are passed in the constructor.
QString \b mNameThe name of the plottable.
QPen \b mPenThe generic pen of the plottable. You should use this pen for the most prominent data representing lines in the plottable (e.g QCPGraph uses this pen for its graph lines and scatters)
QPen \b mSelectedPenThe generic pen that should be used when the plottable is selected (hint: \ref mainPen gives you the right pen, depending on selection state).
QBrush \b mBrushThe generic brush of the plottable. You should use this brush for the most prominent fillable structures in the plottable (e.g. QCPGraph uses this brush to control filling under the graph)
QBrush \b mSelectedBrushThe generic brush that should be used when the plottable is selected (hint: \ref mainBrush gives you the right brush, depending on selection state).
QPointer\b mKeyAxis, \b mValueAxisThe key and value axes this plottable is attached to. Call their QCPAxis::coordToPixel functions to translate coordinates to pixels in either the key or value dimension. + Make sure to check whether the pointer is null before using it. If one of the axes is null, don't draw the plottable.
bool \b mSelectedindicates whether the plottable is selected or not.
+*/ + +/* start of documentation of pure virtual functions */ + +/*! \fn void QCPAbstractPlottable::clearData() = 0 + Clears all data in the plottable. +*/ + +/*! \fn void QCPAbstractPlottable::drawLegendIcon(QCPPainter *painter, const QRect &rect) const = 0 + \internal + + called by QCPLegend::draw (via QCPPlottableLegendItem::draw) to create a graphical representation + of this plottable inside \a rect, next to the plottable name. + + The passed \a painter has its cliprect set to \a rect, so painting outside of \a rect won't + appear outside the legend icon border. +*/ + +/*! \fn QCPRange QCPAbstractPlottable::getKeyRange(bool &foundRange, SignDomain inSignDomain) const = 0 + \internal + + called by rescaleAxes functions to get the full data key bounds. For logarithmic plots, one can + set \a inSignDomain to either \ref sdNegative or \ref sdPositive in order to restrict the + returned range to that sign domain. E.g. when only negative range is wanted, set \a inSignDomain + to \ref sdNegative and all positive points will be ignored for range calculation. For no + restriction, just set \a inSignDomain to \ref sdBoth (default). \a foundRange is an output + parameter that indicates whether a range could be found or not. If this is false, you shouldn't + use the returned range (e.g. no points in data). + + Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by + this function may have size zero, which wouldn't count as a valid range. + + \see rescaleAxes, getValueRange +*/ + +/*! \fn QCPRange QCPAbstractPlottable::getValueRange(bool &foundRange, SignDomain inSignDomain) const = 0 + \internal + + called by rescaleAxes functions to get the full data value bounds. For logarithmic plots, one can + set \a inSignDomain to either \ref sdNegative or \ref sdPositive in order to restrict the + returned range to that sign domain. E.g. when only negative range is wanted, set \a inSignDomain + to \ref sdNegative and all positive points will be ignored for range calculation. For no + restriction, just set \a inSignDomain to \ref sdBoth (default). \a foundRange is an output + parameter that indicates whether a range could be found or not. If this is false, you shouldn't + use the returned range (e.g. no points in data). + + Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by + this function may have size zero, which wouldn't count as a valid range. + + \see rescaleAxes, getKeyRange +*/ + +/* end of documentation of pure virtual functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAbstractPlottable::selectionChanged(bool selected) + + This signal is emitted when the selection state of this plottable has changed, either by user + interaction or by a direct call to \ref setSelected. +*/ + +/*! \fn void QCPAbstractPlottable::selectableChanged(bool selectable); + + This signal is emitted when the selectability of this plottable has changed. + + \see setSelectable +*/ + +/* end of documentation of signals */ + +/*! + Constructs an abstract plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as + its value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance + and have perpendicular orientations. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + Since QCPAbstractPlottable is an abstract class that defines the basic interface to plottables, + it can't be directly instantiated. + + You probably want one of the subclasses like \ref QCPGraph or \ref QCPCurve instead. +*/ +QCPAbstractPlottable::QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPLayerable(keyAxis->parentPlot(), QString(), keyAxis->axisRect()), + mName(), + mAntialiasedFill(true), + mAntialiasedScatters(true), + mAntialiasedErrorBars(false), + mPen(Qt::black), + mSelectedPen(Qt::black), + mBrush(Qt::NoBrush), + mSelectedBrush(Qt::NoBrush), + mKeyAxis(keyAxis), + mValueAxis(valueAxis), + mSelectable(true), + mSelected(false) +{ + if (keyAxis->parentPlot() != valueAxis->parentPlot()) + qDebug() << Q_FUNC_INFO << "Parent plot of keyAxis is not the same as that of valueAxis."; + if (keyAxis->orientation() == valueAxis->orientation()) + qDebug() << Q_FUNC_INFO << "keyAxis and valueAxis must be orthogonal to each other."; +} + +/*! + The name is the textual representation of this plottable as it is displayed in the legend + (\ref QCPLegend). It may contain any UTF-8 characters, including newlines. +*/ +void QCPAbstractPlottable::setName(const QString &name) +{ + mName = name; +} + +/*! + Sets whether fills of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedFill(bool enabled) +{ + mAntialiasedFill = enabled; +} + +/*! + Sets whether the scatter symbols of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedScatters(bool enabled) +{ + mAntialiasedScatters = enabled; +} + +/*! + Sets whether the error bars of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedErrorBars(bool enabled) +{ + mAntialiasedErrorBars = enabled; +} + + +/*! + The pen is used to draw basic lines that make up the plottable representation in the + plot. + + For example, the \ref QCPGraph subclass draws its graph lines with this pen. + + \see setBrush +*/ +void QCPAbstractPlottable::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + When the plottable is selected, this pen is used to draw basic lines instead of the normal + pen set via \ref setPen. + + \see setSelected, setSelectable, setSelectedBrush, selectTest +*/ +void QCPAbstractPlottable::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + The brush is used to draw basic fills of the plottable representation in the + plot. The Fill can be a color, gradient or texture, see the usage of QBrush. + + For example, the \ref QCPGraph subclass draws the fill under the graph with this brush, when + it's not set to Qt::NoBrush. + + \see setPen +*/ +void QCPAbstractPlottable::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + When the plottable is selected, this brush is used to draw fills instead of the normal + brush set via \ref setBrush. + + \see setSelected, setSelectable, setSelectedPen, selectTest +*/ +void QCPAbstractPlottable::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + The key axis of a plottable can be set to any axis of a QCustomPlot, as long as it is orthogonal + to the plottable's value axis. This function performs no checks to make sure this is the case. + The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and the + y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setValueAxis +*/ +void QCPAbstractPlottable::setKeyAxis(QCPAxis *axis) +{ + mKeyAxis = axis; +} + +/*! + The value axis of a plottable can be set to any axis of a QCustomPlot, as long as it is + orthogonal to the plottable's key axis. This function performs no checks to make sure this is the + case. The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and + the y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setKeyAxis +*/ +void QCPAbstractPlottable::setValueAxis(QCPAxis *axis) +{ + mValueAxis = axis; +} + +/*! + Sets whether the user can (de-)select this plottable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains iSelectPlottables.) + + However, even when \a selectable was set to false, it is possible to set the selection manually, + by calling \ref setSelected directly. + + \see setSelected +*/ +void QCPAbstractPlottable::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets whether this plottable is selected or not. When selected, it uses a different pen and brush + to draw its lines and fills, see \ref setSelectedPen and \ref setSelectedBrush. + + The entire selection mechanism for plottables is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectPlottables. You only need to call this function when + you wish to change the selection state manually. + + This function can change the selection state even when \ref setSelectable was set to false. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see setSelectable, selectTest +*/ +void QCPAbstractPlottable::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/*! + Rescales the key and value axes associated with this plottable to contain all displayed data, so + the whole plottable is visible. If the scaling of an axis is logarithmic, rescaleAxes will make + sure not to rescale to an illegal range i.e. a range containing different signs and/or zero. + Instead it will stay in the current sign domain and ignore all parts of the plottable that lie + outside of that domain. + + \a onlyEnlarge makes sure the ranges are only expanded, never reduced. So it's possible to show + multiple plottables in their entirety by multiple calls to rescaleAxes where the first call has + \a onlyEnlarge set to false (the default), and all subsequent set to true. + + \see rescaleKeyAxis, rescaleValueAxis, QCustomPlot::rescaleAxes, QCPAxis::rescale +*/ +void QCPAbstractPlottable::rescaleAxes(bool onlyEnlarge) const +{ + rescaleKeyAxis(onlyEnlarge); + rescaleValueAxis(onlyEnlarge); +} + +/*! + Rescales the key axis of the plottable so the whole plottable is visible. + + See \ref rescaleAxes for detailed behaviour. +*/ +void QCPAbstractPlottable::rescaleKeyAxis(bool onlyEnlarge) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + if (!keyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } + + SignDomain signDomain = sdBoth; + if (keyAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (keyAxis->range().upper < 0 ? sdNegative : sdPositive); + + bool foundRange; + QCPRange newRange = getKeyRange(foundRange, signDomain); + if (foundRange) + { + if (onlyEnlarge) + newRange.expand(keyAxis->range()); + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (keyAxis->scaleType() == QCPAxis::stLinear) + { + newRange.lower = center-keyAxis->range().size()/2.0; + newRange.upper = center+keyAxis->range().size()/2.0; + } else // scaleType() == stLogarithmic + { + newRange.lower = center/qSqrt(keyAxis->range().upper/keyAxis->range().lower); + newRange.upper = center*qSqrt(keyAxis->range().upper/keyAxis->range().lower); + } + } + keyAxis->setRange(newRange); + } +} + +/*! + Rescales the value axis of the plottable so the whole plottable is visible. + + Returns true if the axis was actually scaled. This might not be the case if this plottable has an + invalid range, e.g. because it has no data points. + + See \ref rescaleAxes for detailed behaviour. +*/ +void QCPAbstractPlottable::rescaleValueAxis(bool onlyEnlarge) const +{ + QCPAxis *valueAxis = mValueAxis.data(); + if (!valueAxis) { qDebug() << Q_FUNC_INFO << "invalid value axis"; return; } + + SignDomain signDomain = sdBoth; + if (valueAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (valueAxis->range().upper < 0 ? sdNegative : sdPositive); + + bool foundRange; + QCPRange newRange = getValueRange(foundRange, signDomain); + if (foundRange) + { + if (onlyEnlarge) + newRange.expand(valueAxis->range()); + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (valueAxis->scaleType() == QCPAxis::stLinear) + { + newRange.lower = center-valueAxis->range().size()/2.0; + newRange.upper = center+valueAxis->range().size()/2.0; + } else // scaleType() == stLogarithmic + { + newRange.lower = center/qSqrt(valueAxis->range().upper/valueAxis->range().lower); + newRange.upper = center*qSqrt(valueAxis->range().upper/valueAxis->range().lower); + } + } + valueAxis->setRange(newRange); + } +} + +/*! + Adds this plottable to the legend of the parent QCustomPlot (QCustomPlot::legend). + + Normally, a QCPPlottableLegendItem is created and inserted into the legend. If the plottable + needs a more specialized representation in the legend, this function will take this into account + and instead create the specialized subclass of QCPAbstractLegendItem. + + Returns true on success, i.e. when the legend exists and a legend item associated with this plottable isn't already in + the legend. + + \see removeFromLegend, QCPLegend::addItem +*/ +bool QCPAbstractPlottable::addToLegend() +{ + if (!mParentPlot || !mParentPlot->legend) + return false; + + if (!mParentPlot->legend->hasItemWithPlottable(this)) + { + mParentPlot->legend->addItem(new QCPPlottableLegendItem(mParentPlot->legend, this)); + return true; + } else + return false; +} + +/*! + Removes the plottable from the legend of the parent QCustomPlot. This means the + QCPAbstractLegendItem (usually a QCPPlottableLegendItem) that is associated with this plottable + is removed. + + Returns true on success, i.e. if the legend exists and a legend item associated with this + plottable was found and removed. + + \see addToLegend, QCPLegend::removeItem +*/ +bool QCPAbstractPlottable::removeFromLegend() const +{ + if (!mParentPlot->legend) + return false; + + if (QCPPlottableLegendItem *lip = mParentPlot->legend->itemWithPlottable(this)) + return mParentPlot->legend->removeItem(lip); + else + return false; +} + +/* inherits documentation from base class */ +QRect QCPAbstractPlottable::clipRect() const +{ + if (mKeyAxis && mValueAxis) + return mKeyAxis.data()->axisRect()->rect() & mValueAxis.data()->axisRect()->rect(); + else + return QRect(); +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractPlottable::selectionCategory() const +{ + return QCP::iSelectPlottables; +} + +/*! \internal + + Convenience function for transforming a key/value pair to pixels on the QCustomPlot surface, + taking the orientations of the axes associated with this plottable into account (e.g. whether key + represents x or y). + + \a key and \a value are transformed to the coodinates in pixels and are written to \a x and \a y. + + \see pixelsToCoords, QCPAxis::coordToPixel +*/ +void QCPAbstractPlottable::coordsToPixels(double key, double value, double &x, double &y) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + x = keyAxis->coordToPixel(key); + y = valueAxis->coordToPixel(value); + } else + { + y = keyAxis->coordToPixel(key); + x = valueAxis->coordToPixel(value); + } +} + +/*! \internal + \overload + + Returns the input as pixel coordinates in a QPointF. +*/ +const QPointF QCPAbstractPlottable::coordsToPixels(double key, double value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + if (keyAxis->orientation() == Qt::Horizontal) + return QPointF(keyAxis->coordToPixel(key), valueAxis->coordToPixel(value)); + else + return QPointF(valueAxis->coordToPixel(value), keyAxis->coordToPixel(key)); +} + +/*! \internal + + Convenience function for transforming a x/y pixel pair on the QCustomPlot surface to plot coordinates, + taking the orientations of the axes associated with this plottable into account (e.g. whether key + represents x or y). + + \a x and \a y are transformed to the plot coodinates and are written to \a key and \a value. + + \see coordsToPixels, QCPAxis::coordToPixel +*/ +void QCPAbstractPlottable::pixelsToCoords(double x, double y, double &key, double &value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + key = keyAxis->pixelToCoord(x); + value = valueAxis->pixelToCoord(y); + } else + { + key = keyAxis->pixelToCoord(y); + value = valueAxis->pixelToCoord(x); + } +} + +/*! \internal + \overload + + Returns the pixel input \a pixelPos as plot coordinates \a key and \a value. +*/ +void QCPAbstractPlottable::pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const +{ + pixelsToCoords(pixelPos.x(), pixelPos.y(), key, value); +} + +/*! \internal + + Returns the pen that should be used for drawing lines of the plottable. Returns mPen when the + graph is not selected and mSelectedPen when it is. +*/ +QPen QCPAbstractPlottable::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the plottable. Returns mBrush when the + graph is not selected and mSelectedBrush when it is. +*/ +QBrush QCPAbstractPlottable::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyFillAntialiasingHint, applyScattersAntialiasingHint, applyErrorBarsAntialiasingHint +*/ +void QCPAbstractPlottable::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aePlottables); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable fills. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyDefaultAntialiasingHint, applyScattersAntialiasingHint, applyErrorBarsAntialiasingHint +*/ +void QCPAbstractPlottable::applyFillAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedFill, QCP::aeFills); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable scatter points. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyFillAntialiasingHint, applyDefaultAntialiasingHint, applyErrorBarsAntialiasingHint +*/ +void QCPAbstractPlottable::applyScattersAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedScatters, QCP::aeScatters); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable error bars. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyFillAntialiasingHint, applyScattersAntialiasingHint, applyDefaultAntialiasingHint +*/ +void QCPAbstractPlottable::applyErrorBarsAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedErrorBars, QCP::aeErrorBars); +} + +/*! \internal + + Finds the shortest squared distance of \a point to the line segment defined by \a start and \a + end. + + This function may be used to help with the implementation of the \ref selectTest function for + specific plottables. + + \note This function is identical to QCPAbstractItem::distSqrToLine +*/ +double QCPAbstractPlottable::distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const +{ + QVector2D a(start); + QVector2D b(end); + QVector2D p(point); + QVector2D v(b-a); + + double vLengthSqr = v.lengthSquared(); + if (!qFuzzyIsNull(vLengthSqr)) + { + double mu = QVector2D::dotProduct(p-a, v)/vLengthSqr; + if (mu < 0) + return (a-p).lengthSquared(); + else if (mu > 1) + return (b-p).lengthSquared(); + else + return ((a + mu*v)-p).lengthSquared(); + } else + return (a-p).lengthSquared(); +} + +/* inherits documentation from base class */ +void QCPAbstractPlottable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractPlottable::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemAnchor +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemAnchor + \brief An anchor of an item to which positions can be attached to. + + An item (QCPAbstractItem) may have one or more anchors. Unlike QCPItemPosition, an anchor doesn't + control anything on its item, but provides a way to tie other items via their positions to the + anchor. + + For example, a QCPItemRect is defined by its positions \a topLeft and \a bottomRight. + Additionally it has various anchors like \a top, \a topRight or \a bottomLeft etc. So you can + attach the \a start (which is a QCPItemPosition) of a QCPItemLine to one of the anchors by + calling QCPItemPosition::setParentAnchor on \a start, passing the wanted anchor of the + QCPItemRect. This way the start of the line will now always follow the respective anchor location + on the rect item. + + Note that QCPItemPosition derives from QCPItemAnchor, so every position can also serve as an + anchor to other positions. + + To learn how to provide anchors in your own item subclasses, see the subclassing section of the + QCPAbstractItem documentation. +*/ + +/* start documentation of inline functions */ + +/*! \fn virtual QCPItemPosition *QCPItemAnchor::toQCPItemPosition() + + Returns 0 if this instance is merely a QCPItemAnchor, and a valid pointer of type QCPItemPosition* if + it actually is a QCPItemPosition (which is a subclass of QCPItemAnchor). + + This safe downcast functionality could also be achieved with a dynamic_cast. However, QCustomPlot avoids + dynamic_cast to work with projects that don't have RTTI support enabled (e.g. -fno-rtti flag with + gcc compiler). +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPItemAnchor. You shouldn't create QCPItemAnchor instances directly, even if + you want to make a new item subclass. Use \ref QCPAbstractItem::createAnchor instead, as + explained in the subclassing section of the QCPAbstractItem documentation. +*/ +QCPItemAnchor::QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name, int anchorId) : + mName(name), + mParentPlot(parentPlot), + mParentItem(parentItem), + mAnchorId(anchorId) +{ +} + +QCPItemAnchor::~QCPItemAnchor() +{ + // unregister as parent at children: + foreach (QCPItemPosition *child, mChildrenX.toList()) + { + if (child->parentAnchorX() == this) + child->setParentAnchorX(0); // this acts back on this anchor and child removes itself from mChildrenX + } + foreach (QCPItemPosition *child, mChildrenY.toList()) + { + if (child->parentAnchorY() == this) + child->setParentAnchorY(0); // this acts back on this anchor and child removes itself from mChildrenY + } +} + +/*! + Returns the final absolute pixel position of the QCPItemAnchor on the QCustomPlot surface. + + The pixel information is internally retrieved via QCPAbstractItem::anchorPixelPosition of the + parent item, QCPItemAnchor is just an intermediary. +*/ +QPointF QCPItemAnchor::pixelPoint() const +{ + if (mParentItem) + { + if (mAnchorId > -1) + { + return mParentItem->anchorPixelPoint(mAnchorId); + } else + { + qDebug() << Q_FUNC_INFO << "no valid anchor id set:" << mAnchorId; + return QPointF(); + } + } else + { + qDebug() << Q_FUNC_INFO << "no parent item set"; + return QPointF(); + } +} + +/*! \internal + + Adds \a pos to the childX list of this anchor, which keeps track of which children use this + anchor as parent anchor for the respective coordinate. This is necessary to notify the children + prior to destruction of the anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::addChildX(QCPItemPosition *pos) +{ + if (!mChildrenX.contains(pos)) + mChildrenX.insert(pos); + else + qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); +} + +/*! \internal + + Removes \a pos from the childX list of this anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::removeChildX(QCPItemPosition *pos) +{ + if (!mChildrenX.remove(pos)) + qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); +} + +/*! \internal + + Adds \a pos to the childY list of this anchor, which keeps track of which children use this + anchor as parent anchor for the respective coordinate. This is necessary to notify the children + prior to destruction of the anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::addChildY(QCPItemPosition *pos) +{ + if (!mChildrenY.contains(pos)) + mChildrenY.insert(pos); + else + qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); +} + +/*! \internal + + Removes \a pos from the childY list of this anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::removeChildY(QCPItemPosition *pos) +{ + if (!mChildrenY.remove(pos)) + qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemPosition +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemPosition + \brief Manages the position of an item. + + Every item has at least one public QCPItemPosition member pointer which provides ways to position the + item on the QCustomPlot surface. Some items have multiple positions, for example QCPItemRect has two: + \a topLeft and \a bottomRight. + + QCPItemPosition has a type (\ref PositionType) that can be set with \ref setType. This type + defines how coordinates passed to \ref setCoords are to be interpreted, e.g. as absolute pixel + coordinates, as plot coordinates of certain axes, etc. For more advanced plots it is also + possible to assign different types per X/Y coordinate of the position (see \ref setTypeX, \ref + setTypeY). This way an item could be positioned at a fixed pixel distance from the top in the Y + direction, while following a plot coordinate in the X direction. + + A QCPItemPosition may have a parent QCPItemAnchor, see \ref setParentAnchor. This way you can tie + multiple items together. If the QCPItemPosition has a parent, its coordinates (\ref setCoords) + are considered to be absolute pixels in the reference frame of the parent anchor, where (0, 0) + means directly ontop of the parent anchor. For example, You could attach the \a start position of + a QCPItemLine to the \a bottom anchor of a QCPItemText to make the starting point of the line + always be centered under the text label, no matter where the text is moved to. For more advanced + plots, it is possible to assign different parent anchors per X/Y coordinate of the position, see + \ref setParentAnchorX, \ref setParentAnchorY. This way an item could follow another item in the X + direction but stay at a fixed position in the Y direction. Or even follow item A in X, and item B + in Y. + + Note that every QCPItemPosition inherits from QCPItemAnchor and thus can itself be used as parent + anchor for other positions. + + To set the apparent pixel position on the QCustomPlot surface directly, use \ref setPixelPoint. This + works no matter what type this QCPItemPosition is or what parent-child situation it is in, as \ref + setPixelPoint transforms the coordinates appropriately, to make the position appear at the specified + pixel values. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPItemPosition::PositionType *QCPItemPosition::type() const + + Returns the current position type. + + If different types were set for X and Y (\ref setTypeX, \ref setTypeY), this method returns the + type of the X coordinate. In that case rather use \a typeX() and \a typeY(). + + \see setType +*/ + +/*! \fn QCPItemAnchor *QCPItemPosition::parentAnchor() const + + Returns the current parent anchor. + + If different parent anchors were set for X and Y (\ref setParentAnchorX, \ref setParentAnchorY), + this method returns the parent anchor of the Y coordinate. In that case rather use \a + parentAnchorX() and \a parentAnchorY(). + + \see setParentAnchor +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPItemPosition. You shouldn't create QCPItemPosition instances directly, even if + you want to make a new item subclass. Use \ref QCPAbstractItem::createPosition instead, as + explained in the subclassing section of the QCPAbstractItem documentation. +*/ +QCPItemPosition::QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name) : + QCPItemAnchor(parentPlot, parentItem, name), + mPositionTypeX(ptAbsolute), + mPositionTypeY(ptAbsolute), + mKey(0), + mValue(0), + mParentAnchorX(0), + mParentAnchorY(0) +{ +} + +QCPItemPosition::~QCPItemPosition() +{ + // unregister as parent at children: + // Note: this is done in ~QCPItemAnchor again, but it's important QCPItemPosition does it itself, because only then + // the setParentAnchor(0) call the correct QCPItemPosition::pixelPoint function instead of QCPItemAnchor::pixelPoint + foreach (QCPItemPosition *child, mChildrenX.toList()) + { + if (child->parentAnchorX() == this) + child->setParentAnchorX(0); // this acts back on this anchor and child removes itself from mChildrenX + } + foreach (QCPItemPosition *child, mChildrenY.toList()) + { + if (child->parentAnchorY() == this) + child->setParentAnchorY(0); // this acts back on this anchor and child removes itself from mChildrenY + } + // unregister as child in parent: + if (mParentAnchorX) + mParentAnchorX->removeChildX(this); + if (mParentAnchorY) + mParentAnchorY->removeChildY(this); +} + +/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ +QCPAxisRect *QCPItemPosition::axisRect() const +{ + return mAxisRect.data(); +} + +/*! + Sets the type of the position. The type defines how the coordinates passed to \ref setCoords + should be handled and how the QCPItemPosition should behave in the plot. + + The possible values for \a type can be separated in two main categories: + + \li The position is regarded as a point in plot coordinates. This corresponds to \ref ptPlotCoords + and requires two axes that define the plot coordinate system. They can be specified with \ref setAxes. + By default, the QCustomPlot's x- and yAxis are used. + + \li The position is fixed on the QCustomPlot surface, i.e. independent of axis ranges. This + corresponds to all other types, i.e. \ref ptAbsolute, \ref ptViewportRatio and \ref + ptAxisRectRatio. They differ only in the way the absolute position is described, see the + documentation of \ref PositionType for details. For \ref ptAxisRectRatio, note that you can specify + the axis rect with \ref setAxisRect. By default this is set to the main axis rect. + + Note that the position type \ref ptPlotCoords is only available (and sensible) when the position + has no parent anchor (\ref setParentAnchor). + + If the type is changed, the apparent pixel position on the plot is preserved. This means + the coordinates as retrieved with coords() and set with \ref setCoords may change in the process. + + This method sets the type for both X and Y directions. It is also possible to set different types + for X and Y, see \ref setTypeX, \ref setTypeY. +*/ +void QCPItemPosition::setType(QCPItemPosition::PositionType type) +{ + setTypeX(type); + setTypeY(type); +} + +/*! + This method sets the position type of the X coordinate to \a type. + + For a detailed description of what a position type is, see the documentation of \ref setType. + + \see setType, setTypeY +*/ +void QCPItemPosition::setTypeX(QCPItemPosition::PositionType type) +{ + if (mPositionTypeX != type) + { + // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect + // were deleted), don't try to recover the pixelPoint() because it would output a qDebug warning. + bool retainPixelPosition = true; + if ((mPositionTypeX == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) + retainPixelPosition = false; + if ((mPositionTypeX == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) + retainPixelPosition = false; + + QPointF pixel; + if (retainPixelPosition) + pixel = pixelPoint(); + + mPositionTypeX = type; + + if (retainPixelPosition) + setPixelPoint(pixel); + } +} + +/*! + This method sets the position type of the Y coordinate to \a type. + + For a detailed description of what a position type is, see the documentation of \ref setType. + + \see setType, setTypeX +*/ +void QCPItemPosition::setTypeY(QCPItemPosition::PositionType type) +{ + if (mPositionTypeY != type) + { + // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect + // were deleted), don't try to recover the pixelPoint() because it would output a qDebug warning. + bool retainPixelPosition = true; + if ((mPositionTypeY == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) + retainPixelPosition = false; + if ((mPositionTypeY == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) + retainPixelPosition = false; + + QPointF pixel; + if (retainPixelPosition) + pixel = pixelPoint(); + + mPositionTypeY = type; + + if (retainPixelPosition) + setPixelPoint(pixel); + } +} + +/*! + Sets the parent of this QCPItemPosition to \a parentAnchor. This means the position will now + follow any position changes of the anchor. The local coordinate system of positions with a parent + anchor always is absolute pixels, with (0, 0) being exactly on top of the parent anchor. (Hence + the type shouldn't be set to \ref ptPlotCoords for positions with parent anchors.) + + if \a keepPixelPosition is true, the current pixel position of the QCPItemPosition is preserved + during reparenting. If it's set to false, the coordinates are set to (0, 0), i.e. the position + will be exactly on top of the parent anchor. + + To remove this QCPItemPosition from any parent anchor, set \a parentAnchor to 0. + + If the QCPItemPosition previously had no parent and the type is \ref ptPlotCoords, the type is + set to \ref ptAbsolute, to keep the position in a valid state. + + This method sets the parent anchor for both X and Y directions. It is also possible to set + different parents for X and Y, see \ref setParentAnchorX, \ref setParentAnchorY. +*/ +bool QCPItemPosition::setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + bool successX = setParentAnchorX(parentAnchor, keepPixelPosition); + bool successY = setParentAnchorY(parentAnchor, keepPixelPosition); + return successX && successY; +} + +/*! + This method sets the parent anchor of the X coordinate to \a parentAnchor. + + For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. + + \see setParentAnchor, setParentAnchorY +*/ +bool QCPItemPosition::setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + // make sure self is not assigned as parent: + if (parentAnchor == this) + { + qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); + return false; + } + // make sure no recursive parent-child-relationships are created: + QCPItemAnchor *currentParent = parentAnchor; + while (currentParent) + { + if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) + { + // is a QCPItemPosition, might have further parent, so keep iterating + if (currentParentPos == this) + { + qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); + return false; + } + currentParent = currentParentPos->parentAnchorX(); + } else + { + // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the + // same, to prevent a position being child of an anchor which itself depends on the position, + // because they're both on the same item: + if (currentParent->mParentItem == mParentItem) + { + qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); + return false; + } + break; + } + } + + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: + if (!mParentAnchorX && mPositionTypeX == ptPlotCoords) + setTypeX(ptAbsolute); + + // save pixel position: + QPointF pixelP; + if (keepPixelPosition) + pixelP = pixelPoint(); + // unregister at current parent anchor: + if (mParentAnchorX) + mParentAnchorX->removeChildX(this); + // register at new parent anchor: + if (parentAnchor) + parentAnchor->addChildX(this); + mParentAnchorX = parentAnchor; + // restore pixel position under new parent: + if (keepPixelPosition) + setPixelPoint(pixelP); + else + setCoords(0, coords().y()); + return true; +} + +/*! + This method sets the parent anchor of the Y coordinate to \a parentAnchor. + + For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. + + \see setParentAnchor, setParentAnchorX +*/ +bool QCPItemPosition::setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + // make sure self is not assigned as parent: + if (parentAnchor == this) + { + qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); + return false; + } + // make sure no recursive parent-child-relationships are created: + QCPItemAnchor *currentParent = parentAnchor; + while (currentParent) + { + if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) + { + // is a QCPItemPosition, might have further parent, so keep iterating + if (currentParentPos == this) + { + qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); + return false; + } + currentParent = currentParentPos->parentAnchorY(); + } else + { + // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the + // same, to prevent a position being child of an anchor which itself depends on the position, + // because they're both on the same item: + if (currentParent->mParentItem == mParentItem) + { + qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); + return false; + } + break; + } + } + + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: + if (!mParentAnchorY && mPositionTypeY == ptPlotCoords) + setTypeY(ptAbsolute); + + // save pixel position: + QPointF pixelP; + if (keepPixelPosition) + pixelP = pixelPoint(); + // unregister at current parent anchor: + if (mParentAnchorY) + mParentAnchorY->removeChildY(this); + // register at new parent anchor: + if (parentAnchor) + parentAnchor->addChildY(this); + mParentAnchorY = parentAnchor; + // restore pixel position under new parent: + if (keepPixelPosition) + setPixelPoint(pixelP); + else + setCoords(coords().x(), 0); + return true; +} + +/*! + Sets the coordinates of this QCPItemPosition. What the coordinates mean, is defined by the type + (\ref setType, \ref setTypeX, \ref setTypeY). + + For example, if the type is \ref ptAbsolute, \a key and \a value mean the x and y pixel position + on the QCustomPlot surface. In that case the origin (0, 0) is in the top left corner of the + QCustomPlot viewport. If the type is \ref ptPlotCoords, \a key and \a value mean a point in the + plot coordinate system defined by the axes set by \ref setAxes. By default those are the + QCustomPlot's xAxis and yAxis. See the documentation of \ref setType for other available + coordinate types and their meaning. + + If different types were configured for X and Y (\ref setTypeX, \ref setTypeY), \a key and \a + value must also be provided in the different coordinate systems. Here, the X type refers to \a + key, and the Y type refers to \a value. + + \see setPixelPoint +*/ +void QCPItemPosition::setCoords(double key, double value) +{ + mKey = key; + mValue = value; +} + +/*! \overload + + Sets the coordinates as a QPointF \a pos where pos.x has the meaning of \a key and pos.y the + meaning of \a value of the \ref setCoords(double key, double value) method. +*/ +void QCPItemPosition::setCoords(const QPointF &pos) +{ + setCoords(pos.x(), pos.y()); +} + +/*! + Returns the final absolute pixel position of the QCPItemPosition on the QCustomPlot surface. It + includes all effects of type (\ref setType) and possible parent anchors (\ref setParentAnchor). + + \see setPixelPoint +*/ +QPointF QCPItemPosition::pixelPoint() const +{ + QPointF result; + + // determine X: + switch (mPositionTypeX) + { + case ptAbsolute: + { + result.rx() = mKey; + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPoint().x(); + break; + } + case ptViewportRatio: + { + result.rx() = mKey*mParentPlot->viewport().width(); + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPoint().x(); + else + result.rx() += mParentPlot->viewport().left(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + result.rx() = mKey*mAxisRect.data()->width(); + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPoint().x(); + else + result.rx() += mAxisRect.data()->left(); + } else + qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) + result.rx() = mKeyAxis.data()->coordToPixel(mKey); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) + result.rx() = mValueAxis.data()->coordToPixel(mValue); + else + qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; + break; + } + } + + // determine Y: + switch (mPositionTypeY) + { + case ptAbsolute: + { + result.ry() = mValue; + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPoint().y(); + break; + } + case ptViewportRatio: + { + result.ry() = mValue*mParentPlot->viewport().height(); + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPoint().y(); + else + result.ry() += mParentPlot->viewport().top(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + result.ry() = mValue*mAxisRect.data()->height(); + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPoint().y(); + else + result.ry() += mAxisRect.data()->top(); + } else + qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) + result.ry() = mKeyAxis.data()->coordToPixel(mKey); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) + result.ry() = mValueAxis.data()->coordToPixel(mValue); + else + qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; + break; + } + } + + return result; +} + +/*! + When \ref setType is \ref ptPlotCoords, this function may be used to specify the axes the + coordinates set with \ref setCoords relate to. By default they are set to the initial xAxis and + yAxis of the QCustomPlot. +*/ +void QCPItemPosition::setAxes(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + mKeyAxis = keyAxis; + mValueAxis = valueAxis; +} + +/*! + When \ref setType is \ref ptAxisRectRatio, this function may be used to specify the axis rect the + coordinates set with \ref setCoords relate to. By default this is set to the main axis rect of + the QCustomPlot. +*/ +void QCPItemPosition::setAxisRect(QCPAxisRect *axisRect) +{ + mAxisRect = axisRect; +} + +/*! + Sets the apparent pixel position. This works no matter what type (\ref setType) this + QCPItemPosition is or what parent-child situation it is in, as coordinates are transformed + appropriately, to make the position finally appear at the specified pixel values. + + Only if the type is \ref ptAbsolute and no parent anchor is set, this function's effect is + identical to that of \ref setCoords. + + \see pixelPoint, setCoords +*/ +void QCPItemPosition::setPixelPoint(const QPointF &pixelPoint) +{ + double x = pixelPoint.x(); + double y = pixelPoint.y(); + + switch (mPositionTypeX) + { + case ptAbsolute: + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPoint().x(); + break; + } + case ptViewportRatio: + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPoint().x(); + else + x -= mParentPlot->viewport().left(); + x /= (double)mParentPlot->viewport().width(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPoint().x(); + else + x -= mAxisRect.data()->left(); + x /= (double)mAxisRect.data()->width(); + } else + qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) + x = mKeyAxis.data()->pixelToCoord(x); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) + y = mValueAxis.data()->pixelToCoord(x); + else + qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; + break; + } + } + + switch (mPositionTypeY) + { + case ptAbsolute: + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPoint().y(); + break; + } + case ptViewportRatio: + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPoint().y(); + else + y -= mParentPlot->viewport().top(); + y /= (double)mParentPlot->viewport().height(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPoint().y(); + else + y -= mAxisRect.data()->top(); + y /= (double)mAxisRect.data()->height(); + } else + qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) + x = mKeyAxis.data()->pixelToCoord(y); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) + y = mValueAxis.data()->pixelToCoord(y); + else + qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; + break; + } + } + + setCoords(x, y); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractItem + \brief The abstract base class for all items in a plot. + + In QCustomPlot, items are supplemental graphical elements that are neither plottables + (QCPAbstractPlottable) nor axes (QCPAxis). While plottables are always tied to two axes and thus + plot coordinates, items can also be placed in absolute coordinates independent of any axes. Each + specific item has at least one QCPItemPosition member which controls the positioning. Some items + are defined by more than one coordinate and thus have two or more QCPItemPosition members (For + example, QCPItemRect has \a topLeft and \a bottomRight). + + This abstract base class defines a very basic interface like visibility and clipping. Since this + class is abstract, it can't be instantiated. Use one of the subclasses or create a subclass + yourself to create new items. + + The built-in items are: + + + + + + + + + + +
QCPItemLineA line defined by a start and an end point. May have different ending styles on each side (e.g. arrows).
QCPItemStraightLineA straight line defined by a start and a direction point. Unlike QCPItemLine, the straight line is infinitely long and has no endings.
QCPItemCurveA curve defined by start, end and two intermediate control points. May have different ending styles on each side (e.g. arrows).
QCPItemRectA rectangle
QCPItemEllipseAn ellipse
QCPItemPixmapAn arbitrary pixmap
QCPItemTextA text label
QCPItemBracketA bracket which may be used to reference/highlight certain parts in the plot.
QCPItemTracerAn item that can be attached to a QCPGraph and sticks to its data points, given a key coordinate.
+ + \section items-clipping Clipping + + Items are by default clipped to the main axis rect (they are only visible inside the axis rect). + To make an item visible outside that axis rect, disable clipping via \ref setClipToAxisRect + "setClipToAxisRect(false)". + + On the other hand if you want the item to be clipped to a different axis rect, specify it via + \ref setClipAxisRect. This clipAxisRect property of an item is only used for clipping behaviour, and + in principle is independent of the coordinate axes the item might be tied to via its position + members (\ref QCPItemPosition::setAxes). However, it is common that the axis rect for clipping + also contains the axes used for the item positions. + + \section items-using Using items + + First you instantiate the item you want to use and add it to the plot: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-1 + by default, the positions of the item are bound to the x- and y-Axis of the plot. So we can just + set the plot coordinates where the line should start/end: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-2 + If we don't want the line to be positioned in plot coordinates but a different coordinate system, + e.g. absolute pixel positions on the QCustomPlot surface, we need to change the position type like this: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-3 + Then we can set the coordinates, this time in pixels: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-4 + and make the line visible on the entire QCustomPlot, by disabling clipping to the axis rect: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-5 + + For more advanced plots, it is even possible to set different types and parent anchors per X/Y + coordinate of an item position, using for example \ref QCPItemPosition::setTypeX or \ref + QCPItemPosition::setParentAnchorX. For details, see the documentation of \ref QCPItemPosition. + + \section items-subclassing Creating own items + + To create an own item, you implement a subclass of QCPAbstractItem. These are the pure + virtual functions, you must implement: + \li \ref selectTest + \li \ref draw + + See the documentation of those functions for what they need to do. + + \subsection items-positioning Allowing the item to be positioned + + As mentioned, item positions are represented by QCPItemPosition members. Let's assume the new item shall + have only one point as its position (as opposed to two like a rect or multiple like a polygon). You then add + a public member of type QCPItemPosition like so: + + \code QCPItemPosition * const myPosition;\endcode + + the const makes sure the pointer itself can't be modified from the user of your new item (the QCPItemPosition + instance it points to, can be modified, of course). + The initialization of this pointer is made easy with the \ref createPosition function. Just assign + the return value of this function to each QCPItemPosition in the constructor of your item. \ref createPosition + takes a string which is the name of the position, typically this is identical to the variable name. + For example, the constructor of QCPItemExample could look like this: + + \code + QCPItemExample::QCPItemExample(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + myPosition(createPosition("myPosition")) + { + // other constructor code + } + \endcode + + \subsection items-drawing The draw function + + To give your item a visual representation, reimplement the \ref draw function and use the passed + QCPPainter to draw the item. You can retrieve the item position in pixel coordinates from the + position member(s) via \ref QCPItemPosition::pixelPoint. + + To optimize performance you should calculate a bounding rect first (don't forget to take the pen + width into account), check whether it intersects the \ref clipRect, and only draw the item at all + if this is the case. + + \subsection items-selection The selectTest function + + Your implementation of the \ref selectTest function may use the helpers \ref distSqrToLine and + \ref rectSelectTest. With these, the implementation of the selection test becomes significantly + simpler for most items. See the documentation of \ref selectTest for what the function parameters + mean and what the function should return. + + \subsection anchors Providing anchors + + Providing anchors (QCPItemAnchor) starts off like adding a position. First you create a public + member, e.g. + + \code QCPItemAnchor * const bottom;\endcode + + and create it in the constructor with the \ref createAnchor function, assigning it a name and an + anchor id (an integer enumerating all anchors on the item, you may create an own enum for this). + Since anchors can be placed anywhere, relative to the item's position(s), your item needs to + provide the position of every anchor with the reimplementation of the \ref anchorPixelPoint(int + anchorId) function. + + In essence the QCPItemAnchor is merely an intermediary that itself asks your item for the pixel + position when anything attached to the anchor needs to know the coordinates. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QList QCPAbstractItem::positions() const + + Returns all positions of the item in a list. + + \see anchors, position +*/ + +/*! \fn QList QCPAbstractItem::anchors() const + + Returns all anchors of the item in a list. Note that since a position (QCPItemPosition) is always + also an anchor, the list will also contain the positions of this item. + + \see positions, anchor +*/ + +/* end of documentation of inline functions */ +/* start documentation of pure virtual functions */ + +/*! \fn void QCPAbstractItem::draw(QCPPainter *painter) = 0 + \internal + + Draws this item with the provided \a painter. + + The cliprect of the provided painter is set to the rect returned by \ref clipRect before this + function is called. The clipRect depends on the clipping settings defined by \ref + setClipToAxisRect and \ref setClipAxisRect. +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of signals */ + +/*! \fn void QCPAbstractItem::selectionChanged(bool selected) + This signal is emitted when the selection state of this item has changed, either by user interaction + or by a direct call to \ref setSelected. +*/ + +/* end documentation of signals */ + +/*! + Base class constructor which initializes base class members. +*/ +QCPAbstractItem::QCPAbstractItem(QCustomPlot *parentPlot) : + QCPLayerable(parentPlot), + mClipToAxisRect(false), + mSelectable(true), + mSelected(false) +{ + QList rects = parentPlot->axisRects(); + if (rects.size() > 0) + { + setClipToAxisRect(true); + setClipAxisRect(rects.first()); + } +} + +QCPAbstractItem::~QCPAbstractItem() +{ + // don't delete mPositions because every position is also an anchor and thus in mAnchors + qDeleteAll(mAnchors); +} + +/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ +QCPAxisRect *QCPAbstractItem::clipAxisRect() const +{ + return mClipAxisRect.data(); +} + +/*! + Sets whether the item shall be clipped to an axis rect or whether it shall be visible on the + entire QCustomPlot. The axis rect can be set with \ref setClipAxisRect. + + \see setClipAxisRect +*/ +void QCPAbstractItem::setClipToAxisRect(bool clip) +{ + mClipToAxisRect = clip; + if (mClipToAxisRect) + setParentLayerable(mClipAxisRect.data()); +} + +/*! + Sets the clip axis rect. It defines the rect that will be used to clip the item when \ref + setClipToAxisRect is set to true. + + \see setClipToAxisRect +*/ +void QCPAbstractItem::setClipAxisRect(QCPAxisRect *rect) +{ + mClipAxisRect = rect; + if (mClipToAxisRect) + setParentLayerable(mClipAxisRect.data()); +} + +/*! + Sets whether the user can (de-)select this item by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains QCustomPlot::iSelectItems.) + + However, even when \a selectable was set to false, it is possible to set the selection manually, + by calling \ref setSelected. + + \see QCustomPlot::setInteractions, setSelected +*/ +void QCPAbstractItem::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets whether this item is selected or not. When selected, it might use a different visual + appearance (e.g. pen and brush), this depends on the specific item though. + + The entire selection mechanism for items is handled automatically when \ref + QCustomPlot::setInteractions contains QCustomPlot::iSelectItems. You only need to call this + function when you wish to change the selection state manually. + + This function can change the selection state even when \ref setSelectable was set to false. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see setSelectable, selectTest +*/ +void QCPAbstractItem::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/*! + Returns the QCPItemPosition with the specified \a name. If this item doesn't have a position by + that name, returns 0. + + This function provides an alternative way to access item positions. Normally, you access + positions direcly by their member pointers (which typically have the same variable name as \a + name). + + \see positions, anchor +*/ +QCPItemPosition *QCPAbstractItem::position(const QString &name) const +{ + for (int i=0; iname() == name) + return mPositions.at(i); + } + qDebug() << Q_FUNC_INFO << "position with name not found:" << name; + return 0; +} + +/*! + Returns the QCPItemAnchor with the specified \a name. If this item doesn't have an anchor by + that name, returns 0. + + This function provides an alternative way to access item anchors. Normally, you access + anchors direcly by their member pointers (which typically have the same variable name as \a + name). + + \see anchors, position +*/ +QCPItemAnchor *QCPAbstractItem::anchor(const QString &name) const +{ + for (int i=0; iname() == name) + return mAnchors.at(i); + } + qDebug() << Q_FUNC_INFO << "anchor with name not found:" << name; + return 0; +} + +/*! + Returns whether this item has an anchor with the specified \a name. + + Note that you can check for positions with this function, too. This is because every position is + also an anchor (QCPItemPosition inherits from QCPItemAnchor). + + \see anchor, position +*/ +bool QCPAbstractItem::hasAnchor(const QString &name) const +{ + for (int i=0; iname() == name) + return true; + } + return false; +} + +/*! \internal + + Returns the rect the visual representation of this item is clipped to. This depends on the + current setting of \ref setClipToAxisRect as well as the axis rect set with \ref setClipAxisRect. + + If the item is not clipped to an axis rect, the \ref QCustomPlot::viewport rect is returned. + + \see draw +*/ +QRect QCPAbstractItem::clipRect() const +{ + if (mClipToAxisRect && mClipAxisRect) + return mClipAxisRect.data()->rect(); + else + return mParentPlot->viewport(); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing item lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPAbstractItem::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeItems); +} + +/*! \internal + + Finds the shortest squared distance of \a point to the line segment defined by \a start and \a + end. + + This function may be used to help with the implementation of the \ref selectTest function for + specific items. + + \note This function is identical to QCPAbstractPlottable::distSqrToLine + + \see rectSelectTest +*/ +double QCPAbstractItem::distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const +{ + QVector2D a(start); + QVector2D b(end); + QVector2D p(point); + QVector2D v(b-a); + + double vLengthSqr = v.lengthSquared(); + if (!qFuzzyIsNull(vLengthSqr)) + { + double mu = QVector2D::dotProduct(p-a, v)/vLengthSqr; + if (mu < 0) + return (a-p).lengthSquared(); + else if (mu > 1) + return (b-p).lengthSquared(); + else + return ((a + mu*v)-p).lengthSquared(); + } else + return (a-p).lengthSquared(); +} + +/*! \internal + + A convenience function which returns the selectTest value for a specified \a rect and a specified + click position \a pos. \a filledRect defines whether a click inside the rect should also be + considered a hit or whether only the rect border is sensitive to hits. + + This function may be used to help with the implementation of the \ref selectTest function for + specific items. + + For example, if your item consists of four rects, call this function four times, once for each + rect, in your \ref selectTest reimplementation. Finally, return the minimum of all four returned + values. + + \see distSqrToLine +*/ +double QCPAbstractItem::rectSelectTest(const QRectF &rect, const QPointF &pos, bool filledRect) const +{ + double result = -1; + + // distance to border: + QList lines; + lines << QLineF(rect.topLeft(), rect.topRight()) << QLineF(rect.bottomLeft(), rect.bottomRight()) + << QLineF(rect.topLeft(), rect.bottomLeft()) << QLineF(rect.topRight(), rect.bottomRight()); + double minDistSqr = std::numeric_limits::max(); + for (int i=0; i mParentPlot->selectionTolerance()*0.99) + { + if (rect.contains(pos)) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; +} + +/*! \internal + + Returns the pixel position of the anchor with Id \a anchorId. This function must be reimplemented in + item subclasses if they want to provide anchors (QCPItemAnchor). + + For example, if the item has two anchors with id 0 and 1, this function takes one of these anchor + ids and returns the respective pixel points of the specified anchor. + + \see createAnchor +*/ +QPointF QCPAbstractItem::anchorPixelPoint(int anchorId) const +{ + qDebug() << Q_FUNC_INFO << "called on item which shouldn't have any anchors (this method not reimplemented). anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Creates a QCPItemPosition, registers it with this item and returns a pointer to it. The specified + \a name must be a unique string that is usually identical to the variable name of the position + member (This is needed to provide the name-based \ref position access to positions). + + Don't delete positions created by this function manually, as the item will take care of it. + + Use this function in the constructor (initialization list) of the specific item subclass to + create each position member. Don't create QCPItemPositions with \b new yourself, because they + won't be registered with the item properly. + + \see createAnchor +*/ +QCPItemPosition *QCPAbstractItem::createPosition(const QString &name) +{ + if (hasAnchor(name)) + qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; + QCPItemPosition *newPosition = new QCPItemPosition(mParentPlot, this, name); + mPositions.append(newPosition); + mAnchors.append(newPosition); // every position is also an anchor + newPosition->setAxes(mParentPlot->xAxis, mParentPlot->yAxis); + newPosition->setType(QCPItemPosition::ptPlotCoords); + if (mParentPlot->axisRect()) + newPosition->setAxisRect(mParentPlot->axisRect()); + newPosition->setCoords(0, 0); + return newPosition; +} + +/*! \internal + + Creates a QCPItemAnchor, registers it with this item and returns a pointer to it. The specified + \a name must be a unique string that is usually identical to the variable name of the anchor + member (This is needed to provide the name based \ref anchor access to anchors). + + The \a anchorId must be a number identifying the created anchor. It is recommended to create an + enum (e.g. "AnchorIndex") for this on each item that uses anchors. This id is used by the anchor + to identify itself when it calls QCPAbstractItem::anchorPixelPoint. That function then returns + the correct pixel coordinates for the passed anchor id. + + Don't delete anchors created by this function manually, as the item will take care of it. + + Use this function in the constructor (initialization list) of the specific item subclass to + create each anchor member. Don't create QCPItemAnchors with \b new yourself, because then they + won't be registered with the item properly. + + \see createPosition +*/ +QCPItemAnchor *QCPAbstractItem::createAnchor(const QString &name, int anchorId) +{ + if (hasAnchor(name)) + qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; + QCPItemAnchor *newAnchor = new QCPItemAnchor(mParentPlot, this, name, anchorId); + mAnchors.append(newAnchor); + return newAnchor; +} + +/* inherits documentation from base class */ +void QCPAbstractItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractItem::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractItem::selectionCategory() const +{ + return QCP::iSelectItems; +} + + +/*! \file */ + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCustomPlot +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCustomPlot + + \brief The central class of the library. This is the QWidget which displays the plot and + interacts with the user. + + For tutorials on how to use QCustomPlot, see the website\n + http://www.qcustomplot.com/ +*/ + +/* start of documentation of inline functions */ + +/*! \fn QRect QCustomPlot::viewport() const + + Returns the viewport rect of this QCustomPlot instance. The viewport is the area the plot is + drawn in, all mechanisms, e.g. margin caluclation take the viewport to be the outer border of the + plot. The viewport normally is the rect() of the QCustomPlot widget, i.e. a rect with top left + (0, 0) and size of the QCustomPlot widget. + + Don't confuse the viewport with the axis rect (QCustomPlot::axisRect). An axis rect is typically + an area enclosed by four axes, where the graphs/plottables are drawn in. The viewport is larger + and contains also the axes themselves, their tick numbers, their labels, the plot title etc. + + Only when saving to a file (see \ref savePng, \ref savePdf etc.) the viewport is temporarily + modified to allow saving plots with sizes independent of the current widget size. +*/ + +/*! \fn QCPLayoutGrid *QCustomPlot::plotLayout() const + + Returns the top level layout of this QCustomPlot instance. It is a \ref QCPLayoutGrid, initially containing just + one cell with the main QCPAxisRect inside. +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCustomPlot::mouseDoubleClick(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse double click event. +*/ + +/*! \fn void QCustomPlot::mousePress(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse press event. + + It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref + QCPAxisRect::setRangeDragAxes. +*/ + +/*! \fn void QCustomPlot::mouseMove(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse move event. + + It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref + QCPAxisRect::setRangeDragAxes. + + \warning It is discouraged to change the drag-axes with \ref QCPAxisRect::setRangeDragAxes here, + because the dragging starting point was saved the moment the mouse was pressed. Thus it only has + a meaning for the range drag axes that were set at that moment. If you want to change the drag + axes, consider doing this in the \ref mousePress signal instead. +*/ + +/*! \fn void QCustomPlot::mouseRelease(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse release event. + + It is emitted before QCustomPlot handles any other mechanisms like object selection. So a + slot connected to this signal can still influence the behaviour e.g. with \ref setInteractions or + \ref QCPAbstractPlottable::setSelectable. +*/ + +/*! \fn void QCustomPlot::mouseWheel(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse wheel event. + + It is emitted before QCustomPlot handles any other mechanisms like range zooming. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeZoom, \ref + QCPAxisRect::setRangeZoomAxes or \ref QCPAxisRect::setRangeZoomFactor. +*/ + +/*! \fn void QCustomPlot::plottableClick(QCPAbstractPlottable *plottable, QMouseEvent *event) + + This signal is emitted when a plottable is clicked. + + \a event is the mouse event that caused the click and \a plottable is the plottable that received + the click. + + \see plottableDoubleClick +*/ + +/*! \fn void QCustomPlot::plottableDoubleClick(QCPAbstractPlottable *plottable, QMouseEvent *event) + + This signal is emitted when a plottable is double clicked. + + \a event is the mouse event that caused the click and \a plottable is the plottable that received + the click. + + \see plottableClick +*/ + +/*! \fn void QCustomPlot::itemClick(QCPAbstractItem *item, QMouseEvent *event) + + This signal is emitted when an item is clicked. + + \a event is the mouse event that caused the click and \a item is the item that received the + click. + + \see itemDoubleClick +*/ + +/*! \fn void QCustomPlot::itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event) + + This signal is emitted when an item is double clicked. + + \a event is the mouse event that caused the click and \a item is the item that received the + click. + + \see itemClick +*/ + +/*! \fn void QCustomPlot::axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) + + This signal is emitted when an axis is clicked. + + \a event is the mouse event that caused the click, \a axis is the axis that received the click and + \a part indicates the part of the axis that was clicked. + + \see axisDoubleClick +*/ + +/*! \fn void QCustomPlot::axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) + + This signal is emitted when an axis is double clicked. + + \a event is the mouse event that caused the click, \a axis is the axis that received the click and + \a part indicates the part of the axis that was clicked. + + \see axisClick +*/ + +/*! \fn void QCustomPlot::legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) + + This signal is emitted when a legend (item) is clicked. + + \a event is the mouse event that caused the click, \a legend is the legend that received the + click and \a item is the legend item that received the click. If only the legend and no item is + clicked, \a item is 0. This happens for a click inside the legend padding or the space between + two items. + + \see legendDoubleClick +*/ + +/*! \fn void QCustomPlot::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) + + This signal is emitted when a legend (item) is double clicked. + + \a event is the mouse event that caused the click, \a legend is the legend that received the + click and \a item is the legend item that received the click. If only the legend and no item is + clicked, \a item is 0. This happens for a click inside the legend padding or the space between + two items. + + \see legendClick +*/ + +/*! \fn void QCustomPlot:: titleClick(QMouseEvent *event, QCPPlotTitle *title) + + This signal is emitted when a plot title is clicked. + + \a event is the mouse event that caused the click and \a title is the plot title that received + the click. + + \see titleDoubleClick +*/ + +/*! \fn void QCustomPlot::titleDoubleClick(QMouseEvent *event, QCPPlotTitle *title) + + This signal is emitted when a plot title is double clicked. + + \a event is the mouse event that caused the click and \a title is the plot title that received + the click. + + \see titleClick +*/ + +/*! \fn void QCustomPlot::selectionChangedByUser() + + This signal is emitted after the user has changed the selection in the QCustomPlot, e.g. by + clicking. It is not emitted when the selection state of an object has changed programmatically by + a direct call to setSelected() on an object or by calling \ref deselectAll. + + In addition to this signal, selectable objects also provide individual signals, for example + QCPAxis::selectionChanged or QCPAbstractPlottable::selectionChanged. Note that those signals are + emitted even if the selection state is changed programmatically. + + See the documentation of \ref setInteractions for details about the selection mechanism. + + \see selectedPlottables, selectedGraphs, selectedItems, selectedAxes, selectedLegends +*/ + +/*! \fn void QCustomPlot::beforeReplot() + + This signal is emitted immediately before a replot takes place (caused by a call to the slot \ref + replot). + + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them + replot synchronously, it won't cause an infinite recursion. + + \see replot, afterReplot +*/ + +/*! \fn void QCustomPlot::afterReplot() + + This signal is emitted immediately after a replot has taken place (caused by a call to the slot \ref + replot). + + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them + replot synchronously, it won't cause an infinite recursion. + + \see replot, beforeReplot +*/ + +/* end of documentation of signals */ +/* start of documentation of public members */ + +/*! \var QCPAxis *QCustomPlot::xAxis + + A pointer to the primary x Axis (bottom) of the main axis rect of the plot. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. +*/ + +/*! \var QCPAxis *QCustomPlot::yAxis + + A pointer to the primary y Axis (left) of the main axis rect of the plot. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. +*/ + +/*! \var QCPAxis *QCustomPlot::xAxis2 + + A pointer to the secondary x Axis (top) of the main axis rect of the plot. Secondary axes are + invisible by default. Use QCPAxis::setVisible to change this (or use \ref + QCPAxisRect::setupFullAxesBox). + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. +*/ + +/*! \var QCPAxis *QCustomPlot::yAxis2 + + A pointer to the secondary y Axis (right) of the main axis rect of the plot. Secondary axes are + invisible by default. Use QCPAxis::setVisible to change this (or use \ref + QCPAxisRect::setupFullAxesBox). + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. +*/ + +/*! \var QCPLegend *QCustomPlot::legend + + A pointer to the default legend of the main axis rect. The legend is invisible by default. Use + QCPLegend::setVisible to change this. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple legends to the plot, use the layout system interface to + access the new legend. For example, legends can be placed inside an axis rect's \ref + QCPAxisRect::insetLayout "inset layout", and must then also be accessed via the inset layout. If + the default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointer becomes 0. +*/ + +/* end of documentation of public members */ + +/*! + Constructs a QCustomPlot and sets reasonable default values. +*/ +QCustomPlot::QCustomPlot(QWidget *parent) : + QWidget(parent), + xAxis(0), + yAxis(0), + xAxis2(0), + yAxis2(0), + legend(0), + mPlotLayout(0), + mAutoAddPlottableToLegend(true), + mAntialiasedElements(QCP::aeNone), + mNotAntialiasedElements(QCP::aeNone), + mInteractions(0), + mSelectionTolerance(8), + mNoAntialiasingOnDrag(false), + mBackgroundBrush(Qt::white, Qt::SolidPattern), + mBackgroundScaled(true), + mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), + mCurrentLayer(0), + mPlottingHints(QCP::phCacheLabels|QCP::phForceRepaint), + mMultiSelectModifier(Qt::ControlModifier), + mPaintBuffer(size()), + mMouseEventElement(0), + mReplotting(false) +{ + setAttribute(Qt::WA_NoMousePropagation); + setAttribute(Qt::WA_OpaquePaintEvent); + setMouseTracking(true); + QLocale currentLocale = locale(); + currentLocale.setNumberOptions(QLocale::OmitGroupSeparator); + setLocale(currentLocale); + + // create initial layers: + mLayers.append(new QCPLayer(this, QLatin1String("background"))); + mLayers.append(new QCPLayer(this, QLatin1String("grid"))); + mLayers.append(new QCPLayer(this, QLatin1String("main"))); + mLayers.append(new QCPLayer(this, QLatin1String("axes"))); + mLayers.append(new QCPLayer(this, QLatin1String("legend"))); + updateLayerIndices(); + setCurrentLayer(QLatin1String("main")); + + // create initial layout, axis rect and legend: + mPlotLayout = new QCPLayoutGrid; + mPlotLayout->initializeParentPlot(this); + mPlotLayout->setParent(this); // important because if parent is QWidget, QCPLayout::sizeConstraintsChanged will call QWidget::updateGeometry + mPlotLayout->setLayer(QLatin1String("main")); + QCPAxisRect *defaultAxisRect = new QCPAxisRect(this, true); + mPlotLayout->addElement(0, 0, defaultAxisRect); + xAxis = defaultAxisRect->axis(QCPAxis::atBottom); + yAxis = defaultAxisRect->axis(QCPAxis::atLeft); + xAxis2 = defaultAxisRect->axis(QCPAxis::atTop); + yAxis2 = defaultAxisRect->axis(QCPAxis::atRight); + legend = new QCPLegend; + legend->setVisible(false); + defaultAxisRect->insetLayout()->addElement(legend, Qt::AlignRight|Qt::AlignTop); + defaultAxisRect->insetLayout()->setMargins(QMargins(12, 12, 12, 12)); + + defaultAxisRect->setLayer(QLatin1String("background")); + xAxis->setLayer(QLatin1String("axes")); + yAxis->setLayer(QLatin1String("axes")); + xAxis2->setLayer(QLatin1String("axes")); + yAxis2->setLayer(QLatin1String("axes")); + xAxis->grid()->setLayer(QLatin1String("grid")); + yAxis->grid()->setLayer(QLatin1String("grid")); + xAxis2->grid()->setLayer(QLatin1String("grid")); + yAxis2->grid()->setLayer(QLatin1String("grid")); + legend->setLayer(QLatin1String("legend")); + + setViewport(rect()); // needs to be called after mPlotLayout has been created + + replot(); +} + +QCustomPlot::~QCustomPlot() +{ + clearPlottables(); + clearItems(); + + if (mPlotLayout) + { + delete mPlotLayout; + mPlotLayout = 0; + } + + mCurrentLayer = 0; + qDeleteAll(mLayers); // don't use removeLayer, because it would prevent the last layer to be removed + mLayers.clear(); +} + +/*! + Sets which elements are forcibly drawn antialiased as an \a or combination of QCP::AntialiasedElement. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a antialiasedElements contains \ref QCP::aePlottables, all plottables will be + drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set + to. + + if an element in \a antialiasedElements is already set in \ref setNotAntialiasedElements, it is + removed from there. + + \see setNotAntialiasedElements +*/ +void QCustomPlot::setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements) +{ + mAntialiasedElements = antialiasedElements; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mNotAntialiasedElements |= ~mAntialiasedElements; +} + +/*! + Sets whether the specified \a antialiasedElement is forcibly drawn antialiased. + + See \ref setAntialiasedElements for details. + + \see setNotAntialiasedElement +*/ +void QCustomPlot::setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled) +{ + if (!enabled && mAntialiasedElements.testFlag(antialiasedElement)) + mAntialiasedElements &= ~antialiasedElement; + else if (enabled && !mAntialiasedElements.testFlag(antialiasedElement)) + mAntialiasedElements |= antialiasedElement; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mNotAntialiasedElements |= ~mAntialiasedElements; +} + +/*! + Sets which elements are forcibly drawn not antialiased as an \a or combination of + QCP::AntialiasedElement. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a notAntialiasedElements contains \ref QCP::aePlottables, no plottables will be + drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set + to. + + if an element in \a notAntialiasedElements is already set in \ref setAntialiasedElements, it is + removed from there. + + \see setAntialiasedElements +*/ +void QCustomPlot::setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements) +{ + mNotAntialiasedElements = notAntialiasedElements; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mAntialiasedElements |= ~mNotAntialiasedElements; +} + +/*! + Sets whether the specified \a notAntialiasedElement is forcibly drawn not antialiased. + + See \ref setNotAntialiasedElements for details. + + \see setAntialiasedElement +*/ +void QCustomPlot::setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled) +{ + if (!enabled && mNotAntialiasedElements.testFlag(notAntialiasedElement)) + mNotAntialiasedElements &= ~notAntialiasedElement; + else if (enabled && !mNotAntialiasedElements.testFlag(notAntialiasedElement)) + mNotAntialiasedElements |= notAntialiasedElement; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mAntialiasedElements |= ~mNotAntialiasedElements; +} + +/*! + If set to true, adding a plottable (e.g. a graph) to the QCustomPlot automatically also adds the + plottable to the legend (QCustomPlot::legend). + + \see addPlottable, addGraph, QCPLegend::addItem +*/ +void QCustomPlot::setAutoAddPlottableToLegend(bool on) +{ + mAutoAddPlottableToLegend = on; +} + +/*! + Sets the possible interactions of this QCustomPlot as an or-combination of \ref QCP::Interaction + enums. There are the following types of interactions: + + Axis range manipulation is controlled via \ref QCP::iRangeDrag and \ref QCP::iRangeZoom. When the + respective interaction is enabled, the user may drag axes ranges and zoom with the mouse wheel. + For details how to control which axes the user may drag/zoom and in what orientations, see \ref + QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeDragAxes, + \ref QCPAxisRect::setRangeZoomAxes. + + Plottable selection is controlled by \ref QCP::iSelectPlottables. If \ref QCP::iSelectPlottables is + set, the user may select plottables (graphs, curves, bars,...) by clicking on them or in their + vicinity (\ref setSelectionTolerance). Whether the user can actually select a plottable can + further be restricted with the \ref QCPAbstractPlottable::setSelectable function on the specific + plottable. To find out whether a specific plottable is selected, call + QCPAbstractPlottable::selected(). To retrieve a list of all currently selected plottables, call + \ref selectedPlottables. If you're only interested in QCPGraphs, you may use the convenience + function \ref selectedGraphs. + + Item selection is controlled by \ref QCP::iSelectItems. If \ref QCP::iSelectItems is set, the user + may select items (QCPItemLine, QCPItemText,...) by clicking on them or in their vicinity. To find + out whether a specific item is selected, call QCPAbstractItem::selected(). To retrieve a list of + all currently selected items, call \ref selectedItems. + + Axis selection is controlled with \ref QCP::iSelectAxes. If \ref QCP::iSelectAxes is set, the user + may select parts of the axes by clicking on them. What parts exactly (e.g. Axis base line, tick + labels, axis label) are selectable can be controlled via \ref QCPAxis::setSelectableParts for + each axis. To retrieve a list of all axes that currently contain selected parts, call \ref + selectedAxes. Which parts of an axis are selected, can be retrieved with QCPAxis::selectedParts(). + + Legend selection is controlled with \ref QCP::iSelectLegend. If this is set, the user may + select the legend itself or individual items by clicking on them. What parts exactly are + selectable can be controlled via \ref QCPLegend::setSelectableParts. To find out whether the + legend or any of its child items are selected, check the value of QCPLegend::selectedParts. To + find out which child items are selected, call \ref QCPLegend::selectedItems. + + All other selectable elements The selection of all other selectable objects (e.g. + QCPPlotTitle, or your own layerable subclasses) is controlled with \ref QCP::iSelectOther. If set, the + user may select those objects by clicking on them. To find out which are currently selected, you + need to check their selected state explicitly. + + If the selection state has changed by user interaction, the \ref selectionChangedByUser signal is + emitted. Each selectable object additionally emits an individual selectionChanged signal whenever + their selection state has changed, i.e. not only by user interaction. + + To allow multiple objects to be selected by holding the selection modifier (\ref + setMultiSelectModifier), set the flag \ref QCP::iMultiSelect. + + \note In addition to the selection mechanism presented here, QCustomPlot always emits + corresponding signals, when an object is clicked or double clicked. see \ref plottableClick and + \ref plottableDoubleClick for example. + + \see setInteraction, setSelectionTolerance +*/ +void QCustomPlot::setInteractions(const QCP::Interactions &interactions) +{ + mInteractions = interactions; +} + +/*! + Sets the single \a interaction of this QCustomPlot to \a enabled. + + For details about the interaction system, see \ref setInteractions. + + \see setInteractions +*/ +void QCustomPlot::setInteraction(const QCP::Interaction &interaction, bool enabled) +{ + if (!enabled && mInteractions.testFlag(interaction)) + mInteractions &= ~interaction; + else if (enabled && !mInteractions.testFlag(interaction)) + mInteractions |= interaction; +} + +/*! + Sets the tolerance that is used to decide whether a click selects an object (e.g. a plottable) or + not. + + If the user clicks in the vicinity of the line of e.g. a QCPGraph, it's only regarded as a + potential selection when the minimum distance between the click position and the graph line is + smaller than \a pixels. Objects that are defined by an area (e.g. QCPBars) only react to clicks + directly inside the area and ignore this selection tolerance. In other words, it only has meaning + for parts of objects that are too thin to exactly hit with a click and thus need such a + tolerance. + + \see setInteractions, QCPLayerable::selectTest +*/ +void QCustomPlot::setSelectionTolerance(int pixels) +{ + mSelectionTolerance = pixels; +} + +/*! + Sets whether antialiasing is disabled for this QCustomPlot while the user is dragging axes + ranges. If many objects, especially plottables, are drawn antialiased, this greatly improves + performance during dragging. Thus it creates a more responsive user experience. As soon as the + user stops dragging, the last replot is done with normal antialiasing, to restore high image + quality. + + \see setAntialiasedElements, setNotAntialiasedElements +*/ +void QCustomPlot::setNoAntialiasingOnDrag(bool enabled) +{ + mNoAntialiasingOnDrag = enabled; +} + +/*! + Sets the plotting hints for this QCustomPlot instance as an \a or combination of QCP::PlottingHint. + + \see setPlottingHint +*/ +void QCustomPlot::setPlottingHints(const QCP::PlottingHints &hints) +{ + mPlottingHints = hints; +} + +/*! + Sets the specified plotting \a hint to \a enabled. + + \see setPlottingHints +*/ +void QCustomPlot::setPlottingHint(QCP::PlottingHint hint, bool enabled) +{ + QCP::PlottingHints newHints = mPlottingHints; + if (!enabled) + newHints &= ~hint; + else + newHints |= hint; + + if (newHints != mPlottingHints) + setPlottingHints(newHints); +} + +/*! + Sets the keyboard modifier that will be recognized as multi-select-modifier. + + If \ref QCP::iMultiSelect is specified in \ref setInteractions, the user may select multiple objects + by clicking on them one after the other while holding down \a modifier. + + By default the multi-select-modifier is set to Qt::ControlModifier. + + \see setInteractions +*/ +void QCustomPlot::setMultiSelectModifier(Qt::KeyboardModifier modifier) +{ + mMultiSelectModifier = modifier; +} + +/*! + Sets the viewport of this QCustomPlot. The Viewport is the area that the top level layout + (QCustomPlot::plotLayout()) uses as its rect. Normally, the viewport is the entire widget rect. + + This function is used to allow arbitrary size exports with \ref toPixmap, \ref savePng, \ref + savePdf, etc. by temporarily changing the viewport size. +*/ +void QCustomPlot::setViewport(const QRect &rect) +{ + mViewport = rect; + if (mPlotLayout) + mPlotLayout->setOuterRect(mViewport); +} + +/*! + Sets \a pm as the viewport background pixmap (see \ref setViewport). The pixmap is always drawn + below all other objects in the plot. + + For cases where the provided pixmap doesn't have the same size as the viewport, scaling can be + enabled with \ref setBackgroundScaled and the scaling mode (whether and how the aspect ratio is + preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, + consider using the overloaded version of this function. + + If a background brush was set with \ref setBackground(const QBrush &brush), the viewport will + first be filled with that brush, before drawing the background pixmap. This can be useful for + background pixmaps with translucent areas. + + \see setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QPixmap &pm) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); +} + +/*! + Sets the background brush of the viewport (see \ref setViewport). + + Before drawing everything else, the background is filled with \a brush. If a background pixmap + was set with \ref setBackground(const QPixmap &pm), this brush will be used to fill the viewport + before the background pixmap is drawn. This can be useful for background pixmaps with translucent + areas. + + Set \a brush to Qt::NoBrush or Qt::Transparent to leave background transparent. This can be + useful for exporting to image formats which support transparency, e.g. \ref savePng. + + \see setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QBrush &brush) +{ + mBackgroundBrush = brush; +} + +/*! \overload + + Allows setting the background pixmap of the viewport, whether it shall be scaled and how it + shall be scaled in one call. + + \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); + mBackgroundScaled = scaled; + mBackgroundScaledMode = mode; +} + +/*! + Sets whether the viewport background pixmap shall be scaled to fit the viewport. If \a scaled is + set to true, control whether and how the aspect ratio of the original pixmap is preserved with + \ref setBackgroundScaledMode. + + Note that the scaled version of the original pixmap is buffered, so there is no performance + penalty on replots. (Except when the viewport dimensions are changed continuously.) + + \see setBackground, setBackgroundScaledMode +*/ +void QCustomPlot::setBackgroundScaled(bool scaled) +{ + mBackgroundScaled = scaled; +} + +/*! + If scaling of the viewport background pixmap is enabled (\ref setBackgroundScaled), use this + function to define whether and how the aspect ratio of the original pixmap is preserved. + + \see setBackground, setBackgroundScaled +*/ +void QCustomPlot::setBackgroundScaledMode(Qt::AspectRatioMode mode) +{ + mBackgroundScaledMode = mode; +} + +/*! + Returns the plottable with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last added + plottable, see QCustomPlot::plottable() + + \see plottableCount, addPlottable +*/ +QCPAbstractPlottable *QCustomPlot::plottable(int index) +{ + if (index >= 0 && index < mPlottables.size()) + { + return mPlottables.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last plottable that was added with \ref addPlottable. If there are no plottables in + the plot, returns 0. + + \see plottableCount, addPlottable +*/ +QCPAbstractPlottable *QCustomPlot::plottable() +{ + if (!mPlottables.isEmpty()) + { + return mPlottables.last(); + } else + return 0; +} + +/*! + Adds the specified plottable to the plot and, if \ref setAutoAddPlottableToLegend is enabled, to + the legend (QCustomPlot::legend). QCustomPlot takes ownership of the plottable. + + Returns true on success, i.e. when \a plottable isn't already in the plot and the parent plot of + \a plottable is this QCustomPlot (the latter is controlled by what axes were passed in the + plottable's constructor). + + \see plottable, plottableCount, removePlottable, clearPlottables +*/ +bool QCustomPlot::addPlottable(QCPAbstractPlottable *plottable) +{ + if (mPlottables.contains(plottable)) + { + qDebug() << Q_FUNC_INFO << "plottable already added to this QCustomPlot:" << reinterpret_cast(plottable); + return false; + } + if (plottable->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "plottable not created with this QCustomPlot as parent:" << reinterpret_cast(plottable); + return false; + } + + mPlottables.append(plottable); + // possibly add plottable to legend: + if (mAutoAddPlottableToLegend) + plottable->addToLegend(); + // special handling for QCPGraphs to maintain the simple graph interface: + if (QCPGraph *graph = qobject_cast(plottable)) + mGraphs.append(graph); + if (!plottable->layer()) // usually the layer is already set in the constructor of the plottable (via QCPLayerable constructor) + plottable->setLayer(currentLayer()); + return true; +} + +/*! + Removes the specified plottable from the plot and, if necessary, from the legend (QCustomPlot::legend). + + Returns true on success. + + \see addPlottable, clearPlottables +*/ +bool QCustomPlot::removePlottable(QCPAbstractPlottable *plottable) +{ + if (!mPlottables.contains(plottable)) + { + qDebug() << Q_FUNC_INFO << "plottable not in list:" << reinterpret_cast(plottable); + return false; + } + + // remove plottable from legend: + plottable->removeFromLegend(); + // special handling for QCPGraphs to maintain the simple graph interface: + if (QCPGraph *graph = qobject_cast(plottable)) + mGraphs.removeOne(graph); + // remove plottable: + delete plottable; + mPlottables.removeOne(plottable); + return true; +} + +/*! \overload + + Removes the plottable by its \a index. +*/ +bool QCustomPlot::removePlottable(int index) +{ + if (index >= 0 && index < mPlottables.size()) + return removePlottable(mPlottables[index]); + else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return false; + } +} + +/*! + Removes all plottables from the plot (and the QCustomPlot::legend, if necessary). + + Returns the number of plottables removed. + + \see removePlottable +*/ +int QCustomPlot::clearPlottables() +{ + int c = mPlottables.size(); + for (int i=c-1; i >= 0; --i) + removePlottable(mPlottables[i]); + return c; +} + +/*! + Returns the number of currently existing plottables in the plot + + \see plottable, addPlottable +*/ +int QCustomPlot::plottableCount() const +{ + return mPlottables.size(); +} + +/*! + Returns a list of the selected plottables. If no plottables are currently selected, the list is empty. + + There is a convenience function if you're only interested in selected graphs, see \ref selectedGraphs. + + \see setInteractions, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelected +*/ +QList QCustomPlot::selectedPlottables() const +{ + QList result; + foreach (QCPAbstractPlottable *plottable, mPlottables) + { + if (plottable->selected()) + result.append(plottable); + } + return result; +} + +/*! + Returns the plottable at the pixel position \a pos. Plottables that only consist of single lines + (like graphs) have a tolerance band around them, see \ref setSelectionTolerance. If multiple + plottables come into consideration, the one closest to \a pos is returned. + + If \a onlySelectable is true, only plottables that are selectable + (QCPAbstractPlottable::setSelectable) are considered. + + If there is no plottable at \a pos, the return value is 0. + + \see itemAt, layoutElementAt +*/ +QCPAbstractPlottable *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable) const +{ + QCPAbstractPlottable *resultPlottable = 0; + double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value + + foreach (QCPAbstractPlottable *plottable, mPlottables) + { + if (onlySelectable && !plottable->selectable()) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPabstractPlottable::selectable + continue; + if ((plottable->keyAxis()->axisRect()->rect() & plottable->valueAxis()->axisRect()->rect()).contains(pos.toPoint())) // only consider clicks inside the rect that is spanned by the plottable's key/value axes + { + double currentDistance = plottable->selectTest(pos, false); + if (currentDistance >= 0 && currentDistance < resultDistance) + { + resultPlottable = plottable; + resultDistance = currentDistance; + } + } + } + + return resultPlottable; +} + +/*! + Returns whether this QCustomPlot instance contains the \a plottable. + + \see addPlottable +*/ +bool QCustomPlot::hasPlottable(QCPAbstractPlottable *plottable) const +{ + return mPlottables.contains(plottable); +} + +/*! + Returns the graph with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last created + graph, see QCustomPlot::graph() + + \see graphCount, addGraph +*/ +QCPGraph *QCustomPlot::graph(int index) const +{ + if (index >= 0 && index < mGraphs.size()) + { + return mGraphs.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last graph, that was created with \ref addGraph. If there are no graphs in the plot, + returns 0. + + \see graphCount, addGraph +*/ +QCPGraph *QCustomPlot::graph() const +{ + if (!mGraphs.isEmpty()) + { + return mGraphs.last(); + } else + return 0; +} + +/*! + Creates a new graph inside the plot. If \a keyAxis and \a valueAxis are left unspecified (0), the + bottom (xAxis) is used as key and the left (yAxis) is used as value axis. If specified, \a + keyAxis and \a valueAxis must reside in this QCustomPlot. + + \a keyAxis will be used as key axis (typically "x") and \a valueAxis as value axis (typically + "y") for the graph. + + Returns a pointer to the newly created graph, or 0 if adding the graph failed. + + \see graph, graphCount, removeGraph, clearGraphs +*/ +QCPGraph *QCustomPlot::addGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + if (!keyAxis) keyAxis = xAxis; + if (!valueAxis) valueAxis = yAxis; + if (!keyAxis || !valueAxis) + { + qDebug() << Q_FUNC_INFO << "can't use default QCustomPlot xAxis or yAxis, because at least one is invalid (has been deleted)"; + return 0; + } + if (keyAxis->parentPlot() != this || valueAxis->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "passed keyAxis or valueAxis doesn't have this QCustomPlot as parent"; + return 0; + } + + QCPGraph *newGraph = new QCPGraph(keyAxis, valueAxis); + if (addPlottable(newGraph)) + { + newGraph->setName(QLatin1String("Graph ")+QString::number(mGraphs.size())); + return newGraph; + } else + { + delete newGraph; + return 0; + } +} + +/*! + Removes the specified \a graph from the plot and, if necessary, from the QCustomPlot::legend. If + any other graphs in the plot have a channel fill set towards the removed graph, the channel fill + property of those graphs is reset to zero (no channel fill). + + Returns true on success. + + \see clearGraphs +*/ +bool QCustomPlot::removeGraph(QCPGraph *graph) +{ + return removePlottable(graph); +} + +/*! \overload + + Removes the graph by its \a index. +*/ +bool QCustomPlot::removeGraph(int index) +{ + if (index >= 0 && index < mGraphs.size()) + return removeGraph(mGraphs[index]); + else + return false; +} + +/*! + Removes all graphs from the plot (and the QCustomPlot::legend, if necessary). + + Returns the number of graphs removed. + + \see removeGraph +*/ +int QCustomPlot::clearGraphs() +{ + int c = mGraphs.size(); + for (int i=c-1; i >= 0; --i) + removeGraph(mGraphs[i]); + return c; +} + +/*! + Returns the number of currently existing graphs in the plot + + \see graph, addGraph +*/ +int QCustomPlot::graphCount() const +{ + return mGraphs.size(); +} + +/*! + Returns a list of the selected graphs. If no graphs are currently selected, the list is empty. + + If you are not only interested in selected graphs but other plottables like QCPCurve, QCPBars, + etc., use \ref selectedPlottables. + + \see setInteractions, selectedPlottables, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelected +*/ +QList QCustomPlot::selectedGraphs() const +{ + QList result; + foreach (QCPGraph *graph, mGraphs) + { + if (graph->selected()) + result.append(graph); + } + return result; +} + +/*! + Returns the item with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last added + item, see QCustomPlot::item() + + \see itemCount, addItem +*/ +QCPAbstractItem *QCustomPlot::item(int index) const +{ + if (index >= 0 && index < mItems.size()) + { + return mItems.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last item, that was added with \ref addItem. If there are no items in the plot, + returns 0. + + \see itemCount, addItem +*/ +QCPAbstractItem *QCustomPlot::item() const +{ + if (!mItems.isEmpty()) + { + return mItems.last(); + } else + return 0; +} + +/*! + Adds the specified item to the plot. QCustomPlot takes ownership of the item. + + Returns true on success, i.e. when \a item wasn't already in the plot and the parent plot of \a + item is this QCustomPlot. + + \see item, itemCount, removeItem, clearItems +*/ +bool QCustomPlot::addItem(QCPAbstractItem *item) +{ + if (!mItems.contains(item) && item->parentPlot() == this) + { + mItems.append(item); + return true; + } else + { + qDebug() << Q_FUNC_INFO << "item either already in list or not created with this QCustomPlot as parent:" << reinterpret_cast(item); + return false; + } +} + +/*! + Removes the specified item from the plot. + + Returns true on success. + + \see addItem, clearItems +*/ +bool QCustomPlot::removeItem(QCPAbstractItem *item) +{ + if (mItems.contains(item)) + { + delete item; + mItems.removeOne(item); + return true; + } else + { + qDebug() << Q_FUNC_INFO << "item not in list:" << reinterpret_cast(item); + return false; + } +} + +/*! \overload + + Removes the item by its \a index. +*/ +bool QCustomPlot::removeItem(int index) +{ + if (index >= 0 && index < mItems.size()) + return removeItem(mItems[index]); + else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return false; + } +} + +/*! + Removes all items from the plot. + + Returns the number of items removed. + + \see removeItem +*/ +int QCustomPlot::clearItems() +{ + int c = mItems.size(); + for (int i=c-1; i >= 0; --i) + removeItem(mItems[i]); + return c; +} + +/*! + Returns the number of currently existing items in the plot + + \see item, addItem +*/ +int QCustomPlot::itemCount() const +{ + return mItems.size(); +} + +/*! + Returns a list of the selected items. If no items are currently selected, the list is empty. + + \see setInteractions, QCPAbstractItem::setSelectable, QCPAbstractItem::setSelected +*/ +QList QCustomPlot::selectedItems() const +{ + QList result; + foreach (QCPAbstractItem *item, mItems) + { + if (item->selected()) + result.append(item); + } + return result; +} + +/*! + Returns the item at the pixel position \a pos. Items that only consist of single lines (e.g. \ref + QCPItemLine or \ref QCPItemCurve) have a tolerance band around them, see \ref + setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is + returned. + + If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are + considered. + + If there is no item at \a pos, the return value is 0. + + \see plottableAt, layoutElementAt +*/ +QCPAbstractItem *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const +{ + QCPAbstractItem *resultItem = 0; + double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value + + foreach (QCPAbstractItem *item, mItems) + { + if (onlySelectable && !item->selectable()) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPAbstractItem::selectable + continue; + if (!item->clipToAxisRect() || item->clipRect().contains(pos.toPoint())) // only consider clicks inside axis cliprect of the item if actually clipped to it + { + double currentDistance = item->selectTest(pos, false); + if (currentDistance >= 0 && currentDistance < resultDistance) + { + resultItem = item; + resultDistance = currentDistance; + } + } + } + + return resultItem; +} + +/*! + Returns whether this QCustomPlot contains the \a item. + + \see addItem +*/ +bool QCustomPlot::hasItem(QCPAbstractItem *item) const +{ + return mItems.contains(item); +} + +/*! + Returns the layer with the specified \a name. If there is no layer with the specified name, 0 is + returned. + + Layer names are case-sensitive. + + \see addLayer, moveLayer, removeLayer +*/ +QCPLayer *QCustomPlot::layer(const QString &name) const +{ + foreach (QCPLayer *layer, mLayers) + { + if (layer->name() == name) + return layer; + } + return 0; +} + +/*! \overload + + Returns the layer by \a index. If the index is invalid, 0 is returned. + + \see addLayer, moveLayer, removeLayer +*/ +QCPLayer *QCustomPlot::layer(int index) const +{ + if (index >= 0 && index < mLayers.size()) + { + return mLayers.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! + Returns the layer that is set as current layer (see \ref setCurrentLayer). +*/ +QCPLayer *QCustomPlot::currentLayer() const +{ + return mCurrentLayer; +} + +/*! + Sets the layer with the specified \a name to be the current layer. All layerables (\ref + QCPLayerable), e.g. plottables and items, are created on the current layer. + + Returns true on success, i.e. if there is a layer with the specified \a name in the QCustomPlot. + + Layer names are case-sensitive. + + \see addLayer, moveLayer, removeLayer, QCPLayerable::setLayer +*/ +bool QCustomPlot::setCurrentLayer(const QString &name) +{ + if (QCPLayer *newCurrentLayer = layer(name)) + { + return setCurrentLayer(newCurrentLayer); + } else + { + qDebug() << Q_FUNC_INFO << "layer with name doesn't exist:" << name; + return false; + } +} + +/*! \overload + + Sets the provided \a layer to be the current layer. + + Returns true on success, i.e. when \a layer is a valid layer in the QCustomPlot. + + \see addLayer, moveLayer, removeLayer +*/ +bool QCustomPlot::setCurrentLayer(QCPLayer *layer) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + + mCurrentLayer = layer; + return true; +} + +/*! + Returns the number of currently existing layers in the plot + + \see layer, addLayer +*/ +int QCustomPlot::layerCount() const +{ + return mLayers.size(); +} + +/*! + Adds a new layer to this QCustomPlot instance. The new layer will have the name \a name, which + must be unique. Depending on \a insertMode, it is positioned either below or above \a otherLayer. + + Returns true on success, i.e. if there is no other layer named \a name and \a otherLayer is a + valid layer inside this QCustomPlot. + + If \a otherLayer is 0, the highest layer in the QCustomPlot will be used. + + For an explanation of what layers are in QCustomPlot, see the documentation of \ref QCPLayer. + + \see layer, moveLayer, removeLayer +*/ +bool QCustomPlot::addLayer(const QString &name, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) +{ + if (!otherLayer) + otherLayer = mLayers.last(); + if (!mLayers.contains(otherLayer)) + { + qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); + return false; + } + if (layer(name)) + { + qDebug() << Q_FUNC_INFO << "A layer exists already with the name" << name; + return false; + } + + QCPLayer *newLayer = new QCPLayer(this, name); + mLayers.insert(otherLayer->index() + (insertMode==limAbove ? 1:0), newLayer); + updateLayerIndices(); + return true; +} + +/*! + Removes the specified \a layer and returns true on success. + + All layerables (e.g. plottables and items) on the removed layer will be moved to the layer below + \a layer. If \a layer is the bottom layer, the layerables are moved to the layer above. In both + cases, the total rendering order of all layerables in the QCustomPlot is preserved. + + If \a layer is the current layer (\ref setCurrentLayer), the layer below (or above, if bottom + layer) becomes the new current layer. + + It is not possible to remove the last layer of the plot. + + \see layer, addLayer, moveLayer +*/ +bool QCustomPlot::removeLayer(QCPLayer *layer) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + if (mLayers.size() < 2) + { + qDebug() << Q_FUNC_INFO << "can't remove last layer"; + return false; + } + + // append all children of this layer to layer below (if this is lowest layer, prepend to layer above) + int removedIndex = layer->index(); + bool isFirstLayer = removedIndex==0; + QCPLayer *targetLayer = isFirstLayer ? mLayers.at(removedIndex+1) : mLayers.at(removedIndex-1); + QList children = layer->children(); + if (isFirstLayer) // prepend in reverse order (so order relative to each other stays the same) + { + for (int i=children.size()-1; i>=0; --i) + children.at(i)->moveToLayer(targetLayer, true); + } else // append normally + { + for (int i=0; imoveToLayer(targetLayer, false); + } + // if removed layer is current layer, change current layer to layer below/above: + if (layer == mCurrentLayer) + setCurrentLayer(targetLayer); + // remove layer: + delete layer; + mLayers.removeOne(layer); + updateLayerIndices(); + return true; +} + +/*! + Moves the specified \a layer either above or below \a otherLayer. Whether it's placed above or + below is controlled with \a insertMode. + + Returns true on success, i.e. when both \a layer and \a otherLayer are valid layers in the + QCustomPlot. + + \see layer, addLayer, moveLayer +*/ +bool QCustomPlot::moveLayer(QCPLayer *layer, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + if (!mLayers.contains(otherLayer)) + { + qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); + return false; + } + + if (layer->index() > otherLayer->index()) + mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 1:0)); + else if (layer->index() < otherLayer->index()) + mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 0:-1)); + + updateLayerIndices(); + return true; +} + +/*! + Returns the number of axis rects in the plot. + + All axis rects can be accessed via QCustomPlot::axisRect(). + + Initially, only one axis rect exists in the plot. + + \see axisRect, axisRects +*/ +int QCustomPlot::axisRectCount() const +{ + return axisRects().size(); +} + +/*! + Returns the axis rect with \a index. + + Initially, only one axis rect (with index 0) exists in the plot. If multiple axis rects were + added, all of them may be accessed with this function in a linear fashion (even when they are + nested in a layout hierarchy or inside other axis rects via QCPAxisRect::insetLayout). + + \see axisRectCount, axisRects +*/ +QCPAxisRect *QCustomPlot::axisRect(int index) const +{ + const QList rectList = axisRects(); + if (index >= 0 && index < rectList.size()) + { + return rectList.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "invalid axis rect index" << index; + return 0; + } +} + +/*! + Returns all axis rects in the plot. + + \see axisRectCount, axisRect +*/ +QList QCustomPlot::axisRects() const +{ + QList result; + QStack elementStack; + if (mPlotLayout) + elementStack.push(mPlotLayout); + + while (!elementStack.isEmpty()) + { + foreach (QCPLayoutElement *element, elementStack.pop()->elements(false)) + { + if (element) + { + elementStack.push(element); + if (QCPAxisRect *ar = qobject_cast(element)) + result.append(ar); + } + } + } + + return result; +} + +/*! + Returns the layout element at pixel position \a pos. If there is no element at that position, + returns 0. + + Only visible elements are used. If \ref QCPLayoutElement::setVisible on the element itself or on + any of its parent elements is set to false, it will not be considered. + + \see itemAt, plottableAt +*/ +QCPLayoutElement *QCustomPlot::layoutElementAt(const QPointF &pos) const +{ + QCPLayoutElement *currentElement = mPlotLayout; + bool searchSubElements = true; + while (searchSubElements && currentElement) + { + searchSubElements = false; + foreach (QCPLayoutElement *subElement, currentElement->elements(false)) + { + if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) + { + currentElement = subElement; + searchSubElements = true; + break; + } + } + } + return currentElement; +} + +/*! + Returns the axes that currently have selected parts, i.e. whose selection state is not \ref + QCPAxis::spNone. + + \see selectedPlottables, selectedLegends, setInteractions, QCPAxis::setSelectedParts, + QCPAxis::setSelectableParts +*/ +QList QCustomPlot::selectedAxes() const +{ + QList result, allAxes; + foreach (QCPAxisRect *rect, axisRects()) + allAxes << rect->axes(); + + foreach (QCPAxis *axis, allAxes) + { + if (axis->selectedParts() != QCPAxis::spNone) + result.append(axis); + } + + return result; +} + +/*! + Returns the legends that currently have selected parts, i.e. whose selection state is not \ref + QCPLegend::spNone. + + \see selectedPlottables, selectedAxes, setInteractions, QCPLegend::setSelectedParts, + QCPLegend::setSelectableParts, QCPLegend::selectedItems +*/ +QList QCustomPlot::selectedLegends() const +{ + QList result; + + QStack elementStack; + if (mPlotLayout) + elementStack.push(mPlotLayout); + + while (!elementStack.isEmpty()) + { + foreach (QCPLayoutElement *subElement, elementStack.pop()->elements(false)) + { + if (subElement) + { + elementStack.push(subElement); + if (QCPLegend *leg = qobject_cast(subElement)) + { + if (leg->selectedParts() != QCPLegend::spNone) + result.append(leg); + } + } + } + } + + return result; +} + +/*! + Deselects all layerables (plottables, items, axes, legends,...) of the QCustomPlot. + + Since calling this function is not a user interaction, this does not emit the \ref + selectionChangedByUser signal. The individual selectionChanged signals are emitted though, if the + objects were previously selected. + + \see setInteractions, selectedPlottables, selectedItems, selectedAxes, selectedLegends +*/ +void QCustomPlot::deselectAll() +{ + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + layerable->deselectEvent(0); + } +} + +/*! + Causes a complete replot into the internal buffer. Finally, update() is called, to redraw the + buffer on the QCustomPlot widget surface. This is the method that must be called to make changes, + for example on the axis ranges or data points of graphs, visible. + + Under a few circumstances, QCustomPlot causes a replot by itself. Those are resize events of the + QCustomPlot widget and user interactions (object selection and range dragging/zooming). + + Before the replot happens, the signal \ref beforeReplot is emitted. After the replot, \ref + afterReplot is emitted. It is safe to mutually connect the replot slot with any of those two + signals on two QCustomPlots to make them replot synchronously, it won't cause an infinite + recursion. +*/ +void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority) +{ + if (mReplotting) // incase signals loop back to replot slot + return; + mReplotting = true; + emit beforeReplot(); + + mPaintBuffer.fill(mBackgroundBrush.style() == Qt::SolidPattern ? mBackgroundBrush.color() : Qt::transparent); + QCPPainter painter; + painter.begin(&mPaintBuffer); + if (painter.isActive()) + { + painter.setRenderHint(QPainter::HighQualityAntialiasing); // to make Antialiasing look good if using the OpenGL graphicssystem + if (mBackgroundBrush.style() != Qt::SolidPattern && mBackgroundBrush.style() != Qt::NoBrush) + painter.fillRect(mViewport, mBackgroundBrush); + draw(&painter); + painter.end(); + if ((refreshPriority == rpHint && mPlottingHints.testFlag(QCP::phForceRepaint)) || refreshPriority==rpImmediate) + repaint(); + else + update(); + } else // might happen if QCustomPlot has width or height zero + qDebug() << Q_FUNC_INFO << "Couldn't activate painter on buffer. This usually happens because QCustomPlot has width or height zero."; + + emit afterReplot(); + mReplotting = false; +} + +/*! + Rescales the axes such that all plottables (like graphs) in the plot are fully visible. + + if \a onlyVisiblePlottables is set to true, only the plottables that have their visibility set to true + (QCPLayerable::setVisible), will be used to rescale the axes. + + \see QCPAbstractPlottable::rescaleAxes, QCPAxis::rescale +*/ +void QCustomPlot::rescaleAxes(bool onlyVisiblePlottables) +{ + QList allAxes; + foreach (QCPAxisRect *rect, axisRects()) + allAxes << rect->axes(); + + foreach (QCPAxis *axis, allAxes) + axis->rescale(onlyVisiblePlottables); +} + +/*! + Saves a PDF with the vectorized plot to the file \a fileName. The axis ratio as well as the scale + of texts and lines will be derived from the specified \a width and \a height. This means, the + output will look like the normal on-screen output of a QCustomPlot widget with the corresponding + pixel width and height. If either \a width or \a height is zero, the exported image will have the + same dimensions as the QCustomPlot widget currently has. + + \a noCosmeticPen disables the use of cosmetic pens when drawing to the PDF file. Cosmetic pens + are pens with numerical width 0, which are always drawn as a one pixel wide line, no matter what + zoom factor is set in the PDF-Viewer. For more information about cosmetic pens, see the QPainter + and QPen documentation. + + The objects of the plot will appear in the current selection state. If you don't want any + selected objects to be painted in their selected look, deselect everything with \ref deselectAll + before calling this function. + + Returns true on success. + + \warning + \li If you plan on editing the exported PDF file with a vector graphics editor like + Inkscape, it is advised to set \a noCosmeticPen to true to avoid losing those cosmetic lines + (which might be quite many, because cosmetic pens are the default for e.g. axes and tick marks). + \li If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \a pdfCreator and \a pdfTitle may be used to set the according metadata fields in the resulting + PDF file. + + \note On Android systems, this method does nothing and issues an according qDebug warning + message. This is also the case if for other reasons the define flag QT_NO_PRINTER is set. + + \see savePng, saveBmp, saveJpg, saveRastered +*/ +bool QCustomPlot::savePdf(const QString &fileName, bool noCosmeticPen, int width, int height, const QString &pdfCreator, const QString &pdfTitle) +{ + bool success = false; +#ifdef QT_NO_PRINTER + Q_UNUSED(fileName) + Q_UNUSED(noCosmeticPen) + Q_UNUSED(width) + Q_UNUSED(height) + Q_UNUSED(pdfCreator) + Q_UNUSED(pdfTitle) + qDebug() << Q_FUNC_INFO << "Qt was built without printer support (QT_NO_PRINTER). PDF not created."; +#else + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + + QPrinter printer(QPrinter::ScreenResolution); + printer.setOutputFileName(fileName); + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setColorMode(QPrinter::Color); + printer.printEngine()->setProperty(QPrintEngine::PPK_Creator, pdfCreator); + printer.printEngine()->setProperty(QPrintEngine::PPK_DocumentName, pdfTitle); + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) + printer.setFullPage(true); + printer.setPaperSize(viewport().size(), QPrinter::DevicePixel); +#else + QPageLayout pageLayout; + pageLayout.setMode(QPageLayout::FullPageMode); + pageLayout.setOrientation(QPageLayout::Portrait); + pageLayout.setMargins(QMarginsF(0, 0, 0, 0)); + pageLayout.setPageSize(QPageSize(viewport().size(), QPageSize::Point, QString(), QPageSize::ExactMatch)); + printer.setPageLayout(pageLayout); +#endif + QCPPainter printpainter; + if (printpainter.begin(&printer)) + { + printpainter.setMode(QCPPainter::pmVectorized); + printpainter.setMode(QCPPainter::pmNoCaching); + printpainter.setMode(QCPPainter::pmNonCosmetic, noCosmeticPen); + printpainter.setWindow(mViewport); + if (mBackgroundBrush.style() != Qt::NoBrush && + mBackgroundBrush.color() != Qt::white && + mBackgroundBrush.color() != Qt::transparent && + mBackgroundBrush.color().alpha() > 0) // draw pdf background color if not white/transparent + printpainter.fillRect(viewport(), mBackgroundBrush); + draw(&printpainter); + printpainter.end(); + success = true; + } + setViewport(oldViewport); +#endif // QT_NO_PRINTER + return success; +} + +/*! + Saves a PNG image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels. If either \a width or \a height is zero, the exported image will have + the same dimensions as the QCustomPlot widget currently has. Line widths and texts etc. are not + scaled up when larger widths/heights are used. If you want that effect, use the \a scale parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements via + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + If you want the PNG to have a transparent background, call \ref setBackground(const QBrush + &brush) with no brush (Qt::NoBrush) or a transparent color (Qt::transparent), before saving. + + PNG compression can be controlled with the \a quality parameter which must be between 0 and 100 or + -1 to use the default setting. + + Returns true on success. If this function fails, most likely the PNG format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + \see savePdf, saveBmp, saveJpg, saveRastered +*/ +bool QCustomPlot::savePng(const QString &fileName, int width, int height, double scale, int quality) +{ + return saveRastered(fileName, width, height, scale, "PNG", quality); +} + +/*! + Saves a JPG image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels. If either \a width or \a height is zero, the exported image will have + the same dimensions as the QCustomPlot widget currently has. Line widths and texts etc. are not + scaled up when larger widths/heights are used. If you want that effect, use the \a scale parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements via + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + JPG compression can be controlled with the \a quality parameter which must be between 0 and 100 or + -1 to use the default setting. + + Returns true on success. If this function fails, most likely the JPG format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + \see savePdf, savePng, saveBmp, saveRastered +*/ +bool QCustomPlot::saveJpg(const QString &fileName, int width, int height, double scale, int quality) +{ + return saveRastered(fileName, width, height, scale, "JPG", quality); +} + +/*! + Saves a BMP image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels. If either \a width or \a height is zero, the exported image will have + the same dimensions as the QCustomPlot widget currently has. Line widths and texts etc. are not + scaled up when larger widths/heights are used. If you want that effect, use the \a scale parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements via + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + Returns true on success. If this function fails, most likely the BMP format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + \see savePdf, savePng, saveJpg, saveRastered +*/ +bool QCustomPlot::saveBmp(const QString &fileName, int width, int height, double scale) +{ + return saveRastered(fileName, width, height, scale, "BMP"); +} + +/*! \internal + + Returns a minimum size hint that corresponds to the minimum size of the top level layout + (\ref plotLayout). To prevent QCustomPlot from being collapsed to size/width zero, set a minimum + size (setMinimumSize) either on the whole QCustomPlot or on any layout elements inside the plot. + This is especially important, when placed in a QLayout where other components try to take in as + much space as possible (e.g. QMdiArea). +*/ +QSize QCustomPlot::minimumSizeHint() const +{ + return mPlotLayout->minimumSizeHint(); +} + +/*! \internal + + Returns a size hint that is the same as \ref minimumSizeHint. + +*/ +QSize QCustomPlot::sizeHint() const +{ + return mPlotLayout->minimumSizeHint(); +} + +/*! \internal + + Event handler for when the QCustomPlot widget needs repainting. This does not cause a \ref replot, but + draws the internal buffer on the widget surface. +*/ +void QCustomPlot::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + QPainter painter(this); + painter.drawPixmap(0, 0, mPaintBuffer); +} + +/*! \internal + + Event handler for a resize of the QCustomPlot widget. Causes the internal buffer to be resized to + the new size. The viewport (which becomes the outer rect of mPlotLayout) is resized + appropriately. Finally a \ref replot is performed. +*/ +void QCustomPlot::resizeEvent(QResizeEvent *event) +{ + // resize and repaint the buffer: + mPaintBuffer = QPixmap(event->size()); + setViewport(rect()); + replot(rpQueued); // queued update is important here, to prevent painting issues in some contexts +} + +/*! \internal + + Event handler for when a double click occurs. Emits the \ref mouseDoubleClick signal, then emits + the specialized signals when certain objecs are clicked (e.g. \ref plottableDoubleClick, \ref + axisDoubleClick, etc.). Finally determines the affected layout element and forwards the event to + it. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCustomPlot::mouseDoubleClickEvent(QMouseEvent *event) +{ + emit mouseDoubleClick(event); + + QVariant details; + QCPLayerable *clickedLayerable = layerableAt(event->pos(), false, &details); + + // emit specialized object double click signals: + if (QCPAbstractPlottable *ap = qobject_cast(clickedLayerable)) + emit plottableDoubleClick(ap, event); + else if (QCPAxis *ax = qobject_cast(clickedLayerable)) + emit axisDoubleClick(ax, details.value(), event); + else if (QCPAbstractItem *ai = qobject_cast(clickedLayerable)) + emit itemDoubleClick(ai, event); + else if (QCPLegend *lg = qobject_cast(clickedLayerable)) + emit legendDoubleClick(lg, 0, event); + else if (QCPAbstractLegendItem *li = qobject_cast(clickedLayerable)) + emit legendDoubleClick(li->parentLegend(), li, event); + else if (QCPPlotTitle *pt = qobject_cast(clickedLayerable)) + emit titleDoubleClick(event, pt); + + // call double click event of affected layout element: + if (QCPLayoutElement *el = layoutElementAt(event->pos())) + el->mouseDoubleClickEvent(event); + + // call release event of affected layout element (as in mouseReleaseEvent, since the mouseDoubleClick replaces the second release event in double click case): + if (mMouseEventElement) + { + mMouseEventElement->mouseReleaseEvent(event); + mMouseEventElement = 0; + } + + //QWidget::mouseDoubleClickEvent(event); don't call base class implementation because it would just cause a mousePress/ReleaseEvent, which we don't want. +} + +/*! \internal + + Event handler for when a mouse button is pressed. Emits the mousePress signal. Then determines + the affected layout element and forwards the event to it. + + \see mouseMoveEvent, mouseReleaseEvent +*/ +void QCustomPlot::mousePressEvent(QMouseEvent *event) +{ + emit mousePress(event); + mMousePressPos = event->pos(); // need this to determine in releaseEvent whether it was a click (no position change between press and release) + + // call event of affected layout element: + mMouseEventElement = layoutElementAt(event->pos()); + if (mMouseEventElement) + mMouseEventElement->mousePressEvent(event); + + QWidget::mousePressEvent(event); +} + +/*! \internal + + Event handler for when the cursor is moved. Emits the \ref mouseMove signal. + + If a layout element has mouse capture focus (a mousePressEvent happened on top of the layout + element before), the mouseMoveEvent is forwarded to that element. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCustomPlot::mouseMoveEvent(QMouseEvent *event) +{ + emit mouseMove(event); + + // call event of affected layout element: + if (mMouseEventElement) + mMouseEventElement->mouseMoveEvent(event); + + QWidget::mouseMoveEvent(event); +} + +/*! \internal + + Event handler for when a mouse button is released. Emits the \ref mouseRelease signal. + + If the mouse was moved less than a certain threshold in any direction since the \ref + mousePressEvent, it is considered a click which causes the selection mechanism (if activated via + \ref setInteractions) to possibly change selection states accordingly. Further, specialized mouse + click signals are emitted (e.g. \ref plottableClick, \ref axisClick, etc.) + + If a layout element has mouse capture focus (a \ref mousePressEvent happened on top of the layout + element before), the \ref mouseReleaseEvent is forwarded to that element. + + \see mousePressEvent, mouseMoveEvent +*/ +void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) +{ + emit mouseRelease(event); + bool doReplot = false; + + if ((mMousePressPos-event->pos()).manhattanLength() < 5) // determine whether it was a click operation + { + if (event->button() == Qt::LeftButton) + { + // handle selection mechanism: + QVariant details; + QCPLayerable *clickedLayerable = layerableAt(event->pos(), true, &details); + bool selectionStateChanged = false; + bool additive = mInteractions.testFlag(QCP::iMultiSelect) && event->modifiers().testFlag(mMultiSelectModifier); + // deselect all other layerables if not additive selection: + if (!additive) + { + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + { + if (layerable != clickedLayerable && mInteractions.testFlag(layerable->selectionCategory())) + { + bool selChanged = false; + layerable->deselectEvent(&selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + if (clickedLayerable && mInteractions.testFlag(clickedLayerable->selectionCategory())) + { + // a layerable was actually clicked, call its selectEvent: + bool selChanged = false; + clickedLayerable->selectEvent(event, additive, details, &selChanged); + selectionStateChanged |= selChanged; + } + if (selectionStateChanged) + { + doReplot = true; + emit selectionChangedByUser(); + } + } + + // emit specialized object click signals: + QVariant details; + QCPLayerable *clickedLayerable = layerableAt(event->pos(), false, &details); // for these signals, selectability is ignored, that's why we call this again with onlySelectable set to false + if (QCPAbstractPlottable *ap = qobject_cast(clickedLayerable)) + emit plottableClick(ap, event); + else if (QCPAxis *ax = qobject_cast(clickedLayerable)) + emit axisClick(ax, details.value(), event); + else if (QCPAbstractItem *ai = qobject_cast(clickedLayerable)) + emit itemClick(ai, event); + else if (QCPLegend *lg = qobject_cast(clickedLayerable)) + emit legendClick(lg, 0, event); + else if (QCPAbstractLegendItem *li = qobject_cast(clickedLayerable)) + emit legendClick(li->parentLegend(), li, event); + else if (QCPPlotTitle *pt = qobject_cast(clickedLayerable)) + emit titleClick(event, pt); + } + + // call event of affected layout element: + if (mMouseEventElement) + { + mMouseEventElement->mouseReleaseEvent(event); + mMouseEventElement = 0; + } + + if (doReplot || noAntialiasingOnDrag()) + replot(); + + QWidget::mouseReleaseEvent(event); +} + +/*! \internal + + Event handler for mouse wheel events. First, the \ref mouseWheel signal is emitted. Then + determines the affected layout element and forwards the event to it. + +*/ +void QCustomPlot::wheelEvent(QWheelEvent *event) +{ + emit mouseWheel(event); + + // call event of affected layout element: + if (QCPLayoutElement *el = layoutElementAt(event->pos())) + el->wheelEvent(event); + + QWidget::wheelEvent(event); +} + +/*! \internal + + This is the main draw function. It draws the entire plot, including background pixmap, with the + specified \a painter. Note that it does not fill the background with the background brush (as the + user may specify with \ref setBackground(const QBrush &brush)), this is up to the respective + functions calling this method (e.g. \ref replot, \ref toPixmap and \ref toPainter). +*/ +void QCustomPlot::draw(QCPPainter *painter) +{ + // run through layout phases: + mPlotLayout->update(QCPLayoutElement::upPreparation); + mPlotLayout->update(QCPLayoutElement::upMargins); + mPlotLayout->update(QCPLayoutElement::upLayout); + + // draw viewport background pixmap: + drawBackground(painter); + + // draw all layered objects (grid, axes, plottables, items, legend,...): + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *child, layer->children()) + { + if (child->realVisibility()) + { + painter->save(); + painter->setClipRect(child->clipRect().translated(0, -1)); + child->applyDefaultAntialiasingHint(painter); + child->draw(painter); + painter->restore(); + } + } + } + + /* Debug code to draw all layout element rects + foreach (QCPLayoutElement* el, findChildren()) + { + painter->setBrush(Qt::NoBrush); + painter->setPen(QPen(QColor(0, 0, 0, 100), 0, Qt::DashLine)); + painter->drawRect(el->rect()); + painter->setPen(QPen(QColor(255, 0, 0, 100), 0, Qt::DashLine)); + painter->drawRect(el->outerRect()); + } + */ +} + +/*! \internal + + Draws the viewport background pixmap of the plot. + + If a pixmap was provided via \ref setBackground, this function buffers the scaled version + depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside + the viewport with the provided \a painter. The scaled version is buffered in + mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when + the axis rect has changed in a way that requires a rescale of the background pixmap (this is + dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was + set. + + Note that this function does not draw a fill with the background brush (\ref setBackground(const + QBrush &brush)) beneath the pixmap. + + \see setBackground, setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::drawBackground(QCPPainter *painter) +{ + // Note: background color is handled in individual replot/save functions + + // draw background pixmap (on top of fill, if brush specified): + if (!mBackgroundPixmap.isNull()) + { + if (mBackgroundScaled) + { + // check whether mScaledBackground needs to be updated: + QSize scaledSize(mBackgroundPixmap.size()); + scaledSize.scale(mViewport.size(), mBackgroundScaledMode); + if (mScaledBackgroundPixmap.size() != scaledSize) + mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mViewport.size(), mBackgroundScaledMode, Qt::SmoothTransformation); + painter->drawPixmap(mViewport.topLeft(), mScaledBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height()) & mScaledBackgroundPixmap.rect()); + } else + { + painter->drawPixmap(mViewport.topLeft(), mBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height())); + } + } +} + + +/*! \internal + + This method is used by \ref QCPAxisRect::removeAxis to report removed axes to the QCustomPlot + so it may clear its QCustomPlot::xAxis, yAxis, xAxis2 and yAxis2 members accordingly. +*/ +void QCustomPlot::axisRemoved(QCPAxis *axis) +{ + if (xAxis == axis) + xAxis = 0; + if (xAxis2 == axis) + xAxis2 = 0; + if (yAxis == axis) + yAxis = 0; + if (yAxis2 == axis) + yAxis2 = 0; + + // Note: No need to take care of range drag axes and range zoom axes, because they are stored in smart pointers +} + +/*! \internal + + This method is used by the QCPLegend destructor to report legend removal to the QCustomPlot so + it may clear its QCustomPlot::legend member accordingly. +*/ +void QCustomPlot::legendRemoved(QCPLegend *legend) +{ + if (this->legend == legend) + this->legend = 0; +} + +/*! \internal + + Assigns all layers their index (QCPLayer::mIndex) in the mLayers list. This method is thus called + after every operation that changes the layer indices, like layer removal, layer creation, layer + moving. +*/ +void QCustomPlot::updateLayerIndices() const +{ + for (int i=0; imIndex = i; +} + +/*! \internal + + Returns the layerable at pixel position \a pos. If \a onlySelectable is set to true, only those + layerables that are selectable will be considered. (Layerable subclasses communicate their + selectability via the QCPLayerable::selectTest method, by returning -1.) + + \a selectionDetails is an output parameter that contains selection specifics of the affected + layerable. This is useful if the respective layerable shall be given a subsequent + QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains + information about which part of the layerable was hit, in multi-part layerables (e.g. + QCPAxis::SelectablePart). +*/ +QCPLayerable *QCustomPlot::layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails) const +{ + for (int layerIndex=mLayers.size()-1; layerIndex>=0; --layerIndex) + { + const QList layerables = mLayers.at(layerIndex)->children(); + double minimumDistance = selectionTolerance()*1.1; + QCPLayerable *minimumDistanceLayerable = 0; + for (int i=layerables.size()-1; i>=0; --i) + { + if (!layerables.at(i)->realVisibility()) + continue; + QVariant details; + double dist = layerables.at(i)->selectTest(pos, onlySelectable, &details); + if (dist >= 0 && dist < minimumDistance) + { + minimumDistance = dist; + minimumDistanceLayerable = layerables.at(i); + if (selectionDetails) *selectionDetails = details; + } + } + if (minimumDistance < selectionTolerance()) + return minimumDistanceLayerable; + } + return 0; +} + +/*! + Saves the plot to a rastered image file \a fileName in the image format \a format. The plot is + sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and scale 2.0 lead + to a full resolution file with width 200.) If the \a format supports compression, \a quality may + be between 0 and 100 to control it. + + Returns true on success. If this function fails, most likely the given \a format isn't supported + by the system, see Qt docs about QImageWriter::supportedImageFormats(). + + \see saveBmp, saveJpg, savePng, savePdf +*/ +bool QCustomPlot::saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality) +{ + QPixmap buffer = toPixmap(width, height, scale); + if (!buffer.isNull()) + return buffer.save(fileName, format, quality); + else + return false; +} + +/*! + Renders the plot to a pixmap and returns it. + + The plot is sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and + scale 2.0 lead to a full resolution pixmap with width 200.) + + \see toPainter, saveRastered, saveBmp, savePng, saveJpg, savePdf +*/ +QPixmap QCustomPlot::toPixmap(int width, int height, double scale) +{ + // this method is somewhat similar to toPainter. Change something here, and a change in toPainter might be necessary, too. + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + int scaledWidth = qRound(scale*newWidth); + int scaledHeight = qRound(scale*newHeight); + + QPixmap result(scaledWidth, scaledHeight); + result.fill(mBackgroundBrush.style() == Qt::SolidPattern ? mBackgroundBrush.color() : Qt::transparent); // if using non-solid pattern, make transparent now and draw brush pattern later + QCPPainter painter; + painter.begin(&result); + if (painter.isActive()) + { + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); + painter.setMode(QCPPainter::pmNoCaching); + if (!qFuzzyCompare(scale, 1.0)) + { + if (scale > 1.0) // for scale < 1 we always want cosmetic pens where possible, because else lines might disappear for very small scales + painter.setMode(QCPPainter::pmNonCosmetic); + painter.scale(scale, scale); + } + if (mBackgroundBrush.style() != Qt::SolidPattern && mBackgroundBrush.style() != Qt::NoBrush) // solid fills were done a few lines above with QPixmap::fill + painter.fillRect(mViewport, mBackgroundBrush); + draw(&painter); + setViewport(oldViewport); + painter.end(); + } else // might happen if pixmap has width or height zero + { + qDebug() << Q_FUNC_INFO << "Couldn't activate painter on pixmap"; + return QPixmap(); + } + return result; +} + +/*! + Renders the plot using the passed \a painter. + + The plot is sized to \a width and \a height in pixels. If the \a painter's scale is not 1.0, the resulting plot will + appear scaled accordingly. + + \note If you are restricted to using a QPainter (instead of QCPPainter), create a temporary QPicture and open a QCPPainter + on it. Then call \ref toPainter with this QCPPainter. After ending the paint operation on the picture, draw it with + the QPainter. This will reproduce the painter actions the QCPPainter took, with a QPainter. + + \see toPixmap +*/ +void QCustomPlot::toPainter(QCPPainter *painter, int width, int height) +{ + // this method is somewhat similar to toPixmap. Change something here, and a change in toPixmap might be necessary, too. + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + + if (painter->isActive()) + { + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); + painter->setMode(QCPPainter::pmNoCaching); + if (mBackgroundBrush.style() != Qt::NoBrush) // unlike in toPixmap, we can't do QPixmap::fill for Qt::SolidPattern brush style, so we also draw solid fills with fillRect here + painter->fillRect(mViewport, mBackgroundBrush); + draw(painter); + setViewport(oldViewport); + } else + qDebug() << Q_FUNC_INFO << "Passed painter is not active"; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorGradient +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorGradient + \brief Defines a color gradient for use with e.g. \ref QCPColorMap + + This class describes a color gradient which can be used to encode data with color. For example, + QCPColorMap and QCPColorScale have \ref QCPColorMap::setGradient "setGradient" methods which + take an instance of this class. Colors are set with \ref setColorStopAt(double position, const QColor &color) + with a \a position from 0 to 1. In between these defined color positions, the + color will be interpolated linearly either in RGB or HSV space, see \ref setColorInterpolation. + + Alternatively, load one of the preset color gradients shown in the image below, with \ref + loadPreset, or by directly specifying the preset in the constructor. + + \image html QCPColorGradient.png + + The fact that the \ref QCPColorGradient(GradientPreset preset) constructor allows directly + converting a \ref GradientPreset to a QCPColorGradient, you can also directly pass \ref + GradientPreset to all the \a setGradient methods, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorgradient-setgradient + + The total number of levels used in the gradient can be set with \ref setLevelCount. Whether the + color gradient shall be applied periodically (wrapping around) to data values that lie outside + the data range specified on the plottable instance can be controlled with \ref setPeriodic. +*/ + +/*! + Constructs a new QCPColorGradient initialized with the colors and color interpolation according + to \a preset. + + The color level count is initialized to 350. +*/ +QCPColorGradient::QCPColorGradient(GradientPreset preset) : + mLevelCount(350), + mColorInterpolation(ciRGB), + mPeriodic(false), + mColorBufferInvalidated(true) +{ + mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); + loadPreset(preset); +} + +/* undocumented operator */ +bool QCPColorGradient::operator==(const QCPColorGradient &other) const +{ + return ((other.mLevelCount == this->mLevelCount) && + (other.mColorInterpolation == this->mColorInterpolation) && + (other.mPeriodic == this->mPeriodic) && + (other.mColorStops == this->mColorStops)); +} + +/*! + Sets the number of discretization levels of the color gradient to \a n. The default is 350 which + is typically enough to create a smooth appearance. + + \image html QCPColorGradient-levelcount.png +*/ +void QCPColorGradient::setLevelCount(int n) +{ + if (n < 2) + { + qDebug() << Q_FUNC_INFO << "n must be greater or equal 2 but was" << n; + n = 2; + } + if (n != mLevelCount) + { + mLevelCount = n; + mColorBufferInvalidated = true; + } +} + +/*! + Sets at which positions from 0 to 1 which color shall occur. The positions are the keys, the + colors are the values of the passed QMap \a colorStops. In between these color stops, the color + is interpolated according to \ref setColorInterpolation. + + A more convenient way to create a custom gradient may be to clear all color stops with \ref + clearColorStops and then adding them one by one with \ref setColorStopAt. + + \see clearColorStops +*/ +void QCPColorGradient::setColorStops(const QMap &colorStops) +{ + mColorStops = colorStops; + mColorBufferInvalidated = true; +} + +/*! + Sets the \a color the gradient will have at the specified \a position (from 0 to 1). In between + these color stops, the color is interpolated according to \ref setColorInterpolation. + + \see setColorStops, clearColorStops +*/ +void QCPColorGradient::setColorStopAt(double position, const QColor &color) +{ + mColorStops.insert(position, color); + mColorBufferInvalidated = true; +} + +/*! + Sets whether the colors in between the configured color stops (see \ref setColorStopAt) shall be + interpolated linearly in RGB or in HSV color space. + + For example, a sweep in RGB space from red to green will have a muddy brown intermediate color, + whereas in HSV space the intermediate color is yellow. +*/ +void QCPColorGradient::setColorInterpolation(QCPColorGradient::ColorInterpolation interpolation) +{ + if (interpolation != mColorInterpolation) + { + mColorInterpolation = interpolation; + mColorBufferInvalidated = true; + } +} + +/*! + Sets whether data points that are outside the configured data range (e.g. \ref + QCPColorMap::setDataRange) are colored by periodically repeating the color gradient or whether + they all have the same color, corresponding to the respective gradient boundary color. + + \image html QCPColorGradient-periodic.png + + As shown in the image above, gradients that have the same start and end color are especially + suitable for a periodic gradient mapping, since they produce smooth color transitions throughout + the color map. A preset that has this property is \ref gpHues. + + In practice, using periodic color gradients makes sense when the data corresponds to a periodic + dimension, such as an angle or a phase. If this is not the case, the color encoding might become + ambiguous, because multiple different data values are shown as the same color. +*/ +void QCPColorGradient::setPeriodic(bool enabled) +{ + mPeriodic = enabled; +} + +/*! + This method is used to quickly convert a \a data array to colors. The colors will be output in + the array \a scanLine. Both \a data and \a scanLine must have the length \a n when passed to this + function. The data range that shall be used for mapping the data value to the gradient is passed + in \a range. \a logarithmic indicates whether the data values shall be mapped to colors + logarithmically. + + if \a data actually contains 2D-data linearized via [row*columnCount + column], you can + set \a dataIndexFactor to columnCount to convert a column instead of a row of the data + array, in \a scanLine. \a scanLine will remain a regular (1D) array. This works because \a data + is addressed data[i*dataIndexFactor]. +*/ +void QCPColorGradient::colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic) +{ + // If you change something here, make sure to also adapt ::color() + if (!data) + { + qDebug() << Q_FUNC_INFO << "null pointer given as data"; + return; + } + if (!scanLine) + { + qDebug() << Q_FUNC_INFO << "null pointer given as scanLine"; + return; + } + if (mColorBufferInvalidated) + updateColorBuffer(); + + if (!logarithmic) + { + const double posToIndexFactor = (mLevelCount-1)/range.size(); + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + scanLine[i] = mColorBuffer.at(index); + } + } + } else // logarithmic == true + { + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + scanLine[i] = mColorBuffer.at(index); + } + } + } +} + +/*! \internal + + This method is used to colorize a single data value given in \a position, to colors. The data + range that shall be used for mapping the data value to the gradient is passed in \a range. \a + logarithmic indicates whether the data value shall be mapped to a color logarithmically. + + If an entire array of data values shall be converted, rather use \ref colorize, for better + performance. +*/ +QRgb QCPColorGradient::color(double position, const QCPRange &range, bool logarithmic) +{ + // If you change something here, make sure to also adapt ::colorize() + if (mColorBufferInvalidated) + updateColorBuffer(); + int index = 0; + if (!logarithmic) + index = (position-range.lower)*(mLevelCount-1)/range.size(); + else + index = qLn(position/range.lower)/qLn(range.upper/range.lower)*(mLevelCount-1); + if (mPeriodic) + { + index = index % mLevelCount; + if (index < 0) + index += mLevelCount; + } else + { + if (index < 0) + index = 0; + else if (index >= mLevelCount) + index = mLevelCount-1; + } + return mColorBuffer.at(index); +} + +/*! + Clears the current color stops and loads the specified \a preset. A preset consists of predefined + color stops and the corresponding color interpolation method. + + The available presets are: + \image html QCPColorGradient.png +*/ +void QCPColorGradient::loadPreset(GradientPreset preset) +{ + clearColorStops(); + switch (preset) + { + case gpGrayscale: + setColorInterpolation(ciRGB); + setColorStopAt(0, Qt::black); + setColorStopAt(1, Qt::white); + break; + case gpHot: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(50, 0, 0)); + setColorStopAt(0.2, QColor(180, 10, 0)); + setColorStopAt(0.4, QColor(245, 50, 0)); + setColorStopAt(0.6, QColor(255, 150, 10)); + setColorStopAt(0.8, QColor(255, 255, 50)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpCold: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 50)); + setColorStopAt(0.2, QColor(0, 10, 180)); + setColorStopAt(0.4, QColor(0, 50, 245)); + setColorStopAt(0.6, QColor(10, 150, 255)); + setColorStopAt(0.8, QColor(50, 255, 255)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpNight: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(10, 20, 30)); + setColorStopAt(1, QColor(250, 255, 250)); + break; + case gpCandy: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(0, 0, 255)); + setColorStopAt(1, QColor(255, 250, 250)); + break; + case gpGeography: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(70, 170, 210)); + setColorStopAt(0.20, QColor(90, 160, 180)); + setColorStopAt(0.25, QColor(45, 130, 175)); + setColorStopAt(0.30, QColor(100, 140, 125)); + setColorStopAt(0.5, QColor(100, 140, 100)); + setColorStopAt(0.6, QColor(130, 145, 120)); + setColorStopAt(0.7, QColor(140, 130, 120)); + setColorStopAt(0.9, QColor(180, 190, 190)); + setColorStopAt(1, QColor(210, 210, 230)); + break; + case gpIon: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(50, 10, 10)); + setColorStopAt(0.45, QColor(0, 0, 255)); + setColorStopAt(0.8, QColor(0, 255, 255)); + setColorStopAt(1, QColor(0, 255, 0)); + break; + case gpThermal: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 50)); + setColorStopAt(0.15, QColor(20, 0, 120)); + setColorStopAt(0.33, QColor(200, 30, 140)); + setColorStopAt(0.6, QColor(255, 100, 0)); + setColorStopAt(0.85, QColor(255, 255, 40)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpPolar: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(50, 255, 255)); + setColorStopAt(0.18, QColor(10, 70, 255)); + setColorStopAt(0.28, QColor(10, 10, 190)); + setColorStopAt(0.5, QColor(0, 0, 0)); + setColorStopAt(0.72, QColor(190, 10, 10)); + setColorStopAt(0.82, QColor(255, 70, 10)); + setColorStopAt(1, QColor(255, 255, 50)); + break; + case gpSpectrum: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(50, 0, 50)); + setColorStopAt(0.15, QColor(0, 0, 255)); + setColorStopAt(0.35, QColor(0, 255, 255)); + setColorStopAt(0.6, QColor(255, 255, 0)); + setColorStopAt(0.75, QColor(255, 30, 0)); + setColorStopAt(1, QColor(50, 0, 0)); + break; + case gpJet: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 100)); + setColorStopAt(0.15, QColor(0, 50, 255)); + setColorStopAt(0.35, QColor(0, 255, 255)); + setColorStopAt(0.65, QColor(255, 255, 0)); + setColorStopAt(0.85, QColor(255, 30, 0)); + setColorStopAt(1, QColor(100, 0, 0)); + break; + case gpHues: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(255, 0, 0)); + setColorStopAt(1.0/3.0, QColor(0, 0, 255)); + setColorStopAt(2.0/3.0, QColor(0, 255, 0)); + setColorStopAt(1, QColor(255, 0, 0)); + break; + } +} + +/*! + Clears all color stops. + + \see setColorStops, setColorStopAt +*/ +void QCPColorGradient::clearColorStops() +{ + mColorStops.clear(); + mColorBufferInvalidated = true; +} + +/*! + Returns an inverted gradient. The inverted gradient has all properties as this \ref + QCPColorGradient, but the order of the color stops is inverted. + + \see setColorStops, setColorStopAt +*/ +QCPColorGradient QCPColorGradient::inverted() const +{ + QCPColorGradient result(*this); + result.clearColorStops(); + for (QMap::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) + result.setColorStopAt(1.0-it.key(), it.value()); + return result; +} + +/*! \internal + + Updates the internal color buffer which will be used by \ref colorize and \ref color, to quickly + convert positions to colors. This is where the interpolation between color stops is calculated. +*/ +void QCPColorGradient::updateColorBuffer() +{ + if (mColorBuffer.size() != mLevelCount) + mColorBuffer.resize(mLevelCount); + if (mColorStops.size() > 1) + { + double indexToPosFactor = 1.0/(double)(mLevelCount-1); + for (int i=0; i::const_iterator it = mColorStops.lowerBound(position); + if (it == mColorStops.constEnd()) // position is on or after last stop, use color of last stop + { + mColorBuffer[i] = (it-1).value().rgb(); + } else if (it == mColorStops.constBegin()) // position is on or before first stop, use color of first stop + { + mColorBuffer[i] = it.value().rgb(); + } else // position is in between stops (or on an intermediate stop), interpolate color + { + QMap::const_iterator high = it; + QMap::const_iterator low = it-1; + double t = (position-low.key())/(high.key()-low.key()); // interpolation factor 0..1 + switch (mColorInterpolation) + { + case ciRGB: + { + mColorBuffer[i] = qRgb((1-t)*low.value().red() + t*high.value().red(), + (1-t)*low.value().green() + t*high.value().green(), + (1-t)*low.value().blue() + t*high.value().blue()); + break; + } + case ciHSV: + { + QColor lowHsv = low.value().toHsv(); + QColor highHsv = high.value().toHsv(); + double hue = 0; + double hueDiff = highHsv.hueF()-lowHsv.hueF(); + if (hueDiff > 0.5) + hue = lowHsv.hueF() - t*(1.0-hueDiff); + else if (hueDiff < -0.5) + hue = lowHsv.hueF() + t*(1.0+hueDiff); + else + hue = lowHsv.hueF() + t*hueDiff; + if (hue < 0) hue += 1.0; + else if (hue >= 1.0) hue -= 1.0; + mColorBuffer[i] = QColor::fromHsvF(hue, (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); + break; + } + } + } + } + } else if (mColorStops.size() == 1) + { + mColorBuffer.fill(mColorStops.constBegin().value().rgb()); + } else // mColorStops is empty, fill color buffer with black + { + mColorBuffer.fill(qRgb(0, 0, 0)); + } + mColorBufferInvalidated = false; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisRect +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxisRect + \brief Holds multiple axes and arranges them in a rectangular shape. + + This class represents an axis rect, a rectangular area that is bounded on all sides with an + arbitrary number of axes. + + Initially QCustomPlot has one axis rect, accessible via QCustomPlot::axisRect(). However, the + layout system allows to have multiple axis rects, e.g. arranged in a grid layout + (QCustomPlot::plotLayout). + + By default, QCPAxisRect comes with four axes, at bottom, top, left and right. They can be + accessed via \ref axis by providing the respective axis type (\ref QCPAxis::AxisType) and index. + If you need all axes in the axis rect, use \ref axes. The top and right axes are set to be + invisible initially (QCPAxis::setVisible). To add more axes to a side, use \ref addAxis or \ref + addAxes. To remove an axis, use \ref removeAxis. + + The axis rect layerable itself only draws a background pixmap or color, if specified (\ref + setBackground). It is placed on the "background" layer initially (see \ref QCPLayer for an + explanation of the QCustomPlot layer system). The axes that are held by the axis rect can be + placed on other layers, independently of the axis rect. + + Every axis rect has a child layout of type \ref QCPLayoutInset. It is accessible via \ref + insetLayout and can be used to have other layout elements (or even other layouts with multiple + elements) hovering inside the axis rect. + + If an axis rect is clicked and dragged, it processes this by moving certain axis ranges. The + behaviour can be controlled with \ref setRangeDrag and \ref setRangeDragAxes. If the mouse wheel + is scrolled while the cursor is on the axis rect, certain axes are scaled. This is controllable + via \ref setRangeZoom, \ref setRangeZoomAxes and \ref setRangeZoomFactor. These interactions are + only enabled if \ref QCustomPlot::setInteractions contains \ref QCP::iRangeDrag and \ref + QCP::iRangeZoom. + + \image html AxisRectSpacingOverview.png +
Overview of the spacings and paddings that define the geometry of an axis. The dashed + line on the far left indicates the viewport/widget border.
+*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayoutInset *QCPAxisRect::insetLayout() const + + Returns the inset layout of this axis rect. It can be used to place other layout elements (or + even layouts with multiple other elements) inside/on top of an axis rect. + + \see QCPLayoutInset +*/ + +/*! \fn int QCPAxisRect::left() const + + Returns the pixel position of the left border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::right() const + + Returns the pixel position of the right border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::top() const + + Returns the pixel position of the top border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::bottom() const + + Returns the pixel position of the bottom border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::width() const + + Returns the pixel width of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::height() const + + Returns the pixel height of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QSize QCPAxisRect::size() const + + Returns the pixel size of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::topLeft() const + + Returns the top left corner of this axis rect in pixels. Margins are not taken into account here, + so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::topRight() const + + Returns the top right corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::bottomLeft() const + + Returns the bottom left corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::bottomRight() const + + Returns the bottom right corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::center() const + + Returns the center of this axis rect in pixels. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a QCPAxisRect instance and sets default values. An axis is added for each of the four + sides, the top and right axes are set invisible initially. +*/ +QCPAxisRect::QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes) : + QCPLayoutElement(parentPlot), + mBackgroundBrush(Qt::NoBrush), + mBackgroundScaled(true), + mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), + mInsetLayout(new QCPLayoutInset), + mRangeDrag(Qt::Horizontal|Qt::Vertical), + mRangeZoom(Qt::Horizontal|Qt::Vertical), + mRangeZoomFactorHorz(0.85), + mRangeZoomFactorVert(0.85), + mDragging(false) +{ + mInsetLayout->initializeParentPlot(mParentPlot); + mInsetLayout->setParentLayerable(this); + mInsetLayout->setParent(this); + + setMinimumSize(50, 50); + setMinimumMargins(QMargins(15, 15, 15, 15)); + mAxes.insert(QCPAxis::atLeft, QList()); + mAxes.insert(QCPAxis::atRight, QList()); + mAxes.insert(QCPAxis::atTop, QList()); + mAxes.insert(QCPAxis::atBottom, QList()); + + if (setupDefaultAxes) + { + QCPAxis *xAxis = addAxis(QCPAxis::atBottom); + QCPAxis *yAxis = addAxis(QCPAxis::atLeft); + QCPAxis *xAxis2 = addAxis(QCPAxis::atTop); + QCPAxis *yAxis2 = addAxis(QCPAxis::atRight); + setRangeDragAxes(xAxis, yAxis); + setRangeZoomAxes(xAxis, yAxis); + xAxis2->setVisible(false); + yAxis2->setVisible(false); + xAxis->grid()->setVisible(true); + yAxis->grid()->setVisible(true); + xAxis2->grid()->setVisible(false); + yAxis2->grid()->setVisible(false); + xAxis2->grid()->setZeroLinePen(Qt::NoPen); + yAxis2->grid()->setZeroLinePen(Qt::NoPen); + xAxis2->grid()->setVisible(false); + yAxis2->grid()->setVisible(false); + } +} + +QCPAxisRect::~QCPAxisRect() +{ + delete mInsetLayout; + mInsetLayout = 0; + + QList axesList = axes(); + for (int i=0; i ax(mAxes.value(type)); + if (index >= 0 && index < ax.size()) + { + return ax.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "Axis index out of bounds:" << index; + return 0; + } +} + +/*! + Returns all axes on the axis rect sides specified with \a types. + + \a types may be a single \ref QCPAxis::AxisType or an or-combination, to get the axes of + multiple sides. + + \see axis +*/ +QList QCPAxisRect::axes(QCPAxis::AxisTypes types) const +{ + QList result; + if (types.testFlag(QCPAxis::atLeft)) + result << mAxes.value(QCPAxis::atLeft); + if (types.testFlag(QCPAxis::atRight)) + result << mAxes.value(QCPAxis::atRight); + if (types.testFlag(QCPAxis::atTop)) + result << mAxes.value(QCPAxis::atTop); + if (types.testFlag(QCPAxis::atBottom)) + result << mAxes.value(QCPAxis::atBottom); + return result; +} + +/*! \overload + + Returns all axes of this axis rect. +*/ +QList QCPAxisRect::axes() const +{ + QList result; + QHashIterator > it(mAxes); + while (it.hasNext()) + { + it.next(); + result << it.value(); + } + return result; +} + +/*! + Adds a new axis to the axis rect side specified with \a type, and returns it. If \a axis is 0, a + new QCPAxis instance is created internally. + + You may inject QCPAxis instances (or sublasses of QCPAxis) by setting \a axis to an axis that was + previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership + of the axis, so you may not delete it afterwards. Further, the \a axis must have been created + with this axis rect as parent and with the same axis type as specified in \a type. If this is not + the case, a debug output is generated, the axis is not added, and the method returns 0. + + This method can not be used to move \a axis between axis rects. The same \a axis instance must + not be added multiple times to the same or different axis rects. + + If an axis rect side already contains one or more axes, the lower and upper endings of the new + axis (\ref QCPAxis::setLowerEnding, \ref QCPAxis::setUpperEnding) are set to \ref + QCPLineEnding::esHalfBar. + + \see addAxes, setupFullAxesBox +*/ +QCPAxis *QCPAxisRect::addAxis(QCPAxis::AxisType type, QCPAxis *axis) +{ + QCPAxis *newAxis = axis; + if (!newAxis) + { + newAxis = new QCPAxis(this, type); + } else // user provided existing axis instance, do some sanity checks + { + if (newAxis->axisType() != type) + { + qDebug() << Q_FUNC_INFO << "passed axis has different axis type than specified in type parameter"; + return 0; + } + if (newAxis->axisRect() != this) + { + qDebug() << Q_FUNC_INFO << "passed axis doesn't have this axis rect as parent axis rect"; + return 0; + } + if (axes().contains(newAxis)) + { + qDebug() << Q_FUNC_INFO << "passed axis is already owned by this axis rect"; + return 0; + } + } + if (mAxes[type].size() > 0) // multiple axes on one side, add half-bar axis ending to additional axes with offset + { + bool invert = (type == QCPAxis::atRight) || (type == QCPAxis::atBottom); + newAxis->setLowerEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, !invert)); + newAxis->setUpperEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, invert)); + } + mAxes[type].append(newAxis); + return newAxis; +} + +/*! + Adds a new axis with \ref addAxis to each axis rect side specified in \a types. This may be an + or-combination of QCPAxis::AxisType, so axes can be added to multiple sides at once. + + Returns a list of the added axes. + + \see addAxis, setupFullAxesBox +*/ +QList QCPAxisRect::addAxes(QCPAxis::AxisTypes types) +{ + QList result; + if (types.testFlag(QCPAxis::atLeft)) + result << addAxis(QCPAxis::atLeft); + if (types.testFlag(QCPAxis::atRight)) + result << addAxis(QCPAxis::atRight); + if (types.testFlag(QCPAxis::atTop)) + result << addAxis(QCPAxis::atTop); + if (types.testFlag(QCPAxis::atBottom)) + result << addAxis(QCPAxis::atBottom); + return result; +} + +/*! + Removes the specified \a axis from the axis rect and deletes it. + + Returns true on success, i.e. if \a axis was a valid axis in this axis rect. + + \see addAxis +*/ +bool QCPAxisRect::removeAxis(QCPAxis *axis) +{ + // don't access axis->axisType() to provide safety when axis is an invalid pointer, rather go through all axis containers: + QHashIterator > it(mAxes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(axis)) + { + mAxes[it.key()].removeOne(axis); + if (qobject_cast(parentPlot())) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the axis rect is not in any layout and thus QObject-child of QCustomPlot) + parentPlot()->axisRemoved(axis); + delete axis; + return true; + } + } + qDebug() << Q_FUNC_INFO << "Axis isn't in axis rect:" << reinterpret_cast(axis); + return false; +} + +/*! + Convenience function to create an axis on each side that doesn't have any axes yet and set their + visibility to true. Further, the top/right axes are assigned the following properties of the + bottom/left axes: + + \li range (\ref QCPAxis::setRange) + \li range reversed (\ref QCPAxis::setRangeReversed) + \li scale type (\ref QCPAxis::setScaleType) + \li scale log base (\ref QCPAxis::setScaleLogBase) + \li ticks (\ref QCPAxis::setTicks) + \li auto (major) tick count (\ref QCPAxis::setAutoTickCount) + \li sub tick count (\ref QCPAxis::setSubTickCount) + \li auto sub ticks (\ref QCPAxis::setAutoSubTicks) + \li tick step (\ref QCPAxis::setTickStep) + \li auto tick step (\ref QCPAxis::setAutoTickStep) + \li number format (\ref QCPAxis::setNumberFormat) + \li number precision (\ref QCPAxis::setNumberPrecision) + \li tick label type (\ref QCPAxis::setTickLabelType) + \li date time format (\ref QCPAxis::setDateTimeFormat) + \li date time spec (\ref QCPAxis::setDateTimeSpec) + + Tick labels (\ref QCPAxis::setTickLabels) of the right and top axes are set to false. + + If \a connectRanges is true, the \ref QCPAxis::rangeChanged "rangeChanged" signals of the bottom + and left axes are connected to the \ref QCPAxis::setRange slots of the top and right axes. +*/ +void QCPAxisRect::setupFullAxesBox(bool connectRanges) +{ + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; + if (axisCount(QCPAxis::atBottom) == 0) + xAxis = addAxis(QCPAxis::atBottom); + else + xAxis = axis(QCPAxis::atBottom); + + if (axisCount(QCPAxis::atLeft) == 0) + yAxis = addAxis(QCPAxis::atLeft); + else + yAxis = axis(QCPAxis::atLeft); + + if (axisCount(QCPAxis::atTop) == 0) + xAxis2 = addAxis(QCPAxis::atTop); + else + xAxis2 = axis(QCPAxis::atTop); + + if (axisCount(QCPAxis::atRight) == 0) + yAxis2 = addAxis(QCPAxis::atRight); + else + yAxis2 = axis(QCPAxis::atRight); + + xAxis->setVisible(true); + yAxis->setVisible(true); + xAxis2->setVisible(true); + yAxis2->setVisible(true); + xAxis2->setTickLabels(false); + yAxis2->setTickLabels(false); + + xAxis2->setRange(xAxis->range()); + xAxis2->setRangeReversed(xAxis->rangeReversed()); + xAxis2->setScaleType(xAxis->scaleType()); + xAxis2->setScaleLogBase(xAxis->scaleLogBase()); + xAxis2->setTicks(xAxis->ticks()); + xAxis2->setAutoTickCount(xAxis->autoTickCount()); + xAxis2->setSubTickCount(xAxis->subTickCount()); + xAxis2->setAutoSubTicks(xAxis->autoSubTicks()); + xAxis2->setTickStep(xAxis->tickStep()); + xAxis2->setAutoTickStep(xAxis->autoTickStep()); + xAxis2->setNumberFormat(xAxis->numberFormat()); + xAxis2->setNumberPrecision(xAxis->numberPrecision()); + xAxis2->setTickLabelType(xAxis->tickLabelType()); + xAxis2->setDateTimeFormat(xAxis->dateTimeFormat()); + xAxis2->setDateTimeSpec(xAxis->dateTimeSpec()); + + yAxis2->setRange(yAxis->range()); + yAxis2->setRangeReversed(yAxis->rangeReversed()); + yAxis2->setScaleType(yAxis->scaleType()); + yAxis2->setScaleLogBase(yAxis->scaleLogBase()); + yAxis2->setTicks(yAxis->ticks()); + yAxis2->setAutoTickCount(yAxis->autoTickCount()); + yAxis2->setSubTickCount(yAxis->subTickCount()); + yAxis2->setAutoSubTicks(yAxis->autoSubTicks()); + yAxis2->setTickStep(yAxis->tickStep()); + yAxis2->setAutoTickStep(yAxis->autoTickStep()); + yAxis2->setNumberFormat(yAxis->numberFormat()); + yAxis2->setNumberPrecision(yAxis->numberPrecision()); + yAxis2->setTickLabelType(yAxis->tickLabelType()); + yAxis2->setDateTimeFormat(yAxis->dateTimeFormat()); + yAxis2->setDateTimeSpec(yAxis->dateTimeSpec()); + + if (connectRanges) + { + connect(xAxis, SIGNAL(rangeChanged(QCPRange)), xAxis2, SLOT(setRange(QCPRange))); + connect(yAxis, SIGNAL(rangeChanged(QCPRange)), yAxis2, SLOT(setRange(QCPRange))); + } +} + +/*! + Returns a list of all the plottables that are associated with this axis rect. + + A plottable is considered associated with an axis rect if its key or value axis (or both) is in + this axis rect. + + \see graphs, items +*/ +QList QCPAxisRect::plottables() const +{ + // Note: don't append all QCPAxis::plottables() into a list, because we might get duplicate entries + QList result; + for (int i=0; imPlottables.size(); ++i) + { + if (mParentPlot->mPlottables.at(i)->keyAxis()->axisRect() == this ||mParentPlot->mPlottables.at(i)->valueAxis()->axisRect() == this) + result.append(mParentPlot->mPlottables.at(i)); + } + return result; +} + +/*! + Returns a list of all the graphs that are associated with this axis rect. + + A graph is considered associated with an axis rect if its key or value axis (or both) is in + this axis rect. + + \see plottables, items +*/ +QList QCPAxisRect::graphs() const +{ + // Note: don't append all QCPAxis::graphs() into a list, because we might get duplicate entries + QList result; + for (int i=0; imGraphs.size(); ++i) + { + if (mParentPlot->mGraphs.at(i)->keyAxis()->axisRect() == this || mParentPlot->mGraphs.at(i)->valueAxis()->axisRect() == this) + result.append(mParentPlot->mGraphs.at(i)); + } + return result; +} + +/*! + Returns a list of all the items that are associated with this axis rect. + + An item is considered associated with an axis rect if any of its positions has key or value axis + set to an axis that is in this axis rect, or if any of its positions has \ref + QCPItemPosition::setAxisRect set to the axis rect, or if the clip axis rect (\ref + QCPAbstractItem::setClipAxisRect) is set to this axis rect. + + \see plottables, graphs +*/ +QList QCPAxisRect::items() const +{ + // Note: don't just append all QCPAxis::items() into a list, because we might get duplicate entries + // and miss those items that have this axis rect as clipAxisRect. + QList result; + for (int itemId=0; itemIdmItems.size(); ++itemId) + { + if (mParentPlot->mItems.at(itemId)->clipAxisRect() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + continue; + } + QList positions = mParentPlot->mItems.at(itemId)->positions(); + for (int posId=0; posIdaxisRect() == this || + positions.at(posId)->keyAxis()->axisRect() == this || + positions.at(posId)->valueAxis()->axisRect() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + break; + } + } + } + return result; +} + +/*! + This method is called automatically upon replot and doesn't need to be called by users of + QCPAxisRect. + + Calls the base class implementation to update the margins (see \ref QCPLayoutElement::update), + and finally passes the \ref rect to the inset layout (\ref insetLayout) and calls its + QCPInsetLayout::update function. +*/ +void QCPAxisRect::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + + switch (phase) + { + case upPreparation: + { + QList allAxes = axes(); + for (int i=0; isetupTickVectors(); + break; + } + case upLayout: + { + mInsetLayout->setOuterRect(rect()); + break; + } + default: break; + } + + // pass update call on to inset layout (doesn't happen automatically, because QCPAxisRect doesn't derive from QCPLayout): + mInsetLayout->update(phase); +} + +/* inherits documentation from base class */ +QList QCPAxisRect::elements(bool recursive) const +{ + QList result; + if (mInsetLayout) + { + result << mInsetLayout; + if (recursive) + result << mInsetLayout->elements(recursive); + } + return result; +} + +/* inherits documentation from base class */ +void QCPAxisRect::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + painter->setAntialiasing(false); +} + +/* inherits documentation from base class */ +void QCPAxisRect::draw(QCPPainter *painter) +{ + drawBackground(painter); +} + +/*! + Sets \a pm as the axis background pixmap. The axis background pixmap will be drawn inside the + axis rect. Since axis rects place themselves on the "background" layer by default, the axis rect + backgrounds are usually drawn below everything else. + + For cases where the provided pixmap doesn't have the same size as the axis rect, scaling can be + enabled with \ref setBackgroundScaled and the scaling mode (i.e. whether and how the aspect ratio + is preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, + consider using the overloaded version of this function. + + Below the pixmap, the axis rect may be optionally filled with a brush, if specified with \ref + setBackground(const QBrush &brush). + + \see setBackgroundScaled, setBackgroundScaledMode, setBackground(const QBrush &brush) +*/ +void QCPAxisRect::setBackground(const QPixmap &pm) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); +} + +/*! \overload + + Sets \a brush as the background brush. The axis rect background will be filled with this brush. + Since axis rects place themselves on the "background" layer by default, the axis rect backgrounds + are usually drawn below everything else. + + The brush will be drawn before (under) any background pixmap, which may be specified with \ref + setBackground(const QPixmap &pm). + + To disable drawing of a background brush, set \a brush to Qt::NoBrush. + + \see setBackground(const QPixmap &pm) +*/ +void QCPAxisRect::setBackground(const QBrush &brush) +{ + mBackgroundBrush = brush; +} + +/*! \overload + + Allows setting the background pixmap of the axis rect, whether it shall be scaled and how it + shall be scaled in one call. + + \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode +*/ +void QCPAxisRect::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); + mBackgroundScaled = scaled; + mBackgroundScaledMode = mode; +} + +/*! + Sets whether the axis background pixmap shall be scaled to fit the axis rect or not. If \a scaled + is set to true, you may control whether and how the aspect ratio of the original pixmap is + preserved with \ref setBackgroundScaledMode. + + Note that the scaled version of the original pixmap is buffered, so there is no performance + penalty on replots. (Except when the axis rect dimensions are changed continuously.) + + \see setBackground, setBackgroundScaledMode +*/ +void QCPAxisRect::setBackgroundScaled(bool scaled) +{ + mBackgroundScaled = scaled; +} + +/*! + If scaling of the axis background pixmap is enabled (\ref setBackgroundScaled), use this function to + define whether and how the aspect ratio of the original pixmap passed to \ref setBackground is preserved. + \see setBackground, setBackgroundScaled +*/ +void QCPAxisRect::setBackgroundScaledMode(Qt::AspectRatioMode mode) +{ + mBackgroundScaledMode = mode; +} + +/*! + Returns the range drag axis of the \a orientation provided. + + \see setRangeDragAxes +*/ +QCPAxis *QCPAxisRect::rangeDragAxis(Qt::Orientation orientation) +{ + return (orientation == Qt::Horizontal ? mRangeDragHorzAxis.data() : mRangeDragVertAxis.data()); +} + +/*! + Returns the range zoom axis of the \a orientation provided. + + \see setRangeZoomAxes +*/ +QCPAxis *QCPAxisRect::rangeZoomAxis(Qt::Orientation orientation) +{ + return (orientation == Qt::Horizontal ? mRangeZoomHorzAxis.data() : mRangeZoomVertAxis.data()); +} + +/*! + Returns the range zoom factor of the \a orientation provided. + + \see setRangeZoomFactor +*/ +double QCPAxisRect::rangeZoomFactor(Qt::Orientation orientation) +{ + return (orientation == Qt::Horizontal ? mRangeZoomFactorHorz : mRangeZoomFactorVert); +} + +/*! + Sets which axis orientation may be range dragged by the user with mouse interaction. + What orientation corresponds to which specific axis can be set with + \ref setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical). By + default, the horizontal axis is the bottom axis (xAxis) and the vertical axis + is the left axis (yAxis). + + To disable range dragging entirely, pass 0 as \a orientations or remove \ref QCP::iRangeDrag from \ref + QCustomPlot::setInteractions. To enable range dragging for both directions, pass Qt::Horizontal | + Qt::Vertical as \a orientations. + + In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions + contains \ref QCP::iRangeDrag to enable the range dragging interaction. + + \see setRangeZoom, setRangeDragAxes, QCustomPlot::setNoAntialiasingOnDrag +*/ +void QCPAxisRect::setRangeDrag(Qt::Orientations orientations) +{ + mRangeDrag = orientations; +} + +/*! + Sets which axis orientation may be zoomed by the user with the mouse wheel. What orientation + corresponds to which specific axis can be set with \ref setRangeZoomAxes(QCPAxis *horizontal, + QCPAxis *vertical). By default, the horizontal axis is the bottom axis (xAxis) and the vertical + axis is the left axis (yAxis). + + To disable range zooming entirely, pass 0 as \a orientations or remove \ref QCP::iRangeZoom from \ref + QCustomPlot::setInteractions. To enable range zooming for both directions, pass Qt::Horizontal | + Qt::Vertical as \a orientations. + + In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions + contains \ref QCP::iRangeZoom to enable the range zooming interaction. + + \see setRangeZoomFactor, setRangeZoomAxes, setRangeDrag +*/ +void QCPAxisRect::setRangeZoom(Qt::Orientations orientations) +{ + mRangeZoom = orientations; +} + +/*! + Sets the axes whose range will be dragged when \ref setRangeDrag enables mouse range dragging + on the QCustomPlot widget. + + \see setRangeZoomAxes +*/ +void QCPAxisRect::setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical) +{ + mRangeDragHorzAxis = horizontal; + mRangeDragVertAxis = vertical; +} + +/*! + Sets the axes whose range will be zoomed when \ref setRangeZoom enables mouse wheel zooming on the + QCustomPlot widget. The two axes can be zoomed with different strengths, when different factors + are passed to \ref setRangeZoomFactor(double horizontalFactor, double verticalFactor). + + \see setRangeDragAxes +*/ +void QCPAxisRect::setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical) +{ + mRangeZoomHorzAxis = horizontal; + mRangeZoomVertAxis = vertical; +} + +/*! + Sets how strong one rotation step of the mouse wheel zooms, when range zoom was activated with + \ref setRangeZoom. The two parameters \a horizontalFactor and \a verticalFactor provide a way to + let the horizontal axis zoom at different rates than the vertical axis. Which axis is horizontal + and which is vertical, can be set with \ref setRangeZoomAxes. + + When the zoom factor is greater than one, scrolling the mouse wheel backwards (towards the user) + will zoom in (make the currently visible range smaller). For zoom factors smaller than one, the + same scrolling direction will zoom out. +*/ +void QCPAxisRect::setRangeZoomFactor(double horizontalFactor, double verticalFactor) +{ + mRangeZoomFactorHorz = horizontalFactor; + mRangeZoomFactorVert = verticalFactor; +} + +/*! \overload + + Sets both the horizontal and vertical zoom \a factor. +*/ +void QCPAxisRect::setRangeZoomFactor(double factor) +{ + mRangeZoomFactorHorz = factor; + mRangeZoomFactorVert = factor; +} + +/*! \internal + + Draws the background of this axis rect. It may consist of a background fill (a QBrush) and a + pixmap. + + If a brush was given via \ref setBackground(const QBrush &brush), this function first draws an + according filling inside the axis rect with the provided \a painter. + + Then, if a pixmap was provided via \ref setBackground, this function buffers the scaled version + depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside + the axis rect with the provided \a painter. The scaled version is buffered in + mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when + the axis rect has changed in a way that requires a rescale of the background pixmap (this is + dependant on the \ref setBackgroundScaledMode), or when a differend axis backgroud pixmap was + set. + + \see setBackground, setBackgroundScaled, setBackgroundScaledMode +*/ +void QCPAxisRect::drawBackground(QCPPainter *painter) +{ + // draw background fill: + if (mBackgroundBrush != Qt::NoBrush) + painter->fillRect(mRect, mBackgroundBrush); + + // draw background pixmap (on top of fill, if brush specified): + if (!mBackgroundPixmap.isNull()) + { + if (mBackgroundScaled) + { + // check whether mScaledBackground needs to be updated: + QSize scaledSize(mBackgroundPixmap.size()); + scaledSize.scale(mRect.size(), mBackgroundScaledMode); + if (mScaledBackgroundPixmap.size() != scaledSize) + mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mRect.size(), mBackgroundScaledMode, Qt::SmoothTransformation); + painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mScaledBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height()) & mScaledBackgroundPixmap.rect()); + } else + { + painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height())); + } + } +} + +/*! \internal + + This function makes sure multiple axes on the side specified with \a type don't collide, but are + distributed according to their respective space requirement (QCPAxis::calculateMargin). + + It does this by setting an appropriate offset (\ref QCPAxis::setOffset) on all axes except the + one with index zero. + + This function is called by \ref calculateAutoMargin. +*/ +void QCPAxisRect::updateAxesOffset(QCPAxis::AxisType type) +{ + const QList axesList = mAxes.value(type); + if (axesList.isEmpty()) + return; + + bool isFirstVisible = !axesList.first()->visible(); // if the first axis is visible, the second axis (which is where the loop starts) isn't the first visible axis, so initialize with false + for (int i=1; ioffset() + axesList.at(i-1)->calculateMargin(); + if (axesList.at(i)->visible()) // only add inner tick length to offset if this axis is visible and it's not the first visible one (might happen if true first axis is invisible) + { + if (!isFirstVisible) + offset += axesList.at(i)->tickLengthIn(); + isFirstVisible = false; + } + axesList.at(i)->setOffset(offset); + } +} + +/* inherits documentation from base class */ +int QCPAxisRect::calculateAutoMargin(QCP::MarginSide side) +{ + if (!mAutoMargins.testFlag(side)) + qDebug() << Q_FUNC_INFO << "Called with side that isn't specified as auto margin"; + + updateAxesOffset(QCPAxis::marginSideToAxisType(side)); + + // note: only need to look at the last (outer most) axis to determine the total margin, due to updateAxisOffset call + const QList axesList = mAxes.value(QCPAxis::marginSideToAxisType(side)); + if (axesList.size() > 0) + return axesList.last()->offset() + axesList.last()->calculateMargin(); + else + return 0; +} + +/*! \internal + + Event handler for when a mouse button is pressed on the axis rect. If the left mouse button is + pressed, the range dragging interaction is initialized (the actual range manipulation happens in + the \ref mouseMoveEvent). + + The mDragging flag is set to true and some anchor points are set that are needed to determine the + distance the mouse was dragged in the mouse move/release events later. + + \see mouseMoveEvent, mouseReleaseEvent +*/ +void QCPAxisRect::mousePressEvent(QMouseEvent *event) +{ + mDragStart = event->pos(); // need this even when not LeftButton is pressed, to determine in releaseEvent whether it was a full click (no position change between press and release) + if (event->buttons() & Qt::LeftButton) + { + mDragging = true; + // initialize antialiasing backup in case we start dragging: + if (mParentPlot->noAntialiasingOnDrag()) + { + mAADragBackup = mParentPlot->antialiasedElements(); + mNotAADragBackup = mParentPlot->notAntialiasedElements(); + } + // Mouse range dragging interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + if (mRangeDragHorzAxis) + mDragStartHorzRange = mRangeDragHorzAxis.data()->range(); + if (mRangeDragVertAxis) + mDragStartVertRange = mRangeDragVertAxis.data()->range(); + } + } +} + +/*! \internal + + Event handler for when the mouse is moved on the axis rect. If range dragging was activated in a + preceding \ref mousePressEvent, the range is moved accordingly. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCPAxisRect::mouseMoveEvent(QMouseEvent *event) +{ + // Mouse range dragging interaction: + if (mDragging && mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + if (mRangeDrag.testFlag(Qt::Horizontal)) + { + if (QCPAxis *rangeDragHorzAxis = mRangeDragHorzAxis.data()) + { + if (rangeDragHorzAxis->mScaleType == QCPAxis::stLinear) + { + double diff = rangeDragHorzAxis->pixelToCoord(mDragStart.x()) - rangeDragHorzAxis->pixelToCoord(event->pos().x()); + rangeDragHorzAxis->setRange(mDragStartHorzRange.lower+diff, mDragStartHorzRange.upper+diff); + } else if (rangeDragHorzAxis->mScaleType == QCPAxis::stLogarithmic) + { + double diff = rangeDragHorzAxis->pixelToCoord(mDragStart.x()) / rangeDragHorzAxis->pixelToCoord(event->pos().x()); + rangeDragHorzAxis->setRange(mDragStartHorzRange.lower*diff, mDragStartHorzRange.upper*diff); + } + } + } + if (mRangeDrag.testFlag(Qt::Vertical)) + { + if (QCPAxis *rangeDragVertAxis = mRangeDragVertAxis.data()) + { + if (rangeDragVertAxis->mScaleType == QCPAxis::stLinear) + { + double diff = rangeDragVertAxis->pixelToCoord(mDragStart.y()) - rangeDragVertAxis->pixelToCoord(event->pos().y()); + rangeDragVertAxis->setRange(mDragStartVertRange.lower+diff, mDragStartVertRange.upper+diff); + } else if (rangeDragVertAxis->mScaleType == QCPAxis::stLogarithmic) + { + double diff = rangeDragVertAxis->pixelToCoord(mDragStart.y()) / rangeDragVertAxis->pixelToCoord(event->pos().y()); + rangeDragVertAxis->setRange(mDragStartVertRange.lower*diff, mDragStartVertRange.upper*diff); + } + } + } + if (mRangeDrag != 0) // if either vertical or horizontal drag was enabled, do a replot + { + if (mParentPlot->noAntialiasingOnDrag()) + mParentPlot->setNotAntialiasedElements(QCP::aeAll); + mParentPlot->replot(); + } + } +} + +/* inherits documentation from base class */ +void QCPAxisRect::mouseReleaseEvent(QMouseEvent *event) +{ + Q_UNUSED(event) + mDragging = false; + if (mParentPlot->noAntialiasingOnDrag()) + { + mParentPlot->setAntialiasedElements(mAADragBackup); + mParentPlot->setNotAntialiasedElements(mNotAADragBackup); + } +} + +/*! \internal + + Event handler for mouse wheel events. If rangeZoom is Qt::Horizontal, Qt::Vertical or both, the + ranges of the axes defined as rangeZoomHorzAxis and rangeZoomVertAxis are scaled. The center of + the scaling operation is the current cursor position inside the axis rect. The scaling factor is + dependant on the mouse wheel delta (which direction the wheel was rotated) to provide a natural + zooming feel. The Strength of the zoom can be controlled via \ref setRangeZoomFactor. + + Note, that event->delta() is usually +/-120 for single rotation steps. However, if the mouse + wheel is turned rapidly, many steps may bunch up to one event, so the event->delta() may then be + multiples of 120. This is taken into account here, by calculating \a wheelSteps and using it as + exponent of the range zoom factor. This takes care of the wheel direction automatically, by + inverting the factor, when the wheel step is negative (f^-1 = 1/f). +*/ +void QCPAxisRect::wheelEvent(QWheelEvent *event) +{ + // Mouse range zooming interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeZoom)) + { + if (mRangeZoom != 0) + { + double factor; + double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually + if (mRangeZoom.testFlag(Qt::Horizontal)) + { + factor = qPow(mRangeZoomFactorHorz, wheelSteps); + if (mRangeZoomHorzAxis.data()) + mRangeZoomHorzAxis.data()->scaleRange(factor, mRangeZoomHorzAxis.data()->pixelToCoord(event->pos().x())); + } + if (mRangeZoom.testFlag(Qt::Vertical)) + { + factor = qPow(mRangeZoomFactorVert, wheelSteps); + if (mRangeZoomVertAxis.data()) + mRangeZoomVertAxis.data()->scaleRange(factor, mRangeZoomVertAxis.data()->pixelToCoord(event->pos().y())); + } + mParentPlot->replot(); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractLegendItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractLegendItem + \brief The abstract base class for all entries in a QCPLegend. + + It defines a very basic interface for entries in a QCPLegend. For representing plottables in the + legend, the subclass \ref QCPPlottableLegendItem is more suitable. + + Only derive directly from this class when you need absolute freedom (e.g. a custom legend entry + that's not even associated with a plottable). + + You must implement the following pure virtual functions: + \li \ref draw (from QCPLayerable) + + You inherit the following members you may use: + + + + + + + + +
QCPLegend *\b mParentLegendA pointer to the parent QCPLegend.
QFont \b mFontThe generic font of the item. You should use this font for all or at least the most prominent text of the item.
+*/ + +/* start of documentation of signals */ + +/*! \fn void QCPAbstractLegendItem::selectionChanged(bool selected) + + This signal is emitted when the selection state of this legend item has changed, either by user + interaction or by a direct call to \ref setSelected. +*/ + +/* end of documentation of signals */ + +/*! + Constructs a QCPAbstractLegendItem and associates it with the QCPLegend \a parent. This does not + cause the item to be added to \a parent, so \ref QCPLegend::addItem must be called separately. +*/ +QCPAbstractLegendItem::QCPAbstractLegendItem(QCPLegend *parent) : + QCPLayoutElement(parent->parentPlot()), + mParentLegend(parent), + mFont(parent->font()), + mTextColor(parent->textColor()), + mSelectedFont(parent->selectedFont()), + mSelectedTextColor(parent->selectedTextColor()), + mSelectable(true), + mSelected(false) +{ + setLayer(QLatin1String("legend")); + setMargins(QMargins(8, 2, 8, 2)); +} + +/*! + Sets the default font of this specific legend item to \a font. + + \see setTextColor, QCPLegend::setFont +*/ +void QCPAbstractLegendItem::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the default text color of this specific legend item to \a color. + + \see setFont, QCPLegend::setTextColor +*/ +void QCPAbstractLegendItem::setTextColor(const QColor &color) +{ + mTextColor = color; +} + +/*! + When this legend item is selected, \a font is used to draw generic text, instead of the normal + font set with \ref setFont. + + \see setFont, QCPLegend::setSelectedFont +*/ +void QCPAbstractLegendItem::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + When this legend item is selected, \a color is used to draw generic text, instead of the normal + color set with \ref setTextColor. + + \see setTextColor, QCPLegend::setSelectedTextColor +*/ +void QCPAbstractLegendItem::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; +} + +/*! + Sets whether this specific legend item is selectable. + + \see setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAbstractLegendItem::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets whether this specific legend item is selected. + + It is possible to set the selection state of this item by calling this function directly, even if + setSelectable is set to false. + + \see setSelectableParts, QCustomPlot::setInteractions +*/ +void QCPAbstractLegendItem::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/* inherits documentation from base class */ +double QCPAbstractLegendItem::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (!mParentPlot) return -1; + if (onlySelectable && (!mSelectable || !mParentLegend->selectableParts().testFlag(QCPLegend::spItems))) + return -1; + + if (mRect.contains(pos.toPoint())) + return mParentPlot->selectionTolerance()*0.99; + else + return -1; +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeLegendItems); +} + +/* inherits documentation from base class */ +QRect QCPAbstractLegendItem::clipRect() const +{ + return mOuterRect; +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPlottableLegendItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPlottableLegendItem + \brief A legend item representing a plottable with an icon and the plottable name. + + This is the standard legend item for plottables. It displays an icon of the plottable next to the + plottable name. The icon is drawn by the respective plottable itself (\ref + QCPAbstractPlottable::drawLegendIcon), and tries to give an intuitive symbol for the plottable. + For example, the QCPGraph draws a centered horizontal line and/or a single scatter point in the + middle. + + Legend items of this type are always associated with one plottable (retrievable via the + plottable() function and settable with the constructor). You may change the font of the plottable + name with \ref setFont. Icon padding and border pen is taken from the parent QCPLegend, see \ref + QCPLegend::setIconBorderPen and \ref QCPLegend::setIconTextPadding. + + The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend + creates/removes legend items of this type in the default implementation. However, these functions + may be reimplemented such that a different kind of legend item (e.g a direct subclass of + QCPAbstractLegendItem) is used for that plottable. + + Since QCPLegend is based on QCPLayoutGrid, a legend item itself is just a subclass of + QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout + interface, QCPLegend has specialized functions for handling legend items conveniently, see the + documentation of \ref QCPLegend. +*/ + +/*! + Creates a new legend item associated with \a plottable. + + Once it's created, it can be added to the legend via \ref QCPLegend::addItem. + + A more convenient way of adding/removing a plottable to/from the legend is via the functions \ref + QCPAbstractPlottable::addToLegend and \ref QCPAbstractPlottable::removeFromLegend. +*/ +QCPPlottableLegendItem::QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable) : + QCPAbstractLegendItem(parent), + mPlottable(plottable) +{ +} + +/*! \internal + + Returns the pen that shall be used to draw the icon border, taking into account the selection + state of this item. +*/ +QPen QCPPlottableLegendItem::getIconBorderPen() const +{ + return mSelected ? mParentLegend->selectedIconBorderPen() : mParentLegend->iconBorderPen(); +} + +/*! \internal + + Returns the text color that shall be used to draw text, taking into account the selection state + of this item. +*/ +QColor QCPPlottableLegendItem::getTextColor() const +{ + return mSelected ? mSelectedTextColor : mTextColor; +} + +/*! \internal + + Returns the font that shall be used to draw text, taking into account the selection state of this + item. +*/ +QFont QCPPlottableLegendItem::getFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Draws the item with \a painter. The size and position of the drawn legend item is defined by the + parent layout (typically a \ref QCPLegend) and the \ref minimumSizeHint and \ref maximumSizeHint + of this legend item. +*/ +void QCPPlottableLegendItem::draw(QCPPainter *painter) +{ + if (!mPlottable) return; + painter->setFont(getFont()); + painter->setPen(QPen(getTextColor())); + QSizeF iconSize = mParentLegend->iconSize(); + QRectF textRect = painter->fontMetrics().boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->name()); + QRectF iconRect(mRect.topLeft(), iconSize); + int textHeight = qMax(textRect.height(), iconSize.height()); // if text has smaller height than icon, center text vertically in icon height, else align tops + painter->drawText(mRect.x()+iconSize.width()+mParentLegend->iconTextPadding(), mRect.y(), textRect.width(), textHeight, Qt::TextDontClip, mPlottable->name()); + // draw icon: + painter->save(); + painter->setClipRect(iconRect, Qt::IntersectClip); + mPlottable->drawLegendIcon(painter, iconRect); + painter->restore(); + // draw icon border: + if (getIconBorderPen().style() != Qt::NoPen) + { + painter->setPen(getIconBorderPen()); + painter->setBrush(Qt::NoBrush); + painter->drawRect(iconRect); + } +} + +/*! \internal + + Calculates and returns the size of this item. This includes the icon, the text and the padding in + between. +*/ +QSize QCPPlottableLegendItem::minimumSizeHint() const +{ + if (!mPlottable) return QSize(); + QSize result(0, 0); + QRect textRect; + QFontMetrics fontMetrics(getFont()); + QSize iconSize = mParentLegend->iconSize(); + textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->name()); + result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width() + mMargins.left() + mMargins.right()); + result.setHeight(qMax(textRect.height(), iconSize.height()) + mMargins.top() + mMargins.bottom()); + return result; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLegend +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLegend + \brief Manages a legend inside a QCustomPlot. + + A legend is a small box somewhere in the plot which lists plottables with their name and icon. + + Normally, the legend is populated by calling \ref QCPAbstractPlottable::addToLegend. The + respective legend item can be removed with \ref QCPAbstractPlottable::removeFromLegend. However, + QCPLegend also offers an interface to add and manipulate legend items directly: \ref item, \ref + itemWithPlottable, \ref itemCount, \ref addItem, \ref removeItem, etc. + + The QCPLegend derives from QCPLayoutGrid and as such can be placed in any position a + QCPLayoutElement may be positioned. The legend items are themselves QCPLayoutElements which are + placed in the grid layout of the legend. QCPLegend only adds an interface specialized for + handling child elements of type QCPAbstractLegendItem, as mentioned above. In principle, any + other layout elements may also be added to a legend via the normal \ref QCPLayoutGrid interface. + However, the QCPAbstractLegendItem-Interface will ignore those elements (e.g. \ref itemCount will + only return the number of items with QCPAbstractLegendItems type). + + By default, every QCustomPlot has one legend (QCustomPlot::legend) which is placed in the inset + layout of the main axis rect (\ref QCPAxisRect::insetLayout). To move the legend to another + position inside the axis rect, use the methods of the \ref QCPLayoutInset. To move the legend + outside of the axis rect, place it anywhere else with the QCPLayout/QCPLayoutElement interface. +*/ + +/* start of documentation of signals */ + +/*! \fn void QCPLegend::selectionChanged(QCPLegend::SelectableParts selection); + + This signal is emitted when the selection state of this legend has changed. + + \see setSelectedParts, setSelectableParts +*/ + +/* end of documentation of signals */ + +/*! + Constructs a new QCPLegend instance with \a parentPlot as the containing plot and default values. + + Note that by default, QCustomPlot already contains a legend ready to be used as + QCustomPlot::legend +*/ +QCPLegend::QCPLegend() +{ + setRowSpacing(0); + setColumnSpacing(10); + setMargins(QMargins(2, 3, 2, 2)); + setAntialiased(false); + setIconSize(32, 18); + + setIconTextPadding(7); + + setSelectableParts(spLegendBox | spItems); + setSelectedParts(spNone); + + setBorderPen(QPen(Qt::black)); + setSelectedBorderPen(QPen(Qt::blue, 2)); + setIconBorderPen(Qt::NoPen); + setSelectedIconBorderPen(QPen(Qt::blue, 2)); + setBrush(Qt::white); + setSelectedBrush(Qt::white); + setTextColor(Qt::black); + setSelectedTextColor(Qt::blue); +} + +QCPLegend::~QCPLegend() +{ + clearItems(); + if (qobject_cast(mParentPlot)) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the legend is not in any layout and thus QObject-child of QCustomPlot) + mParentPlot->legendRemoved(this); +} + +/* no doc for getter, see setSelectedParts */ +QCPLegend::SelectableParts QCPLegend::selectedParts() const +{ + // check whether any legend elements selected, if yes, add spItems to return value + bool hasSelectedItems = false; + for (int i=0; iselected()) + { + hasSelectedItems = true; + break; + } + } + if (hasSelectedItems) + return mSelectedParts | spItems; + else + return mSelectedParts & ~spItems; +} + +/*! + Sets the pen, the border of the entire legend is drawn with. +*/ +void QCPLegend::setBorderPen(const QPen &pen) +{ + mBorderPen = pen; +} + +/*! + Sets the brush of the legend background. +*/ +void QCPLegend::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the default font of legend text. Legend items that draw text (e.g. the name of a graph) will + use this font by default. However, a different font can be specified on a per-item-basis by + accessing the specific legend item. + + This function will also set \a font on all already existing legend items. + + \see QCPAbstractLegendItem::setFont +*/ +void QCPLegend::setFont(const QFont &font) +{ + mFont = font; + for (int i=0; isetFont(mFont); + } +} + +/*! + Sets the default color of legend text. Legend items that draw text (e.g. the name of a graph) + will use this color by default. However, a different colors can be specified on a per-item-basis + by accessing the specific legend item. + + This function will also set \a color on all already existing legend items. + + \see QCPAbstractLegendItem::setTextColor +*/ +void QCPLegend::setTextColor(const QColor &color) +{ + mTextColor = color; + for (int i=0; isetTextColor(color); + } +} + +/*! + Sets the size of legend icons. Legend items that draw an icon (e.g. a visual + representation of the graph) will use this size by default. +*/ +void QCPLegend::setIconSize(const QSize &size) +{ + mIconSize = size; +} + +/*! \overload +*/ +void QCPLegend::setIconSize(int width, int height) +{ + mIconSize.setWidth(width); + mIconSize.setHeight(height); +} + +/*! + Sets the horizontal space in pixels between the legend icon and the text next to it. + Legend items that draw an icon (e.g. a visual representation of the graph) and text (e.g. the + name of the graph) will use this space by default. +*/ +void QCPLegend::setIconTextPadding(int padding) +{ + mIconTextPadding = padding; +} + +/*! + Sets the pen used to draw a border around each legend icon. Legend items that draw an + icon (e.g. a visual representation of the graph) will use this pen by default. + + If no border is wanted, set this to \a Qt::NoPen. +*/ +void QCPLegend::setIconBorderPen(const QPen &pen) +{ + mIconBorderPen = pen; +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains \ref QCP::iSelectLegend.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelectedParts + directly. + + \see SelectablePart, setSelectedParts +*/ +void QCPLegend::setSelectableParts(const SelectableParts &selectable) +{ + if (mSelectableParts != selectable) + { + mSelectableParts = selectable; + emit selectableChanged(mSelectableParts); + } +} + +/*! + Sets the selected state of the respective legend parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font and brush. If some legend items are selected and \a selected + doesn't contain \ref spItems, those items become deselected. + + The entire selection mechanism is handled automatically when \ref QCustomPlot::setInteractions + contains iSelectLegend. You only need to call this function when you wish to change the selection + state manually. + + This function can change the selection state of a part even when \ref setSelectableParts was set to a + value that actually excludes the part. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + Note that it doesn't make sense to set the selected state \ref spItems here when it wasn't set + before, because there's no way to specify which exact items to newly select. Do this by calling + \ref QCPAbstractLegendItem::setSelected directly on the legend item you wish to select. + + \see SelectablePart, setSelectableParts, selectTest, setSelectedBorderPen, setSelectedIconBorderPen, setSelectedBrush, + setSelectedFont +*/ +void QCPLegend::setSelectedParts(const SelectableParts &selected) +{ + SelectableParts newSelected = selected; + mSelectedParts = this->selectedParts(); // update mSelectedParts in case item selection changed + + if (mSelectedParts != newSelected) + { + if (!mSelectedParts.testFlag(spItems) && newSelected.testFlag(spItems)) // attempt to set spItems flag (can't do that) + { + qDebug() << Q_FUNC_INFO << "spItems flag can not be set, it can only be unset with this function"; + newSelected &= ~spItems; + } + if (mSelectedParts.testFlag(spItems) && !newSelected.testFlag(spItems)) // spItems flag was unset, so clear item selection + { + for (int i=0; isetSelected(false); + } + } + mSelectedParts = newSelected; + emit selectionChanged(mSelectedParts); + } +} + +/*! + When the legend box is selected, this pen is used to draw the border instead of the normal pen + set via \ref setBorderPen. + + \see setSelectedParts, setSelectableParts, setSelectedBrush +*/ +void QCPLegend::setSelectedBorderPen(const QPen &pen) +{ + mSelectedBorderPen = pen; +} + +/*! + Sets the pen legend items will use to draw their icon borders, when they are selected. + + \see setSelectedParts, setSelectableParts, setSelectedFont +*/ +void QCPLegend::setSelectedIconBorderPen(const QPen &pen) +{ + mSelectedIconBorderPen = pen; +} + +/*! + When the legend box is selected, this brush is used to draw the legend background instead of the normal brush + set via \ref setBrush. + + \see setSelectedParts, setSelectableParts, setSelectedBorderPen +*/ +void QCPLegend::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the default font that is used by legend items when they are selected. + + This function will also set \a font on all already existing legend items. + + \see setFont, QCPAbstractLegendItem::setSelectedFont +*/ +void QCPLegend::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; + for (int i=0; isetSelectedFont(font); + } +} + +/*! + Sets the default text color that is used by legend items when they are selected. + + This function will also set \a color on all already existing legend items. + + \see setTextColor, QCPAbstractLegendItem::setSelectedTextColor +*/ +void QCPLegend::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; + for (int i=0; isetSelectedTextColor(color); + } +} + +/*! + Returns the item with index \a i. + + \see itemCount +*/ +QCPAbstractLegendItem *QCPLegend::item(int index) const +{ + return qobject_cast(elementAt(index)); +} + +/*! + Returns the QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). + If such an item isn't in the legend, returns 0. + + \see hasItemWithPlottable +*/ +QCPPlottableLegendItem *QCPLegend::itemWithPlottable(const QCPAbstractPlottable *plottable) const +{ + for (int i=0; i(item(i))) + { + if (pli->plottable() == plottable) + return pli; + } + } + return 0; +} + +/*! + Returns the number of items currently in the legend. + \see item +*/ +int QCPLegend::itemCount() const +{ + return elementCount(); +} + +/*! + Returns whether the legend contains \a itm. +*/ +bool QCPLegend::hasItem(QCPAbstractLegendItem *item) const +{ + for (int i=0; iitem(i)) + return true; + } + return false; +} + +/*! + Returns whether the legend contains a QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). + If such an item isn't in the legend, returns false. + + \see itemWithPlottable +*/ +bool QCPLegend::hasItemWithPlottable(const QCPAbstractPlottable *plottable) const +{ + return itemWithPlottable(plottable); +} + +/*! + Adds \a item to the legend, if it's not present already. + + Returns true on sucess, i.e. if the item wasn't in the list already and has been successfuly added. + + The legend takes ownership of the item. +*/ +bool QCPLegend::addItem(QCPAbstractLegendItem *item) +{ + if (!hasItem(item)) + { + return addElement(rowCount(), 0, item); + } else + return false; +} + +/*! + Removes the item with index \a index from the legend. + + Returns true, if successful. + + \see itemCount, clearItems +*/ +bool QCPLegend::removeItem(int index) +{ + if (QCPAbstractLegendItem *ali = item(index)) + { + bool success = remove(ali); + simplify(); + return success; + } else + return false; +} + +/*! \overload + + Removes \a item from the legend. + + Returns true, if successful. + + \see clearItems +*/ +bool QCPLegend::removeItem(QCPAbstractLegendItem *item) +{ + bool success = remove(item); + simplify(); + return success; +} + +/*! + Removes all items from the legend. +*/ +void QCPLegend::clearItems() +{ + for (int i=itemCount()-1; i>=0; --i) + removeItem(i); +} + +/*! + Returns the legend items that are currently selected. If no items are selected, + the list is empty. + + \see QCPAbstractLegendItem::setSelected, setSelectable +*/ +QList QCPLegend::selectedItems() const +{ + QList result; + for (int i=0; iselected()) + result.append(ali); + } + } + return result; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing main legend elements. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPLegend::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeLegend); +} + +/*! \internal + + Returns the pen used to paint the border of the legend, taking into account the selection state + of the legend box. +*/ +QPen QCPLegend::getBorderPen() const +{ + return mSelectedParts.testFlag(spLegendBox) ? mSelectedBorderPen : mBorderPen; +} + +/*! \internal + + Returns the brush used to paint the background of the legend, taking into account the selection + state of the legend box. +*/ +QBrush QCPLegend::getBrush() const +{ + return mSelectedParts.testFlag(spLegendBox) ? mSelectedBrush : mBrush; +} + +/*! \internal + + Draws the legend box with the provided \a painter. The individual legend items are layerables + themselves, thus are drawn independently. +*/ +void QCPLegend::draw(QCPPainter *painter) +{ + // draw background rect: + painter->setBrush(getBrush()); + painter->setPen(getBorderPen()); + painter->drawRect(mOuterRect); +} + +/* inherits documentation from base class */ +double QCPLegend::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mParentPlot) return -1; + if (onlySelectable && !mSelectableParts.testFlag(spLegendBox)) + return -1; + + if (mOuterRect.contains(pos.toPoint())) + { + if (details) details->setValue(spLegendBox); + return mParentPlot->selectionTolerance()*0.99; + } + return -1; +} + +/* inherits documentation from base class */ +void QCPLegend::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + mSelectedParts = selectedParts(); // in case item selection has changed + if (details.value() == spLegendBox && mSelectableParts.testFlag(spLegendBox)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(additive ? mSelectedParts^spLegendBox : mSelectedParts|spLegendBox); // no need to unset spItems in !additive case, because they will be deselected by QCustomPlot (they're normal QCPLayerables with own deselectEvent) + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPLegend::deselectEvent(bool *selectionStateChanged) +{ + mSelectedParts = selectedParts(); // in case item selection has changed + if (mSelectableParts.testFlag(spLegendBox)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(selectedParts() & ~spLegendBox); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +QCP::Interaction QCPLegend::selectionCategory() const +{ + return QCP::iSelectLegend; +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractLegendItem::selectionCategory() const +{ + return QCP::iSelectLegend; +} + +/* inherits documentation from base class */ +void QCPLegend::parentPlotInitialized(QCustomPlot *parentPlot) +{ + Q_UNUSED(parentPlot) +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPlotTitle +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPlotTitle + \brief A layout element displaying a plot title text + + The text may be specified with \ref setText, theformatting can be controlled with \ref setFont + and \ref setTextColor. + + A plot title can be added as follows: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpplottitle-creation + + Since a plot title is a common requirement, QCustomPlot offers specialized selection signals for + easy interaction with QCPPlotTitle. If a layout element of type QCPPlotTitle is clicked, the + signal \ref QCustomPlot::titleClick is emitted. A double click emits the \ref + QCustomPlot::titleDoubleClick signal. +*/ + +/* start documentation of signals */ + +/*! \fn void QCPPlotTitle::selectionChanged(bool selected) + + This signal is emitted when the selection state has changed to \a selected, either by user + interaction or by a direct call to \ref setSelected. + + \see setSelected, setSelectable +*/ + +/* end documentation of signals */ + +/*! + Creates a new QCPPlotTitle instance and sets default values. The initial text is empty (\ref setText). + + To set the title text in the constructor, rather use \ref QCPPlotTitle(QCustomPlot *parentPlot, const QString &text). +*/ +QCPPlotTitle::QCPPlotTitle(QCustomPlot *parentPlot) : + QCPLayoutElement(parentPlot), + mFont(QFont(QLatin1String("sans serif"), 13*1.5, QFont::Bold)), + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), 13*1.6, QFont::Bold)), + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + setLayer(parentPlot->currentLayer()); + mFont = QFont(parentPlot->font().family(), parentPlot->font().pointSize()*1.5, QFont::Bold); + mSelectedFont = QFont(parentPlot->font().family(), parentPlot->font().pointSize()*1.6, QFont::Bold); + } + setMargins(QMargins(5, 5, 5, 0)); +} + +/*! \overload + + Creates a new QCPPlotTitle instance and sets default values. The initial text is set to \a text. +*/ +QCPPlotTitle::QCPPlotTitle(QCustomPlot *parentPlot, const QString &text) : + QCPLayoutElement(parentPlot), + mText(text), + mFont(QFont(parentPlot->font().family(), parentPlot->font().pointSize()*1.5, QFont::Bold)), + mTextColor(Qt::black), + mSelectedFont(QFont(parentPlot->font().family(), parentPlot->font().pointSize()*1.6, QFont::Bold)), + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + setLayer(QLatin1String("axes")); + setMargins(QMargins(5, 5, 5, 0)); +} + +/*! + Sets the text that will be displayed to \a text. Multiple lines can be created by insertion of "\n". + + \see setFont, setTextColor +*/ +void QCPPlotTitle::setText(const QString &text) +{ + mText = text; +} + +/*! + Sets the \a font of the title text. + + \see setTextColor, setSelectedFont +*/ +void QCPPlotTitle::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the \a color of the title text. + + \see setFont, setSelectedTextColor +*/ +void QCPPlotTitle::setTextColor(const QColor &color) +{ + mTextColor = color; +} + +/*! + Sets the \a font of the title text that will be used if the plot title is selected (\ref setSelected). + + \see setFont +*/ +void QCPPlotTitle::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + Sets the \a color of the title text that will be used if the plot title is selected (\ref setSelected). + + \see setTextColor +*/ +void QCPPlotTitle::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; +} + +/*! + Sets whether the user may select this plot title to \a selectable. + + Note that even when \a selectable is set to false, the selection state may be changed + programmatically via \ref setSelected. +*/ +void QCPPlotTitle::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets the selection state of this plot title to \a selected. If the selection has changed, \ref + selectionChanged is emitted. + + Note that this function can change the selection state independently of the current \ref + setSelectable state. +*/ +void QCPPlotTitle::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/* inherits documentation from base class */ +void QCPPlotTitle::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeNone); +} + +/* inherits documentation from base class */ +void QCPPlotTitle::draw(QCPPainter *painter) +{ + painter->setFont(mainFont()); + painter->setPen(QPen(mainTextColor())); + painter->drawText(mRect, Qt::AlignCenter, mText, &mTextBoundingRect); +} + +/* inherits documentation from base class */ +QSize QCPPlotTitle::minimumSizeHint() const +{ + QFontMetrics metrics(mFont); + QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size(); + result.rwidth() += mMargins.left() + mMargins.right(); + result.rheight() += mMargins.top() + mMargins.bottom(); + return result; +} + +/* inherits documentation from base class */ +QSize QCPPlotTitle::maximumSizeHint() const +{ + QFontMetrics metrics(mFont); + QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size(); + result.rheight() += mMargins.top() + mMargins.bottom(); + result.setWidth(QWIDGETSIZE_MAX); + return result; +} + +/* inherits documentation from base class */ +void QCPPlotTitle::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPPlotTitle::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +double QCPPlotTitle::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + if (mTextBoundingRect.contains(pos.toPoint())) + return mParentPlot->selectionTolerance()*0.99; + else + return -1; +} + +/*! \internal + + Returns the main font to be used. This is mSelectedFont if \ref setSelected is set to + true, else mFont is returned. +*/ +QFont QCPPlotTitle::mainFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Returns the main color to be used. This is mSelectedTextColor if \ref setSelected is set to + true, else mTextColor is returned. +*/ +QColor QCPPlotTitle::mainTextColor() const +{ + return mSelected ? mSelectedTextColor : mTextColor; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorScale +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorScale + \brief A color scale for use with color coding data such as QCPColorMap + + This layout element can be placed on the plot to correlate a color gradient with data values. It + is usually used in combination with one or multiple \ref QCPColorMap "QCPColorMaps". + + \image html QCPColorScale.png + + The color scale can be either horizontal or vertical, as shown in the image above. The + orientation and the side where the numbers appear is controlled with \ref setType. + + Use \ref QCPColorMap::setColorScale to connect a color map with a color scale. Once they are + connected, they share their gradient, data range and data scale type (\ref setGradient, \ref + setDataRange, \ref setDataScaleType). Multiple color maps may be associated with a single color + scale, to make them all synchronize these properties. + + To have finer control over the number display and axis behaviour, you can directly access the + \ref axis. See the documentation of QCPAxis for details about configuring axes. For example, if + you want to change the number of automatically generated ticks, call + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-autotickcount + + Placing a color scale next to the main axis rect works like with any other layout element: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-creation + In this case we have placed it to the right of the default axis rect, so it wasn't necessary to + call \ref setType, since \ref QCPAxis::atRight is already the default. The text next to the color + scale can be set with \ref setLabel. + + For optimum appearance (like in the image above), it may be desirable to line up the axis rect and + the borders of the color scale. Use a \ref QCPMarginGroup to achieve this: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-margingroup + + Color scales are initialized with a non-zero minimum top and bottom margin (\ref + setMinimumMargins), because vertical color scales are most common and the minimum top/bottom + margin makes sure it keeps some distance to the top/bottom widget border. So if you change to a + horizontal color scale by setting \ref setType to \ref QCPAxis::atBottom or \ref QCPAxis::atTop, you + might want to also change the minimum margins accordingly, e.g. setMinimumMargins(QMargins(6, 0, 6, 0)). +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPAxis *QCPColorScale::axis() const + + Returns the internal \ref QCPAxis instance of this color scale. You can access it to alter the + appearance and behaviour of the axis. \ref QCPColorScale duplicates some properties in its + interface for convenience. Those are \ref setDataRange (\ref QCPAxis::setRange), \ref + setDataScaleType (\ref QCPAxis::setScaleType), and the method \ref setLabel (\ref + QCPAxis::setLabel). As they each are connected, it does not matter whether you use the method on + the QCPColorScale or on its QCPAxis. + + If the type of the color scale is changed with \ref setType, the axis returned by this method + will change, too, to either the left, right, bottom or top axis, depending on which type was set. +*/ + +/* end documentation of signals */ +/* start documentation of signals */ + +/*! \fn void QCPColorScale::dataRangeChanged(QCPRange newRange); + + This signal is emitted when the data range changes. + + \see setDataRange +*/ + +/*! \fn void QCPColorScale::dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + + This signal is emitted when the data scale type changes. + + \see setDataScaleType +*/ + +/*! \fn void QCPColorScale::gradientChanged(QCPColorGradient newGradient); + + This signal is emitted when the gradient changes. + + \see setGradient +*/ + +/* end documentation of signals */ + +/*! + Constructs a new QCPColorScale. +*/ +QCPColorScale::QCPColorScale(QCustomPlot *parentPlot) : + QCPLayoutElement(parentPlot), + mType(QCPAxis::atTop), // set to atTop such that setType(QCPAxis::atRight) below doesn't skip work because it thinks it's already atRight + mDataScaleType(QCPAxis::stLinear), + mBarWidth(20), + mAxisRect(new QCPColorScaleAxisRectPrivate(this)) +{ + setMinimumMargins(QMargins(0, 6, 0, 6)); // for default right color scale types, keep some room at bottom and top (important if no margin group is used) + setType(QCPAxis::atRight); + setDataRange(QCPRange(0, 6)); +} + +QCPColorScale::~QCPColorScale() +{ + delete mAxisRect; +} + +/* undocumented getter */ +QString QCPColorScale::label() const +{ + if (!mColorAxis) + { + qDebug() << Q_FUNC_INFO << "internal color axis undefined"; + return QString(); + } + + return mColorAxis.data()->label(); +} + +/* undocumented getter */ +bool QCPColorScale::rangeDrag() const +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return false; + } + + return mAxisRect.data()->rangeDrag().testFlag(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); +} + +/* undocumented getter */ +bool QCPColorScale::rangeZoom() const +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return false; + } + + return mAxisRect.data()->rangeZoom().testFlag(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); +} + +/*! + Sets at which side of the color scale the axis is placed, and thus also its orientation. + + Note that after setting \a type to a different value, the axis returned by \ref axis() will + be a different one. The new axis will adopt the following properties from the previous axis: The + range, scale type, log base and label. +*/ +void QCPColorScale::setType(QCPAxis::AxisType type) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + if (mType != type) + { + mType = type; + QCPRange rangeTransfer(0, 6); + double logBaseTransfer = 10; + QString labelTransfer; + // revert some settings on old axis: + if (mColorAxis) + { + rangeTransfer = mColorAxis.data()->range(); + labelTransfer = mColorAxis.data()->label(); + logBaseTransfer = mColorAxis.data()->scaleLogBase(); + mColorAxis.data()->setLabel(QString()); + disconnect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + disconnect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } + QList allAxisTypes = QList() << QCPAxis::atLeft << QCPAxis::atRight << QCPAxis::atBottom << QCPAxis::atTop; + foreach (QCPAxis::AxisType atype, allAxisTypes) + { + mAxisRect.data()->axis(atype)->setTicks(atype == mType); + mAxisRect.data()->axis(atype)->setTickLabels(atype== mType); + } + // set new mColorAxis pointer: + mColorAxis = mAxisRect.data()->axis(mType); + // transfer settings to new axis: + mColorAxis.data()->setRange(rangeTransfer); // transfer range of old axis to new one (necessary if axis changes from vertical to horizontal or vice versa) + mColorAxis.data()->setLabel(labelTransfer); + mColorAxis.data()->setScaleLogBase(logBaseTransfer); // scaleType is synchronized among axes in realtime via signals (connected in QCPColorScale ctor), so we only need to take care of log base here + connect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + connect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + mAxisRect.data()->setRangeDragAxes(QCPAxis::orientation(mType) == Qt::Horizontal ? mColorAxis.data() : 0, + QCPAxis::orientation(mType) == Qt::Vertical ? mColorAxis.data() : 0); + } +} + +/*! + Sets the range spanned by the color gradient and that is shown by the axis in the color scale. + + It is equivalent to calling QCPColorMap::setDataRange on any of the connected color maps. It is + also equivalent to directly accessing the \ref axis and setting its range with \ref + QCPAxis::setRange. + + \see setDataScaleType, setGradient, rescaleDataRange +*/ +void QCPColorScale::setDataRange(const QCPRange &dataRange) +{ + if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) + { + mDataRange = dataRange; + if (mColorAxis) + mColorAxis.data()->setRange(mDataRange); + emit dataRangeChanged(mDataRange); + } +} + +/*! + Sets the scale type of the color scale, i.e. whether values are linearly associated with colors + or logarithmically. + + It is equivalent to calling QCPColorMap::setDataScaleType on any of the connected color maps. It is + also equivalent to directly accessing the \ref axis and setting its scale type with \ref + QCPAxis::setScaleType. + + \see setDataRange, setGradient +*/ +void QCPColorScale::setDataScaleType(QCPAxis::ScaleType scaleType) +{ + if (mDataScaleType != scaleType) + { + mDataScaleType = scaleType; + if (mColorAxis) + mColorAxis.data()->setScaleType(mDataScaleType); + if (mDataScaleType == QCPAxis::stLogarithmic) + setDataRange(mDataRange.sanitizedForLogScale()); + emit dataScaleTypeChanged(mDataScaleType); + } +} + +/*! + Sets the color gradient that will be used to represent data values. + + It is equivalent to calling QCPColorMap::setGradient on any of the connected color maps. + + \see setDataRange, setDataScaleType +*/ +void QCPColorScale::setGradient(const QCPColorGradient &gradient) +{ + if (mGradient != gradient) + { + mGradient = gradient; + if (mAxisRect) + mAxisRect.data()->mGradientImageInvalidated = true; + emit gradientChanged(mGradient); + } +} + +/*! + Sets the axis label of the color scale. This is equivalent to calling \ref QCPAxis::setLabel on + the internal \ref axis. +*/ +void QCPColorScale::setLabel(const QString &str) +{ + if (!mColorAxis) + { + qDebug() << Q_FUNC_INFO << "internal color axis undefined"; + return; + } + + mColorAxis.data()->setLabel(str); +} + +/*! + Sets the width (or height, for horizontal color scales) the bar where the gradient is displayed + will have. +*/ +void QCPColorScale::setBarWidth(int width) +{ + mBarWidth = width; +} + +/*! + Sets whether the user can drag the data range (\ref setDataRange). + + Note that \ref QCP::iRangeDrag must be in the QCustomPlot's interactions (\ref + QCustomPlot::setInteractions) to allow range dragging. +*/ +void QCPColorScale::setRangeDrag(bool enabled) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + if (enabled) + mAxisRect.data()->setRangeDrag(QCPAxis::orientation(mType)); + else + mAxisRect.data()->setRangeDrag(0); +} + +/*! + Sets whether the user can zoom the data range (\ref setDataRange) by scrolling the mouse wheel. + + Note that \ref QCP::iRangeZoom must be in the QCustomPlot's interactions (\ref + QCustomPlot::setInteractions) to allow range dragging. +*/ +void QCPColorScale::setRangeZoom(bool enabled) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + if (enabled) + mAxisRect.data()->setRangeZoom(QCPAxis::orientation(mType)); + else + mAxisRect.data()->setRangeZoom(0); +} + +/*! + Returns a list of all the color maps associated with this color scale. +*/ +QList QCPColorScale::colorMaps() const +{ + QList result; + for (int i=0; iplottableCount(); ++i) + { + if (QCPColorMap *cm = qobject_cast(mParentPlot->plottable(i))) + if (cm->colorScale() == this) + result.append(cm); + } + return result; +} + +/*! + Changes the data range such that all color maps associated with this color scale are fully mapped + to the gradient in the data dimension. + + \see setDataRange +*/ +void QCPColorScale::rescaleDataRange(bool onlyVisibleMaps) +{ + QList maps = colorMaps(); + QCPRange newRange; + bool haveRange = false; + int sign = 0; // TODO: should change this to QCPAbstractPlottable::SignDomain later (currently is protected, maybe move to QCP namespace) + if (mDataScaleType == QCPAxis::stLogarithmic) + sign = (mDataRange.upper < 0 ? -1 : 1); + for (int i=0; irealVisibility() && onlyVisibleMaps) + continue; + QCPRange mapRange; + if (maps.at(i)->colorScale() == this) + { + bool currentFoundRange = true; + mapRange = maps.at(i)->data()->dataBounds(); + if (sign == 1) + { + if (mapRange.lower <= 0 && mapRange.upper > 0) + mapRange.lower = mapRange.upper*1e-3; + else if (mapRange.lower <= 0 && mapRange.upper <= 0) + currentFoundRange = false; + } else if (sign == -1) + { + if (mapRange.upper >= 0 && mapRange.lower < 0) + mapRange.upper = mapRange.lower*1e-3; + else if (mapRange.upper >= 0 && mapRange.lower >= 0) + currentFoundRange = false; + } + if (currentFoundRange) + { + if (!haveRange) + newRange = mapRange; + else + newRange.expand(mapRange); + haveRange = true; + } + } + } + if (haveRange) + { + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this dimension), shift current range to at least center the data + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (mDataScaleType == QCPAxis::stLinear) + { + newRange.lower = center-mDataRange.size()/2.0; + newRange.upper = center+mDataRange.size()/2.0; + } else // mScaleType == stLogarithmic + { + newRange.lower = center/qSqrt(mDataRange.upper/mDataRange.lower); + newRange.upper = center*qSqrt(mDataRange.upper/mDataRange.lower); + } + } + setDataRange(newRange); + } +} + +/* inherits documentation from base class */ +void QCPColorScale::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + mAxisRect.data()->update(phase); + + switch (phase) + { + case upMargins: + { + if (mType == QCPAxis::atBottom || mType == QCPAxis::atTop) + { + setMaximumSize(QWIDGETSIZE_MAX, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()+margins().top()+margins().bottom()); + setMinimumSize(0, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()+margins().top()+margins().bottom()); + } else + { + setMaximumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right()+margins().left()+margins().right(), QWIDGETSIZE_MAX); + setMinimumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right()+margins().left()+margins().right(), 0); + } + break; + } + case upLayout: + { + mAxisRect.data()->setOuterRect(rect()); + break; + } + default: break; + } +} + +/* inherits documentation from base class */ +void QCPColorScale::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + painter->setAntialiasing(false); +} + +/* inherits documentation from base class */ +void QCPColorScale::mousePressEvent(QMouseEvent *event) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mousePressEvent(event); +} + +/* inherits documentation from base class */ +void QCPColorScale::mouseMoveEvent(QMouseEvent *event) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mouseMoveEvent(event); +} + +/* inherits documentation from base class */ +void QCPColorScale::mouseReleaseEvent(QMouseEvent *event) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mouseReleaseEvent(event); +} + +/* inherits documentation from base class */ +void QCPColorScale::wheelEvent(QWheelEvent *event) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->wheelEvent(event); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorScaleAxisRectPrivate +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorScaleAxisRectPrivate + + \internal + \brief An axis rect subclass for use in a QCPColorScale + + This is a private class and not part of the public QCustomPlot interface. + + It provides the axis rect functionality for the QCPColorScale class. +*/ + + +/*! + Creates a new instance, as a child of \a parentColorScale. +*/ +QCPColorScaleAxisRectPrivate::QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale) : + QCPAxisRect(parentColorScale->parentPlot(), true), + mParentColorScale(parentColorScale), + mGradientImageInvalidated(true) +{ + setParentLayerable(parentColorScale); + setMinimumMargins(QMargins(0, 0, 0, 0)); + QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + axis(type)->setVisible(true); + axis(type)->grid()->setVisible(false); + axis(type)->setPadding(0); + connect(axis(type), SIGNAL(selectionChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectionChanged(QCPAxis::SelectableParts))); + connect(axis(type), SIGNAL(selectableChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectableChanged(QCPAxis::SelectableParts))); + } + + connect(axis(QCPAxis::atLeft), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atRight), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atRight), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atLeft), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atTop), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atTop), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atBottom), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atLeft), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atRight), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atRight), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atLeft), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atBottom), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atTop), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atTop), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atBottom), SLOT(setScaleType(QCPAxis::ScaleType))); + + // make layer transfers of color scale transfer to axis rect and axes + // the axes must be set after axis rect, such that they appear above color gradient drawn by axis rect: + connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), this, SLOT(setLayer(QCPLayer*))); + foreach (QCPAxis::AxisType type, allAxisTypes) + connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), axis(type), SLOT(setLayer(QCPLayer*))); +} + +/*! \internal + Updates the color gradient image if necessary, by calling \ref updateGradientImage, then draws + it. Then the axes are drawn by calling the \ref QCPAxisRect::draw base class implementation. +*/ +void QCPColorScaleAxisRectPrivate::draw(QCPPainter *painter) +{ + if (mGradientImageInvalidated) + updateGradientImage(); + + bool mirrorHorz = false; + bool mirrorVert = false; + if (mParentColorScale->mColorAxis) + { + mirrorHorz = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atBottom || mParentColorScale->type() == QCPAxis::atTop); + mirrorVert = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atLeft || mParentColorScale->type() == QCPAxis::atRight); + } + + painter->drawImage(rect().adjusted(0, -1, 0, -1), mGradientImage.mirrored(mirrorHorz, mirrorVert)); + QCPAxisRect::draw(painter); +} + +/*! \internal + + Uses the current gradient of the parent \ref QCPColorScale (specified in the constructor) to + generate a gradient image. This gradient image will be used in the \ref draw method. +*/ +void QCPColorScaleAxisRectPrivate::updateGradientImage() +{ + if (rect().isEmpty()) + return; + + int n = mParentColorScale->mGradient.levelCount(); + int w, h; + QVector data(n); + for (int i=0; imType == QCPAxis::atBottom || mParentColorScale->mType == QCPAxis::atTop) + { + w = n; + h = rect().height(); + mGradientImage = QImage(w, h, QImage::Format_RGB32); + QVector pixels; + for (int y=0; y(mGradientImage.scanLine(y))); + mParentColorScale->mGradient.colorize(data.constData(), QCPRange(0, n-1), pixels.first(), n); + for (int y=1; y(mGradientImage.scanLine(y)); + const QRgb lineColor = mParentColorScale->mGradient.color(data[h-1-y], QCPRange(0, n-1)); + for (int x=0; x allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + if (QCPAxis *senderAxis = qobject_cast(sender())) + if (senderAxis->axisType() == type) + continue; + + if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) + { + if (selectedParts.testFlag(QCPAxis::spAxis)) + axis(type)->setSelectedParts(axis(type)->selectedParts() | QCPAxis::spAxis); + else + axis(type)->setSelectedParts(axis(type)->selectedParts() & ~QCPAxis::spAxis); + } + } +} + +/*! \internal + + This slot is connected to the selectableChanged signals of the four axes in the constructor. It + synchronizes the selectability of the axes. +*/ +void QCPColorScaleAxisRectPrivate::axisSelectableChanged(QCPAxis::SelectableParts selectableParts) +{ + // synchronize axis base selectability: + QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + if (QCPAxis *senderAxis = qobject_cast(sender())) + if (senderAxis->axisType() == type) + continue; + + if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) + { + if (selectableParts.testFlag(QCPAxis::spAxis)) + axis(type)->setSelectableParts(axis(type)->selectableParts() | QCPAxis::spAxis); + else + axis(type)->setSelectableParts(axis(type)->selectableParts() & ~QCPAxis::spAxis); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPData + \brief Holds the data of one single data point for QCPGraph. + + The container for storing multiple data points is \ref QCPDataMap. + + The stored data is: + \li \a key: coordinate on the key axis of this data point + \li \a value: coordinate on the value axis of this data point + \li \a keyErrorMinus: negative error in the key dimension (for error bars) + \li \a keyErrorPlus: positive error in the key dimension (for error bars) + \li \a valueErrorMinus: negative error in the value dimension (for error bars) + \li \a valueErrorPlus: positive error in the value dimension (for error bars) + + \see QCPDataMap +*/ + +/*! + Constructs a data point with key, value and all errors set to zero. +*/ +QCPData::QCPData() : + key(0), + value(0), + keyErrorPlus(0), + keyErrorMinus(0), + valueErrorPlus(0), + valueErrorMinus(0) +{ +} + +/*! + Constructs a data point with the specified \a key and \a value. All errors are set to zero. +*/ +QCPData::QCPData(double key, double value) : + key(key), + value(value), + keyErrorPlus(0), + keyErrorMinus(0), + valueErrorPlus(0), + valueErrorMinus(0) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGraph +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGraph + \brief A plottable representing a graph in a plot. + + \image html QCPGraph.png + + Usually you create new graphs by calling QCustomPlot::addGraph. The resulting instance can be + accessed via QCustomPlot::graph. + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the graph's data via the \ref data method, which returns a pointer to the + internal \ref QCPDataMap. + + Graphs are used to display single-valued data. Single-valued means that there should only be one + data point per unique key coordinate. In other words, the graph can't have \a loops. If you do + want to plot non-single-valued curves, rather use the QCPCurve plottable. + + Gaps in the graph line can be created by adding data points with NaN as value + (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be + separated. + + \section appearance Changing the appearance + + The appearance of the graph is mainly determined by the line style, scatter style, brush and pen + of the graph (\ref setLineStyle, \ref setScatterStyle, \ref setBrush, \ref setPen). + + \subsection filling Filling under or between graphs + + QCPGraph knows two types of fills: Normal graph fills towards the zero-value-line parallel to + the key axis of the graph, and fills between two graphs, called channel fills. To enable a fill, + just set a brush with \ref setBrush which is neither Qt::NoBrush nor fully transparent. + + By default, a normal fill towards the zero-value-line will be drawn. To set up a channel fill + between this graph and another one, call \ref setChannelFillGraph with the other graph as + parameter. + + \see QCustomPlot::addGraph, QCustomPlot::graph +*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPDataMap *QCPGraph::data() const + + Returns a pointer to the internal data storage of type \ref QCPDataMap. You may use it to + directly manipulate the data, which may be more convenient and faster than using the regular \ref + setData or \ref addData methods, in certain situations. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a graph which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The constructed QCPGraph can be added to the plot with QCustomPlot::addPlottable, QCustomPlot + then takes ownership of the graph. + + To directly create a graph inside a plot, you can also use the simpler QCustomPlot::addGraph function. +*/ +QCPGraph::QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis) +{ + mData = new QCPDataMap; + + setPen(QPen(Qt::blue, 0)); + setErrorPen(QPen(Qt::black)); + setBrush(Qt::NoBrush); + setSelectedPen(QPen(QColor(80, 80, 255), 2.5)); + setSelectedBrush(Qt::NoBrush); + + setLineStyle(lsLine); + setErrorType(etNone); + setErrorBarSize(6); + setErrorBarSkipSymbol(true); + setChannelFillGraph(0); + setAdaptiveSampling(true); +} + +QCPGraph::~QCPGraph() +{ + delete mData; +} + +/*! + Replaces the current data with the provided \a data. + + If \a copy is set to true, data points in \a data will only be copied. if false, the graph + takes ownership of the passed data and replaces the internal data pointer with it. This is + significantly faster than copying for large datasets. + + Alternatively, you can also access and modify the graph's data via the \ref data method, which + returns a pointer to the internal \ref QCPDataMap. +*/ +void QCPGraph::setData(QCPDataMap *data, bool copy) +{ + if (mData == data) + { + qDebug() << Q_FUNC_INFO << "The data pointer is already in (and owned by) this plottable" << reinterpret_cast(data); + return; + } + if (copy) + { + *mData = *data; + } else + { + delete mData; + mData = data; + } +} + +/*! \overload + + Replaces the current data with the provided points in \a key and \a value pairs. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. +*/ +void QCPGraph::setData(const QVector &key, const QVector &value) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + QCPData newData; + for (int i=0; iinsertMulti(newData.key, newData); + } +} + +/*! + Replaces the current data with the provided points in \a key and \a value pairs. Additionally the + symmetrical value error of the data points are set to the values in \a valueError. + For error bars to show appropriately, see \ref setErrorType. + The provided vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + For asymmetrical errors (plus different from minus), see the overloaded version of this function. +*/ +void QCPGraph::setDataValueError(const QVector &key, const QVector &value, const QVector &valueError) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + n = qMin(n, valueError.size()); + QCPData newData; + for (int i=0; iinsertMulti(key[i], newData); + } +} + +/*! + \overload + Replaces the current data with the provided points in \a key and \a value pairs. Additionally the + negative value error of the data points are set to the values in \a valueErrorMinus, the positive + value error to \a valueErrorPlus. + For error bars to show appropriately, see \ref setErrorType. + The provided vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. +*/ +void QCPGraph::setDataValueError(const QVector &key, const QVector &value, const QVector &valueErrorMinus, const QVector &valueErrorPlus) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + n = qMin(n, valueErrorMinus.size()); + n = qMin(n, valueErrorPlus.size()); + QCPData newData; + for (int i=0; iinsertMulti(key[i], newData); + } +} + +/*! + Replaces the current data with the provided points in \a key and \a value pairs. Additionally the + symmetrical key error of the data points are set to the values in \a keyError. + For error bars to show appropriately, see \ref setErrorType. + The provided vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + For asymmetrical errors (plus different from minus), see the overloaded version of this function. +*/ +void QCPGraph::setDataKeyError(const QVector &key, const QVector &value, const QVector &keyError) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + n = qMin(n, keyError.size()); + QCPData newData; + for (int i=0; iinsertMulti(key[i], newData); + } +} + +/*! + \overload + Replaces the current data with the provided points in \a key and \a value pairs. Additionally the + negative key error of the data points are set to the values in \a keyErrorMinus, the positive + key error to \a keyErrorPlus. + For error bars to show appropriately, see \ref setErrorType. + The provided vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. +*/ +void QCPGraph::setDataKeyError(const QVector &key, const QVector &value, const QVector &keyErrorMinus, const QVector &keyErrorPlus) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + n = qMin(n, keyErrorMinus.size()); + n = qMin(n, keyErrorPlus.size()); + QCPData newData; + for (int i=0; iinsertMulti(key[i], newData); + } +} + +/*! + Replaces the current data with the provided points in \a key and \a value pairs. Additionally the + symmetrical key and value errors of the data points are set to the values in \a keyError and \a valueError. + For error bars to show appropriately, see \ref setErrorType. + The provided vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + For asymmetrical errors (plus different from minus), see the overloaded version of this function. +*/ +void QCPGraph::setDataBothError(const QVector &key, const QVector &value, const QVector &keyError, const QVector &valueError) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + n = qMin(n, valueError.size()); + n = qMin(n, keyError.size()); + QCPData newData; + for (int i=0; iinsertMulti(key[i], newData); + } +} + +/*! + \overload + Replaces the current data with the provided points in \a key and \a value pairs. Additionally the + negative key and value errors of the data points are set to the values in \a keyErrorMinus and \a valueErrorMinus. The positive + key and value errors are set to the values in \a keyErrorPlus \a valueErrorPlus. + For error bars to show appropriately, see \ref setErrorType. + The provided vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. +*/ +void QCPGraph::setDataBothError(const QVector &key, const QVector &value, const QVector &keyErrorMinus, const QVector &keyErrorPlus, const QVector &valueErrorMinus, const QVector &valueErrorPlus) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + n = qMin(n, valueErrorMinus.size()); + n = qMin(n, valueErrorPlus.size()); + n = qMin(n, keyErrorMinus.size()); + n = qMin(n, keyErrorPlus.size()); + QCPData newData; + for (int i=0; iinsertMulti(key[i], newData); + } +} + + +/*! + Sets how the single data points are connected in the plot. For scatter-only plots, set \a ls to + \ref lsNone and \ref setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPGraph::setLineStyle(LineStyle ls) +{ + mLineStyle = ls; +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref QCPScatterStyle::ssNone, no scatter points + are drawn (e.g. for line-only-plots with appropriate line style). + + \see QCPScatterStyle, setLineStyle +*/ +void QCPGraph::setScatterStyle(const QCPScatterStyle &style) +{ + mScatterStyle = style; +} + +/*! + Sets which kind of error bars (Key Error, Value Error or both) should be drawn on each data + point. If you set \a errorType to something other than \ref etNone, make sure to actually pass + error data via the specific setData functions along with the data points (e.g. \ref + setDataValueError, \ref setDataKeyError, \ref setDataBothError). + + \see ErrorType +*/ +void QCPGraph::setErrorType(ErrorType errorType) +{ + mErrorType = errorType; +} + +/*! + Sets the pen with which the error bars will be drawn. + \see setErrorBarSize, setErrorType +*/ +void QCPGraph::setErrorPen(const QPen &pen) +{ + mErrorPen = pen; +} + +/*! + Sets the width of the handles at both ends of an error bar in pixels. +*/ +void QCPGraph::setErrorBarSize(double size) +{ + mErrorBarSize = size; +} + +/*! + If \a enabled is set to true, the error bar will not be drawn as a solid line under the scatter symbol but + leave some free space around the symbol. + + This feature uses the current scatter size (\ref QCPScatterStyle::setSize) to determine the size + of the area to leave blank. So when drawing Pixmaps as scatter points (\ref + QCPScatterStyle::ssPixmap), the scatter size must be set manually to a value corresponding to the + size of the Pixmap, if the error bars should leave gaps to its boundaries. + + \ref setErrorType, setErrorBarSize, setScatterStyle +*/ +void QCPGraph::setErrorBarSkipSymbol(bool enabled) +{ + mErrorBarSkipSymbol = enabled; +} + +/*! + Sets the target graph for filling the area between this graph and \a targetGraph with the current + brush (\ref setBrush). + + When \a targetGraph is set to 0, a normal graph fill to the zero-value-line will be shown. To + disable any filling, set the brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPGraph::setChannelFillGraph(QCPGraph *targetGraph) +{ + // prevent setting channel target to this graph itself: + if (targetGraph == this) + { + qDebug() << Q_FUNC_INFO << "targetGraph is this graph itself"; + mChannelFillGraph = 0; + return; + } + // prevent setting channel target to a graph not in the plot: + if (targetGraph && targetGraph->mParentPlot != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "targetGraph not in same plot"; + mChannelFillGraph = 0; + return; + } + + mChannelFillGraph = targetGraph; +} + +/*! + Sets whether adaptive sampling shall be used when plotting this graph. QCustomPlot's adaptive + sampling technique can drastically improve the replot performance for graphs with a larger number + of points (e.g. above 10,000), without notably changing the appearance of the graph. + + By default, adaptive sampling is enabled. Even if enabled, QCustomPlot decides whether adaptive + sampling shall actually be used on a per-graph basis. So leaving adaptive sampling enabled has no + disadvantage in almost all cases. + + \image html adaptive-sampling-line.png "A line plot of 500,000 points without and with adaptive sampling" + + As can be seen, line plots experience no visual degradation from adaptive sampling. Outliers are + reproduced reliably, as well as the overall shape of the data set. The replot time reduces + dramatically though. This allows QCustomPlot to display large amounts of data in realtime. + + \image html adaptive-sampling-scatter.png "A scatter plot of 100,000 points without and with adaptive sampling" + + Care must be taken when using high-density scatter plots in combination with adaptive sampling. + The adaptive sampling algorithm treats scatter plots more carefully than line plots which still + gives a significant reduction of replot times, but not quite as much as for line plots. This is + because scatter plots inherently need more data points to be preserved in order to still resemble + the original, non-adaptive-sampling plot. As shown above, the results still aren't quite + identical, as banding occurs for the outer data points. This is in fact intentional, such that + the boundaries of the data cloud stay visible to the viewer. How strong the banding appears, + depends on the point density, i.e. the number of points in the plot. + + For some situations with scatter plots it might thus be desirable to manually turn adaptive + sampling off. For example, when saving the plot to disk. This can be achieved by setting \a + enabled to false before issuing a command like \ref QCustomPlot::savePng, and setting \a enabled + back to true afterwards. +*/ +void QCPGraph::setAdaptiveSampling(bool enabled) +{ + mAdaptiveSampling = enabled; +} + +/*! + Adds the provided data points in \a dataMap to the current data. + + Alternatively, you can also access and modify the graph's data via the \ref data method, which + returns a pointer to the internal \ref QCPDataMap. + + \see removeData +*/ +void QCPGraph::addData(const QCPDataMap &dataMap) +{ + mData->unite(dataMap); +} + +/*! \overload + Adds the provided single data point in \a data to the current data. + + Alternatively, you can also access and modify the graph's data via the \ref data method, which + returns a pointer to the internal \ref QCPDataMap. + + \see removeData +*/ +void QCPGraph::addData(const QCPData &data) +{ + mData->insertMulti(data.key, data); +} + +/*! \overload + Adds the provided single data point as \a key and \a value pair to the current data. + + Alternatively, you can also access and modify the graph's data via the \ref data method, which + returns a pointer to the internal \ref QCPDataMap. + + \see removeData +*/ +void QCPGraph::addData(double key, double value) +{ + QCPData newData; + newData.key = key; + newData.value = value; + mData->insertMulti(newData.key, newData); +} + +/*! \overload + Adds the provided data points as \a key and \a value pairs to the current data. + + Alternatively, you can also access and modify the graph's data via the \ref data method, which + returns a pointer to the internal \ref QCPDataMap. + + \see removeData +*/ +void QCPGraph::addData(const QVector &keys, const QVector &values) +{ + int n = qMin(keys.size(), values.size()); + QCPData newData; + for (int i=0; iinsertMulti(newData.key, newData); + } +} + +/*! + Removes all data points with keys smaller than \a key. + \see addData, clearData +*/ +void QCPGraph::removeDataBefore(double key) +{ + QCPDataMap::iterator it = mData->begin(); + while (it != mData->end() && it.key() < key) + it = mData->erase(it); +} + +/*! + Removes all data points with keys greater than \a key. + \see addData, clearData +*/ +void QCPGraph::removeDataAfter(double key) +{ + if (mData->isEmpty()) return; + QCPDataMap::iterator it = mData->upperBound(key); + while (it != mData->end()) + it = mData->erase(it); +} + +/*! + Removes all data points with keys between \a fromKey and \a toKey. + if \a fromKey is greater or equal to \a toKey, the function does nothing. To remove + a single data point with known key, use \ref removeData(double key). + + \see addData, clearData +*/ +void QCPGraph::removeData(double fromKey, double toKey) +{ + if (fromKey >= toKey || mData->isEmpty()) return; + QCPDataMap::iterator it = mData->upperBound(fromKey); + QCPDataMap::iterator itEnd = mData->upperBound(toKey); + while (it != itEnd) + it = mData->erase(it); +} + +/*! \overload + + Removes a single data point at \a key. If the position is not known with absolute precision, + consider using \ref removeData(double fromKey, double toKey) with a small fuzziness interval around + the suspected position, depeding on the precision with which the key is known. + + \see addData, clearData +*/ +void QCPGraph::removeData(double key) +{ + mData->remove(key); +} + +/*! + Removes all data points. + \see removeData, removeDataAfter, removeDataBefore +*/ +void QCPGraph::clearData() +{ + mData->clear(); +} + +/* inherits documentation from base class */ +double QCPGraph::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && !mSelectable) || mData->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + return pointDistance(pos); + else + return -1; +} + +/*! \overload + + Allows to define whether error bars are taken into consideration when determining the new axis + range. + + \see rescaleKeyAxis, rescaleValueAxis, QCPAbstractPlottable::rescaleAxes, QCustomPlot::rescaleAxes +*/ +void QCPGraph::rescaleAxes(bool onlyEnlarge, bool includeErrorBars) const +{ + rescaleKeyAxis(onlyEnlarge, includeErrorBars); + rescaleValueAxis(onlyEnlarge, includeErrorBars); +} + +/*! \overload + + Allows to define whether error bars (of kind \ref QCPGraph::etKey) are taken into consideration + when determining the new axis range. + + \see rescaleAxes, QCPAbstractPlottable::rescaleKeyAxis +*/ +void QCPGraph::rescaleKeyAxis(bool onlyEnlarge, bool includeErrorBars) const +{ + // this code is a copy of QCPAbstractPlottable::rescaleKeyAxis with the only change + // that getKeyRange is passed the includeErrorBars value. + if (mData->isEmpty()) return; + + QCPAxis *keyAxis = mKeyAxis.data(); + if (!keyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } + + SignDomain signDomain = sdBoth; + if (keyAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (keyAxis->range().upper < 0 ? sdNegative : sdPositive); + + bool foundRange; + QCPRange newRange = getKeyRange(foundRange, signDomain, includeErrorBars); + + if (foundRange) + { + if (onlyEnlarge) + { + if (keyAxis->range().lower < newRange.lower) + newRange.lower = keyAxis->range().lower; + if (keyAxis->range().upper > newRange.upper) + newRange.upper = keyAxis->range().upper; + } + keyAxis->setRange(newRange); + } +} + +/*! \overload + + Allows to define whether error bars (of kind \ref QCPGraph::etValue) are taken into consideration + when determining the new axis range. + + \see rescaleAxes, QCPAbstractPlottable::rescaleValueAxis +*/ +void QCPGraph::rescaleValueAxis(bool onlyEnlarge, bool includeErrorBars) const +{ + // this code is a copy of QCPAbstractPlottable::rescaleValueAxis with the only change + // is that getValueRange is passed the includeErrorBars value. + if (mData->isEmpty()) return; + + QCPAxis *valueAxis = mValueAxis.data(); + if (!valueAxis) { qDebug() << Q_FUNC_INFO << "invalid value axis"; return; } + + SignDomain signDomain = sdBoth; + if (valueAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (valueAxis->range().upper < 0 ? sdNegative : sdPositive); + + bool foundRange; + QCPRange newRange = getValueRange(foundRange, signDomain, includeErrorBars); + + if (foundRange) + { + if (onlyEnlarge) + { + if (valueAxis->range().lower < newRange.lower) + newRange.lower = valueAxis->range().lower; + if (valueAxis->range().upper > newRange.upper) + newRange.upper = valueAxis->range().upper; + } + valueAxis->setRange(newRange); + } +} + +/* inherits documentation from base class */ +void QCPGraph::draw(QCPPainter *painter) +{ + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mKeyAxis.data()->range().size() <= 0 || mData->isEmpty()) return; + if (mLineStyle == lsNone && mScatterStyle.isNone()) return; + + // allocate line and (if necessary) point vectors: + QVector *lineData = new QVector; + QVector *scatterData = 0; + if (!mScatterStyle.isNone()) + scatterData = new QVector; + + // fill vectors with data appropriate to plot style: + getPlotData(lineData, scatterData); + + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + QCPDataMap::const_iterator it; + for (it = mData->constBegin(); it != mData->constEnd(); ++it) + { + if (QCP::isInvalidData(it.value().key, it.value().value) || + QCP::isInvalidData(it.value().keyErrorPlus, it.value().keyErrorMinus) || + QCP::isInvalidData(it.value().valueErrorPlus, it.value().valueErrorPlus)) + qDebug() << Q_FUNC_INFO << "Data point at" << it.key() << "invalid." << "Plottable name:" << name(); + } +#endif + + // draw fill of graph: + if (mLineStyle != lsNone) + drawFill(painter, lineData); + + // draw line: + if (mLineStyle == lsImpulse) + drawImpulsePlot(painter, lineData); + else if (mLineStyle != lsNone) + drawLinePlot(painter, lineData); // also step plots can be drawn as a line plot + + // draw scatters: + if (scatterData) + drawScatterPlot(painter, scatterData); + + // free allocated line and point vectors: + delete lineData; + if (scatterData) + delete scatterData; +} + +/* inherits documentation from base class */ +void QCPGraph::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw fill: + if (mBrush.style() != Qt::NoBrush) + { + applyFillAntialiasingHint(painter); + painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (!mScatterStyle.isNone()) + { + applyScattersAntialiasingHint(painter); + // scale scatter pixmap if it's too large to fit in legend icon rect: + if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) + { + QCPScatterStyle scaledStyle(mScatterStyle); + scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + scaledStyle.applyTo(painter, mPen); + scaledStyle.drawShape(painter, QRectF(rect).center()); + } else + { + mScatterStyle.applyTo(painter, mPen); + mScatterStyle.drawShape(painter, QRectF(rect).center()); + } + } +} + +/*! \internal + + This function branches out to the line style specific "get(...)PlotData" functions, according to + the line style of the graph. + + \a lineData will be filled with raw points that will be drawn with the according draw functions, + e.g. \ref drawLinePlot and \ref drawImpulsePlot. These aren't necessarily the original data + points, since for step plots for example, additional points are needed for drawing lines that + make up steps. If the line style of the graph is \ref lsNone, the \a lineData vector will be left + untouched. + + \a scatterData will be filled with the original data points so \ref drawScatterPlot can draw the + scatter symbols accordingly. If no scatters need to be drawn, i.e. the scatter style's shape is + \ref QCPScatterStyle::ssNone, pass 0 as \a scatterData, and this step will be skipped. + + \see getScatterPlotData, getLinePlotData, getStepLeftPlotData, getStepRightPlotData, + getStepCenterPlotData, getImpulsePlotData +*/ +void QCPGraph::getPlotData(QVector *lineData, QVector *scatterData) const +{ + switch(mLineStyle) + { + case lsNone: getScatterPlotData(scatterData); break; + case lsLine: getLinePlotData(lineData, scatterData); break; + case lsStepLeft: getStepLeftPlotData(lineData, scatterData); break; + case lsStepRight: getStepRightPlotData(lineData, scatterData); break; + case lsStepCenter: getStepCenterPlotData(lineData, scatterData); break; + case lsImpulse: getImpulsePlotData(lineData, scatterData); break; + } +} + +/*! \internal + + If line style is \ref lsNone and the scatter style's shape is not \ref QCPScatterStyle::ssNone, + this function serves at providing the visible data points in \a scatterData, so the \ref + drawScatterPlot function can draw the scatter points accordingly. + + If line style is not \ref lsNone, this function is not called and the data for the scatter points + are (if needed) calculated inside the corresponding other "get(...)PlotData" functions. + + \see drawScatterPlot +*/ +void QCPGraph::getScatterPlotData(QVector *scatterData) const +{ + getPreparedData(0, scatterData); +} + +/*! \internal + + Places the raw data points needed for a normal linearly connected graph in \a linePixelData. + + As for all plot data retrieval functions, \a scatterData just contains all unaltered data (scatter) + points that are visible for drawing scatter points, if necessary. If drawing scatter points is + disabled (i.e. the scatter style's shape is \ref QCPScatterStyle::ssNone), pass 0 as \a + scatterData, and the function will skip filling the vector. + + \see drawLinePlot +*/ +void QCPGraph::getLinePlotData(QVector *linePixelData, QVector *scatterData) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (!linePixelData) { qDebug() << Q_FUNC_INFO << "null pointer passed as linePixelData"; return; } + + QVector lineData; + getPreparedData(&lineData, scatterData); + linePixelData->reserve(lineData.size()+2); // added 2 to reserve memory for lower/upper fill base points that might be needed for fill + linePixelData->resize(lineData.size()); + + // transform lineData points to pixels: + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(lineData.at(i).value)); + (*linePixelData)[i].setY(keyAxis->coordToPixel(lineData.at(i).key)); + } + } else // key axis is horizontal + { + for (int i=0; icoordToPixel(lineData.at(i).key)); + (*linePixelData)[i].setY(valueAxis->coordToPixel(lineData.at(i).value)); + } + } +} + +/*! + \internal + Places the raw data points needed for a step plot with left oriented steps in \a lineData. + + As for all plot data retrieval functions, \a scatterData just contains all unaltered data (scatter) + points that are visible for drawing scatter points, if necessary. If drawing scatter points is + disabled (i.e. the scatter style's shape is \ref QCPScatterStyle::ssNone), pass 0 as \a + scatterData, and the function will skip filling the vector. + + \see drawLinePlot +*/ +void QCPGraph::getStepLeftPlotData(QVector *linePixelData, QVector *scatterData) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (!linePixelData) { qDebug() << Q_FUNC_INFO << "null pointer passed as lineData"; return; } + + QVector lineData; + getPreparedData(&lineData, scatterData); + linePixelData->reserve(lineData.size()*2+2); // added 2 to reserve memory for lower/upper fill base points that might be needed for fill + linePixelData->resize(lineData.size()*2); + + // calculate steps from lineData and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastValue = valueAxis->coordToPixel(lineData.first().value); + double key; + for (int i=0; icoordToPixel(lineData.at(i).key); + (*linePixelData)[i*2+0].setX(lastValue); + (*linePixelData)[i*2+0].setY(key); + lastValue = valueAxis->coordToPixel(lineData.at(i).value); + (*linePixelData)[i*2+1].setX(lastValue); + (*linePixelData)[i*2+1].setY(key); + } + } else // key axis is horizontal + { + double lastValue = valueAxis->coordToPixel(lineData.first().value); + double key; + for (int i=0; icoordToPixel(lineData.at(i).key); + (*linePixelData)[i*2+0].setX(key); + (*linePixelData)[i*2+0].setY(lastValue); + lastValue = valueAxis->coordToPixel(lineData.at(i).value); + (*linePixelData)[i*2+1].setX(key); + (*linePixelData)[i*2+1].setY(lastValue); + } + } +} + +/*! + \internal + Places the raw data points needed for a step plot with right oriented steps in \a lineData. + + As for all plot data retrieval functions, \a scatterData just contains all unaltered data (scatter) + points that are visible for drawing scatter points, if necessary. If drawing scatter points is + disabled (i.e. the scatter style's shape is \ref QCPScatterStyle::ssNone), pass 0 as \a + scatterData, and the function will skip filling the vector. + + \see drawLinePlot +*/ +void QCPGraph::getStepRightPlotData(QVector *linePixelData, QVector *scatterData) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (!linePixelData) { qDebug() << Q_FUNC_INFO << "null pointer passed as lineData"; return; } + + QVector lineData; + getPreparedData(&lineData, scatterData); + linePixelData->reserve(lineData.size()*2+2); // added 2 to reserve memory for lower/upper fill base points that might be needed for fill + linePixelData->resize(lineData.size()*2); + + // calculate steps from lineData and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastKey = keyAxis->coordToPixel(lineData.first().key); + double value; + for (int i=0; icoordToPixel(lineData.at(i).value); + (*linePixelData)[i*2+0].setX(value); + (*linePixelData)[i*2+0].setY(lastKey); + lastKey = keyAxis->coordToPixel(lineData.at(i).key); + (*linePixelData)[i*2+1].setX(value); + (*linePixelData)[i*2+1].setY(lastKey); + } + } else // key axis is horizontal + { + double lastKey = keyAxis->coordToPixel(lineData.first().key); + double value; + for (int i=0; icoordToPixel(lineData.at(i).value); + (*linePixelData)[i*2+0].setX(lastKey); + (*linePixelData)[i*2+0].setY(value); + lastKey = keyAxis->coordToPixel(lineData.at(i).key); + (*linePixelData)[i*2+1].setX(lastKey); + (*linePixelData)[i*2+1].setY(value); + } + } +} + +/*! + \internal + Places the raw data points needed for a step plot with centered steps in \a lineData. + + As for all plot data retrieval functions, \a scatterData just contains all unaltered data (scatter) + points that are visible for drawing scatter points, if necessary. If drawing scatter points is + disabled (i.e. the scatter style's shape is \ref QCPScatterStyle::ssNone), pass 0 as \a + scatterData, and the function will skip filling the vector. + + \see drawLinePlot +*/ +void QCPGraph::getStepCenterPlotData(QVector *linePixelData, QVector *scatterData) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (!linePixelData) { qDebug() << Q_FUNC_INFO << "null pointer passed as lineData"; return; } + + QVector lineData; + getPreparedData(&lineData, scatterData); + linePixelData->reserve(lineData.size()*2+2); // added 2 to reserve memory for lower/upper fill base points that might be needed for fill + linePixelData->resize(lineData.size()*2); + // calculate steps from lineData and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastKey = keyAxis->coordToPixel(lineData.first().key); + double lastValue = valueAxis->coordToPixel(lineData.first().value); + double key; + (*linePixelData)[0].setX(lastValue); + (*linePixelData)[0].setY(lastKey); + for (int i=1; icoordToPixel(lineData.at(i).key)+lastKey)*0.5; + (*linePixelData)[i*2-1].setX(lastValue); + (*linePixelData)[i*2-1].setY(key); + lastValue = valueAxis->coordToPixel(lineData.at(i).value); + lastKey = keyAxis->coordToPixel(lineData.at(i).key); + (*linePixelData)[i*2+0].setX(lastValue); + (*linePixelData)[i*2+0].setY(key); + } + (*linePixelData)[lineData.size()*2-1].setX(lastValue); + (*linePixelData)[lineData.size()*2-1].setY(lastKey); + } else // key axis is horizontal + { + double lastKey = keyAxis->coordToPixel(lineData.first().key); + double lastValue = valueAxis->coordToPixel(lineData.first().value); + double key; + (*linePixelData)[0].setX(lastKey); + (*linePixelData)[0].setY(lastValue); + for (int i=1; icoordToPixel(lineData.at(i).key)+lastKey)*0.5; + (*linePixelData)[i*2-1].setX(key); + (*linePixelData)[i*2-1].setY(lastValue); + lastValue = valueAxis->coordToPixel(lineData.at(i).value); + lastKey = keyAxis->coordToPixel(lineData.at(i).key); + (*linePixelData)[i*2+0].setX(key); + (*linePixelData)[i*2+0].setY(lastValue); + } + (*linePixelData)[lineData.size()*2-1].setX(lastKey); + (*linePixelData)[lineData.size()*2-1].setY(lastValue); + } + +} + +/*! + \internal + Places the raw data points needed for an impulse plot in \a lineData. + + As for all plot data retrieval functions, \a scatterData just contains all unaltered data (scatter) + points that are visible for drawing scatter points, if necessary. If drawing scatter points is + disabled (i.e. the scatter style's shape is \ref QCPScatterStyle::ssNone), pass 0 as \a + scatterData, and the function will skip filling the vector. + + \see drawImpulsePlot +*/ +void QCPGraph::getImpulsePlotData(QVector *linePixelData, QVector *scatterData) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (!linePixelData) { qDebug() << Q_FUNC_INFO << "null pointer passed as linePixelData"; return; } + + QVector lineData; + getPreparedData(&lineData, scatterData); + linePixelData->resize(lineData.size()*2); // no need to reserve 2 extra points because impulse plot has no fill + + // transform lineData points to pixels: + if (keyAxis->orientation() == Qt::Vertical) + { + double zeroPointX = valueAxis->coordToPixel(0); + double key; + for (int i=0; icoordToPixel(lineData.at(i).key); + (*linePixelData)[i*2+0].setX(zeroPointX); + (*linePixelData)[i*2+0].setY(key); + (*linePixelData)[i*2+1].setX(valueAxis->coordToPixel(lineData.at(i).value)); + (*linePixelData)[i*2+1].setY(key); + } + } else // key axis is horizontal + { + double zeroPointY = valueAxis->coordToPixel(0); + double key; + for (int i=0; icoordToPixel(lineData.at(i).key); + (*linePixelData)[i*2+0].setX(key); + (*linePixelData)[i*2+0].setY(zeroPointY); + (*linePixelData)[i*2+1].setX(key); + (*linePixelData)[i*2+1].setY(valueAxis->coordToPixel(lineData.at(i).value)); + } + } +} + +/*! \internal + + Draws the fill of the graph with the specified brush. + + If the fill is a normal fill towards the zero-value-line, only the \a lineData is required (and + two extra points at the zero-value-line, which are added by \ref addFillBasePoints and removed by + \ref removeFillBasePoints after the fill drawing is done). + + If the fill is a channel fill between this QCPGraph and another QCPGraph (mChannelFillGraph), the + more complex polygon is calculated with the \ref getChannelFillPolygon function. + + \see drawLinePlot +*/ +void QCPGraph::drawFill(QCPPainter *painter, QVector *lineData) const +{ + if (mLineStyle == lsImpulse) return; // fill doesn't make sense for impulse plot + if (mainBrush().style() == Qt::NoBrush || mainBrush().color().alpha() == 0) return; + + applyFillAntialiasingHint(painter); + if (!mChannelFillGraph) + { + // draw base fill under graph, fill goes all the way to the zero-value-line: + addFillBasePoints(lineData); + painter->setPen(Qt::NoPen); + painter->setBrush(mainBrush()); + painter->drawPolygon(QPolygonF(*lineData)); + removeFillBasePoints(lineData); + } else + { + // draw channel fill between this graph and mChannelFillGraph: + painter->setPen(Qt::NoPen); + painter->setBrush(mainBrush()); + painter->drawPolygon(getChannelFillPolygon(lineData)); + } +} + +/*! \internal + + Draws scatter symbols at every data point passed in \a scatterData. scatter symbols are independent + of the line style and are always drawn if the scatter style's shape is not \ref + QCPScatterStyle::ssNone. Hence, the \a scatterData vector is outputted by all "get(...)PlotData" + functions, together with the (line style dependent) line data. + + \see drawLinePlot, drawImpulsePlot +*/ +void QCPGraph::drawScatterPlot(QCPPainter *painter, QVector *scatterData) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + // draw error bars: + if (mErrorType != etNone) + { + applyErrorBarsAntialiasingHint(painter); + painter->setPen(mErrorPen); + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; isize(); ++i) + drawError(painter, valueAxis->coordToPixel(scatterData->at(i).value), keyAxis->coordToPixel(scatterData->at(i).key), scatterData->at(i)); + } else + { + for (int i=0; isize(); ++i) + drawError(painter, keyAxis->coordToPixel(scatterData->at(i).key), valueAxis->coordToPixel(scatterData->at(i).value), scatterData->at(i)); + } + } + + // draw scatter point symbols: + applyScattersAntialiasingHint(painter); + mScatterStyle.applyTo(painter, mPen); + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; isize(); ++i) + if (!qIsNaN(scatterData->at(i).value)) + mScatterStyle.drawShape(painter, valueAxis->coordToPixel(scatterData->at(i).value), keyAxis->coordToPixel(scatterData->at(i).key)); + } else + { + for (int i=0; isize(); ++i) + if (!qIsNaN(scatterData->at(i).value)) + mScatterStyle.drawShape(painter, keyAxis->coordToPixel(scatterData->at(i).key), valueAxis->coordToPixel(scatterData->at(i).value)); + } +} + +/*! \internal + + Draws line graphs from the provided data. It connects all points in \a lineData, which was + created by one of the "get(...)PlotData" functions for line styles that require simple line + connections between the point vector they create. These are for example \ref getLinePlotData, + \ref getStepLeftPlotData, \ref getStepRightPlotData and \ref getStepCenterPlotData. + + \see drawScatterPlot, drawImpulsePlot +*/ +void QCPGraph::drawLinePlot(QCPPainter *painter, QVector *lineData) const +{ + // draw line of graph: + if (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mainPen()); + painter->setBrush(Qt::NoBrush); + + /* Draws polyline in batches, currently not used: + int p = 0; + while (p < lineData->size()) + { + int batch = qMin(25, lineData->size()-p); + if (p != 0) + { + ++batch; + --p; // to draw the connection lines between two batches + } + painter->drawPolyline(lineData->constData()+p, batch); + p += batch; + } + */ + + // if drawing solid line and not in PDF, use much faster line drawing instead of polyline: + if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) && + painter->pen().style() == Qt::SolidLine && + !painter->modes().testFlag(QCPPainter::pmVectorized) && + !painter->modes().testFlag(QCPPainter::pmNoCaching)) + { + int i = 0; + bool lastIsNan = false; + const int lineDataSize = lineData->size(); + while (i < lineDataSize && (qIsNaN(lineData->at(i).y()) || qIsNaN(lineData->at(i).x()))) // make sure first point is not NaN + ++i; + ++i; // because drawing works in 1 point retrospect + while (i < lineDataSize) + { + if (!qIsNaN(lineData->at(i).y()) && !qIsNaN(lineData->at(i).x())) // NaNs create a gap in the line + { + if (!lastIsNan) + painter->drawLine(lineData->at(i-1), lineData->at(i)); + else + lastIsNan = false; + } else + lastIsNan = true; + ++i; + } + } else + { + int segmentStart = 0; + int i = 0; + const int lineDataSize = lineData->size(); + while (i < lineDataSize) + { + if (qIsNaN(lineData->at(i).y()) || qIsNaN(lineData->at(i).x()) || qIsInf(lineData->at(i).y())) // NaNs create a gap in the line. Also filter Infs which make drawPolyline block + { + painter->drawPolyline(lineData->constData()+segmentStart, i-segmentStart); // i, because we don't want to include the current NaN point + segmentStart = i+1; + } + ++i; + } + // draw last segment: + painter->drawPolyline(lineData->constData()+segmentStart, lineDataSize-segmentStart); + } + } +} + +/*! \internal + + Draws impulses from the provided data, i.e. it connects all line pairs in \a lineData, which was + created by \ref getImpulsePlotData. + + \see drawScatterPlot, drawLinePlot +*/ +void QCPGraph::drawImpulsePlot(QCPPainter *painter, QVector *lineData) const +{ + // draw impulses: + if (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + QPen pen = mainPen(); + pen.setCapStyle(Qt::FlatCap); // so impulse line doesn't reach beyond zero-line + painter->setPen(pen); + painter->setBrush(Qt::NoBrush); + painter->drawLines(*lineData); + } +} + +/*! \internal + + Returns the \a lineData and \a scatterData that need to be plotted for this graph taking into + consideration the current axis ranges and, if \ref setAdaptiveSampling is enabled, local point + densities. + + 0 may be passed as \a lineData or \a scatterData to indicate that the respective dataset isn't + needed. For example, if the scatter style (\ref setScatterStyle) is \ref QCPScatterStyle::ssNone, \a + scatterData should be 0 to prevent unnecessary calculations. + + This method is used by the various "get(...)PlotData" methods to get the basic working set of data. +*/ +void QCPGraph::getPreparedData(QVector *lineData, QVector *scatterData) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + // get visible data range: + QCPDataMap::const_iterator lower, upper; // note that upper is the actual upper point, and not 1 step after the upper point + getVisibleDataBounds(lower, upper); + if (lower == mData->constEnd() || upper == mData->constEnd()) + return; + + // count points in visible range, taking into account that we only need to count to the limit maxCount if using adaptive sampling: + int maxCount = std::numeric_limits::max(); + if (mAdaptiveSampling) + { + int keyPixelSpan = qAbs(keyAxis->coordToPixel(lower.key())-keyAxis->coordToPixel(upper.key())); + maxCount = 2*keyPixelSpan+2; + } + int dataCount = countDataInBounds(lower, upper, maxCount); + + if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average + { + if (lineData) + { + QCPDataMap::const_iterator it = lower; + QCPDataMap::const_iterator upperEnd = upper+1; + double minValue = it.value().value; + double maxValue = it.value().value; + QCPDataMap::const_iterator currentIntervalFirstPoint = it; + int reversedFactor = keyAxis->rangeReversed() != (keyAxis->orientation()==Qt::Vertical) ? -1 : 1; // is used to calculate keyEpsilon pixel into the correct direction + int reversedRound = keyAxis->rangeReversed() != (keyAxis->orientation()==Qt::Vertical) ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey + double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(lower.key())+reversedRound)); + double lastIntervalEndKey = currentIntervalStartKey; + double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates + bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) + int intervalDataCount = 1; + ++it; // advance iterator to second data point because adaptive sampling works in 1 point retrospect + while (it != upperEnd) + { + if (it.key() < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this cluster if necessary + { + if (it.value().value < minValue) + minValue = it.value().value; + else if (it.value().value > maxValue) + maxValue = it.value().value; + ++intervalDataCount; + } else // new pixel interval started + { + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster + { + if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point is further away, so first point of this cluster must be at a real data point + lineData->append(QCPData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint.value().value)); + lineData->append(QCPData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); + lineData->append(QCPData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); + if (it.key() > currentIntervalStartKey+keyEpsilon*2) // new pixel started further away from previous cluster, so make sure the last point of the cluster is at a real data point + lineData->append(QCPData(currentIntervalStartKey+keyEpsilon*0.8, (it-1).value().value)); + } else + lineData->append(QCPData(currentIntervalFirstPoint.key(), currentIntervalFirstPoint.value().value)); + lastIntervalEndKey = (it-1).value().key; + minValue = it.value().value; + maxValue = it.value().value; + currentIntervalFirstPoint = it; + currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it.key())+reversedRound)); + if (keyEpsilonVariable) + keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); + intervalDataCount = 1; + } + ++it; + } + // handle last interval: + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster + { + if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point wasn't a cluster, so first point of this cluster must be at a real data point + lineData->append(QCPData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint.value().value)); + lineData->append(QCPData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); + lineData->append(QCPData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); + } else + lineData->append(QCPData(currentIntervalFirstPoint.key(), currentIntervalFirstPoint.value().value)); + } + + if (scatterData) + { + double valueMaxRange = valueAxis->range().upper; + double valueMinRange = valueAxis->range().lower; + QCPDataMap::const_iterator it = lower; + QCPDataMap::const_iterator upperEnd = upper+1; + double minValue = it.value().value; + double maxValue = it.value().value; + QCPDataMap::const_iterator minValueIt = it; + QCPDataMap::const_iterator maxValueIt = it; + QCPDataMap::const_iterator currentIntervalStart = it; + int reversedFactor = keyAxis->rangeReversed() ? -1 : 1; // is used to calculate keyEpsilon pixel into the correct direction + int reversedRound = keyAxis->rangeReversed() ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey + double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(lower.key())+reversedRound)); + double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates + bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) + int intervalDataCount = 1; + ++it; // advance iterator to second data point because adaptive sampling works in 1 point retrospect + while (it != upperEnd) + { + if (it.key() < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this pixel if necessary + { + if (it.value().value < minValue && it.value().value > valueMinRange && it.value().value < valueMaxRange) + { + minValue = it.value().value; + minValueIt = it; + } else if (it.value().value > maxValue && it.value().value > valueMinRange && it.value().value < valueMaxRange) + { + maxValue = it.value().value; + maxValueIt = it; + } + ++intervalDataCount; + } else // new pixel started + { + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them + { + // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): + double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); + int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average + QCPDataMap::const_iterator intervalIt = currentIntervalStart; + int c = 0; + while (intervalIt != it) + { + if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt.value().value > valueMinRange && intervalIt.value().value < valueMaxRange) + scatterData->append(intervalIt.value()); + ++c; + ++intervalIt; + } + } else if (currentIntervalStart.value().value > valueMinRange && currentIntervalStart.value().value < valueMaxRange) + scatterData->append(currentIntervalStart.value()); + minValue = it.value().value; + maxValue = it.value().value; + currentIntervalStart = it; + currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it.key())+reversedRound)); + if (keyEpsilonVariable) + keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); + intervalDataCount = 1; + } + ++it; + } + // handle last interval: + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them + { + // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): + double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); + int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average + QCPDataMap::const_iterator intervalIt = currentIntervalStart; + int c = 0; + while (intervalIt != it) + { + if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt.value().value > valueMinRange && intervalIt.value().value < valueMaxRange) + scatterData->append(intervalIt.value()); + ++c; + ++intervalIt; + } + } else if (currentIntervalStart.value().value > valueMinRange && currentIntervalStart.value().value < valueMaxRange) + scatterData->append(currentIntervalStart.value()); + } + } else // don't use adaptive sampling algorithm, transfer points one-to-one from the map into the output parameters + { + QVector *dataVector = 0; + if (lineData) + dataVector = lineData; + else if (scatterData) + dataVector = scatterData; + if (dataVector) + { + QCPDataMap::const_iterator it = lower; + QCPDataMap::const_iterator upperEnd = upper+1; + dataVector->reserve(dataCount+2); // +2 for possible fill end points + while (it != upperEnd) + { + dataVector->append(it.value()); + ++it; + } + } + if (lineData && scatterData) + *scatterData = *dataVector; + } +} + +/*! \internal + + called by the scatter drawing function (\ref drawScatterPlot) to draw the error bars on one data + point. \a x and \a y pixel positions of the data point are passed since they are already known in + pixel coordinates in the drawing function, so we save some extra coordToPixel transforms here. \a + data is therefore only used for the errors, not key and value. +*/ +void QCPGraph::drawError(QCPPainter *painter, double x, double y, const QCPData &data) const +{ + if (qIsNaN(data.value)) + return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + double a, b; // positions of error bar bounds in pixels + double barWidthHalf = mErrorBarSize*0.5; + double skipSymbolMargin = mScatterStyle.size(); // pixels left blank per side, when mErrorBarSkipSymbol is true + + if (keyAxis->orientation() == Qt::Vertical) + { + // draw key error vertically and value error horizontally + if (mErrorType == etKey || mErrorType == etBoth) + { + a = keyAxis->coordToPixel(data.key-data.keyErrorMinus); + b = keyAxis->coordToPixel(data.key+data.keyErrorPlus); + if (keyAxis->rangeReversed()) + qSwap(a,b); + // draw spine: + if (mErrorBarSkipSymbol) + { + if (a-y > skipSymbolMargin) // don't draw spine if error is so small it's within skipSymbolmargin + painter->drawLine(QLineF(x, a, x, y+skipSymbolMargin)); + if (y-b > skipSymbolMargin) + painter->drawLine(QLineF(x, y-skipSymbolMargin, x, b)); + } else + painter->drawLine(QLineF(x, a, x, b)); + // draw handles: + painter->drawLine(QLineF(x-barWidthHalf, a, x+barWidthHalf, a)); + painter->drawLine(QLineF(x-barWidthHalf, b, x+barWidthHalf, b)); + } + if (mErrorType == etValue || mErrorType == etBoth) + { + a = valueAxis->coordToPixel(data.value-data.valueErrorMinus); + b = valueAxis->coordToPixel(data.value+data.valueErrorPlus); + if (valueAxis->rangeReversed()) + qSwap(a,b); + // draw spine: + if (mErrorBarSkipSymbol) + { + if (x-a > skipSymbolMargin) // don't draw spine if error is so small it's within skipSymbolmargin + painter->drawLine(QLineF(a, y, x-skipSymbolMargin, y)); + if (b-x > skipSymbolMargin) + painter->drawLine(QLineF(x+skipSymbolMargin, y, b, y)); + } else + painter->drawLine(QLineF(a, y, b, y)); + // draw handles: + painter->drawLine(QLineF(a, y-barWidthHalf, a, y+barWidthHalf)); + painter->drawLine(QLineF(b, y-barWidthHalf, b, y+barWidthHalf)); + } + } else // mKeyAxis->orientation() is Qt::Horizontal + { + // draw value error vertically and key error horizontally + if (mErrorType == etKey || mErrorType == etBoth) + { + a = keyAxis->coordToPixel(data.key-data.keyErrorMinus); + b = keyAxis->coordToPixel(data.key+data.keyErrorPlus); + if (keyAxis->rangeReversed()) + qSwap(a,b); + // draw spine: + if (mErrorBarSkipSymbol) + { + if (x-a > skipSymbolMargin) // don't draw spine if error is so small it's within skipSymbolmargin + painter->drawLine(QLineF(a, y, x-skipSymbolMargin, y)); + if (b-x > skipSymbolMargin) + painter->drawLine(QLineF(x+skipSymbolMargin, y, b, y)); + } else + painter->drawLine(QLineF(a, y, b, y)); + // draw handles: + painter->drawLine(QLineF(a, y-barWidthHalf, a, y+barWidthHalf)); + painter->drawLine(QLineF(b, y-barWidthHalf, b, y+barWidthHalf)); + } + if (mErrorType == etValue || mErrorType == etBoth) + { + a = valueAxis->coordToPixel(data.value-data.valueErrorMinus); + b = valueAxis->coordToPixel(data.value+data.valueErrorPlus); + if (valueAxis->rangeReversed()) + qSwap(a,b); + // draw spine: + if (mErrorBarSkipSymbol) + { + if (a-y > skipSymbolMargin) // don't draw spine if error is so small it's within skipSymbolmargin + painter->drawLine(QLineF(x, a, x, y+skipSymbolMargin)); + if (y-b > skipSymbolMargin) + painter->drawLine(QLineF(x, y-skipSymbolMargin, x, b)); + } else + painter->drawLine(QLineF(x, a, x, b)); + // draw handles: + painter->drawLine(QLineF(x-barWidthHalf, a, x+barWidthHalf, a)); + painter->drawLine(QLineF(x-barWidthHalf, b, x+barWidthHalf, b)); + } + } +} + +/*! \internal + + called by \ref getPreparedData to determine which data (key) range is visible at the current key + axis range setting, so only that needs to be processed. + + \a lower returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + lower may still be just outside the visible range. + + \a upper returns an iterator to the highest data point. Same as before, \a upper may also lie + just outside of the visible range. + + if the graph contains no data, both \a lower and \a upper point to constEnd. +*/ +void QCPGraph::getVisibleDataBounds(QCPDataMap::const_iterator &lower, QCPDataMap::const_iterator &upper) const +{ + if (!mKeyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } + if (mData->isEmpty()) + { + lower = mData->constEnd(); + upper = mData->constEnd(); + return; + } + + // get visible data range as QMap iterators + QCPDataMap::const_iterator lbound = mData->lowerBound(mKeyAxis.data()->range().lower); + QCPDataMap::const_iterator ubound = mData->upperBound(mKeyAxis.data()->range().upper); + bool lowoutlier = lbound != mData->constBegin(); // indicates whether there exist points below axis range + bool highoutlier = ubound != mData->constEnd(); // indicates whether there exist points above axis range + + lower = (lowoutlier ? lbound-1 : lbound); // data point range that will be actually drawn + upper = (highoutlier ? ubound : ubound-1); // data point range that will be actually drawn +} + +/*! \internal + + Counts the number of data points between \a lower and \a upper (including them), up to a maximum + of \a maxCount. + + This function is used by \ref getPreparedData to determine whether adaptive sampling shall be + used (if enabled via \ref setAdaptiveSampling) or not. This is also why counting of data points + only needs to be done until \a maxCount is reached, which should be set to the number of data + points at which adaptive sampling sets in. +*/ +int QCPGraph::countDataInBounds(const QCPDataMap::const_iterator &lower, const QCPDataMap::const_iterator &upper, int maxCount) const +{ + if (upper == mData->constEnd() && lower == mData->constEnd()) + return 0; + QCPDataMap::const_iterator it = lower; + int count = 1; + while (it != upper && count < maxCount) + { + ++it; + ++count; + } + return count; +} + +/*! \internal + + The line data vector generated by e.g. getLinePlotData contains only the line that connects the + data points. If the graph needs to be filled, two additional points need to be added at the + value-zero-line in the lower and upper key positions of the graph. This function calculates these + points and adds them to the end of \a lineData. Since the fill is typically drawn before the line + stroke, these added points need to be removed again after the fill is done, with the + removeFillBasePoints function. + + The expanding of \a lineData by two points will not cause unnecessary memory reallocations, + because the data vector generation functions (getLinePlotData etc.) reserve two extra points when + they allocate memory for \a lineData. + + \see removeFillBasePoints, lowerFillBasePoint, upperFillBasePoint +*/ +void QCPGraph::addFillBasePoints(QVector *lineData) const +{ + if (!mKeyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } + if (!lineData) { qDebug() << Q_FUNC_INFO << "passed null as lineData"; return; } + if (lineData->isEmpty()) return; + + // append points that close the polygon fill at the key axis: + if (mKeyAxis.data()->orientation() == Qt::Vertical) + { + *lineData << upperFillBasePoint(lineData->last().y()); + *lineData << lowerFillBasePoint(lineData->first().y()); + } else + { + *lineData << upperFillBasePoint(lineData->last().x()); + *lineData << lowerFillBasePoint(lineData->first().x()); + } +} + +/*! \internal + + removes the two points from \a lineData that were added by \ref addFillBasePoints. + + \see addFillBasePoints, lowerFillBasePoint, upperFillBasePoint +*/ +void QCPGraph::removeFillBasePoints(QVector *lineData) const +{ + if (!lineData) { qDebug() << Q_FUNC_INFO << "passed null as lineData"; return; } + if (lineData->isEmpty()) return; + + lineData->remove(lineData->size()-2, 2); +} + +/*! \internal + + called by \ref addFillBasePoints to conveniently assign the point which closes the fill polygon + on the lower side of the zero-value-line parallel to the key axis. The logarithmic axis scale + case is a bit special, since the zero-value-line in pixel coordinates is in positive or negative + infinity. So this case is handled separately by just closing the fill polygon on the axis which + lies in the direction towards the zero value. + + \a lowerKey will be the the key (in pixels) of the returned point. Depending on whether the key + axis is horizontal or vertical, \a lowerKey will end up as the x or y value of the returned + point, respectively. + + \see upperFillBasePoint, addFillBasePoints +*/ +QPointF QCPGraph::lowerFillBasePoint(double lowerKey) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + QPointF point; + if (valueAxis->scaleType() == QCPAxis::stLinear) + { + if (keyAxis->axisType() == QCPAxis::atLeft) + { + point.setX(valueAxis->coordToPixel(0)); + point.setY(lowerKey); + } else if (keyAxis->axisType() == QCPAxis::atRight) + { + point.setX(valueAxis->coordToPixel(0)); + point.setY(lowerKey); + } else if (keyAxis->axisType() == QCPAxis::atTop) + { + point.setX(lowerKey); + point.setY(valueAxis->coordToPixel(0)); + } else if (keyAxis->axisType() == QCPAxis::atBottom) + { + point.setX(lowerKey); + point.setY(valueAxis->coordToPixel(0)); + } + } else // valueAxis->mScaleType == QCPAxis::stLogarithmic + { + // In logarithmic scaling we can't just draw to value zero so we just fill all the way + // to the axis which is in the direction towards zero + if (keyAxis->orientation() == Qt::Vertical) + { + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + point.setX(keyAxis->axisRect()->right()); + else + point.setX(keyAxis->axisRect()->left()); + point.setY(lowerKey); + } else if (keyAxis->axisType() == QCPAxis::atTop || keyAxis->axisType() == QCPAxis::atBottom) + { + point.setX(lowerKey); + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + point.setY(keyAxis->axisRect()->top()); + else + point.setY(keyAxis->axisRect()->bottom()); + } + } + return point; +} + +/*! \internal + + called by \ref addFillBasePoints to conveniently assign the point which closes the fill + polygon on the upper side of the zero-value-line parallel to the key axis. The logarithmic axis + scale case is a bit special, since the zero-value-line in pixel coordinates is in positive or + negative infinity. So this case is handled separately by just closing the fill polygon on the + axis which lies in the direction towards the zero value. + + \a upperKey will be the the key (in pixels) of the returned point. Depending on whether the key + axis is horizontal or vertical, \a upperKey will end up as the x or y value of the returned + point, respectively. + + \see lowerFillBasePoint, addFillBasePoints +*/ +QPointF QCPGraph::upperFillBasePoint(double upperKey) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + QPointF point; + if (valueAxis->scaleType() == QCPAxis::stLinear) + { + if (keyAxis->axisType() == QCPAxis::atLeft) + { + point.setX(valueAxis->coordToPixel(0)); + point.setY(upperKey); + } else if (keyAxis->axisType() == QCPAxis::atRight) + { + point.setX(valueAxis->coordToPixel(0)); + point.setY(upperKey); + } else if (keyAxis->axisType() == QCPAxis::atTop) + { + point.setX(upperKey); + point.setY(valueAxis->coordToPixel(0)); + } else if (keyAxis->axisType() == QCPAxis::atBottom) + { + point.setX(upperKey); + point.setY(valueAxis->coordToPixel(0)); + } + } else // valueAxis->mScaleType == QCPAxis::stLogarithmic + { + // In logarithmic scaling we can't just draw to value 0 so we just fill all the way + // to the axis which is in the direction towards 0 + if (keyAxis->orientation() == Qt::Vertical) + { + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + point.setX(keyAxis->axisRect()->right()); + else + point.setX(keyAxis->axisRect()->left()); + point.setY(upperKey); + } else if (keyAxis->axisType() == QCPAxis::atTop || keyAxis->axisType() == QCPAxis::atBottom) + { + point.setX(upperKey); + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + point.setY(keyAxis->axisRect()->top()); + else + point.setY(keyAxis->axisRect()->bottom()); + } + } + return point; +} + +/*! \internal + + Generates the polygon needed for drawing channel fills between this graph (data passed via \a + lineData) and the graph specified by mChannelFillGraph (data generated by calling its \ref + getPlotData function). May return an empty polygon if the key ranges have no overlap or fill + target graph and this graph don't have same orientation (i.e. both key axes horizontal or both + key axes vertical). For increased performance (due to implicit sharing), keep the returned + QPolygonF const. +*/ +const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *lineData) const +{ + if (!mChannelFillGraph) + return QPolygonF(); + + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPolygonF(); } + if (!mChannelFillGraph.data()->mKeyAxis) { qDebug() << Q_FUNC_INFO << "channel fill target key axis invalid"; return QPolygonF(); } + + if (mChannelFillGraph.data()->mKeyAxis.data()->orientation() != keyAxis->orientation()) + return QPolygonF(); // don't have same axis orientation, can't fill that (Note: if keyAxis fits, valueAxis will fit too, because it's always orthogonal to keyAxis) + + if (lineData->isEmpty()) return QPolygonF(); + QVector otherData; + mChannelFillGraph.data()->getPlotData(&otherData, 0); + if (otherData.isEmpty()) return QPolygonF(); + QVector thisData; + thisData.reserve(lineData->size()+otherData.size()); // because we will join both vectors at end of this function + for (int i=0; isize(); ++i) // don't use the vector<<(vector), it squeezes internally, which ruins the performance tuning with reserve() + thisData << lineData->at(i); + + // pointers to be able to swap them, depending which data range needs cropping: + QVector *staticData = &thisData; + QVector *croppedData = &otherData; + + // crop both vectors to ranges in which the keys overlap (which coord is key, depends on axisType): + if (keyAxis->orientation() == Qt::Horizontal) + { + // x is key + // if an axis range is reversed, the data point keys will be descending. Reverse them, since following algorithm assumes ascending keys: + if (staticData->first().x() > staticData->last().x()) + { + int size = staticData->size(); + for (int i=0; ifirst().x() > croppedData->last().x()) + { + int size = croppedData->size(); + for (int i=0; ifirst().x() < croppedData->first().x()) // other one must be cropped + qSwap(staticData, croppedData); + int lowBound = findIndexBelowX(croppedData, staticData->first().x()); + if (lowBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(0, lowBound); + // set lowest point of cropped data to fit exactly key position of first static data + // point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + double slope; + if (croppedData->at(1).x()-croppedData->at(0).x() != 0) + slope = (croppedData->at(1).y()-croppedData->at(0).y())/(croppedData->at(1).x()-croppedData->at(0).x()); + else + slope = 0; + (*croppedData)[0].setY(croppedData->at(0).y()+slope*(staticData->first().x()-croppedData->at(0).x())); + (*croppedData)[0].setX(staticData->first().x()); + + // crop upper bound: + if (staticData->last().x() > croppedData->last().x()) // other one must be cropped + qSwap(staticData, croppedData); + int highBound = findIndexAboveX(croppedData, staticData->last().x()); + if (highBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); + // set highest point of cropped data to fit exactly key position of last static data + // point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + int li = croppedData->size()-1; // last index + if (croppedData->at(li).x()-croppedData->at(li-1).x() != 0) + slope = (croppedData->at(li).y()-croppedData->at(li-1).y())/(croppedData->at(li).x()-croppedData->at(li-1).x()); + else + slope = 0; + (*croppedData)[li].setY(croppedData->at(li-1).y()+slope*(staticData->last().x()-croppedData->at(li-1).x())); + (*croppedData)[li].setX(staticData->last().x()); + } else // mKeyAxis->orientation() == Qt::Vertical + { + // y is key + // similar to "x is key" but switched x,y. Further, lower/upper meaning is inverted compared to x, + // because in pixel coordinates, y increases from top to bottom, not bottom to top like data coordinate. + // if an axis range is reversed, the data point keys will be descending. Reverse them, since following algorithm assumes ascending keys: + if (staticData->first().y() < staticData->last().y()) + { + int size = staticData->size(); + for (int i=0; ifirst().y() < croppedData->last().y()) + { + int size = croppedData->size(); + for (int i=0; ifirst().y() > croppedData->first().y()) // other one must be cropped + qSwap(staticData, croppedData); + int lowBound = findIndexAboveY(croppedData, staticData->first().y()); + if (lowBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(0, lowBound); + // set lowest point of cropped data to fit exactly key position of first static data + // point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + double slope; + if (croppedData->at(1).y()-croppedData->at(0).y() != 0) // avoid division by zero in step plots + slope = (croppedData->at(1).x()-croppedData->at(0).x())/(croppedData->at(1).y()-croppedData->at(0).y()); + else + slope = 0; + (*croppedData)[0].setX(croppedData->at(0).x()+slope*(staticData->first().y()-croppedData->at(0).y())); + (*croppedData)[0].setY(staticData->first().y()); + + // crop upper bound: + if (staticData->last().y() < croppedData->last().y()) // other one must be cropped + qSwap(staticData, croppedData); + int highBound = findIndexBelowY(croppedData, staticData->last().y()); + if (highBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); + // set highest point of cropped data to fit exactly key position of last static data + // point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + int li = croppedData->size()-1; // last index + if (croppedData->at(li).y()-croppedData->at(li-1).y() != 0) // avoid division by zero in step plots + slope = (croppedData->at(li).x()-croppedData->at(li-1).x())/(croppedData->at(li).y()-croppedData->at(li-1).y()); + else + slope = 0; + (*croppedData)[li].setX(croppedData->at(li-1).x()+slope*(staticData->last().y()-croppedData->at(li-1).y())); + (*croppedData)[li].setY(staticData->last().y()); + } + + // return joined: + for (int i=otherData.size()-1; i>=0; --i) // insert reversed, otherwise the polygon will be twisted + thisData << otherData.at(i); + return QPolygonF(thisData); +} + +/*! \internal + + Finds the smallest index of \a data, whose points x value is just above \a x. Assumes x values in + \a data points are ordered ascending, as is the case when plotting with horizontal key axis. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexAboveX(const QVector *data, double x) const +{ + for (int i=data->size()-1; i>=0; --i) + { + if (data->at(i).x() < x) + { + if (isize()-1) + return i+1; + else + return data->size()-1; + } + } + return -1; +} + +/*! \internal + + Finds the highest index of \a data, whose points x value is just below \a x. Assumes x values in + \a data points are ordered ascending, as is the case when plotting with horizontal key axis. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexBelowX(const QVector *data, double x) const +{ + for (int i=0; isize(); ++i) + { + if (data->at(i).x() > x) + { + if (i>0) + return i-1; + else + return 0; + } + } + return -1; +} + +/*! \internal + + Finds the smallest index of \a data, whose points y value is just above \a y. Assumes y values in + \a data points are ordered descending, as is the case when plotting with vertical key axis. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexAboveY(const QVector *data, double y) const +{ + for (int i=0; isize(); ++i) + { + if (data->at(i).y() < y) + { + if (i>0) + return i-1; + else + return 0; + } + } + return -1; +} + +/*! \internal + + Calculates the (minimum) distance (in pixels) the graph's representation has from the given \a + pixelPoint in pixels. This is used to determine whether the graph was clicked or not, e.g. in + \ref selectTest. + + If either the graph has no data or if the line style is \ref lsNone and the scatter style's shape + is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the graph), returns -1.0. +*/ +double QCPGraph::pointDistance(const QPointF &pixelPoint) const +{ + if (mData->isEmpty()) + return -1.0; + if (mLineStyle == lsNone && mScatterStyle.isNone()) + return -1.0; + + // calculate minimum distances to graph representation: + if (mLineStyle == lsNone) + { + // no line displayed, only calculate distance to scatter points: + QVector scatterData; + getScatterPlotData(&scatterData); + if (scatterData.size() > 0) + { + double minDistSqr = std::numeric_limits::max(); + for (int i=0; i lineData; + getPlotData(&lineData, 0); // unlike with getScatterPlotData we get pixel coordinates here + if (lineData.size() > 1) // at least one line segment, compare distance to line segments + { + double minDistSqr = std::numeric_limits::max(); + if (mLineStyle == lsImpulse) + { + // impulse plot differs from other line styles in that the lineData points are only pairwise connected: + for (int i=0; i 0) // only single data point, calculate distance to that point + { + return QVector2D(lineData.at(0)-pixelPoint).length(); + } else // no data available in view to calculate distance to + return -1.0; + } +} + +/*! \internal + + Finds the highest index of \a data, whose points y value is just below \a y. Assumes y values in + \a data points are ordered descending, as is the case when plotting with vertical key axis (since + keys are ordered ascending). + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexBelowY(const QVector *data, double y) const +{ + for (int i=data->size()-1; i>=0; --i) + { + if (data->at(i).y() > y) + { + if (isize()-1) + return i+1; + else + return data->size()-1; + } + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPGraph::getKeyRange(bool &foundRange, SignDomain inSignDomain) const +{ + // just call the specialized version which takes an additional argument whether error bars + // should also be taken into consideration for range calculation. We set this to true here. + return getKeyRange(foundRange, inSignDomain, true); +} + +/* inherits documentation from base class */ +QCPRange QCPGraph::getValueRange(bool &foundRange, SignDomain inSignDomain) const +{ + // just call the specialized version which takes an additional argument whether error bars + // should also be taken into consideration for range calculation. We set this to true here. + return getValueRange(foundRange, inSignDomain, true); +} + +/*! \overload + + Allows to specify whether the error bars should be included in the range calculation. + + \see getKeyRange(bool &foundRange, SignDomain inSignDomain) +*/ +QCPRange QCPGraph::getKeyRange(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const +{ + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + + double current, currentErrorMinus, currentErrorPlus; + + if (inSignDomain == sdBoth) // range may be anywhere + { + QCPDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + if (!qIsNaN(it.value().value)) + { + current = it.value().key; + currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0); + currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0); + if (current-currentErrorMinus < range.lower || !haveLower) + { + range.lower = current-currentErrorMinus; + haveLower = true; + } + if (current+currentErrorPlus > range.upper || !haveUpper) + { + range.upper = current+currentErrorPlus; + haveUpper = true; + } + } + ++it; + } + } else if (inSignDomain == sdNegative) // range may only be in the negative sign domain + { + QCPDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + if (!qIsNaN(it.value().value)) + { + current = it.value().key; + currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0); + currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0); + if ((current-currentErrorMinus < range.lower || !haveLower) && current-currentErrorMinus < 0) + { + range.lower = current-currentErrorMinus; + haveLower = true; + } + if ((current+currentErrorPlus > range.upper || !haveUpper) && current+currentErrorPlus < 0) + { + range.upper = current+currentErrorPlus; + haveUpper = true; + } + if (includeErrors) // in case point is in valid sign domain but errobars stretch beyond it, we still want to geht that point. + { + if ((current < range.lower || !haveLower) && current < 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current < 0) + { + range.upper = current; + haveUpper = true; + } + } + } + ++it; + } + } else if (inSignDomain == sdPositive) // range may only be in the positive sign domain + { + QCPDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + if (!qIsNaN(it.value().value)) + { + current = it.value().key; + currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0); + currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0); + if ((current-currentErrorMinus < range.lower || !haveLower) && current-currentErrorMinus > 0) + { + range.lower = current-currentErrorMinus; + haveLower = true; + } + if ((current+currentErrorPlus > range.upper || !haveUpper) && current+currentErrorPlus > 0) + { + range.upper = current+currentErrorPlus; + haveUpper = true; + } + if (includeErrors) // in case point is in valid sign domain but errobars stretch beyond it, we still want to get that point. + { + if ((current < range.lower || !haveLower) && current > 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current > 0) + { + range.upper = current; + haveUpper = true; + } + } + } + ++it; + } + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! \overload + + Allows to specify whether the error bars should be included in the range calculation. + + \see getValueRange(bool &foundRange, SignDomain inSignDomain) +*/ +QCPRange QCPGraph::getValueRange(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const +{ + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + + double current, currentErrorMinus, currentErrorPlus; + + if (inSignDomain == sdBoth) // range may be anywhere + { + QCPDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().value; + if (!qIsNaN(current)) + { + currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0); + currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0); + if (current-currentErrorMinus < range.lower || !haveLower) + { + range.lower = current-currentErrorMinus; + haveLower = true; + } + if (current+currentErrorPlus > range.upper || !haveUpper) + { + range.upper = current+currentErrorPlus; + haveUpper = true; + } + } + ++it; + } + } else if (inSignDomain == sdNegative) // range may only be in the negative sign domain + { + QCPDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().value; + if (!qIsNaN(current)) + { + currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0); + currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0); + if ((current-currentErrorMinus < range.lower || !haveLower) && current-currentErrorMinus < 0) + { + range.lower = current-currentErrorMinus; + haveLower = true; + } + if ((current+currentErrorPlus > range.upper || !haveUpper) && current+currentErrorPlus < 0) + { + range.upper = current+currentErrorPlus; + haveUpper = true; + } + if (includeErrors) // in case point is in valid sign domain but errobars stretch beyond it, we still want to get that point. + { + if ((current < range.lower || !haveLower) && current < 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current < 0) + { + range.upper = current; + haveUpper = true; + } + } + } + ++it; + } + } else if (inSignDomain == sdPositive) // range may only be in the positive sign domain + { + QCPDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().value; + if (!qIsNaN(current)) + { + currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0); + currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0); + if ((current-currentErrorMinus < range.lower || !haveLower) && current-currentErrorMinus > 0) + { + range.lower = current-currentErrorMinus; + haveLower = true; + } + if ((current+currentErrorPlus > range.upper || !haveUpper) && current+currentErrorPlus > 0) + { + range.upper = current+currentErrorPlus; + haveUpper = true; + } + if (includeErrors) // in case point is in valid sign domain but errobars stretch beyond it, we still want to geht that point. + { + if ((current < range.lower || !haveLower) && current > 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current > 0) + { + range.upper = current; + haveUpper = true; + } + } + } + ++it; + } + } + + foundRange = haveLower && haveUpper; + return range; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPCurveData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPCurveData + \brief Holds the data of one single data point for QCPCurve. + + The container for storing multiple data points is \ref QCPCurveDataMap. + + The stored data is: + \li \a t: the free parameter of the curve at this curve point (cp. the mathematical vector (x(t), y(t))) + \li \a key: coordinate on the key axis of this curve point + \li \a value: coordinate on the value axis of this curve point + + \see QCPCurveDataMap +*/ + +/*! + Constructs a curve data point with t, key and value set to zero. +*/ +QCPCurveData::QCPCurveData() : + t(0), + key(0), + value(0) +{ +} + +/*! + Constructs a curve data point with the specified \a t, \a key and \a value. +*/ +QCPCurveData::QCPCurveData(double t, double key, double value) : + t(t), + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPCurve +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPCurve + \brief A plottable representing a parametric curve in a plot. + + \image html QCPCurve.png + + Unlike QCPGraph, plottables of this type may have multiple points with the same key coordinate, + so their visual representation can have \a loops. This is realized by introducing a third + coordinate \a t, which defines the order of the points described by the other two coordinates \a + x and \a y. + + To plot data, assign it with the \ref setData or \ref addData functions. + + Gaps in the curve can be created by adding data points with NaN as key and value + (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be + separated. + + \section appearance Changing the appearance + + The appearance of the curve is determined by the pen and the brush (\ref setPen, \ref setBrush). + \section usage Usage + + Like all data representing objects in QCustomPlot, the QCPCurve is a plottable (QCPAbstractPlottable). So + the plottable-interface of QCustomPlot applies (QCustomPlot::plottable, QCustomPlot::addPlottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance and add it to the customPlot: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-1 + and then modify the properties of the newly created plottable, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-2 +*/ + +/*! + Constructs a curve which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The constructed QCPCurve can be added to the plot with QCustomPlot::addPlottable, QCustomPlot + then takes ownership of the graph. +*/ +QCPCurve::QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis) +{ + mData = new QCPCurveDataMap; + mPen.setColor(Qt::blue); + mPen.setStyle(Qt::SolidLine); + mBrush.setColor(Qt::blue); + mBrush.setStyle(Qt::NoBrush); + mSelectedPen = mPen; + mSelectedPen.setWidthF(2.5); + mSelectedPen.setColor(QColor(80, 80, 255)); // lighter than Qt::blue of mPen + mSelectedBrush = mBrush; + + setScatterStyle(QCPScatterStyle()); + setLineStyle(lsLine); +} + +QCPCurve::~QCPCurve() +{ + delete mData; +} + +/*! + Replaces the current data with the provided \a data. + + If \a copy is set to true, data points in \a data will only be copied. if false, the plottable + takes ownership of the passed data and replaces the internal data pointer with it. This is + significantly faster than copying for large datasets. +*/ +void QCPCurve::setData(QCPCurveDataMap *data, bool copy) +{ + if (mData == data) + { + qDebug() << Q_FUNC_INFO << "The data pointer is already in (and owned by) this plottable" << reinterpret_cast(data); + return; + } + if (copy) + { + *mData = *data; + } else + { + delete mData; + mData = data; + } +} + +/*! \overload + + Replaces the current data with the provided points in \a t, \a key and \a value tuples. The + provided vectors should have equal length. Else, the number of added points will be the size of + the smallest vector. +*/ +void QCPCurve::setData(const QVector &t, const QVector &key, const QVector &value) +{ + mData->clear(); + int n = t.size(); + n = qMin(n, key.size()); + n = qMin(n, value.size()); + QCPCurveData newData; + for (int i=0; iinsertMulti(newData.t, newData); + } +} + +/*! \overload + + Replaces the current data with the provided \a key and \a value pairs. The t parameter + of each data point will be set to the integer index of the respective key/value pair. +*/ +void QCPCurve::setData(const QVector &key, const QVector &value) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + QCPCurveData newData; + for (int i=0; iinsertMulti(newData.t, newData); + } +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref + QCPScatterStyle::ssNone, no scatter points are drawn (e.g. for line-only plots with appropriate + line style). + + \see QCPScatterStyle, setLineStyle +*/ +void QCPCurve::setScatterStyle(const QCPScatterStyle &style) +{ + mScatterStyle = style; +} + +/*! + Sets how the single data points are connected in the plot or how they are represented visually + apart from the scatter symbol. For scatter-only plots, set \a style to \ref lsNone and \ref + setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPCurve::setLineStyle(QCPCurve::LineStyle style) +{ + mLineStyle = style; +} + +/*! + Adds the provided data points in \a dataMap to the current data. + \see removeData +*/ +void QCPCurve::addData(const QCPCurveDataMap &dataMap) +{ + mData->unite(dataMap); +} + +/*! \overload + Adds the provided single data point in \a data to the current data. + \see removeData +*/ +void QCPCurve::addData(const QCPCurveData &data) +{ + mData->insertMulti(data.t, data); +} + +/*! \overload + Adds the provided single data point as \a t, \a key and \a value tuple to the current data + \see removeData +*/ +void QCPCurve::addData(double t, double key, double value) +{ + QCPCurveData newData; + newData.t = t; + newData.key = key; + newData.value = value; + mData->insertMulti(newData.t, newData); +} + +/*! \overload + + Adds the provided single data point as \a key and \a value pair to the current data The t + parameter of the data point is set to the t of the last data point plus 1. If there is no last + data point, t will be set to 0. + + \see removeData +*/ +void QCPCurve::addData(double key, double value) +{ + QCPCurveData newData; + if (!mData->isEmpty()) + newData.t = (mData->constEnd()-1).key()+1; + else + newData.t = 0; + newData.key = key; + newData.value = value; + mData->insertMulti(newData.t, newData); +} + +/*! \overload + Adds the provided data points as \a t, \a key and \a value tuples to the current data. + \see removeData +*/ +void QCPCurve::addData(const QVector &ts, const QVector &keys, const QVector &values) +{ + int n = ts.size(); + n = qMin(n, keys.size()); + n = qMin(n, values.size()); + QCPCurveData newData; + for (int i=0; iinsertMulti(newData.t, newData); + } +} + +/*! + Removes all data points with curve parameter t smaller than \a t. + \see addData, clearData +*/ +void QCPCurve::removeDataBefore(double t) +{ + QCPCurveDataMap::iterator it = mData->begin(); + while (it != mData->end() && it.key() < t) + it = mData->erase(it); +} + +/*! + Removes all data points with curve parameter t greater than \a t. + \see addData, clearData +*/ +void QCPCurve::removeDataAfter(double t) +{ + if (mData->isEmpty()) return; + QCPCurveDataMap::iterator it = mData->upperBound(t); + while (it != mData->end()) + it = mData->erase(it); +} + +/*! + Removes all data points with curve parameter t between \a fromt and \a tot. if \a fromt is + greater or equal to \a tot, the function does nothing. To remove a single data point with known + t, use \ref removeData(double t). + + \see addData, clearData +*/ +void QCPCurve::removeData(double fromt, double tot) +{ + if (fromt >= tot || mData->isEmpty()) return; + QCPCurveDataMap::iterator it = mData->upperBound(fromt); + QCPCurveDataMap::iterator itEnd = mData->upperBound(tot); + while (it != itEnd) + it = mData->erase(it); +} + +/*! \overload + + Removes a single data point at curve parameter \a t. If the position is not known with absolute + precision, consider using \ref removeData(double fromt, double tot) with a small fuzziness + interval around the suspected position, depeding on the precision with which the curve parameter + is known. + + \see addData, clearData +*/ +void QCPCurve::removeData(double t) +{ + mData->remove(t); +} + +/*! + Removes all data points. + \see removeData, removeDataAfter, removeDataBefore +*/ +void QCPCurve::clearData() +{ + mData->clear(); +} + +/* inherits documentation from base class */ +double QCPCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && !mSelectable) || mData->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + return pointDistance(pos); + else + return -1; +} + +/* inherits documentation from base class */ +void QCPCurve::draw(QCPPainter *painter) +{ + if (mData->isEmpty()) return; + + // allocate line vector: + QVector *lineData = new QVector; + + // fill with curve data: + getCurveData(lineData); + + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + QCPCurveDataMap::const_iterator it; + for (it = mData->constBegin(); it != mData->constEnd(); ++it) + { + if (QCP::isInvalidData(it.value().t) || + QCP::isInvalidData(it.value().key, it.value().value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it.key() << "invalid." << "Plottable name:" << name(); + } +#endif + + // draw curve fill: + if (mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0) + { + applyFillAntialiasingHint(painter); + painter->setPen(Qt::NoPen); + painter->setBrush(mainBrush()); + painter->drawPolygon(QPolygonF(*lineData)); + } + + // draw curve line: + if (mLineStyle != lsNone && mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mainPen()); + painter->setBrush(Qt::NoBrush); + // if drawing solid line and not in PDF, use much faster line drawing instead of polyline: + if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) && + painter->pen().style() == Qt::SolidLine && + !painter->modes().testFlag(QCPPainter::pmVectorized) && + !painter->modes().testFlag(QCPPainter::pmNoCaching)) + { + int i = 0; + bool lastIsNan = false; + const int lineDataSize = lineData->size(); + while (i < lineDataSize && (qIsNaN(lineData->at(i).y()) || qIsNaN(lineData->at(i).x()))) // make sure first point is not NaN + ++i; + ++i; // because drawing works in 1 point retrospect + while (i < lineDataSize) + { + if (!qIsNaN(lineData->at(i).y()) && !qIsNaN(lineData->at(i).x())) // NaNs create a gap in the line + { + if (!lastIsNan) + painter->drawLine(lineData->at(i-1), lineData->at(i)); + else + lastIsNan = false; + } else + lastIsNan = true; + ++i; + } + } else + { + int segmentStart = 0; + int i = 0; + const int lineDataSize = lineData->size(); + while (i < lineDataSize) + { + if (qIsNaN(lineData->at(i).y()) || qIsNaN(lineData->at(i).x())) // NaNs create a gap in the line + { + painter->drawPolyline(lineData->constData()+segmentStart, i-segmentStart); // i, because we don't want to include the current NaN point + segmentStart = i+1; + } + ++i; + } + // draw last segment: + painter->drawPolyline(lineData->constData()+segmentStart, lineDataSize-segmentStart); + } + } + + // draw scatters: + if (!mScatterStyle.isNone()) + drawScatterPlot(painter, lineData); + + // free allocated line data: + delete lineData; +} + +/* inherits documentation from base class */ +void QCPCurve::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw fill: + if (mBrush.style() != Qt::NoBrush) + { + applyFillAntialiasingHint(painter); + painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (!mScatterStyle.isNone()) + { + applyScattersAntialiasingHint(painter); + // scale scatter pixmap if it's too large to fit in legend icon rect: + if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) + { + QCPScatterStyle scaledStyle(mScatterStyle); + scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + scaledStyle.applyTo(painter, mPen); + scaledStyle.drawShape(painter, QRectF(rect).center()); + } else + { + mScatterStyle.applyTo(painter, mPen); + mScatterStyle.drawShape(painter, QRectF(rect).center()); + } + } +} + +/*! \internal + + Draws scatter symbols at every data point passed in \a pointData. scatter symbols are independent of + the line style and are always drawn if scatter shape is not \ref QCPScatterStyle::ssNone. +*/ +void QCPCurve::drawScatterPlot(QCPPainter *painter, const QVector *pointData) const +{ + // draw scatter point symbols: + applyScattersAntialiasingHint(painter); + mScatterStyle.applyTo(painter, mPen); + for (int i=0; isize(); ++i) + if (!qIsNaN(pointData->at(i).x()) && !qIsNaN(pointData->at(i).y())) + mScatterStyle.drawShape(painter, pointData->at(i)); +} + +/*! \internal + + called by QCPCurve::draw to generate a point vector (in pixel coordinates) which represents the + line of the curve. + + Line segments that aren't visible in the current axis rect are handled in an optimized way. They + are projected onto a rectangle slightly larger than the visible axis rect and simplified + regarding point count. The algorithm makes sure to preserve appearance of lines and fills inside + the visible axis rect by generating new temporary points on the outer rect if necessary. + + Methods that are also involved in the algorithm are: \ref getRegion, \ref getOptimizedPoint, \ref + getOptimizedCornerPoints \ref mayTraverse, \ref getTraverse, \ref getTraverseCornerPoints. +*/ +void QCPCurve::getCurveData(QVector *lineData) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + // add margins to rect to compensate for stroke width + double strokeMargin = qMax(qreal(1.0), qreal(mainPen().widthF()*0.75)); // stroke radius + 50% safety + if (!mScatterStyle.isNone()) + strokeMargin = qMax(strokeMargin, mScatterStyle.size()); + double rectLeft = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().lower)-strokeMargin*((keyAxis->orientation()==Qt::Vertical)!=keyAxis->rangeReversed()?-1:1)); + double rectRight = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().upper)+strokeMargin*((keyAxis->orientation()==Qt::Vertical)!=keyAxis->rangeReversed()?-1:1)); + double rectBottom = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().lower)+strokeMargin*((valueAxis->orientation()==Qt::Horizontal)!=valueAxis->rangeReversed()?-1:1)); + double rectTop = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().upper)-strokeMargin*((valueAxis->orientation()==Qt::Horizontal)!=valueAxis->rangeReversed()?-1:1)); + int currentRegion; + QCPCurveDataMap::const_iterator it = mData->constBegin(); + QCPCurveDataMap::const_iterator prevIt = mData->constEnd()-1; + int prevRegion = getRegion(prevIt.value().key, prevIt.value().value, rectLeft, rectTop, rectRight, rectBottom); + QVector trailingPoints; // points that must be applied after all other points (are generated only when handling first point to get virtual segment between last and first point right) + while (it != mData->constEnd()) + { + currentRegion = getRegion(it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom); + if (currentRegion != prevRegion) // changed region, possibly need to add some optimized edge points or original points if entering R + { + if (currentRegion != 5) // segment doesn't end in R, so it's a candidate for removal + { + QPointF crossA, crossB; + if (prevRegion == 5) // we're coming from R, so add this point optimized + { + lineData->append(getOptimizedPoint(currentRegion, it.value().key, it.value().value, prevIt.value().key, prevIt.value().value, rectLeft, rectTop, rectRight, rectBottom)); + // in the situations 5->1/7/9/3 the segment may leave R and directly cross through two outer regions. In these cases we need to add an additional corner point + *lineData << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom); + } else if (mayTraverse(prevRegion, currentRegion) && + getTraverse(prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom, crossA, crossB)) + { + // add the two cross points optimized if segment crosses R and if segment isn't virtual zeroth segment between last and first curve point: + QVector beforeTraverseCornerPoints, afterTraverseCornerPoints; + getTraverseCornerPoints(prevRegion, currentRegion, rectLeft, rectTop, rectRight, rectBottom, beforeTraverseCornerPoints, afterTraverseCornerPoints); + if (it != mData->constBegin()) + { + *lineData << beforeTraverseCornerPoints; + lineData->append(crossA); + lineData->append(crossB); + *lineData << afterTraverseCornerPoints; + } else + { + lineData->append(crossB); + *lineData << afterTraverseCornerPoints; + trailingPoints << beforeTraverseCornerPoints << crossA ; + } + } else // doesn't cross R, line is just moving around in outside regions, so only need to add optimized point(s) at the boundary corner(s) + { + *lineData << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom); + } + } else // segment does end in R, so we add previous point optimized and this point at original position + { + if (it == mData->constBegin()) // it is first point in curve and prevIt is last one. So save optimized point for adding it to the lineData in the end + trailingPoints << getOptimizedPoint(prevRegion, prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom); + else + lineData->append(getOptimizedPoint(prevRegion, prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom)); + lineData->append(coordsToPixels(it.value().key, it.value().value)); + } + } else // region didn't change + { + if (currentRegion == 5) // still in R, keep adding original points + { + lineData->append(coordsToPixels(it.value().key, it.value().value)); + } else // still outside R, no need to add anything + { + // see how this is not doing anything? That's the main optimization... + } + } + prevIt = it; + prevRegion = currentRegion; + ++it; + } + *lineData << trailingPoints; +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveData. + + It returns the region of the given point (\a x, \a y) with respect to a rectangle defined by \a + rectLeft, \a rectTop, \a rectRight, and \a rectBottom. + + The regions are enumerated from top to bottom and left to right: + + + + + +
147
258
369
+ + With the rectangle being region 5, and the outer regions extending infinitely outwards. In the + curve optimization algorithm, region 5 is considered to be the visible portion of the plot. +*/ +int QCPCurve::getRegion(double x, double y, double rectLeft, double rectTop, double rectRight, double rectBottom) const +{ + if (x < rectLeft) // region 123 + { + if (y > rectTop) + return 1; + else if (y < rectBottom) + return 3; + else + return 2; + } else if (x > rectRight) // region 789 + { + if (y > rectTop) + return 7; + else if (y < rectBottom) + return 9; + else + return 8; + } else // region 456 + { + if (y > rectTop) + return 4; + else if (y < rectBottom) + return 6; + else + return 5; + } +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveData. + + This method is used in case the current segment passes from inside the visible rect (region 5, + see \ref getRegion) to any of the outer regions (\a otherRegion). The current segment is given by + the line connecting (\a key, \a value) with (\a otherKey, \a otherValue). + + It returns the intersection point of the segment with the border of region 5. + + For this function it doesn't matter whether (\a key, \a value) is the point inside region 5 or + whether it's (\a otherKey, \a otherValue), i.e. whether the segment is coming from region 5 or + leaving it. It is important though that \a otherRegion correctly identifies the other region not + equal to 5. +*/ +QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double otherValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom) const +{ + double intersectKey = rectLeft; // initial value is just fail-safe + double intersectValue = rectTop; // initial value is just fail-safe + switch (otherRegion) + { + case 1: // top and left edge + { + intersectValue = rectTop; + intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue); + if (intersectKey < rectLeft || intersectKey > rectRight) // doesn't intersect, so must intersect other: + { + intersectKey = rectLeft; + intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey); + } + break; + } + case 2: // left edge + { + intersectKey = rectLeft; + intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey); + break; + } + case 3: // bottom and left edge + { + intersectValue = rectBottom; + intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue); + if (intersectKey < rectLeft || intersectKey > rectRight) // doesn't intersect, so must intersect other: + { + intersectKey = rectLeft; + intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey); + } + break; + } + case 4: // top edge + { + intersectValue = rectTop; + intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue); + break; + } + case 5: + { + break; // case 5 shouldn't happen for this function but we add it anyway to prevent potential discontinuity in branch table + } + case 6: // bottom edge + { + intersectValue = rectBottom; + intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue); + break; + } + case 7: // top and right edge + { + intersectValue = rectTop; + intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue); + if (intersectKey < rectLeft || intersectKey > rectRight) // doesn't intersect, so must intersect other: + { + intersectKey = rectRight; + intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey); + } + break; + } + case 8: // right edge + { + intersectKey = rectRight; + intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey); + break; + } + case 9: // bottom and right edge + { + intersectValue = rectBottom; + intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue); + if (intersectKey < rectLeft || intersectKey > rectRight) // doesn't intersect, so must intersect other: + { + intersectKey = rectRight; + intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey); + } + break; + } + } + return coordsToPixels(intersectKey, intersectValue); +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveData. + + In situations where a single segment skips over multiple regions it might become necessary to add + extra points at the corners of region 5 (see \ref getRegion) such that the optimized segment + doesn't unintentionally cut through the visible area of the axis rect and create plot artifacts. + This method provides these points that must be added, assuming the original segment doesn't + start, end, or traverse region 5. (Corner points where region 5 is traversed are calculated by + \ref getTraverseCornerPoints.) + + For example, consider a segment which directly goes from region 4 to 2 but originally is far out + to the top left such that it doesn't cross region 5. Naively optimizing these points by + projecting them on the top and left borders of region 5 will create a segment that surely crosses + 5, creating a visual artifact in the plot. This method prevents this by providing extra points at + the top left corner, making the optimized curve correctly pass from region 4 to 1 to 2 without + traversing 5. +*/ +QVector QCPCurve::getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom) const +{ + QVector result; + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 2: { result << coordsToPixels(rectLeft, rectTop); break; } + case 4: { result << coordsToPixels(rectLeft, rectTop); break; } + case 3: { result << coordsToPixels(rectLeft, rectTop) << coordsToPixels(rectLeft, rectBottom); break; } + case 7: { result << coordsToPixels(rectLeft, rectTop) << coordsToPixels(rectRight, rectTop); break; } + case 6: { result << coordsToPixels(rectLeft, rectTop) << coordsToPixels(rectLeft, rectBottom); result.append(result.last()); break; } + case 8: { result << coordsToPixels(rectLeft, rectTop) << coordsToPixels(rectRight, rectTop); result.append(result.last()); break; } + case 9: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(rectLeft-key)+value < rectBottom) // segment passes below R + { result << coordsToPixels(rectLeft, rectTop) << coordsToPixels(rectLeft, rectBottom); result.append(result.last()); result << coordsToPixels(rectRight, rectBottom); } + else + { result << coordsToPixels(rectLeft, rectTop) << coordsToPixels(rectRight, rectTop); result.append(result.last()); result << coordsToPixels(rectRight, rectBottom); } + break; + } + } + break; + } + case 2: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(rectLeft, rectTop); break; } + case 3: { result << coordsToPixels(rectLeft, rectBottom); break; } + case 4: { result << coordsToPixels(rectLeft, rectTop); result.append(result.last()); break; } + case 6: { result << coordsToPixels(rectLeft, rectBottom); result.append(result.last()); break; } + case 7: { result << coordsToPixels(rectLeft, rectTop); result.append(result.last()); result << coordsToPixels(rectRight, rectTop); break; } + case 9: { result << coordsToPixels(rectLeft, rectBottom); result.append(result.last()); result << coordsToPixels(rectRight, rectBottom); break; } + } + break; + } + case 3: + { + switch (currentRegion) + { + case 2: { result << coordsToPixels(rectLeft, rectBottom); break; } + case 6: { result << coordsToPixels(rectLeft, rectBottom); break; } + case 1: { result << coordsToPixels(rectLeft, rectBottom) << coordsToPixels(rectLeft, rectTop); break; } + case 9: { result << coordsToPixels(rectLeft, rectBottom) << coordsToPixels(rectRight, rectBottom); break; } + case 4: { result << coordsToPixels(rectLeft, rectBottom) << coordsToPixels(rectLeft, rectTop); result.append(result.last()); break; } + case 8: { result << coordsToPixels(rectLeft, rectBottom) << coordsToPixels(rectRight, rectBottom); result.append(result.last()); break; } + case 7: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(rectRight-key)+value < rectBottom) // segment passes below R + { result << coordsToPixels(rectLeft, rectBottom) << coordsToPixels(rectRight, rectBottom); result.append(result.last()); result << coordsToPixels(rectRight, rectTop); } + else + { result << coordsToPixels(rectLeft, rectBottom) << coordsToPixels(rectLeft, rectTop); result.append(result.last()); result << coordsToPixels(rectRight, rectTop); } + break; + } + } + break; + } + case 4: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(rectLeft, rectTop); break; } + case 7: { result << coordsToPixels(rectRight, rectTop); break; } + case 2: { result << coordsToPixels(rectLeft, rectTop); result.append(result.last()); break; } + case 8: { result << coordsToPixels(rectRight, rectTop); result.append(result.last()); break; } + case 3: { result << coordsToPixels(rectLeft, rectTop); result.append(result.last()); result << coordsToPixels(rectLeft, rectBottom); break; } + case 9: { result << coordsToPixels(rectRight, rectTop); result.append(result.last()); result << coordsToPixels(rectRight, rectBottom); break; } + } + break; + } + case 5: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(rectLeft, rectTop); break; } + case 7: { result << coordsToPixels(rectRight, rectTop); break; } + case 9: { result << coordsToPixels(rectRight, rectBottom); break; } + case 3: { result << coordsToPixels(rectLeft, rectBottom); break; } + } + break; + } + case 6: + { + switch (currentRegion) + { + case 3: { result << coordsToPixels(rectLeft, rectBottom); break; } + case 9: { result << coordsToPixels(rectRight, rectBottom); break; } + case 2: { result << coordsToPixels(rectLeft, rectBottom); result.append(result.last()); break; } + case 8: { result << coordsToPixels(rectRight, rectBottom); result.append(result.last()); break; } + case 1: { result << coordsToPixels(rectLeft, rectBottom); result.append(result.last()); result << coordsToPixels(rectLeft, rectTop); break; } + case 7: { result << coordsToPixels(rectRight, rectBottom); result.append(result.last()); result << coordsToPixels(rectRight, rectTop); break; } + } + break; + } + case 7: + { + switch (currentRegion) + { + case 4: { result << coordsToPixels(rectRight, rectTop); break; } + case 8: { result << coordsToPixels(rectRight, rectTop); break; } + case 1: { result << coordsToPixels(rectRight, rectTop) << coordsToPixels(rectLeft, rectTop); break; } + case 9: { result << coordsToPixels(rectRight, rectTop) << coordsToPixels(rectRight, rectBottom); break; } + case 2: { result << coordsToPixels(rectRight, rectTop) << coordsToPixels(rectLeft, rectTop); result.append(result.last()); break; } + case 6: { result << coordsToPixels(rectRight, rectTop) << coordsToPixels(rectRight, rectBottom); result.append(result.last()); break; } + case 3: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(rectRight-key)+value < rectBottom) // segment passes below R + { result << coordsToPixels(rectRight, rectTop) << coordsToPixels(rectRight, rectBottom); result.append(result.last()); result << coordsToPixels(rectLeft, rectBottom); } + else + { result << coordsToPixels(rectRight, rectTop) << coordsToPixels(rectLeft, rectTop); result.append(result.last()); result << coordsToPixels(rectLeft, rectBottom); } + break; + } + } + break; + } + case 8: + { + switch (currentRegion) + { + case 7: { result << coordsToPixels(rectRight, rectTop); break; } + case 9: { result << coordsToPixels(rectRight, rectBottom); break; } + case 4: { result << coordsToPixels(rectRight, rectTop); result.append(result.last()); break; } + case 6: { result << coordsToPixels(rectRight, rectBottom); result.append(result.last()); break; } + case 1: { result << coordsToPixels(rectRight, rectTop); result.append(result.last()); result << coordsToPixels(rectLeft, rectTop); break; } + case 3: { result << coordsToPixels(rectRight, rectBottom); result.append(result.last()); result << coordsToPixels(rectLeft, rectBottom); break; } + } + break; + } + case 9: + { + switch (currentRegion) + { + case 6: { result << coordsToPixels(rectRight, rectBottom); break; } + case 8: { result << coordsToPixels(rectRight, rectBottom); break; } + case 3: { result << coordsToPixels(rectRight, rectBottom) << coordsToPixels(rectLeft, rectBottom); break; } + case 7: { result << coordsToPixels(rectRight, rectBottom) << coordsToPixels(rectRight, rectTop); break; } + case 2: { result << coordsToPixels(rectRight, rectBottom) << coordsToPixels(rectLeft, rectBottom); result.append(result.last()); break; } + case 4: { result << coordsToPixels(rectRight, rectBottom) << coordsToPixels(rectRight, rectTop); result.append(result.last()); break; } + case 1: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(rectLeft-key)+value < rectBottom) // segment passes below R + { result << coordsToPixels(rectRight, rectBottom) << coordsToPixels(rectLeft, rectBottom); result.append(result.last()); result << coordsToPixels(rectLeft, rectTop); } + else + { result << coordsToPixels(rectRight, rectBottom) << coordsToPixels(rectRight, rectTop); result.append(result.last()); result << coordsToPixels(rectLeft, rectTop); } + break; + } + } + break; + } + } + return result; +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveData. + + This method returns whether a segment going from \a prevRegion to \a currentRegion (see \ref + getRegion) may traverse the visible region 5. This function assumes that neither \a prevRegion + nor \a currentRegion is 5 itself. + + If this method returns false, the segment for sure doesn't pass region 5. If it returns true, the + segment may or may not pass region 5 and a more fine-grained calculation must be used (\ref + getTraverse). +*/ +bool QCPCurve::mayTraverse(int prevRegion, int currentRegion) const +{ + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 4: + case 7: + case 2: + case 3: return false; + default: return true; + } + } + case 2: + { + switch (currentRegion) + { + case 1: + case 3: return false; + default: return true; + } + } + case 3: + { + switch (currentRegion) + { + case 1: + case 2: + case 6: + case 9: return false; + default: return true; + } + } + case 4: + { + switch (currentRegion) + { + case 1: + case 7: return false; + default: return true; + } + } + case 5: return false; // should never occur + case 6: + { + switch (currentRegion) + { + case 3: + case 9: return false; + default: return true; + } + } + case 7: + { + switch (currentRegion) + { + case 1: + case 4: + case 8: + case 9: return false; + default: return true; + } + } + case 8: + { + switch (currentRegion) + { + case 7: + case 9: return false; + default: return true; + } + } + case 9: + { + switch (currentRegion) + { + case 3: + case 6: + case 8: + case 7: return false; + default: return true; + } + } + default: return true; + } +} + + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveData. + + This method assumes that the \ref mayTraverse test has returned true, so there is a chance the + segment defined by (\a prevKey, \a prevValue) and (\a key, \a value) goes through the visible + region 5. + + The return value of this method indicates whether the segment actually traverses region 5 or not. + + If the segment traverses 5, the output parameters \a crossA and \a crossB indicate the entry and + exit points of region 5. They will become the optimized points for that segment. +*/ +bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom, QPointF &crossA, QPointF &crossB) const +{ + QList intersections; // x of QPointF corresponds to key and y to value + if (qFuzzyIsNull(key-prevKey)) // line is parallel to value axis + { + // due to region filter in mayTraverseR(), if line is parallel to value or key axis, R is traversed here + intersections.append(QPointF(key, rectBottom)); // direction will be taken care of at end of method + intersections.append(QPointF(key, rectTop)); + } else if (qFuzzyIsNull(value-prevValue)) // line is parallel to key axis + { + // due to region filter in mayTraverseR(), if line is parallel to value or key axis, R is traversed here + intersections.append(QPointF(rectLeft, value)); // direction will be taken care of at end of method + intersections.append(QPointF(rectRight, value)); + } else // line is skewed + { + double gamma; + double keyPerValue = (key-prevKey)/(value-prevValue); + // check top of rect: + gamma = prevKey + (rectTop-prevValue)*keyPerValue; + if (gamma >= rectLeft && gamma <= rectRight) + intersections.append(QPointF(gamma, rectTop)); + // check bottom of rect: + gamma = prevKey + (rectBottom-prevValue)*keyPerValue; + if (gamma >= rectLeft && gamma <= rectRight) + intersections.append(QPointF(gamma, rectBottom)); + double valuePerKey = 1.0/keyPerValue; + // check left of rect: + gamma = prevValue + (rectLeft-prevKey)*valuePerKey; + if (gamma >= rectBottom && gamma <= rectTop) + intersections.append(QPointF(rectLeft, gamma)); + // check right of rect: + gamma = prevValue + (rectRight-prevKey)*valuePerKey; + if (gamma >= rectBottom && gamma <= rectTop) + intersections.append(QPointF(rectRight, gamma)); + } + + // handle cases where found points isn't exactly 2: + if (intersections.size() > 2) + { + // line probably goes through corner of rect, and we got duplicate points there. single out the point pair with greatest distance in between: + double distSqrMax = 0; + QPointF pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = intersections.at(i); + pv2 = intersections.at(k); + distSqrMax = distSqr; + } + } + } + intersections = QList() << pv1 << pv2; + } else if (intersections.size() != 2) + { + // one or even zero points found (shouldn't happen unless line perfectly tangent to corner), no need to draw segment + return false; + } + + // possibly re-sort points so optimized point segment has same direction as original segment: + if ((key-prevKey)*(intersections.at(1).x()-intersections.at(0).x()) + (value-prevValue)*(intersections.at(1).y()-intersections.at(0).y()) < 0) // scalar product of both segments < 0 -> opposite direction + intersections.move(0, 1); + crossA = coordsToPixels(intersections.at(0).x(), intersections.at(0).y()); + crossB = coordsToPixels(intersections.at(1).x(), intersections.at(1).y()); + return true; +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveData. + + This method assumes that the \ref getTraverse test has returned true, so the segment definitely + traverses the visible region 5 when going from \a prevRegion to \a currentRegion. + + In certain situations it is not sufficient to merely generate the entry and exit points of the + segment into/out of region 5, as \ref getTraverse provides. It may happen that a single segment, in + addition to traversing region 5, skips another region outside of region 5, which makes it + necessary to add an optimized corner point there (very similar to the job \ref + getOptimizedCornerPoints does for segments that are completely in outside regions and don't + traverse 5). + + As an example, consider a segment going from region 1 to region 6, traversing the lower left + corner of region 5. In this configuration, the segment additionally crosses the border between + region 1 and 2 before entering region 5. This makes it necessary to add an additional point in + the top left corner, before adding the optimized traverse points. So in this case, the output + parameter \a beforeTraverse will contain the top left corner point, and \a afterTraverse will be + empty. + + In some cases, such as when going from region 1 to 9, it may even be necessary to add additional + corner points before and after the traverse. Then both \a beforeTraverse and \a afterTraverse + return the respective corner points. +*/ +void QCPCurve::getTraverseCornerPoints(int prevRegion, int currentRegion, double rectLeft, double rectTop, double rectRight, double rectBottom, QVector &beforeTraverse, QVector &afterTraverse) const +{ + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 6: { beforeTraverse << coordsToPixels(rectLeft, rectTop); break; } + case 9: { beforeTraverse << coordsToPixels(rectLeft, rectTop); afterTraverse << coordsToPixels(rectRight, rectBottom); break; } + case 8: { beforeTraverse << coordsToPixels(rectLeft, rectTop); break; } + } + break; + } + case 2: + { + switch (currentRegion) + { + case 7: { afterTraverse << coordsToPixels(rectRight, rectTop); break; } + case 9: { afterTraverse << coordsToPixels(rectRight, rectBottom); break; } + } + break; + } + case 3: + { + switch (currentRegion) + { + case 4: { beforeTraverse << coordsToPixels(rectLeft, rectBottom); break; } + case 7: { beforeTraverse << coordsToPixels(rectLeft, rectBottom); afterTraverse << coordsToPixels(rectRight, rectTop); break; } + case 8: { beforeTraverse << coordsToPixels(rectLeft, rectBottom); break; } + } + break; + } + case 4: + { + switch (currentRegion) + { + case 3: { afterTraverse << coordsToPixels(rectLeft, rectBottom); break; } + case 9: { afterTraverse << coordsToPixels(rectRight, rectBottom); break; } + } + break; + } + case 5: { break; } // shouldn't happen because this method only handles full traverses + case 6: + { + switch (currentRegion) + { + case 1: { afterTraverse << coordsToPixels(rectLeft, rectTop); break; } + case 7: { afterTraverse << coordsToPixels(rectRight, rectTop); break; } + } + break; + } + case 7: + { + switch (currentRegion) + { + case 2: { beforeTraverse << coordsToPixels(rectRight, rectTop); break; } + case 3: { beforeTraverse << coordsToPixels(rectRight, rectTop); afterTraverse << coordsToPixels(rectLeft, rectBottom); break; } + case 6: { beforeTraverse << coordsToPixels(rectRight, rectTop); break; } + } + break; + } + case 8: + { + switch (currentRegion) + { + case 1: { afterTraverse << coordsToPixels(rectLeft, rectTop); break; } + case 3: { afterTraverse << coordsToPixels(rectLeft, rectBottom); break; } + } + break; + } + case 9: + { + switch (currentRegion) + { + case 2: { beforeTraverse << coordsToPixels(rectRight, rectBottom); break; } + case 1: { beforeTraverse << coordsToPixels(rectRight, rectBottom); afterTraverse << coordsToPixels(rectLeft, rectTop); break; } + case 4: { beforeTraverse << coordsToPixels(rectRight, rectBottom); break; } + } + break; + } + } +} + +/*! \internal + + Calculates the (minimum) distance (in pixels) the curve's representation has from the given \a + pixelPoint in pixels. This is used to determine whether the curve was clicked or not, e.g. in + \ref selectTest. +*/ +double QCPCurve::pointDistance(const QPointF &pixelPoint) const +{ + if (mData->isEmpty()) + { + qDebug() << Q_FUNC_INFO << "requested point distance on curve" << mName << "without data"; + return 500; + } + if (mData->size() == 1) + { + QPointF dataPoint = coordsToPixels(mData->constBegin().key(), mData->constBegin().value().value); + return QVector2D(dataPoint-pixelPoint).length(); + } + + // calculate minimum distance to line segments: + QVector *lineData = new QVector; + getCurveData(lineData); + double minDistSqr = std::numeric_limits::max(); + for (int i=0; isize()-1; ++i) + { + double currentDistSqr = distSqrToLine(lineData->at(i), lineData->at(i+1), pixelPoint); + if (currentDistSqr < minDistSqr) + minDistSqr = currentDistSqr; + } + delete lineData; + return qSqrt(minDistSqr); +} + +/* inherits documentation from base class */ +QCPRange QCPCurve::getKeyRange(bool &foundRange, SignDomain inSignDomain) const +{ + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + + double current; + + QCPCurveDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().key; + if (!qIsNaN(current) && !qIsNaN(it.value().value)) + { + if (inSignDomain == sdBoth || (inSignDomain == sdNegative && current < 0) || (inSignDomain == sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } + ++it; + } + + foundRange = haveLower && haveUpper; + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPCurve::getValueRange(bool &foundRange, SignDomain inSignDomain) const +{ + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + + double current; + + QCPCurveDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().value; + if (!qIsNaN(current) && !qIsNaN(it.value().key)) + { + if (inSignDomain == sdBoth || (inSignDomain == sdNegative && current < 0) || (inSignDomain == sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } + ++it; + } + + foundRange = haveLower && haveUpper; + return range; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPBarsGroup +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPBarsGroup + \brief Groups multiple QCPBars together so they appear side by side + + \image html QCPBarsGroup.png + + When showing multiple QCPBars in one plot which have bars at identical keys, it may be desirable + to have them appearing next to each other at each key. This is what adding the respective QCPBars + plottables to a QCPBarsGroup achieves. (An alternative approach is to stack them on top of each + other, see \ref QCPBars::moveAbove.) + + \section qcpbarsgroup-usage Usage + + To add a QCPBars plottable to the group, create a new group and then add the respective bars + intances: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbarsgroup-creation + Alternatively to appending to the group like shown above, you can also set the group on the + QCPBars plottable via \ref QCPBars::setBarsGroup. + + The spacing between the bars can be configured via \ref setSpacingType and \ref setSpacing. The + bars in this group appear in the plot in the order they were appended. To insert a bars plottable + at a certain index position, or to reposition a bars plottable which is already in the group, use + \ref insert. + + To remove specific bars from the group, use either \ref remove or call \ref + QCPBars::setBarsGroup "QCPBars::setBarsGroup(0)" on the respective bars plottable. + + To clear the entire group, call \ref clear, or simply delete the group. + + \section qcpbarsgroup-example Example + + The image above is generated with the following code: + \snippet documentation/doc-image-generator/mainwindow.cpp qcpbarsgroup-example +*/ + +/* start of documentation of inline functions */ + +/*! \fn QList QCPBarsGroup::bars() const + + Returns all bars currently in this group. + + \see bars(int index) +*/ + +/*! \fn int QCPBarsGroup::size() const + + Returns the number of QCPBars plottables that are part of this group. + +*/ + +/*! \fn bool QCPBarsGroup::isEmpty() const + + Returns whether this bars group is empty. + + \see size +*/ + +/*! \fn bool QCPBarsGroup::contains(QCPBars *bars) + + Returns whether the specified \a bars plottable is part of this group. + +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a new bars group for the specified QCustomPlot instance. +*/ +QCPBarsGroup::QCPBarsGroup(QCustomPlot *parentPlot) : + QObject(parentPlot), + mParentPlot(parentPlot), + mSpacingType(stAbsolute), + mSpacing(4) +{ +} + +QCPBarsGroup::~QCPBarsGroup() +{ + clear(); +} + +/*! + Sets how the spacing between adjacent bars is interpreted. See \ref SpacingType. + + The actual spacing can then be specified with \ref setSpacing. + + \see setSpacing +*/ +void QCPBarsGroup::setSpacingType(SpacingType spacingType) +{ + mSpacingType = spacingType; +} + +/*! + Sets the spacing between adjacent bars. What the number passed as \a spacing actually means, is + defined by the current \ref SpacingType, which can be set with \ref setSpacingType. + + \see setSpacingType +*/ +void QCPBarsGroup::setSpacing(double spacing) +{ + mSpacing = spacing; +} + +/*! + Returns the QCPBars instance with the specified \a index in this group. If no such QCPBars + exists, returns 0. + + \see bars(), size +*/ +QCPBars *QCPBarsGroup::bars(int index) const +{ + if (index >= 0 && index < mBars.size()) + { + return mBars.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! + Removes all QCPBars plottables from this group. + + \see isEmpty +*/ +void QCPBarsGroup::clear() +{ + foreach (QCPBars *bars, mBars) // since foreach takes a copy, removing bars in the loop is okay + bars->setBarsGroup(0); // removes itself via removeBars +} + +/*! + Adds the specified \a bars plottable to this group. Alternatively, you can also use \ref + QCPBars::setBarsGroup on the \a bars instance. + + \see insert, remove +*/ +void QCPBarsGroup::append(QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + if (!mBars.contains(bars)) + bars->setBarsGroup(this); + else + qDebug() << Q_FUNC_INFO << "bars plottable is already in this bars group:" << reinterpret_cast(bars); +} + +/*! + Inserts the specified \a bars plottable into this group at the specified index position \a i. + This gives you full control over the ordering of the bars. + + \a bars may already be part of this group. In that case, \a bars is just moved to the new index + position. + + \see append, remove +*/ +void QCPBarsGroup::insert(int i, QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + // first append to bars list normally: + if (!mBars.contains(bars)) + bars->setBarsGroup(this); + // then move to according position: + mBars.move(mBars.indexOf(bars), qBound(0, i, mBars.size()-1)); +} + +/*! + Removes the specified \a bars plottable from this group. + + \see contains, clear +*/ +void QCPBarsGroup::remove(QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + if (mBars.contains(bars)) + bars->setBarsGroup(0); + else + qDebug() << Q_FUNC_INFO << "bars plottable is not in this bars group:" << reinterpret_cast(bars); +} + +/*! \internal + + Adds the specified \a bars to the internal mBars list of bars. This method does not change the + barsGroup property on \a bars. + + \see unregisterBars +*/ +void QCPBarsGroup::registerBars(QCPBars *bars) +{ + if (!mBars.contains(bars)) + mBars.append(bars); +} + +/*! \internal + + Removes the specified \a bars from the internal mBars list of bars. This method does not change + the barsGroup property on \a bars. + + \see registerBars +*/ +void QCPBarsGroup::unregisterBars(QCPBars *bars) +{ + mBars.removeOne(bars); +} + +/*! \internal + + Returns the pixel offset in the key dimension the specified \a bars plottable should have at the + given key coordinate \a keyCoord. The offset is relative to the pixel position of the key + coordinate \a keyCoord. +*/ +double QCPBarsGroup::keyPixelOffset(const QCPBars *bars, double keyCoord) +{ + // find list of all base bars in case some mBars are stacked: + QList baseBars; + foreach (const QCPBars *b, mBars) + { + while (b->barBelow()) + b = b->barBelow(); + if (!baseBars.contains(b)) + baseBars.append(b); + } + // find base bar this "bars" is stacked on: + const QCPBars *thisBase = bars; + while (thisBase->barBelow()) + thisBase = thisBase->barBelow(); + + // determine key pixel offset of this base bars considering all other base bars in this barsgroup: + double result = 0; + int index = baseBars.indexOf(thisBase); + if (index >= 0) + { + int startIndex; + double lowerPixelWidth, upperPixelWidth; + if (baseBars.size() % 2 == 1 && index == (baseBars.size()-1)/2) // is center bar (int division on purpose) + { + return result; + } else if (index < (baseBars.size()-1)/2.0) // bar is to the left of center + { + if (baseBars.size() % 2 == 0) // even number of bars + { + startIndex = baseBars.size()/2-1; + result -= getPixelSpacing(baseBars.at(startIndex), keyCoord)*0.5; // half of middle spacing + } else // uneven number of bars + { + startIndex = (baseBars.size()-1)/2-1; + baseBars.at((baseBars.size()-1)/2)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result -= qAbs(upperPixelWidth-lowerPixelWidth)*0.5; // half of center bar + result -= getPixelSpacing(baseBars.at((baseBars.size()-1)/2), keyCoord); // center bar spacing + } + for (int i=startIndex; i>index; --i) // add widths and spacings of bars in between center and our bars + { + baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result -= qAbs(upperPixelWidth-lowerPixelWidth); + result -= getPixelSpacing(baseBars.at(i), keyCoord); + } + // finally half of our bars width: + baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result -= qAbs(upperPixelWidth-lowerPixelWidth)*0.5; + } else // bar is to the right of center + { + if (baseBars.size() % 2 == 0) // even number of bars + { + startIndex = baseBars.size()/2; + result += getPixelSpacing(baseBars.at(startIndex), keyCoord)*0.5; // half of middle spacing + } else // uneven number of bars + { + startIndex = (baseBars.size()-1)/2+1; + baseBars.at((baseBars.size()-1)/2)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; // half of center bar + result += getPixelSpacing(baseBars.at((baseBars.size()-1)/2), keyCoord); // center bar spacing + } + for (int i=startIndex; igetPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth); + result += getPixelSpacing(baseBars.at(i), keyCoord); + } + // finally half of our bars width: + baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; + } + } + return result; +} + +/*! \internal + + Returns the spacing in pixels which is between this \a bars and the following one, both at the + key coordinate \a keyCoord. + + \note Typically the returned value doesn't depend on \a bars or \a keyCoord. \a bars is only + needed to get acces to the key axis transformation and axis rect for the modes \ref + stAxisRectRatio and \ref stPlotCoords. The \a keyCoord is only relevant for spacings given in + \ref stPlotCoords on a logarithmic axis. +*/ +double QCPBarsGroup::getPixelSpacing(const QCPBars *bars, double keyCoord) +{ + switch (mSpacingType) + { + case stAbsolute: + { + return mSpacing; + } + case stAxisRectRatio: + { + if (bars->keyAxis()->orientation() == Qt::Horizontal) + return bars->keyAxis()->axisRect()->width()*mSpacing; + else + return bars->keyAxis()->axisRect()->height()*mSpacing; + } + case stPlotCoords: + { + double keyPixel = bars->keyAxis()->coordToPixel(keyCoord); + return bars->keyAxis()->coordToPixel(keyCoord+mSpacing)-keyPixel; + } + } + return 0; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPBarData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPBarData + \brief Holds the data of one single data point (one bar) for QCPBars. + + The container for storing multiple data points is \ref QCPBarDataMap. + + The stored data is: + \li \a key: coordinate on the key axis of this bar + \li \a value: height coordinate on the value axis of this bar + + \see QCPBarDataaMap +*/ + +/*! + Constructs a bar data point with key and value set to zero. +*/ +QCPBarData::QCPBarData() : + key(0), + value(0) +{ +} + +/*! + Constructs a bar data point with the specified \a key and \a value. +*/ +QCPBarData::QCPBarData(double key, double value) : + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPBars +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPBars + \brief A plottable representing a bar chart in a plot. + + \image html QCPBars.png + + To plot data, assign it with the \ref setData or \ref addData functions. + + \section appearance Changing the appearance + + The appearance of the bars is determined by the pen and the brush (\ref setPen, \ref setBrush). + The width of the individual bars can be controlled with \ref setWidthType and \ref setWidth. + + Bar charts are stackable. This means, two QCPBars plottables can be placed on top of each other + (see \ref QCPBars::moveAbove). So when two bars are at the same key position, they will appear + stacked. + + If you would like to group multiple QCPBars plottables together so they appear side by side as + shown below, use QCPBarsGroup. + + \image html QCPBarsGroup.png + + \section usage Usage + + Like all data representing objects in QCustomPlot, the QCPBars is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::addPlottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-1 + add it to the customPlot with QCustomPlot::addPlottable: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-2 + and then modify the properties of the newly created plottable, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-3 +*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPBars *QCPBars::barBelow() const + Returns the bars plottable that is directly below this bars plottable. + If there is no such plottable, returns 0. + + \see barAbove, moveBelow, moveAbove +*/ + +/*! \fn QCPBars *QCPBars::barAbove() const + Returns the bars plottable that is directly above this bars plottable. + If there is no such plottable, returns 0. + + \see barBelow, moveBelow, moveAbove +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a bar chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The constructed QCPBars can be added to the plot with QCustomPlot::addPlottable, QCustomPlot + then takes ownership of the bar chart. +*/ +QCPBars::QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mData(new QCPBarDataMap), + mWidth(0.75), + mWidthType(wtPlotCoords), + mBarsGroup(0), + mBaseValue(0) +{ + // modify inherited properties from abstract plottable: + mPen.setColor(Qt::blue); + mPen.setStyle(Qt::SolidLine); + mBrush.setColor(QColor(40, 50, 255, 30)); + mBrush.setStyle(Qt::SolidPattern); + mSelectedPen = mPen; + mSelectedPen.setWidthF(2.5); + mSelectedPen.setColor(QColor(80, 80, 255)); // lighter than Qt::blue of mPen + mSelectedBrush = mBrush; +} + +QCPBars::~QCPBars() +{ + setBarsGroup(0); + if (mBarBelow || mBarAbove) + connectBars(mBarBelow.data(), mBarAbove.data()); // take this bar out of any stacking + delete mData; +} + +/*! + Sets the width of the bars. + + How the number passed as \a width is interpreted (e.g. screen pixels, plot coordinates,...), + depends on the currently set width type, see \ref setWidthType and \ref WidthType. +*/ +void QCPBars::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets how the width of the bars is defined. See the documentation of \ref WidthType for an + explanation of the possible values for \a widthType. + + The default value is \ref wtPlotCoords. + + \see setWidth +*/ +void QCPBars::setWidthType(QCPBars::WidthType widthType) +{ + mWidthType = widthType; +} + +/*! + Sets to which QCPBarsGroup this QCPBars instance belongs to. Alternatively, you can also use \ref + QCPBarsGroup::append. + + To remove this QCPBars from any group, set \a barsGroup to 0. +*/ +void QCPBars::setBarsGroup(QCPBarsGroup *barsGroup) +{ + // deregister at old group: + if (mBarsGroup) + mBarsGroup->unregisterBars(this); + mBarsGroup = barsGroup; + // register at new group: + if (mBarsGroup) + mBarsGroup->registerBars(this); +} + +/*! + Sets the base value of this bars plottable. + + The base value defines where on the value coordinate the bars start. How far the bars extend from + the base value is given by their individual value data. For example, if the base value is set to + 1, a bar with data value 2 will have its lowest point at value coordinate 1 and highest point at + 3. + + For stacked bars, only the base value of the bottom-most QCPBars has meaning. + + The default base value is 0. +*/ +void QCPBars::setBaseValue(double baseValue) +{ + mBaseValue = baseValue; +} + +/*! + Replaces the current data with the provided \a data. + + If \a copy is set to true, data points in \a data will only be copied. if false, the plottable + takes ownership of the passed data and replaces the internal data pointer with it. This is + significantly faster than copying for large datasets. +*/ +void QCPBars::setData(QCPBarDataMap *data, bool copy) +{ + if (mData == data) + { + qDebug() << Q_FUNC_INFO << "The data pointer is already in (and owned by) this plottable" << reinterpret_cast(data); + return; + } + if (copy) + { + *mData = *data; + } else + { + delete mData; + mData = data; + } +} + +/*! \overload + + Replaces the current data with the provided points in \a key and \a value tuples. The + provided vectors should have equal length. Else, the number of added points will be the size of + the smallest vector. +*/ +void QCPBars::setData(const QVector &key, const QVector &value) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, value.size()); + QCPBarData newData; + for (int i=0; iinsertMulti(newData.key, newData); + } +} + +/*! + Moves this bars plottable below \a bars. In other words, the bars of this plottable will appear + below the bars of \a bars. The move target \a bars must use the same key and value axis as this + plottable. + + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already + has a bars object below itself, this bars object is inserted between the two. If this bars object + is already between two other bars, the two other bars will be stacked on top of each other after + the operation. + + To remove this bars plottable from any stacking, set \a bars to 0. + + \see moveBelow, barAbove, barBelow +*/ +void QCPBars::moveBelow(QCPBars *bars) +{ + if (bars == this) return; + if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) + { + qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; + return; + } + // remove from stacking: + connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 + // if new bar given, insert this bar below it: + if (bars) + { + if (bars->mBarBelow) + connectBars(bars->mBarBelow.data(), this); + connectBars(this, bars); + } +} + +/*! + Moves this bars plottable above \a bars. In other words, the bars of this plottable will appear + above the bars of \a bars. The move target \a bars must use the same key and value axis as this + plottable. + + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already + has a bars object above itself, this bars object is inserted between the two. If this bars object + is already between two other bars, the two other bars will be stacked on top of each other after + the operation. + + To remove this bars plottable from any stacking, set \a bars to 0. + + \see moveBelow, barBelow, barAbove +*/ +void QCPBars::moveAbove(QCPBars *bars) +{ + if (bars == this) return; + if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) + { + qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; + return; + } + // remove from stacking: + connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 + // if new bar given, insert this bar above it: + if (bars) + { + if (bars->mBarAbove) + connectBars(this, bars->mBarAbove.data()); + connectBars(bars, this); + } +} + +/*! + Adds the provided data points in \a dataMap to the current data. + \see removeData +*/ +void QCPBars::addData(const QCPBarDataMap &dataMap) +{ + mData->unite(dataMap); +} + +/*! \overload + Adds the provided single data point in \a data to the current data. + \see removeData +*/ +void QCPBars::addData(const QCPBarData &data) +{ + mData->insertMulti(data.key, data); +} + +/*! \overload + Adds the provided single data point as \a key and \a value tuple to the current data + \see removeData +*/ +void QCPBars::addData(double key, double value) +{ + QCPBarData newData; + newData.key = key; + newData.value = value; + mData->insertMulti(newData.key, newData); +} + +/*! \overload + Adds the provided data points as \a key and \a value tuples to the current data. + \see removeData +*/ +void QCPBars::addData(const QVector &keys, const QVector &values) +{ + int n = keys.size(); + n = qMin(n, values.size()); + QCPBarData newData; + for (int i=0; iinsertMulti(newData.key, newData); + } +} + +/*! + Removes all data points with key smaller than \a key. + \see addData, clearData +*/ +void QCPBars::removeDataBefore(double key) +{ + QCPBarDataMap::iterator it = mData->begin(); + while (it != mData->end() && it.key() < key) + it = mData->erase(it); +} + +/*! + Removes all data points with key greater than \a key. + \see addData, clearData +*/ +void QCPBars::removeDataAfter(double key) +{ + if (mData->isEmpty()) return; + QCPBarDataMap::iterator it = mData->upperBound(key); + while (it != mData->end()) + it = mData->erase(it); +} + +/*! + Removes all data points with key between \a fromKey and \a toKey. if \a fromKey is + greater or equal to \a toKey, the function does nothing. To remove a single data point with known + key, use \ref removeData(double key). + + \see addData, clearData +*/ +void QCPBars::removeData(double fromKey, double toKey) +{ + if (fromKey >= toKey || mData->isEmpty()) return; + QCPBarDataMap::iterator it = mData->upperBound(fromKey); + QCPBarDataMap::iterator itEnd = mData->upperBound(toKey); + while (it != itEnd) + it = mData->erase(it); +} + +/*! \overload + + Removes a single data point at \a key. If the position is not known with absolute precision, + consider using \ref removeData(double fromKey, double toKey) with a small fuzziness interval + around the suspected position, depeding on the precision with which the key is known. + + \see addData, clearData +*/ +void QCPBars::removeData(double key) +{ + mData->remove(key); +} + +/*! + Removes all data points. + \see removeData, removeDataAfter, removeDataBefore +*/ +void QCPBars::clearData() +{ + mData->clear(); +} + +/* inherits documentation from base class */ +double QCPBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + QCPBarDataMap::ConstIterator it; + for (it = mData->constBegin(); it != mData->constEnd(); ++it) + { + if (getBarPolygon(it.value().key, it.value().value).boundingRect().contains(pos)) + return mParentPlot->selectionTolerance()*0.99; + } + } + return -1; +} + +/* inherits documentation from base class */ +void QCPBars::draw(QCPPainter *painter) +{ + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mData->isEmpty()) return; + + QCPBarDataMap::const_iterator it, lower, upperEnd; + getVisibleDataBounds(lower, upperEnd); + for (it = lower; it != upperEnd; ++it) + { + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + if (QCP::isInvalidData(it.value().key, it.value().value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it.key() << "of drawn range invalid." << "Plottable name:" << name(); +#endif + QPolygonF barPolygon = getBarPolygon(it.key(), it.value().value); + // draw bar fill: + if (mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0) + { + applyFillAntialiasingHint(painter); + painter->setPen(Qt::NoPen); + painter->setBrush(mainBrush()); + painter->drawPolygon(barPolygon); + } + // draw bar line: + if (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mainPen()); + painter->setBrush(Qt::NoBrush); + painter->drawPolyline(barPolygon); + } + } +} + +/* inherits documentation from base class */ +void QCPBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw filled rect: + applyDefaultAntialiasingHint(painter); + painter->setBrush(mBrush); + painter->setPen(mPen); + QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); + r.moveCenter(rect.center()); + painter->drawRect(r); +} + +/*! \internal + + called by \ref draw to determine which data (key) range is visible at the current key axis range + setting, so only that needs to be processed. It also takes into account the bar width. + + \a lower returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + lower may still be just outside the visible range. + + \a upperEnd returns an iterator one higher than the highest visible data point. Same as before, \a + upperEnd may also lie just outside of the visible range. + + if the bars plottable contains no data, both \a lower and \a upperEnd point to constEnd. +*/ +void QCPBars::getVisibleDataBounds(QCPBarDataMap::const_iterator &lower, QCPBarDataMap::const_iterator &upperEnd) const +{ + if (!mKeyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } + if (mData->isEmpty()) + { + lower = mData->constEnd(); + upperEnd = mData->constEnd(); + return; + } + + // get visible data range as QMap iterators + lower = mData->lowerBound(mKeyAxis.data()->range().lower); + upperEnd = mData->upperBound(mKeyAxis.data()->range().upper); + double lowerPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().lower); + double upperPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().upper); + bool isVisible = false; + // walk left from lbound to find lower bar that actually is completely outside visible pixel range: + QCPBarDataMap::const_iterator it = lower; + while (it != mData->constBegin()) + { + --it; + QRectF barBounds = getBarPolygon(it.value().key, it.value().value).boundingRect(); + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + isVisible = ((!mKeyAxis.data()->rangeReversed() && barBounds.right() >= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barBounds.left() <= lowerPixelBound)); + else // keyaxis is vertical + isVisible = ((!mKeyAxis.data()->rangeReversed() && barBounds.top() <= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barBounds.bottom() >= lowerPixelBound)); + if (isVisible) + lower = it; + else + break; + } + // walk right from ubound to find upper bar that actually is completely outside visible pixel range: + it = upperEnd; + while (it != mData->constEnd()) + { + QRectF barBounds = getBarPolygon(upperEnd.value().key, upperEnd.value().value).boundingRect(); + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + isVisible = ((!mKeyAxis.data()->rangeReversed() && barBounds.left() <= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barBounds.right() >= upperPixelBound)); + else // keyaxis is vertical + isVisible = ((!mKeyAxis.data()->rangeReversed() && barBounds.bottom() >= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barBounds.top() <= upperPixelBound)); + if (isVisible) + upperEnd = it+1; + else + break; + ++it; + } +} + +/*! \internal + + Returns the polygon of a single bar with \a key and \a value. The Polygon is open at the bottom + and shifted according to the bar stacking (see \ref moveAbove) and base value (see \ref + setBaseValue). +*/ +QPolygonF QCPBars::getBarPolygon(double key, double value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPolygonF(); } + + QPolygonF result; + double lowerPixelWidth, upperPixelWidth; + getPixelWidth(key, lowerPixelWidth, upperPixelWidth); + double base = getStackedBaseValue(key, value >= 0); + double basePixel = valueAxis->coordToPixel(base); + double valuePixel = valueAxis->coordToPixel(base+value); + double keyPixel = keyAxis->coordToPixel(key); + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, key); + if (keyAxis->orientation() == Qt::Horizontal) + { + result << QPointF(keyPixel+lowerPixelWidth, basePixel); + result << QPointF(keyPixel+lowerPixelWidth, valuePixel); + result << QPointF(keyPixel+upperPixelWidth, valuePixel); + result << QPointF(keyPixel+upperPixelWidth, basePixel); + } else + { + result << QPointF(basePixel, keyPixel+lowerPixelWidth); + result << QPointF(valuePixel, keyPixel+lowerPixelWidth); + result << QPointF(valuePixel, keyPixel+upperPixelWidth); + result << QPointF(basePixel, keyPixel+upperPixelWidth); + } + return result; +} + +/*! \internal + + This function is used to determine the width of the bar at coordinate \a key, according to the + specified width (\ref setWidth) and width type (\ref setWidthType). + + The output parameters \a lower and \a upper return the number of pixels the bar extends to lower + and higher keys, relative to the \a key coordinate (so with a non-reversed horizontal axis, \a + lower is negative and \a upper positive). +*/ +void QCPBars::getPixelWidth(double key, double &lower, double &upper) const +{ + switch (mWidthType) + { + case wtAbsolute: + { + upper = mWidth*0.5; + lower = -upper; + if (mKeyAxis && (mKeyAxis.data()->rangeReversed() ^ (mKeyAxis.data()->orientation() == Qt::Vertical))) + qSwap(lower, upper); + break; + } + case wtAxisRectRatio: + { + if (mKeyAxis && mKeyAxis.data()->axisRect()) + { + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + upper = mKeyAxis.data()->axisRect()->width()*mWidth*0.5; + else + upper = mKeyAxis.data()->axisRect()->height()*mWidth*0.5; + lower = -upper; + if (mKeyAxis && (mKeyAxis.data()->rangeReversed() ^ (mKeyAxis.data()->orientation() == Qt::Vertical))) + qSwap(lower, upper); + } else + qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; + break; + } + case wtPlotCoords: + { + if (mKeyAxis) + { + double keyPixel = mKeyAxis.data()->coordToPixel(key); + upper = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; + lower = mKeyAxis.data()->coordToPixel(key-mWidth*0.5)-keyPixel; + // no need to qSwap(lower, higher) when range reversed, because higher/lower are gained by + // coordinate transform which includes range direction + } else + qDebug() << Q_FUNC_INFO << "No key axis defined"; + break; + } + } +} + +/*! \internal + + This function is called to find at which value to start drawing the base of a bar at \a key, when + it is stacked on top of another QCPBars (e.g. with \ref moveAbove). + + positive and negative bars are separated per stack (positive are stacked above baseValue upwards, + negative are stacked below baseValue downwards). This can be indicated with \a positive. So if the + bar for which we need the base value is negative, set \a positive to false. +*/ +double QCPBars::getStackedBaseValue(double key, bool positive) const +{ + if (mBarBelow) + { + double max = 0; // don't use mBaseValue here because only base value of bottom-most bar has meaning in a bar stack + // find bars of mBarBelow that are approximately at key and find largest one: + double epsilon = qAbs(key)*1e-6; // should be safe even when changed to use float at some point + if (key == 0) + epsilon = 1e-6; + QCPBarDataMap::const_iterator it = mBarBelow.data()->mData->lowerBound(key-epsilon); + QCPBarDataMap::const_iterator itEnd = mBarBelow.data()->mData->upperBound(key+epsilon); + while (it != itEnd) + { + if ((positive && it.value().value > max) || + (!positive && it.value().value < max)) + max = it.value().value; + ++it; + } + // recurse down the bar-stack to find the total height: + return max + mBarBelow.data()->getStackedBaseValue(key, positive); + } else + return mBaseValue; +} + +/*! \internal + + Connects \a below and \a above to each other via their mBarAbove/mBarBelow properties. The bar(s) + currently above lower and below upper will become disconnected to lower/upper. + + If lower is zero, upper will be disconnected at the bottom. + If upper is zero, lower will be disconnected at the top. +*/ +void QCPBars::connectBars(QCPBars *lower, QCPBars *upper) +{ + if (!lower && !upper) return; + + if (!lower) // disconnect upper at bottom + { + // disconnect old bar below upper: + if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) + upper->mBarBelow.data()->mBarAbove = 0; + upper->mBarBelow = 0; + } else if (!upper) // disconnect lower at top + { + // disconnect old bar above lower: + if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) + lower->mBarAbove.data()->mBarBelow = 0; + lower->mBarAbove = 0; + } else // connect lower and upper + { + // disconnect old bar above lower: + if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) + lower->mBarAbove.data()->mBarBelow = 0; + // disconnect old bar below upper: + if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) + upper->mBarBelow.data()->mBarAbove = 0; + lower->mBarAbove = upper; + upper->mBarBelow = lower; + } +} + +/* inherits documentation from base class */ +QCPRange QCPBars::getKeyRange(bool &foundRange, SignDomain inSignDomain) const +{ + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + + double current; + QCPBarDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().key; + if (inSignDomain == sdBoth || (inSignDomain == sdNegative && current < 0) || (inSignDomain == sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + // determine exact range of bars by including bar width and barsgroup offset: + if (haveLower && mKeyAxis) + { + double lowerPixelWidth, upperPixelWidth, keyPixel; + getPixelWidth(range.lower, lowerPixelWidth, upperPixelWidth); + keyPixel = mKeyAxis.data()->coordToPixel(range.lower) + lowerPixelWidth; + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, range.lower); + range.lower = mKeyAxis.data()->pixelToCoord(keyPixel); + } + if (haveUpper && mKeyAxis) + { + double lowerPixelWidth, upperPixelWidth, keyPixel; + getPixelWidth(range.upper, lowerPixelWidth, upperPixelWidth); + keyPixel = mKeyAxis.data()->coordToPixel(range.upper) + upperPixelWidth; + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, range.upper); + range.upper = mKeyAxis.data()->pixelToCoord(keyPixel); + } + foundRange = haveLower && haveUpper; + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPBars::getValueRange(bool &foundRange, SignDomain inSignDomain) const +{ + QCPRange range; + range.lower = mBaseValue; + range.upper = mBaseValue; + bool haveLower = true; // set to true, because baseValue should always be visible in bar charts + bool haveUpper = true; // set to true, because baseValue should always be visible in bar charts + double current; + + QCPBarDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().value + getStackedBaseValue(it.value().key, it.value().value >= 0); + if (inSignDomain == sdBoth || (inSignDomain == sdNegative && current < 0) || (inSignDomain == sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + + foundRange = true; // return true because bar charts always have the 0-line visible + return range; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPStatisticalBox +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPStatisticalBox + \brief A plottable representing a single statistical box in a plot. + + \image html QCPStatisticalBox.png + + To plot data, assign it with the individual parameter functions or use \ref setData to set all + parameters at once. The individual functions are: + \li \ref setMinimum + \li \ref setLowerQuartile + \li \ref setMedian + \li \ref setUpperQuartile + \li \ref setMaximum + + Additionally you can define a list of outliers, drawn as scatter datapoints: + \li \ref setOutliers + + \section appearance Changing the appearance + + The appearance of the box itself is controlled via \ref setPen and \ref setBrush. You may change + the width of the box with \ref setWidth in plot coordinates (not pixels). + + Analog functions exist for the minimum/maximum-whiskers: \ref setWhiskerPen, \ref + setWhiskerBarPen, \ref setWhiskerWidth. The whisker width is the width of the bar at the top + (maximum) and bottom (minimum). + + The median indicator line has its own pen, \ref setMedianPen. + + If the whisker backbone pen is changed, make sure to set the capStyle to Qt::FlatCap. Else, the + backbone line might exceed the whisker bars by a few pixels due to the pen cap being not + perfectly flat. + + The Outlier data points are drawn as normal scatter points. Their look can be controlled with + \ref setOutlierStyle + + \section usage Usage + + Like all data representing objects in QCustomPlot, the QCPStatisticalBox is a plottable. + Usually, you first create an instance and add it to the customPlot: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-1 + and then modify the properties of the newly created plottable, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-2 +*/ + +/*! + Constructs a statistical box which uses \a keyAxis as its key axis ("x") and \a valueAxis as its + value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and + not have the same orientation. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + The constructed statistical box can be added to the plot with QCustomPlot::addPlottable, + QCustomPlot then takes ownership of the statistical box. +*/ +QCPStatisticalBox::QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mKey(0), + mMinimum(0), + mLowerQuartile(0), + mMedian(0), + mUpperQuartile(0), + mMaximum(0) +{ + setOutlierStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, Qt::blue, 6)); + setWhiskerWidth(0.2); + setWidth(0.5); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2.5)); + setMedianPen(QPen(Qt::black, 3, Qt::SolidLine, Qt::FlatCap)); + setWhiskerPen(QPen(Qt::black, 0, Qt::DashLine, Qt::FlatCap)); + setWhiskerBarPen(QPen(Qt::black)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +/*! + Sets the key coordinate of the statistical box. +*/ +void QCPStatisticalBox::setKey(double key) +{ + mKey = key; +} + +/*! + Sets the parameter "minimum" of the statistical box plot. This is the position of the lower + whisker, typically the minimum measurement of the sample that's not considered an outlier. + + \see setMaximum, setWhiskerPen, setWhiskerBarPen, setWhiskerWidth +*/ +void QCPStatisticalBox::setMinimum(double value) +{ + mMinimum = value; +} + +/*! + Sets the parameter "lower Quartile" of the statistical box plot. This is the lower end of the + box. The lower and the upper quartiles are the two statistical quartiles around the median of the + sample, they contain 50% of the sample data. + + \see setUpperQuartile, setPen, setBrush, setWidth +*/ +void QCPStatisticalBox::setLowerQuartile(double value) +{ + mLowerQuartile = value; +} + +/*! + Sets the parameter "median" of the statistical box plot. This is the value of the median mark + inside the quartile box. The median separates the sample data in half (50% of the sample data is + below/above the median). + + \see setMedianPen +*/ +void QCPStatisticalBox::setMedian(double value) +{ + mMedian = value; +} + +/*! + Sets the parameter "upper Quartile" of the statistical box plot. This is the upper end of the + box. The lower and the upper quartiles are the two statistical quartiles around the median of the + sample, they contain 50% of the sample data. + + \see setLowerQuartile, setPen, setBrush, setWidth +*/ +void QCPStatisticalBox::setUpperQuartile(double value) +{ + mUpperQuartile = value; +} + +/*! + Sets the parameter "maximum" of the statistical box plot. This is the position of the upper + whisker, typically the maximum measurement of the sample that's not considered an outlier. + + \see setMinimum, setWhiskerPen, setWhiskerBarPen, setWhiskerWidth +*/ +void QCPStatisticalBox::setMaximum(double value) +{ + mMaximum = value; +} + +/*! + Sets a vector of outlier values that will be drawn as scatters. Any data points in the sample + that are not within the whiskers (\ref setMinimum, \ref setMaximum) should be considered outliers + and displayed as such. + + \see setOutlierStyle +*/ +void QCPStatisticalBox::setOutliers(const QVector &values) +{ + mOutliers = values; +} + +/*! + Sets all parameters of the statistical box plot at once. + + \see setKey, setMinimum, setLowerQuartile, setMedian, setUpperQuartile, setMaximum +*/ +void QCPStatisticalBox::setData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum) +{ + setKey(key); + setMinimum(minimum); + setLowerQuartile(lowerQuartile); + setMedian(median); + setUpperQuartile(upperQuartile); + setMaximum(maximum); +} + +/*! + Sets the width of the box in key coordinates. + + \see setWhiskerWidth +*/ +void QCPStatisticalBox::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets the width of the whiskers (\ref setMinimum, \ref setMaximum) in key coordinates. + + \see setWidth +*/ +void QCPStatisticalBox::setWhiskerWidth(double width) +{ + mWhiskerWidth = width; +} + +/*! + Sets the pen used for drawing the whisker backbone (That's the line parallel to the value axis). + + Make sure to set the \a pen capStyle to Qt::FlatCap to prevent the whisker backbone from reaching + a few pixels past the whisker bars, when using a non-zero pen width. + + \see setWhiskerBarPen +*/ +void QCPStatisticalBox::setWhiskerPen(const QPen &pen) +{ + mWhiskerPen = pen; +} + +/*! + Sets the pen used for drawing the whisker bars (Those are the lines parallel to the key axis at + each end of the whisker backbone). + + \see setWhiskerPen +*/ +void QCPStatisticalBox::setWhiskerBarPen(const QPen &pen) +{ + mWhiskerBarPen = pen; +} + +/*! + Sets the pen used for drawing the median indicator line inside the statistical box. +*/ +void QCPStatisticalBox::setMedianPen(const QPen &pen) +{ + mMedianPen = pen; +} + +/*! + Sets the appearance of the outlier data points. + + \see setOutliers +*/ +void QCPStatisticalBox::setOutlierStyle(const QCPScatterStyle &style) +{ + mOutlierStyle = style; +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::clearData() +{ + setOutliers(QVector()); + setKey(0); + setMinimum(0); + setLowerQuartile(0); + setMedian(0); + setUpperQuartile(0); + setMaximum(0); +} + +/* inherits documentation from base class */ +double QCPStatisticalBox::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + // quartile box: + QCPRange keyRange(mKey-mWidth*0.5, mKey+mWidth*0.5); + QCPRange valueRange(mLowerQuartile, mUpperQuartile); + if (keyRange.contains(posKey) && valueRange.contains(posValue)) + return mParentPlot->selectionTolerance()*0.99; + + // min/max whiskers: + if (QCPRange(mMinimum, mMaximum).contains(posValue)) + return qAbs(mKeyAxis.data()->coordToPixel(mKey)-mKeyAxis.data()->coordToPixel(posKey)); + } + return -1; +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::draw(QCPPainter *painter) +{ + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + if (QCP::isInvalidData(mKey, mMedian) || + QCP::isInvalidData(mLowerQuartile, mUpperQuartile) || + QCP::isInvalidData(mMinimum, mMaximum)) + qDebug() << Q_FUNC_INFO << "Data point at" << mKey << "of drawn range has invalid data." << "Plottable name:" << name(); + for (int i=0; isave(); + painter->setClipRect(quartileBox, Qt::IntersectClip); + drawMedian(painter); + painter->restore(); + + drawWhiskers(painter); + drawOutliers(painter); +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw filled rect: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->setBrush(mBrush); + QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); + r.moveCenter(rect.center()); + painter->drawRect(r); +} + +/*! \internal + + Draws the quartile box. \a box is an output parameter that returns the quartile box (in pixel + coordinates) which is used to set the clip rect of the painter before calling \ref drawMedian (so + the median doesn't draw outside the quartile box). +*/ +void QCPStatisticalBox::drawQuartileBox(QCPPainter *painter, QRectF *quartileBox) const +{ + QRectF box; + box.setTopLeft(coordsToPixels(mKey-mWidth*0.5, mUpperQuartile)); + box.setBottomRight(coordsToPixels(mKey+mWidth*0.5, mLowerQuartile)); + applyDefaultAntialiasingHint(painter); + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(box); + if (quartileBox) + *quartileBox = box; +} + +/*! \internal + + Draws the median line inside the quartile box. +*/ +void QCPStatisticalBox::drawMedian(QCPPainter *painter) const +{ + QLineF medianLine; + medianLine.setP1(coordsToPixels(mKey-mWidth*0.5, mMedian)); + medianLine.setP2(coordsToPixels(mKey+mWidth*0.5, mMedian)); + applyDefaultAntialiasingHint(painter); + painter->setPen(mMedianPen); + painter->drawLine(medianLine); +} + +/*! \internal + + Draws both whisker backbones and bars. +*/ +void QCPStatisticalBox::drawWhiskers(QCPPainter *painter) const +{ + QLineF backboneMin, backboneMax, barMin, barMax; + backboneMax.setPoints(coordsToPixels(mKey, mUpperQuartile), coordsToPixels(mKey, mMaximum)); + backboneMin.setPoints(coordsToPixels(mKey, mLowerQuartile), coordsToPixels(mKey, mMinimum)); + barMax.setPoints(coordsToPixels(mKey-mWhiskerWidth*0.5, mMaximum), coordsToPixels(mKey+mWhiskerWidth*0.5, mMaximum)); + barMin.setPoints(coordsToPixels(mKey-mWhiskerWidth*0.5, mMinimum), coordsToPixels(mKey+mWhiskerWidth*0.5, mMinimum)); + applyErrorBarsAntialiasingHint(painter); + painter->setPen(mWhiskerPen); + painter->drawLine(backboneMin); + painter->drawLine(backboneMax); + painter->setPen(mWhiskerBarPen); + painter->drawLine(barMin); + painter->drawLine(barMax); +} + +/*! \internal + + Draws the outlier scatter points. +*/ +void QCPStatisticalBox::drawOutliers(QCPPainter *painter) const +{ + applyScattersAntialiasingHint(painter); + mOutlierStyle.applyTo(painter, mPen); + for (int i=0; i 0) + return QCPRange(mKey-mWidth*0.5, mKey+mWidth*0.5); + else if (mKey > 0) + return QCPRange(mKey, mKey+mWidth*0.5); + else + { + foundRange = false; + return QCPRange(); + } + } + foundRange = false; + return QCPRange(); +} + +/* inherits documentation from base class */ +QCPRange QCPStatisticalBox::getValueRange(bool &foundRange, SignDomain inSignDomain) const +{ + QVector values; // values that must be considered (i.e. all outliers and the five box-parameters) + values.reserve(mOutliers.size() + 5); + values << mMaximum << mUpperQuartile << mMedian << mLowerQuartile << mMinimum; + values << mOutliers; + // go through values and find the ones in legal range: + bool haveUpper = false; + bool haveLower = false; + double upper = 0; + double lower = 0; + for (int i=0; i 0) || + (inSignDomain == sdBoth)) + { + if (values.at(i) > upper || !haveUpper) + { + upper = values.at(i); + haveUpper = true; + } + if (values.at(i) < lower || !haveLower) + { + lower = values.at(i); + haveLower = true; + } + } + } + // return the bounds if we found some sensible values: + if (haveLower && haveUpper) + { + foundRange = true; + return QCPRange(lower, upper); + } else // might happen if all values are in other sign domain + { + foundRange = false; + return QCPRange(); + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorMapData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorMapData + \brief Holds the two-dimensional data of a QCPColorMap plottable. + + This class is a data storage for \ref QCPColorMap. It holds a two-dimensional array, which \ref + QCPColorMap then displays as a 2D image in the plot, where the array values are represented by a + color, depending on the value. + + The size of the array can be controlled via \ref setSize (or \ref setKeySize, \ref setValueSize). + Which plot coordinates these cells correspond to can be configured with \ref setRange (or \ref + setKeyRange, \ref setValueRange). + + The data cells can be accessed in two ways: They can be directly addressed by an integer index + with \ref setCell. This is the fastest method. Alternatively, they can be addressed by their plot + coordinate with \ref setData. plot coordinate to cell index transformations and vice versa are + provided by the functions \ref coordToCell and \ref cellToCoord. + + This class also buffers the minimum and maximum values that are in the data set, to provide + QCPColorMap::rescaleDataRange with the necessary information quickly. Setting a cell to a value + that is greater than the current maximum increases this maximum to the new value. However, + setting the cell that currently holds the maximum value to a smaller value doesn't decrease the + maximum again, because finding the true new maximum would require going through the entire data + array, which might be time consuming. The same holds for the data minimum. This functionality is + given by \ref recalculateDataBounds, such that you can decide when it is sensible to find the + true current minimum and maximum. The method QCPColorMap::rescaleDataRange offers a convenience + parameter \a recalculateDataBounds which may be set to true to automatically call \ref + recalculateDataBounds internally. +*/ + +/* start of documentation of inline functions */ + +/*! \fn bool QCPColorMapData::isEmpty() const + + Returns whether this instance carries no data. This is equivalent to having a size where at least + one of the dimensions is 0 (see \ref setSize). +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a new QCPColorMapData instance. The instance has \a keySize cells in the key direction + and \a valueSize cells in the value direction. These cells will be displayed by the \ref QCPColorMap + at the coordinates \a keyRange and \a valueRange. + + \see setSize, setKeySize, setValueSize, setRange, setKeyRange, setValueRange +*/ +QCPColorMapData::QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange) : + mKeySize(0), + mValueSize(0), + mKeyRange(keyRange), + mValueRange(valueRange), + mIsEmpty(true), + mData(0), + mDataModified(true) +{ + setSize(keySize, valueSize); + fill(0); +} + +QCPColorMapData::~QCPColorMapData() +{ + if (mData) + delete[] mData; +} + +/*! + Constructs a new QCPColorMapData instance copying the data and range of \a other. +*/ +QCPColorMapData::QCPColorMapData(const QCPColorMapData &other) : + mKeySize(0), + mValueSize(0), + mIsEmpty(true), + mData(0), + mDataModified(true) +{ + *this = other; +} + +/*! + Overwrites this color map data instance with the data stored in \a other. +*/ +QCPColorMapData &QCPColorMapData::operator=(const QCPColorMapData &other) +{ + if (&other != this) + { + const int keySize = other.keySize(); + const int valueSize = other.valueSize(); + setSize(keySize, valueSize); + setRange(other.keyRange(), other.valueRange()); + if (!mIsEmpty) + memcpy(mData, other.mData, sizeof(mData[0])*keySize*valueSize); + mDataBounds = other.mDataBounds; + mDataModified = true; + } + return *this; +} + +/* undocumented getter */ +double QCPColorMapData::data(double key, double value) +{ + int keyCell = (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5; + int valueCell = (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5; + if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) + return mData[valueCell*mKeySize + keyCell]; + else + return 0; +} + +/* undocumented getter */ +double QCPColorMapData::cell(int keyIndex, int valueIndex) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + return mData[valueIndex*mKeySize + keyIndex]; + else + return 0; +} + +/*! + Resizes the data array to have \a keySize cells in the key dimension and \a valueSize cells in + the value dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting at least one of \a keySize or \a valueSize to zero frees the internal data array and \ref + isEmpty returns true. + + \see setRange, setKeySize, setValueSize +*/ +void QCPColorMapData::setSize(int keySize, int valueSize) +{ + if (keySize != mKeySize || valueSize != mValueSize) + { + mKeySize = keySize; + mValueSize = valueSize; + if (mData) + delete[] mData; + mIsEmpty = mKeySize == 0 || mValueSize == 0; + if (!mIsEmpty) + { +#ifdef __EXCEPTIONS + try { // 2D arrays get memory intensive fast. So if the allocation fails, at least output debug message +#endif + mData = new double[mKeySize*mValueSize]; +#ifdef __EXCEPTIONS + } catch (...) { mData = 0; } +#endif + if (mData) + fill(0); + else + qDebug() << Q_FUNC_INFO << "out of memory for data dimensions "<< mKeySize << "*" << mValueSize; + } else + mData = 0; + mDataModified = true; + } +} + +/*! + Resizes the data array to have \a keySize cells in the key dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting \a keySize to zero frees the internal data array and \ref isEmpty returns true. + + \see setKeyRange, setSize, setValueSize +*/ +void QCPColorMapData::setKeySize(int keySize) +{ + setSize(keySize, mValueSize); +} + +/*! + Resizes the data array to have \a valueSize cells in the value dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting \a valueSize to zero frees the internal data array and \ref isEmpty returns true. + + \see setValueRange, setSize, setKeySize +*/ +void QCPColorMapData::setValueSize(int valueSize) +{ + setSize(mKeySize, valueSize); +} + +/*! + Sets the coordinate ranges the data shall be distributed over. This defines the rectangular area + covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will + be cells centered on the key coordinates 2, 2.5 and 3. + + \see setSize +*/ +void QCPColorMapData::setRange(const QCPRange &keyRange, const QCPRange &valueRange) +{ + setKeyRange(keyRange); + setValueRange(valueRange); +} + +/*! + Sets the coordinate range the data shall be distributed over in the key dimension. Together with + the value range, This defines the rectangular area covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will + be cells centered on the key coordinates 2, 2.5 and 3. + + \see setRange, setValueRange, setSize +*/ +void QCPColorMapData::setKeyRange(const QCPRange &keyRange) +{ + mKeyRange = keyRange; +} + +/*! + Sets the coordinate range the data shall be distributed over in the value dimension. Together with + the key range, This defines the rectangular area covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the value size (\ref setValueSize) is 3 and \a valueRange is set to QCPRange(2, 3) there + will be cells centered on the value coordinates 2, 2.5 and 3. + + \see setRange, setKeyRange, setSize +*/ +void QCPColorMapData::setValueRange(const QCPRange &valueRange) +{ + mValueRange = valueRange; +} + +/*! + Sets the data of the cell, which lies at the plot coordinates given by \a key and \a value, to \a + z. + + \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or + value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes, + you shouldn't use the \ref QCPColorMapData::setData method as it uses a linear transformation to + determine the cell index. Rather directly access the cell index with \ref + QCPColorMapData::setCell. + + \see setCell, setRange +*/ +void QCPColorMapData::setData(double key, double value, double z) +{ + int keyCell = (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5; + int valueCell = (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5; + if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) + { + mData[valueCell*mKeySize + keyCell] = z; + if (z < mDataBounds.lower) + mDataBounds.lower = z; + if (z > mDataBounds.upper) + mDataBounds.upper = z; + mDataModified = true; + } +} + +/*! + Sets the data of the cell with indices \a keyIndex and \a valueIndex to \a z. The indices + enumerate the cells starting from zero, up to the map's size-1 in the respective dimension (see + \ref setSize). + + In the standard plot configuration (horizontal key axis and vertical value axis, both not + range-reversed), the cell with indices (0, 0) is in the bottom left corner and the cell with + indices (keySize-1, valueSize-1) is in the top right corner of the color map. + + \see setData, setSize +*/ +void QCPColorMapData::setCell(int keyIndex, int valueIndex, double z) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + { + mData[valueIndex*mKeySize + keyIndex] = z; + if (z < mDataBounds.lower) + mDataBounds.lower = z; + if (z > mDataBounds.upper) + mDataBounds.upper = z; + mDataModified = true; + } +} + +/*! + Goes through the data and updates the buffered minimum and maximum data values. + + Calling this method is only advised if you are about to call \ref QCPColorMap::rescaleDataRange + and can not guarantee that the cells holding the maximum or minimum data haven't been overwritten + with a smaller or larger value respectively, since the buffered maximum/minimum values have been + updated the last time. Why this is the case is explained in the class description (\ref + QCPColorMapData). + + Note that the method \ref QCPColorMap::rescaleDataRange provides a parameter \a + recalculateDataBounds for convenience. Setting this to true will call this method for you, before + doing the rescale. +*/ +void QCPColorMapData::recalculateDataBounds() +{ + if (mKeySize > 0 && mValueSize > 0) + { + double minHeight = mData[0]; + double maxHeight = mData[0]; + const int dataCount = mValueSize*mKeySize; + for (int i=0; i maxHeight) + maxHeight = mData[i]; + if (mData[i] < minHeight) + minHeight = mData[i]; + } + mDataBounds.lower = minHeight; + mDataBounds.upper = maxHeight; + } +} + +/*! + Frees the internal data memory. + + This is equivalent to calling \ref setSize "setSize(0, 0)". +*/ +void QCPColorMapData::clear() +{ + setSize(0, 0); +} + +/*! + Sets all cells to the value \a z. +*/ +void QCPColorMapData::fill(double z) +{ + const int dataCount = mValueSize*mKeySize; + for (int i=0; i(data); + return; + } + if (copy) + { + *mMapData = *data; + } else + { + delete mMapData; + mMapData = data; + } + mMapImageInvalidated = true; +} + +/*! + Sets the data range of this color map to \a dataRange. The data range defines which data values + are mapped to the color gradient. + + To make the data range span the full range of the data set, use \ref rescaleDataRange. + + \see QCPColorScale::setDataRange +*/ +void QCPColorMap::setDataRange(const QCPRange &dataRange) +{ + if (!QCPRange::validRange(dataRange)) return; + if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) + { + if (mDataScaleType == QCPAxis::stLogarithmic) + mDataRange = dataRange.sanitizedForLogScale(); + else + mDataRange = dataRange.sanitizedForLinScale(); + mMapImageInvalidated = true; + emit dataRangeChanged(mDataRange); + } +} + +/*! + Sets whether the data is correlated with the color gradient linearly or logarithmically. + + \see QCPColorScale::setDataScaleType +*/ +void QCPColorMap::setDataScaleType(QCPAxis::ScaleType scaleType) +{ + if (mDataScaleType != scaleType) + { + mDataScaleType = scaleType; + mMapImageInvalidated = true; + emit dataScaleTypeChanged(mDataScaleType); + if (mDataScaleType == QCPAxis::stLogarithmic) + setDataRange(mDataRange.sanitizedForLogScale()); + } +} + +/*! + Sets the color gradient that is used to represent the data. For more details on how to create an + own gradient or use one of the preset gradients, see \ref QCPColorGradient. + + The colors defined by the gradient will be used to represent data values in the currently set + data range, see \ref setDataRange. Data points that are outside this data range will either be + colored uniformly with the respective gradient boundary color, or the gradient will repeat, + depending on \ref QCPColorGradient::setPeriodic. + + \see QCPColorScale::setGradient +*/ +void QCPColorMap::setGradient(const QCPColorGradient &gradient) +{ + if (mGradient != gradient) + { + mGradient = gradient; + mMapImageInvalidated = true; + emit gradientChanged(mGradient); + } +} + +/*! + Sets whether the color map image shall use bicubic interpolation when displaying the color map + shrinked or expanded, and not at a 1:1 pixel-to-data scale. + + \image html QCPColorMap-interpolate.png "A 10*10 color map, with interpolation and without interpolation enabled" +*/ +void QCPColorMap::setInterpolate(bool enabled) +{ + mInterpolate = enabled; + mMapImageInvalidated = true; // because oversampling factors might need to change +} + +/*! + Sets whether the outer most data rows and columns are clipped to the specified key and value + range (see \ref QCPColorMapData::setKeyRange, \ref QCPColorMapData::setValueRange). + + if \a enabled is set to false, the data points at the border of the color map are drawn with the + same width and height as all other data points. Since the data points are represented by + rectangles of one color centered on the data coordinate, this means that the shown color map + extends by half a data point over the specified key/value range in each direction. + + \image html QCPColorMap-tightboundary.png "A color map, with tight boundary enabled and disabled" +*/ +void QCPColorMap::setTightBoundary(bool enabled) +{ + mTightBoundary = enabled; +} + +/*! + Associates the color scale \a colorScale with this color map. + + This means that both the color scale and the color map synchronize their gradient, data range and + data scale type (\ref setGradient, \ref setDataRange, \ref setDataScaleType). Multiple color maps + can be associated with one single color scale. This causes the color maps to also synchronize + those properties, via the mutual color scale. + + This function causes the color map to adopt the current color gradient, data range and data scale + type of \a colorScale. After this call, you may change these properties at either the color map + or the color scale, and the setting will be applied to both. + + Pass 0 as \a colorScale to disconnect the color scale from this color map again. +*/ +void QCPColorMap::setColorScale(QCPColorScale *colorScale) +{ + if (mColorScale) // unconnect signals from old color scale + { + disconnect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); + disconnect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); + disconnect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); + disconnect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + disconnect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); + disconnect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } + mColorScale = colorScale; + if (mColorScale) // connect signals to new color scale + { + setGradient(mColorScale.data()->gradient()); + setDataRange(mColorScale.data()->dataRange()); + setDataScaleType(mColorScale.data()->dataScaleType()); + connect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); + connect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); + connect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); + connect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + connect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); + connect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } +} + +/*! + Sets the data range (\ref setDataRange) to span the minimum and maximum values that occur in the + current data set. This corresponds to the \ref rescaleKeyAxis or \ref rescaleValueAxis methods, + only for the third data dimension of the color map. + + The minimum and maximum values of the data set are buffered in the internal QCPColorMapData + instance (\ref data). As data is updated via its \ref QCPColorMapData::setCell or \ref + QCPColorMapData::setData, the buffered minimum and maximum values are updated, too. For + performance reasons, however, they are only updated in an expanding fashion. So the buffered + maximum can only increase and the buffered minimum can only decrease. In consequence, changes to + the data that actually lower the maximum of the data set (by overwriting the cell holding the + current maximum with a smaller value), aren't recognized and the buffered maximum overestimates + the true maximum of the data set. The same happens for the buffered minimum. To recalculate the + true minimum and maximum by explicitly looking at each cell, the method + QCPColorMapData::recalculateDataBounds can be used. For convenience, setting the parameter \a + recalculateDataBounds calls this method before setting the data range to the buffered minimum and + maximum. + + \see setDataRange +*/ +void QCPColorMap::rescaleDataRange(bool recalculateDataBounds) +{ + if (recalculateDataBounds) + mMapData->recalculateDataBounds(); + setDataRange(mMapData->dataBounds()); +} + +/*! + Takes the current appearance of the color map and updates the legend icon, which is used to + represent this color map in the legend (see \ref QCPLegend). + + The \a transformMode specifies whether the rescaling is done by a faster, low quality image + scaling algorithm (Qt::FastTransformation) or by a slower, higher quality algorithm + (Qt::SmoothTransformation). + + The current color map appearance is scaled down to \a thumbSize. Ideally, this should be equal to + the size of the legend icon (see \ref QCPLegend::setIconSize). If it isn't exactly the configured + legend icon size, the thumb will be rescaled during drawing of the legend item. + + \see setDataRange +*/ +void QCPColorMap::updateLegendIcon(Qt::TransformationMode transformMode, const QSize &thumbSize) +{ + if (mMapImage.isNull() && !data()->isEmpty()) + updateMapImage(); // try to update map image if it's null (happens if no draw has happened yet) + + if (!mMapImage.isNull()) // might still be null, e.g. if data is empty, so check here again + { + bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); + bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); + mLegendIcon = QPixmap::fromImage(mMapImage.mirrored(mirrorX, mirrorY)).scaled(thumbSize, Qt::KeepAspectRatio, transformMode); + } +} + +/*! + Clears the colormap data by calling \ref QCPColorMapData::clear() on the internal data. This also + resizes the map to 0x0 cells. +*/ +void QCPColorMap::clearData() +{ + mMapData->clear(); +} + +/* inherits documentation from base class */ +double QCPColorMap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (mMapData->keyRange().contains(posKey) && mMapData->valueRange().contains(posValue)) + return mParentPlot->selectionTolerance()*0.99; + } + return -1; +} + +/*! \internal + + Updates the internal map image buffer by going through the internal \ref QCPColorMapData and + turning the data values into color pixels with \ref QCPColorGradient::colorize. + + This method is called by \ref QCPColorMap::draw if either the data has been modified or the map image + has been invalidated for a different reason (e.g. a change of the data range with \ref + setDataRange). + + If the map cell count is low, the image created will be oversampled in order to avoid a + QPainter::drawImage bug which makes inner pixel boundaries jitter when stretch-drawing images + without smooth transform enabled. Accordingly, oversampling isn't performed if \ref + setInterpolate is true. +*/ +void QCPColorMap::updateMapImage() +{ + QCPAxis *keyAxis = mKeyAxis.data(); + if (!keyAxis) return; + if (mMapData->isEmpty()) return; + + const int keySize = mMapData->keySize(); + const int valueSize = mMapData->valueSize(); + int keyOversamplingFactor = mInterpolate ? 1 : (int)(1.0+100.0/(double)keySize); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on + int valueOversamplingFactor = mInterpolate ? 1 : (int)(1.0+100.0/(double)valueSize); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on + + // resize mMapImage to correct dimensions including possible oversampling factors, according to key/value axes orientation: + if (keyAxis->orientation() == Qt::Horizontal && (mMapImage.width() != keySize*keyOversamplingFactor || mMapImage.height() != valueSize*valueOversamplingFactor)) + mMapImage = QImage(QSize(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor), QImage::Format_RGB32); + else if (keyAxis->orientation() == Qt::Vertical && (mMapImage.width() != valueSize*valueOversamplingFactor || mMapImage.height() != keySize*keyOversamplingFactor)) + mMapImage = QImage(QSize(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor), QImage::Format_RGB32); + + QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates. Either the final mMapImage, or if we need oversampling, mUndersampledMapImage + if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) + { + // resize undersampled map image to actual key/value cell sizes: + if (keyAxis->orientation() == Qt::Horizontal && (mUndersampledMapImage.width() != keySize || mUndersampledMapImage.height() != valueSize)) + mUndersampledMapImage = QImage(QSize(keySize, valueSize), QImage::Format_RGB32); + else if (keyAxis->orientation() == Qt::Vertical && (mUndersampledMapImage.width() != valueSize || mUndersampledMapImage.height() != keySize)) + mUndersampledMapImage = QImage(QSize(valueSize, keySize), QImage::Format_RGB32); + localMapImage = &mUndersampledMapImage; // make the colorization run on the undersampled image + } else if (!mUndersampledMapImage.isNull()) + mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size has changed) but mUndersampledMapImage still has nonzero size, free it + + const double *rawData = mMapData->mData; + if (keyAxis->orientation() == Qt::Horizontal) + { + const int lineCount = valueSize; + const int rowCount = keySize; + for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) + mGradient.colorize(rawData+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); + } + } else // keyAxis->orientation() == Qt::Vertical + { + const int lineCount = keySize; + const int rowCount = valueSize; + for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) + mGradient.colorize(rawData+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); + } + } + + if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) + { + if (keyAxis->orientation() == Qt::Horizontal) + mMapImage = mUndersampledMapImage.scaled(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); + else + mMapImage = mUndersampledMapImage.scaled(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); + } + mMapData->mDataModified = false; + mMapImageInvalidated = false; +} + +/* inherits documentation from base class */ +void QCPColorMap::draw(QCPPainter *painter) +{ + if (mMapData->isEmpty()) return; + if (!mKeyAxis || !mValueAxis) return; + applyDefaultAntialiasingHint(painter); + + if (mMapData->mDataModified || mMapImageInvalidated) + updateMapImage(); + + // use buffer if painting vectorized (PDF): + bool useBuffer = painter->modes().testFlag(QCPPainter::pmVectorized); + QCPPainter *localPainter = painter; // will be redirected to paint on mapBuffer if painting vectorized + QRectF mapBufferTarget; // the rect in absolute widget coordinates where the visible map portion/buffer will end up in + QPixmap mapBuffer; + double mapBufferPixelRatio = 3; // factor by which DPI is increased in embedded bitmaps + if (useBuffer) + { + mapBufferTarget = painter->clipRegion().boundingRect(); + mapBuffer = QPixmap((mapBufferTarget.size()*mapBufferPixelRatio).toSize()); + mapBuffer.fill(Qt::transparent); + localPainter = new QCPPainter(&mapBuffer); + localPainter->scale(mapBufferPixelRatio, mapBufferPixelRatio); + localPainter->translate(-mapBufferTarget.topLeft()); + } + + QRectF imageRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), + coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); + // extend imageRect to contain outer halves/quarters of bordering/cornering pixels (cells are centered on map range boundary): + double halfCellWidth = 0; // in pixels + double halfCellHeight = 0; // in pixels + if (keyAxis()->orientation() == Qt::Horizontal) + { + if (mMapData->keySize() > 1) + halfCellWidth = 0.5*imageRect.width()/(double)(mMapData->keySize()-1); + if (mMapData->valueSize() > 1) + halfCellHeight = 0.5*imageRect.height()/(double)(mMapData->valueSize()-1); + } else // keyAxis orientation is Qt::Vertical + { + if (mMapData->keySize() > 1) + halfCellHeight = 0.5*imageRect.height()/(double)(mMapData->keySize()-1); + if (mMapData->valueSize() > 1) + halfCellWidth = 0.5*imageRect.width()/(double)(mMapData->valueSize()-1); + } + imageRect.adjust(-halfCellWidth, -halfCellHeight, halfCellWidth, halfCellHeight); + bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); + bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); + bool smoothBackup = localPainter->renderHints().testFlag(QPainter::SmoothPixmapTransform); + localPainter->setRenderHint(QPainter::SmoothPixmapTransform, mInterpolate); + QRegion clipBackup; + if (mTightBoundary) + { + clipBackup = localPainter->clipRegion(); + QRectF tightClipRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), + coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); + localPainter->setClipRect(tightClipRect, Qt::IntersectClip); + } + localPainter->drawImage(imageRect, mMapImage.mirrored(mirrorX, mirrorY)); + if (mTightBoundary) + localPainter->setClipRegion(clipBackup); + localPainter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup); + + if (useBuffer) // localPainter painted to mapBuffer, so now draw buffer with original painter + { + delete localPainter; + painter->drawPixmap(mapBufferTarget.toRect(), mapBuffer); + } +} + +/* inherits documentation from base class */ +void QCPColorMap::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + applyDefaultAntialiasingHint(painter); + // draw map thumbnail: + if (!mLegendIcon.isNull()) + { + QPixmap scaledIcon = mLegendIcon.scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::FastTransformation); + QRectF iconRect = QRectF(0, 0, scaledIcon.width(), scaledIcon.height()); + iconRect.moveCenter(rect.center()); + painter->drawPixmap(iconRect.topLeft(), scaledIcon); + } + /* + // draw frame: + painter->setBrush(Qt::NoBrush); + painter->setPen(Qt::black); + painter->drawRect(rect.adjusted(1, 1, 0, 0)); + */ +} + +/* inherits documentation from base class */ +QCPRange QCPColorMap::getKeyRange(bool &foundRange, SignDomain inSignDomain) const +{ + foundRange = true; + QCPRange result = mMapData->keyRange(); + result.normalize(); + if (inSignDomain == QCPAbstractPlottable::sdPositive) + { + if (result.lower <= 0 && result.upper > 0) + result.lower = result.upper*1e-3; + else if (result.lower <= 0 && result.upper <= 0) + foundRange = false; + } else if (inSignDomain == QCPAbstractPlottable::sdNegative) + { + if (result.upper >= 0 && result.lower < 0) + result.upper = result.lower*1e-3; + else if (result.upper >= 0 && result.lower >= 0) + foundRange = false; + } + return result; +} + +/* inherits documentation from base class */ +QCPRange QCPColorMap::getValueRange(bool &foundRange, SignDomain inSignDomain) const +{ + foundRange = true; + QCPRange result = mMapData->valueRange(); + result.normalize(); + if (inSignDomain == QCPAbstractPlottable::sdPositive) + { + if (result.lower <= 0 && result.upper > 0) + result.lower = result.upper*1e-3; + else if (result.lower <= 0 && result.upper <= 0) + foundRange = false; + } else if (inSignDomain == QCPAbstractPlottable::sdNegative) + { + if (result.upper >= 0 && result.lower < 0) + result.upper = result.lower*1e-3; + else if (result.upper >= 0 && result.lower >= 0) + foundRange = false; + } + return result; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPFinancialData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPFinancialData + \brief Holds the data of one single data point for QCPFinancial. + + The container for storing multiple data points is \ref QCPFinancialDataMap. + + The stored data is: + \li \a key: coordinate on the key axis of this data point + \li \a open: The opening value at the data point + \li \a high: The high/maximum value at the data point + \li \a low: The low/minimum value at the data point + \li \a close: The closing value at the data point + + \see QCPFinancialDataMap +*/ + +/*! + Constructs a data point with key and all values set to zero. +*/ +QCPFinancialData::QCPFinancialData() : + key(0), + open(0), + high(0), + low(0), + close(0) +{ +} + +/*! + Constructs a data point with the specified \a key and OHLC values. +*/ +QCPFinancialData::QCPFinancialData(double key, double open, double high, double low, double close) : + key(key), + open(open), + high(high), + low(low), + close(close) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPFinancial +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPFinancial + \brief A plottable representing a financial stock chart + + \image html QCPFinancial.png + + This plottable represents time series data binned to certain intervals, mainly used for stock + charts. The two common representations OHLC (Open-High-Low-Close) bars and Candlesticks can be + set via \ref setChartStyle. + + The data is passed via \ref setData as a set of open/high/low/close values at certain keys + (typically times). This means the data must be already binned appropriately. If data is only + available as a series of values (e.g. \a price against \a time), you can use the static + convenience function \ref timeSeriesToOhlc to generate binned OHLC-data which can then be passed + to \ref setData. + + The width of the OHLC bars/candlesticks can be controlled with \ref setWidth and is given in plot + key coordinates. A typical choice is to set it to (or slightly less than) one bin interval width. + + \section appearance Changing the appearance + + Charts can be either single- or two-colored (\ref setTwoColored). If set to be single-colored, + lines are drawn with the plottable's pen (\ref setPen) and fills with the brush (\ref setBrush). + + If set to two-colored, positive changes of the value during an interval (\a close >= \a open) are + represented with a different pen and brush than negative changes (\a close < \a open). These can + be configured with \ref setPenPositive, \ref setPenNegative, \ref setBrushPositive, and \ref + setBrushNegative. In two-colored mode, the normal plottable pen/brush is ignored. Upon selection + however, the normal selected pen/brush (\ref setSelectedPen, \ref setSelectedBrush) is used, + irrespective of whether the chart is single- or two-colored. + +*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPFinancialDataMap *QCPFinancial::data() const + + Returns a pointer to the internal data storage of type \ref QCPFinancialDataMap. You may use it to + directly manipulate the data, which may be more convenient and faster than using the regular \ref + setData or \ref addData methods, in certain situations. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a financial chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The constructed QCPFinancial can be added to the plot with QCustomPlot::addPlottable, QCustomPlot + then takes ownership of the financial chart. +*/ +QCPFinancial::QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mData(0), + mChartStyle(csOhlc), + mWidth(0.5), + mTwoColored(false), + mBrushPositive(QBrush(QColor(210, 210, 255))), + mBrushNegative(QBrush(QColor(255, 210, 210))), + mPenPositive(QPen(QColor(10, 40, 180))), + mPenNegative(QPen(QColor(180, 40, 10))) +{ + mData = new QCPFinancialDataMap; + + setSelectedPen(QPen(QColor(80, 80, 255), 2.5)); + setSelectedBrush(QBrush(QColor(80, 80, 255))); +} + +QCPFinancial::~QCPFinancial() +{ + delete mData; +} + +/*! + Replaces the current data with the provided \a data. + + If \a copy is set to true, data points in \a data will only be copied. if false, the plottable + takes ownership of the passed data and replaces the internal data pointer with it. This is + significantly faster than copying for large datasets. + + Alternatively, you can also access and modify the plottable's data via the \ref data method, which + returns a pointer to the internal \ref QCPFinancialDataMap. + + \see timeSeriesToOhlc +*/ +void QCPFinancial::setData(QCPFinancialDataMap *data, bool copy) +{ + if (mData == data) + { + qDebug() << Q_FUNC_INFO << "The data pointer is already in (and owned by) this plottable" << reinterpret_cast(data); + return; + } + if (copy) + { + *mData = *data; + } else + { + delete mData; + mData = data; + } +} + +/*! \overload + + Replaces the current data with the provided open/high/low/close data. The provided vectors should + have equal length. Else, the number of added points will be the size of the smallest vector. + + \see timeSeriesToOhlc +*/ +void QCPFinancial::setData(const QVector &key, const QVector &open, const QVector &high, const QVector &low, const QVector &close) +{ + mData->clear(); + int n = key.size(); + n = qMin(n, open.size()); + n = qMin(n, high.size()); + n = qMin(n, low.size()); + n = qMin(n, close.size()); + for (int i=0; iinsertMulti(key[i], QCPFinancialData(key[i], open[i], high[i], low[i], close[i])); + } +} + +/*! + Sets which representation style shall be used to display the OHLC data. +*/ +void QCPFinancial::setChartStyle(QCPFinancial::ChartStyle style) +{ + mChartStyle = style; +} + +/*! + Sets the width of the individual bars/candlesticks to \a width in plot key coordinates. + + A typical choice is to set it to (or slightly less than) one bin interval width. +*/ +void QCPFinancial::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets whether this chart shall contrast positive from negative trends per data point by using two + separate colors to draw the respective bars/candlesticks. + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenPositive, setPenNegative, setBrushPositive, setBrushNegative +*/ +void QCPFinancial::setTwoColored(bool twoColored) +{ + mTwoColored = twoColored; +} + +/*! + If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills + of data points with a positive trend (i.e. bars/candlesticks with close >= open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setBrushNegative, setPenPositive, setPenNegative +*/ +void QCPFinancial::setBrushPositive(const QBrush &brush) +{ + mBrushPositive = brush; +} + +/*! + If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills + of data points with a negative trend (i.e. bars/candlesticks with close < open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setBrushPositive, setPenNegative, setPenPositive +*/ +void QCPFinancial::setBrushNegative(const QBrush &brush) +{ + mBrushNegative = brush; +} + +/*! + If \ref setTwoColored is set to true, this function controls the pen that is used to draw + outlines of data points with a positive trend (i.e. bars/candlesticks with close >= open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenNegative, setBrushPositive, setBrushNegative +*/ +void QCPFinancial::setPenPositive(const QPen &pen) +{ + mPenPositive = pen; +} + +/*! + If \ref setTwoColored is set to true, this function controls the pen that is used to draw + outlines of data points with a negative trend (i.e. bars/candlesticks with close < open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenPositive, setBrushNegative, setBrushPositive +*/ +void QCPFinancial::setPenNegative(const QPen &pen) +{ + mPenNegative = pen; +} + +/*! + Adds the provided data points in \a dataMap to the current data. + + Alternatively, you can also access and modify the data via the \ref data method, which returns a + pointer to the internal \ref QCPFinancialDataMap. + + \see removeData +*/ +void QCPFinancial::addData(const QCPFinancialDataMap &dataMap) +{ + mData->unite(dataMap); +} + +/*! \overload + + Adds the provided single data point in \a data to the current data. + + Alternatively, you can also access and modify the data via the \ref data method, which returns a + pointer to the internal \ref QCPFinancialData. + + \see removeData +*/ +void QCPFinancial::addData(const QCPFinancialData &data) +{ + mData->insertMulti(data.key, data); +} + +/*! \overload + + Adds the provided single data point given by \a key, \a open, \a high, \a low, and \a close to + the current data. + + Alternatively, you can also access and modify the data via the \ref data method, which returns a + pointer to the internal \ref QCPFinancialData. + + \see removeData +*/ +void QCPFinancial::addData(double key, double open, double high, double low, double close) +{ + mData->insertMulti(key, QCPFinancialData(key, open, high, low, close)); +} + +/*! \overload + + Adds the provided open/high/low/close data to the current data. + + Alternatively, you can also access and modify the data via the \ref data method, which returns a + pointer to the internal \ref QCPFinancialData. + + \see removeData +*/ +void QCPFinancial::addData(const QVector &key, const QVector &open, const QVector &high, const QVector &low, const QVector &close) +{ + int n = key.size(); + n = qMin(n, open.size()); + n = qMin(n, high.size()); + n = qMin(n, low.size()); + n = qMin(n, close.size()); + for (int i=0; iinsertMulti(key[i], QCPFinancialData(key[i], open[i], high[i], low[i], close[i])); + } +} + +/*! + Removes all data points with keys smaller than \a key. + + \see addData, clearData +*/ +void QCPFinancial::removeDataBefore(double key) +{ + QCPFinancialDataMap::iterator it = mData->begin(); + while (it != mData->end() && it.key() < key) + it = mData->erase(it); +} + +/*! + Removes all data points with keys greater than \a key. + + \see addData, clearData +*/ +void QCPFinancial::removeDataAfter(double key) +{ + if (mData->isEmpty()) return; + QCPFinancialDataMap::iterator it = mData->upperBound(key); + while (it != mData->end()) + it = mData->erase(it); +} + +/*! + Removes all data points with keys between \a fromKey and \a toKey. if \a fromKey is greater or + equal to \a toKey, the function does nothing. To remove a single data point with known key, use + \ref removeData(double key). + + \see addData, clearData +*/ +void QCPFinancial::removeData(double fromKey, double toKey) +{ + if (fromKey >= toKey || mData->isEmpty()) return; + QCPFinancialDataMap::iterator it = mData->upperBound(fromKey); + QCPFinancialDataMap::iterator itEnd = mData->upperBound(toKey); + while (it != itEnd) + it = mData->erase(it); +} + +/*! \overload + + Removes a single data point at \a key. If the position is not known with absolute precision, + consider using \ref removeData(double fromKey, double toKey) with a small fuzziness interval + around the suspected position, depeding on the precision with which the key is known. + + \see addData, clearData +*/ +void QCPFinancial::removeData(double key) +{ + mData->remove(key); +} + +/*! + Removes all data points. + + \see removeData, removeDataAfter, removeDataBefore +*/ +void QCPFinancial::clearData() +{ + mData->clear(); +} + +/* inherits documentation from base class */ +double QCPFinancial::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + // get visible data range: + QCPFinancialDataMap::const_iterator lower, upper; // note that upper is the actual upper point, and not 1 step after the upper point + getVisibleDataBounds(lower, upper); + if (lower == mData->constEnd() || upper == mData->constEnd()) + return -1; + // perform select test according to configured style: + switch (mChartStyle) + { + case QCPFinancial::csOhlc: + return ohlcSelectTest(pos, lower, upper+1); break; + case QCPFinancial::csCandlestick: + return candlestickSelectTest(pos, lower, upper+1); break; + } + } + return -1; +} + +/*! + A convenience function that converts time series data (\a value against \a time) to OHLC binned + data points. The return value can then be passed on to \ref setData. + + The size of the bins can be controlled with \a timeBinSize in the same units as \a time is given. + For example, if the unit of \a time is seconds and single OHLC/Candlesticks should span an hour + each, set \a timeBinSize to 3600. + + \a timeBinOffset allows to control precisely at what \a time coordinate a bin should start. The + value passed as \a timeBinOffset doesn't need to be in the range encompassed by the \a time keys. + It merely defines the mathematical offset/phase of the bins that will be used to process the + data. +*/ +QCPFinancialDataMap QCPFinancial::timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset) +{ + QCPFinancialDataMap map; + int count = qMin(time.size(), value.size()); + if (count == 0) + return QCPFinancialDataMap(); + + QCPFinancialData currentBinData(0, value.first(), value.first(), value.first(), value.first()); + int currentBinIndex = qFloor((time.first()-timeBinOffset)/timeBinSize+0.5); + for (int i=0; i currentBinData.high) currentBinData.high = value.at(i); + if (i == count-1) // last data point is in current bin, finalize bin: + { + currentBinData.close = value.at(i); + currentBinData.key = timeBinOffset+(index)*timeBinSize; + map.insert(currentBinData.key, currentBinData); + } + } else // data point not anymore in current bin, set close of old and open of new bin, and add old to map: + { + // finalize current bin: + currentBinData.close = value.at(i-1); + currentBinData.key = timeBinOffset+(index-1)*timeBinSize; + map.insert(currentBinData.key, currentBinData); + // start next bin: + currentBinIndex = index; + currentBinData.open = value.at(i); + currentBinData.high = value.at(i); + currentBinData.low = value.at(i); + } + } + + return map; +} + +/* inherits documentation from base class */ +void QCPFinancial::draw(QCPPainter *painter) +{ + // get visible data range: + QCPFinancialDataMap::const_iterator lower, upper; // note that upper is the actual upper point, and not 1 step after the upper point + getVisibleDataBounds(lower, upper); + if (lower == mData->constEnd() || upper == mData->constEnd()) + return; + + // draw visible data range according to configured style: + switch (mChartStyle) + { + case QCPFinancial::csOhlc: + drawOhlcPlot(painter, lower, upper+1); break; + case QCPFinancial::csCandlestick: + drawCandlestickPlot(painter, lower, upper+1); break; + } +} + +/* inherits documentation from base class */ +void QCPFinancial::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + painter->setAntialiasing(false); // legend icon especially of csCandlestick looks better without antialiasing + if (mChartStyle == csOhlc) + { + if (mTwoColored) + { + // draw upper left half icon with positive color: + painter->setBrush(mBrushPositive); + painter->setPen(mPenPositive); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + // draw bottom right hald icon with negative color: + painter->setBrush(mBrushNegative); + painter->setPen(mPenNegative); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + } + } else if (mChartStyle == csCandlestick) + { + if (mTwoColored) + { + // draw upper left half icon with positive color: + painter->setBrush(mBrushPositive); + painter->setPen(mPenPositive); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + // draw bottom right hald icon with negative color: + painter->setBrush(mBrushNegative); + painter->setPen(mPenNegative); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + } + } +} + +/* inherits documentation from base class */ +QCPRange QCPFinancial::getKeyRange(bool &foundRange, QCPAbstractPlottable::SignDomain inSignDomain) const +{ + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + + double current; + QCPFinancialDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + current = it.value().key; + if (inSignDomain == sdBoth || (inSignDomain == sdNegative && current < 0) || (inSignDomain == sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + // determine exact range by including width of bars/flags: + if (haveLower && mKeyAxis) + range.lower = range.lower-mWidth*0.5; + if (haveUpper && mKeyAxis) + range.upper = range.upper+mWidth*0.5; + foundRange = haveLower && haveUpper; + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPFinancial::getValueRange(bool &foundRange, QCPAbstractPlottable::SignDomain inSignDomain) const +{ + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + + QCPFinancialDataMap::const_iterator it = mData->constBegin(); + while (it != mData->constEnd()) + { + // high: + if (inSignDomain == sdBoth || (inSignDomain == sdNegative && it.value().high < 0) || (inSignDomain == sdPositive && it.value().high > 0)) + { + if (it.value().high < range.lower || !haveLower) + { + range.lower = it.value().high; + haveLower = true; + } + if (it.value().high > range.upper || !haveUpper) + { + range.upper = it.value().high; + haveUpper = true; + } + } + // low: + if (inSignDomain == sdBoth || (inSignDomain == sdNegative && it.value().low < 0) || (inSignDomain == sdPositive && it.value().low > 0)) + { + if (it.value().low < range.lower || !haveLower) + { + range.lower = it.value().low; + haveLower = true; + } + if (it.value().low > range.upper || !haveUpper) + { + range.upper = it.value().low; + haveUpper = true; + } + } + ++it; + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! \internal + + Draws the data from \a begin to \a end as OHLC bars with the provided \a painter. + + This method is a helper function for \ref draw. It is used when the chart style is \ref csOhlc. +*/ +void QCPFinancial::drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QPen linePen; + + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataMap::const_iterator it = begin; it != end; ++it) + { + if (mSelected) + linePen = mSelectedPen; + else if (mTwoColored) + linePen = it.value().close >= it.value().open ? mPenPositive : mPenNegative; + else + linePen = mPen; + painter->setPen(linePen); + double keyPixel = keyAxis->coordToPixel(it.value().key); + double openPixel = valueAxis->coordToPixel(it.value().open); + double closePixel = valueAxis->coordToPixel(it.value().close); + // draw backbone: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it.value().high)), QPointF(keyPixel, valueAxis->coordToPixel(it.value().low))); + // draw open: + double keyWidthPixels = keyPixel-keyAxis->coordToPixel(it.value().key-mWidth*0.5); // sign of this makes sure open/close are on correct sides + painter->drawLine(QPointF(keyPixel-keyWidthPixels, openPixel), QPointF(keyPixel, openPixel)); + // draw close: + painter->drawLine(QPointF(keyPixel, closePixel), QPointF(keyPixel+keyWidthPixels, closePixel)); + } + } else + { + for (QCPFinancialDataMap::const_iterator it = begin; it != end; ++it) + { + if (mSelected) + linePen = mSelectedPen; + else if (mTwoColored) + linePen = it.value().close >= it.value().open ? mPenPositive : mPenNegative; + else + linePen = mPen; + painter->setPen(linePen); + double keyPixel = keyAxis->coordToPixel(it.value().key); + double openPixel = valueAxis->coordToPixel(it.value().open); + double closePixel = valueAxis->coordToPixel(it.value().close); + // draw backbone: + painter->drawLine(QPointF(valueAxis->coordToPixel(it.value().high), keyPixel), QPointF(valueAxis->coordToPixel(it.value().low), keyPixel)); + // draw open: + double keyWidthPixels = keyPixel-keyAxis->coordToPixel(it.value().key-mWidth*0.5); // sign of this makes sure open/close are on correct sides + painter->drawLine(QPointF(openPixel, keyPixel-keyWidthPixels), QPointF(openPixel, keyPixel)); + // draw close: + painter->drawLine(QPointF(closePixel, keyPixel), QPointF(closePixel, keyPixel+keyWidthPixels)); + } + } +} + +/*! \internal + + Draws the data from \a begin to \a end as Candlesticks with the provided \a painter. + + This method is a helper function for \ref draw. It is used when the chart style is \ref csCandlestick. +*/ +void QCPFinancial::drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QPen linePen; + QBrush boxBrush; + + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataMap::const_iterator it = begin; it != end; ++it) + { + if (mSelected) + { + linePen = mSelectedPen; + boxBrush = mSelectedBrush; + } else if (mTwoColored) + { + if (it.value().close >= it.value().open) + { + linePen = mPenPositive; + boxBrush = mBrushPositive; + } else + { + linePen = mPenNegative; + boxBrush = mBrushNegative; + } + } else + { + linePen = mPen; + boxBrush = mBrush; + } + painter->setPen(linePen); + painter->setBrush(boxBrush); + double keyPixel = keyAxis->coordToPixel(it.value().key); + double openPixel = valueAxis->coordToPixel(it.value().open); + double closePixel = valueAxis->coordToPixel(it.value().close); + // draw high: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it.value().high)), QPointF(keyPixel, valueAxis->coordToPixel(qMax(it.value().open, it.value().close)))); + // draw low: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it.value().low)), QPointF(keyPixel, valueAxis->coordToPixel(qMin(it.value().open, it.value().close)))); + // draw open-close box: + double keyWidthPixels = keyPixel-keyAxis->coordToPixel(it.value().key-mWidth*0.5); + painter->drawRect(QRectF(QPointF(keyPixel-keyWidthPixels, closePixel), QPointF(keyPixel+keyWidthPixels, openPixel))); + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataMap::const_iterator it = begin; it != end; ++it) + { + if (mSelected) + { + linePen = mSelectedPen; + boxBrush = mSelectedBrush; + } else if (mTwoColored) + { + if (it.value().close >= it.value().open) + { + linePen = mPenPositive; + boxBrush = mBrushPositive; + } else + { + linePen = mPenNegative; + boxBrush = mBrushNegative; + } + } else + { + linePen = mPen; + boxBrush = mBrush; + } + painter->setPen(linePen); + painter->setBrush(boxBrush); + double keyPixel = keyAxis->coordToPixel(it.value().key); + double openPixel = valueAxis->coordToPixel(it.value().open); + double closePixel = valueAxis->coordToPixel(it.value().close); + // draw high: + painter->drawLine(QPointF(valueAxis->coordToPixel(it.value().high), keyPixel), QPointF(valueAxis->coordToPixel(qMax(it.value().open, it.value().close)), keyPixel)); + // draw low: + painter->drawLine(QPointF(valueAxis->coordToPixel(it.value().low), keyPixel), QPointF(valueAxis->coordToPixel(qMin(it.value().open, it.value().close)), keyPixel)); + // draw open-close box: + double keyWidthPixels = keyPixel-keyAxis->coordToPixel(it.value().key-mWidth*0.5); + painter->drawRect(QRectF(QPointF(closePixel, keyPixel-keyWidthPixels), QPointF(openPixel, keyPixel+keyWidthPixels))); + } + } +} + +/*! \internal + + This method is a helper function for \ref selectTest. It is used to test for selection when the + chart style is \ref csOhlc. It only tests against the data points between \a begin and \a end. +*/ +double QCPFinancial::ohlcSelectTest(const QPointF &pos, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + double minDistSqr = std::numeric_limits::max(); + QCPFinancialDataMap::const_iterator it; + if (keyAxis->orientation() == Qt::Horizontal) + { + for (it = begin; it != end; ++it) + { + double keyPixel = keyAxis->coordToPixel(it.value().key); + // calculate distance to backbone: + double currentDistSqr = distSqrToLine(QPointF(keyPixel, valueAxis->coordToPixel(it.value().high)), QPointF(keyPixel, valueAxis->coordToPixel(it.value().low)), pos); + if (currentDistSqr < minDistSqr) + minDistSqr = currentDistSqr; + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (it = begin; it != end; ++it) + { + double keyPixel = keyAxis->coordToPixel(it.value().key); + // calculate distance to backbone: + double currentDistSqr = distSqrToLine(QPointF(valueAxis->coordToPixel(it.value().high), keyPixel), QPointF(valueAxis->coordToPixel(it.value().low), keyPixel), pos); + if (currentDistSqr < minDistSqr) + minDistSqr = currentDistSqr; + } + } + return qSqrt(minDistSqr); +} + +/*! \internal + + This method is a helper function for \ref selectTest. It is used to test for selection when the + chart style is \ref csCandlestick. It only tests against the data points between \a begin and \a + end. +*/ +double QCPFinancial::candlestickSelectTest(const QPointF &pos, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + double minDistSqr = std::numeric_limits::max(); + QCPFinancialDataMap::const_iterator it; + if (keyAxis->orientation() == Qt::Horizontal) + { + for (it = begin; it != end; ++it) + { + double currentDistSqr; + // determine whether pos is in open-close-box: + QCPRange boxKeyRange(it.value().key-mWidth*0.5, it.value().key+mWidth*0.5); + QCPRange boxValueRange(it.value().close, it.value().open); + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box + { + currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + } else + { + // calculate distance to high/low lines: + double keyPixel = keyAxis->coordToPixel(it.value().key); + double highLineDistSqr = distSqrToLine(QPointF(keyPixel, valueAxis->coordToPixel(it.value().high)), QPointF(keyPixel, valueAxis->coordToPixel(qMax(it.value().open, it.value().close))), pos); + double lowLineDistSqr = distSqrToLine(QPointF(keyPixel, valueAxis->coordToPixel(it.value().low)), QPointF(keyPixel, valueAxis->coordToPixel(qMin(it.value().open, it.value().close))), pos); + currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); + } + if (currentDistSqr < minDistSqr) + minDistSqr = currentDistSqr; + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (it = begin; it != end; ++it) + { + double currentDistSqr; + // determine whether pos is in open-close-box: + QCPRange boxKeyRange(it.value().key-mWidth*0.5, it.value().key+mWidth*0.5); + QCPRange boxValueRange(it.value().close, it.value().open); + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box + { + currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + } else + { + // calculate distance to high/low lines: + double keyPixel = keyAxis->coordToPixel(it.value().key); + double highLineDistSqr = distSqrToLine(QPointF(valueAxis->coordToPixel(it.value().high), keyPixel), QPointF(valueAxis->coordToPixel(qMax(it.value().open, it.value().close)), keyPixel), pos); + double lowLineDistSqr = distSqrToLine(QPointF(valueAxis->coordToPixel(it.value().low), keyPixel), QPointF(valueAxis->coordToPixel(qMin(it.value().open, it.value().close)), keyPixel), pos); + currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); + } + if (currentDistSqr < minDistSqr) + minDistSqr = currentDistSqr; + } + } + return qSqrt(minDistSqr); +} + +/*! \internal + + called by the drawing methods to determine which data (key) range is visible at the current key + axis range setting, so only that needs to be processed. + + \a lower returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + lower may still be just outside the visible range. + + \a upper returns an iterator to the highest data point. Same as before, \a upper may also lie + just outside of the visible range. + + if the plottable contains no data, both \a lower and \a upper point to constEnd. + + \see QCPGraph::getVisibleDataBounds +*/ +void QCPFinancial::getVisibleDataBounds(QCPFinancialDataMap::const_iterator &lower, QCPFinancialDataMap::const_iterator &upper) const +{ + if (!mKeyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } + if (mData->isEmpty()) + { + lower = mData->constEnd(); + upper = mData->constEnd(); + return; + } + + // get visible data range as QMap iterators + QCPFinancialDataMap::const_iterator lbound = mData->lowerBound(mKeyAxis.data()->range().lower); + QCPFinancialDataMap::const_iterator ubound = mData->upperBound(mKeyAxis.data()->range().upper); + bool lowoutlier = lbound != mData->constBegin(); // indicates whether there exist points below axis range + bool highoutlier = ubound != mData->constEnd(); // indicates whether there exist points above axis range + + lower = (lowoutlier ? lbound-1 : lbound); // data point range that will be actually drawn + upper = (highoutlier ? ubound : ubound-1); // data point range that will be actually drawn +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemStraightLine +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemStraightLine + \brief A straight line that spans infinitely in both directions + + \image html QCPItemStraightLine.png "Straight line example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a point1 and \a point2, which define the straight line. +*/ + +/*! + Creates a straight line item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemStraightLine::QCPItemStraightLine(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + point1(createPosition(QLatin1String("point1"))), + point2(createPosition(QLatin1String("point2"))) +{ + point1->setCoords(0, 0); + point2->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemStraightLine::~QCPItemStraightLine() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemStraightLine::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemStraightLine::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/* inherits documentation from base class */ +double QCPItemStraightLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return distToStraightLine(QVector2D(point1->pixelPoint()), QVector2D(point2->pixelPoint()-point1->pixelPoint()), QVector2D(pos)); +} + +/* inherits documentation from base class */ +void QCPItemStraightLine::draw(QCPPainter *painter) +{ + QVector2D start(point1->pixelPoint()); + QVector2D end(point2->pixelPoint()); + // get visible segment of straight line inside clipRect: + double clipPad = mainPen().widthF(); + QLineF line = getRectClippedStraightLine(start, end-start, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); + // paint visible segment, if existent: + if (!line.isNull()) + { + painter->setPen(mainPen()); + painter->drawLine(line); + } +} + +/*! \internal + + finds the shortest distance of \a point to the straight line defined by the base point \a + base and the direction vector \a vec. + + This is a helper function for \ref selectTest. +*/ +double QCPItemStraightLine::distToStraightLine(const QVector2D &base, const QVector2D &vec, const QVector2D &point) const +{ + return qAbs((base.y()-point.y())*vec.x()-(base.x()-point.x())*vec.y())/vec.length(); +} + +/*! \internal + + Returns the section of the straight line defined by \a base and direction vector \a + vec, that is visible in the specified \a rect. + + This is a helper function for \ref draw. +*/ +QLineF QCPItemStraightLine::getRectClippedStraightLine(const QVector2D &base, const QVector2D &vec, const QRect &rect) const +{ + double bx, by; + double gamma; + QLineF result; + if (vec.x() == 0 && vec.y() == 0) + return result; + if (qFuzzyIsNull(vec.x())) // line is vertical + { + // check top of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + result.setLine(bx+gamma, rect.top(), bx+gamma, rect.bottom()); // no need to check bottom because we know line is vertical + } else if (qFuzzyIsNull(vec.y())) // line is horizontal + { + // check left of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + result.setLine(rect.left(), by+gamma, rect.right(), by+gamma); // no need to check right because we know line is horizontal + } else // line is skewed + { + QList pointVectors; + // check top of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QVector2D(bx+gamma, by)); + // check bottom of rect: + bx = rect.left(); + by = rect.bottom(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QVector2D(bx+gamma, by)); + // check left of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QVector2D(bx, by+gamma)); + // check right of rect: + bx = rect.right(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QVector2D(bx, by+gamma)); + + // evaluate points: + if (pointVectors.size() == 2) + { + result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); + } else if (pointVectors.size() > 2) + { + // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: + double distSqrMax = 0; + QVector2D pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = pointVectors.at(i); + pv2 = pointVectors.at(k); + distSqrMax = distSqr; + } + } + } + result.setPoints(pv1.toPointF(), pv2.toPointF()); + } + } + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemStraightLine::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemLine +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemLine + \brief A line from one point to another + + \image html QCPItemLine.png "Line example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a start and \a end, which define the end points of the line. + + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an arrow. +*/ + +/*! + Creates a line item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemLine::QCPItemLine(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + start(createPosition(QLatin1String("start"))), + end(createPosition(QLatin1String("end"))) +{ + start->setCoords(0, 0); + end->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemLine::~QCPItemLine() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemLine::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemLine::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the line ending style of the head. The head corresponds to the \a end position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode + + \see setTail +*/ +void QCPItemLine::setHead(const QCPLineEnding &head) +{ + mHead = head; +} + +/*! + Sets the line ending style of the tail. The tail corresponds to the \a start position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode + + \see setHead +*/ +void QCPItemLine::setTail(const QCPLineEnding &tail) +{ + mTail = tail; +} + +/* inherits documentation from base class */ +double QCPItemLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return qSqrt(distSqrToLine(start->pixelPoint(), end->pixelPoint(), pos)); +} + +/* inherits documentation from base class */ +void QCPItemLine::draw(QCPPainter *painter) +{ + QVector2D startVec(start->pixelPoint()); + QVector2D endVec(end->pixelPoint()); + if (startVec.toPoint() == endVec.toPoint()) + return; + // get visible segment of straight line inside clipRect: + double clipPad = qMax(mHead.boundingDistance(), mTail.boundingDistance()); + clipPad = qMax(clipPad, (double)mainPen().widthF()); + QLineF line = getRectClippedLine(startVec, endVec, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); + // paint visible segment, if existent: + if (!line.isNull()) + { + painter->setPen(mainPen()); + painter->drawLine(line); + painter->setBrush(Qt::SolidPattern); + if (mTail.style() != QCPLineEnding::esNone) + mTail.draw(painter, startVec, startVec-endVec); + if (mHead.style() != QCPLineEnding::esNone) + mHead.draw(painter, endVec, endVec-startVec); + } +} + +/*! \internal + + Returns the section of the line defined by \a start and \a end, that is visible in the specified + \a rect. + + This is a helper function for \ref draw. +*/ +QLineF QCPItemLine::getRectClippedLine(const QVector2D &start, const QVector2D &end, const QRect &rect) const +{ + bool containsStart = rect.contains(start.x(), start.y()); + bool containsEnd = rect.contains(end.x(), end.y()); + if (containsStart && containsEnd) + return QLineF(start.toPointF(), end.toPointF()); + + QVector2D base = start; + QVector2D vec = end-start; + double bx, by; + double gamma, mu; + QLineF result; + QList pointVectors; + + if (!qFuzzyIsNull(vec.y())) // line is not horizontal + { + // check top of rect: + bx = rect.left(); + by = rect.top(); + mu = (by-base.y())/vec.y(); + if (mu >= 0 && mu <= 1) + { + gamma = base.x()-bx + mu*vec.x(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QVector2D(bx+gamma, by)); + } + // check bottom of rect: + bx = rect.left(); + by = rect.bottom(); + mu = (by-base.y())/vec.y(); + if (mu >= 0 && mu <= 1) + { + gamma = base.x()-bx + mu*vec.x(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QVector2D(bx+gamma, by)); + } + } + if (!qFuzzyIsNull(vec.x())) // line is not vertical + { + // check left of rect: + bx = rect.left(); + by = rect.top(); + mu = (bx-base.x())/vec.x(); + if (mu >= 0 && mu <= 1) + { + gamma = base.y()-by + mu*vec.y(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QVector2D(bx, by+gamma)); + } + // check right of rect: + bx = rect.right(); + by = rect.top(); + mu = (bx-base.x())/vec.x(); + if (mu >= 0 && mu <= 1) + { + gamma = base.y()-by + mu*vec.y(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QVector2D(bx, by+gamma)); + } + } + + if (containsStart) + pointVectors.append(start); + if (containsEnd) + pointVectors.append(end); + + // evaluate points: + if (pointVectors.size() == 2) + { + result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); + } else if (pointVectors.size() > 2) + { + // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: + double distSqrMax = 0; + QVector2D pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = pointVectors.at(i); + pv2 = pointVectors.at(k); + distSqrMax = distSqr; + } + } + } + result.setPoints(pv1.toPointF(), pv2.toPointF()); + } + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemLine::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemCurve +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemCurve + \brief A curved line from one point to another + + \image html QCPItemCurve.png "Curve example. Blue dotted circles are anchors, solid blue discs are positions." + + It has four positions, \a start and \a end, which define the end points of the line, and two + control points which define the direction the line exits from the start and the direction from + which it approaches the end: \a startDir and \a endDir. + + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an + arrow. + + Often it is desirable for the control points to stay at fixed relative positions to the start/end + point. This can be achieved by setting the parent anchor e.g. of \a startDir simply to \a start, + and then specify the desired pixel offset with QCPItemPosition::setCoords on \a startDir. +*/ + +/*! + Creates a curve item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemCurve::QCPItemCurve(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + start(createPosition(QLatin1String("start"))), + startDir(createPosition(QLatin1String("startDir"))), + endDir(createPosition(QLatin1String("endDir"))), + end(createPosition(QLatin1String("end"))) +{ + start->setCoords(0, 0); + startDir->setCoords(0.5, 0); + endDir->setCoords(0, 0.5); + end->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemCurve::~QCPItemCurve() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemCurve::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemCurve::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the line ending style of the head. The head corresponds to the \a end position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode + + \see setTail +*/ +void QCPItemCurve::setHead(const QCPLineEnding &head) +{ + mHead = head; +} + +/*! + Sets the line ending style of the tail. The tail corresponds to the \a start position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode + + \see setHead +*/ +void QCPItemCurve::setTail(const QCPLineEnding &tail) +{ + mTail = tail; +} + +/* inherits documentation from base class */ +double QCPItemCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF startVec(start->pixelPoint()); + QPointF startDirVec(startDir->pixelPoint()); + QPointF endDirVec(endDir->pixelPoint()); + QPointF endVec(end->pixelPoint()); + + QPainterPath cubicPath(startVec); + cubicPath.cubicTo(startDirVec, endDirVec, endVec); + + QPolygonF polygon = cubicPath.toSubpathPolygons().first(); + double minDistSqr = std::numeric_limits::max(); + for (int i=1; ipixelPoint()); + QPointF startDirVec(startDir->pixelPoint()); + QPointF endDirVec(endDir->pixelPoint()); + QPointF endVec(end->pixelPoint()); + if (QVector2D(endVec-startVec).length() > 1e10f) // too large curves cause crash + return; + + QPainterPath cubicPath(startVec); + cubicPath.cubicTo(startDirVec, endDirVec, endVec); + + // paint visible segment, if existent: + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + QRect cubicRect = cubicPath.controlPointRect().toRect(); + if (cubicRect.isEmpty()) // may happen when start and end exactly on same x or y position + cubicRect.adjust(0, 0, 1, 1); + if (clip.intersects(cubicRect)) + { + painter->setPen(mainPen()); + painter->drawPath(cubicPath); + painter->setBrush(Qt::SolidPattern); + if (mTail.style() != QCPLineEnding::esNone) + mTail.draw(painter, QVector2D(startVec), M_PI-cubicPath.angleAtPercent(0)/180.0*M_PI); + if (mHead.style() != QCPLineEnding::esNone) + mHead.draw(painter, QVector2D(endVec), -cubicPath.angleAtPercent(1)/180.0*M_PI); + } +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemCurve::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemRect +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemRect + \brief A rectangle + + \image html QCPItemRect.png "Rectangle example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rectangle. +*/ + +/*! + Creates a rectangle item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemRect::QCPItemRect(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPItemRect::~QCPItemRect() +{ +} + +/*! + Sets the pen that will be used to draw the line of the rectangle + + \see setSelectedPen, setBrush +*/ +void QCPItemRect::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the rectangle when selected + + \see setPen, setSelected +*/ +void QCPItemRect::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to fill the rectangle. To disable filling, set \a brush to + Qt::NoBrush. + + \see setSelectedBrush, setPen +*/ +void QCPItemRect::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to fill the rectangle when selected. To disable filling, set \a + brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemRect::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/* inherits documentation from base class */ +double QCPItemRect::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QRectF rect = QRectF(topLeft->pixelPoint(), bottomRight->pixelPoint()).normalized(); + bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; + return rectSelectTest(rect, pos, filledRect); +} + +/* inherits documentation from base class */ +void QCPItemRect::draw(QCPPainter *painter) +{ + QPointF p1 = topLeft->pixelPoint(); + QPointF p2 = bottomRight->pixelPoint(); + if (p1.toPoint() == p2.toPoint()) + return; + QRectF rect = QRectF(p1, p2).normalized(); + double clipPad = mainPen().widthF(); + QRectF boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (boundingRect.intersects(clipRect())) // only draw if bounding rect of rect item is visible in cliprect + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(rect); + } +} + +/* inherits documentation from base class */ +QPointF QCPItemRect::anchorPixelPoint(int anchorId) const +{ + QRectF rect = QRectF(topLeft->pixelPoint(), bottomRight->pixelPoint()); + switch (anchorId) + { + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRight: return rect.topRight(); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeft: return rect.bottomLeft(); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemRect::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemRect::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemText +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemText + \brief A text label + + \image html QCPItemText.png "Text example. Blue dotted circles are anchors, solid blue discs are positions." + + Its position is defined by the member \a position and the setting of \ref setPositionAlignment. + The latter controls which part of the text rect shall be aligned with \a position. + + The text alignment itself (i.e. left, center, right) can be controlled with \ref + setTextAlignment. + + The text may be rotated around the \a position point with \ref setRotation. +*/ + +/*! + Creates a text item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemText::QCPItemText(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + topLeft(createAnchor(QLatin1String("topLeft"), aiTopLeft)), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottomRight(createAnchor(QLatin1String("bottomRight"), aiBottomRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)) +{ + position->setCoords(0, 0); + + setRotation(0); + setTextAlignment(Qt::AlignTop|Qt::AlignHCenter); + setPositionAlignment(Qt::AlignCenter); + setText(QLatin1String("text")); + + setPen(Qt::NoPen); + setSelectedPen(Qt::NoPen); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); + setColor(Qt::black); + setSelectedColor(Qt::blue); +} + +QCPItemText::~QCPItemText() +{ +} + +/*! + Sets the color of the text. +*/ +void QCPItemText::setColor(const QColor &color) +{ + mColor = color; +} + +/*! + Sets the color of the text that will be used when the item is selected. +*/ +void QCPItemText::setSelectedColor(const QColor &color) +{ + mSelectedColor = color; +} + +/*! + Sets the pen that will be used do draw a rectangular border around the text. To disable the + border, set \a pen to Qt::NoPen. + + \see setSelectedPen, setBrush, setPadding +*/ +void QCPItemText::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used do draw a rectangular border around the text, when the item is + selected. To disable the border, set \a pen to Qt::NoPen. + + \see setPen +*/ +void QCPItemText::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used do fill the background of the text. To disable the + background, set \a brush to Qt::NoBrush. + + \see setSelectedBrush, setPen, setPadding +*/ +void QCPItemText::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used do fill the background of the text, when the item is selected. To disable the + background, set \a brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemText::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the font of the text. + + \see setSelectedFont, setColor +*/ +void QCPItemText::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the font of the text that will be used when the item is selected. + + \see setFont +*/ +void QCPItemText::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + Sets the text that will be displayed. Multi-line texts are supported by inserting a line break + character, e.g. '\n'. + + \see setFont, setColor, setTextAlignment +*/ +void QCPItemText::setText(const QString &text) +{ + mText = text; +} + +/*! + Sets which point of the text rect shall be aligned with \a position. + + Examples: + \li If \a alignment is Qt::AlignHCenter | Qt::AlignTop, the text will be positioned such + that the top of the text rect will be horizontally centered on \a position. + \li If \a alignment is Qt::AlignLeft | Qt::AlignBottom, \a position will indicate the + bottom left corner of the text rect. + + If you want to control the alignment of (multi-lined) text within the text rect, use \ref + setTextAlignment. +*/ +void QCPItemText::setPositionAlignment(Qt::Alignment alignment) +{ + mPositionAlignment = alignment; +} + +/*! + Controls how (multi-lined) text is aligned inside the text rect (typically Qt::AlignLeft, Qt::AlignCenter or Qt::AlignRight). +*/ +void QCPItemText::setTextAlignment(Qt::Alignment alignment) +{ + mTextAlignment = alignment; +} + +/*! + Sets the angle in degrees by which the text (and the text rectangle, if visible) will be rotated + around \a position. +*/ +void QCPItemText::setRotation(double degrees) +{ + mRotation = degrees; +} + +/*! + Sets the distance between the border of the text rectangle and the text. The appearance (and + visibility) of the text rectangle can be controlled with \ref setPen and \ref setBrush. +*/ +void QCPItemText::setPadding(const QMargins &padding) +{ + mPadding = padding; +} + +/* inherits documentation from base class */ +double QCPItemText::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + // The rect may be rotated, so we transform the actual clicked pos to the rotated + // coordinate system, so we can use the normal rectSelectTest function for non-rotated rects: + QPointF positionPixels(position->pixelPoint()); + QTransform inputTransform; + inputTransform.translate(positionPixels.x(), positionPixels.y()); + inputTransform.rotate(-mRotation); + inputTransform.translate(-positionPixels.x(), -positionPixels.y()); + QPointF rotatedPos = inputTransform.map(pos); + QFontMetrics fontMetrics(mFont); + QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(positionPixels, textBoxRect, mPositionAlignment); + textBoxRect.moveTopLeft(textPos.toPoint()); + + return rectSelectTest(textBoxRect, rotatedPos, true); +} + +/* inherits documentation from base class */ +void QCPItemText::draw(QCPPainter *painter) +{ + QPointF pos(position->pixelPoint()); + QTransform transform = painter->transform(); + transform.translate(pos.x(), pos.y()); + if (!qFuzzyIsNull(mRotation)) + transform.rotate(mRotation); + painter->setFont(mainFont()); + QRect textRect = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation + textRect.moveTopLeft(textPos.toPoint()+QPoint(mPadding.left(), mPadding.top())); + textBoxRect.moveTopLeft(textPos.toPoint()); + double clipPad = mainPen().widthF(); + QRect boundingRect = textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (transform.mapRect(boundingRect).intersects(painter->transform().mapRect(clipRect()))) + { + painter->setTransform(transform); + if ((mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0) || + (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0)) + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(textBoxRect); + } + painter->setBrush(Qt::NoBrush); + painter->setPen(QPen(mainColor())); + painter->drawText(textRect, Qt::TextDontClip|mTextAlignment, mText); + } +} + +/* inherits documentation from base class */ +QPointF QCPItemText::anchorPixelPoint(int anchorId) const +{ + // get actual rect points (pretty much copied from draw function): + QPointF pos(position->pixelPoint()); + QTransform transform; + transform.translate(pos.x(), pos.y()); + if (!qFuzzyIsNull(mRotation)) + transform.rotate(mRotation); + QFontMetrics fontMetrics(mainFont()); + QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRectF textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation + textBoxRect.moveTopLeft(textPos.toPoint()); + QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect)); + + switch (anchorId) + { + case aiTopLeft: return rectPoly.at(0); + case aiTop: return (rectPoly.at(0)+rectPoly.at(1))*0.5; + case aiTopRight: return rectPoly.at(1); + case aiRight: return (rectPoly.at(1)+rectPoly.at(2))*0.5; + case aiBottomRight: return rectPoly.at(2); + case aiBottom: return (rectPoly.at(2)+rectPoly.at(3))*0.5; + case aiBottomLeft: return rectPoly.at(3); + case aiLeft: return (rectPoly.at(3)+rectPoly.at(0))*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the point that must be given to the QPainter::drawText function (which expects the top + left point of the text rect), according to the position \a pos, the text bounding box \a rect and + the requested \a positionAlignment. + + For example, if \a positionAlignment is Qt::AlignLeft | Qt::AlignBottom the returned point + will be shifted upward by the height of \a rect, starting from \a pos. So if the text is finally + drawn at that point, the lower left corner of the resulting text rect is at \a pos. +*/ +QPointF QCPItemText::getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const +{ + if (positionAlignment == 0 || positionAlignment == (Qt::AlignLeft|Qt::AlignTop)) + return pos; + + QPointF result = pos; // start at top left + if (positionAlignment.testFlag(Qt::AlignHCenter)) + result.rx() -= rect.width()/2.0; + else if (positionAlignment.testFlag(Qt::AlignRight)) + result.rx() -= rect.width(); + if (positionAlignment.testFlag(Qt::AlignVCenter)) + result.ry() -= rect.height()/2.0; + else if (positionAlignment.testFlag(Qt::AlignBottom)) + result.ry() -= rect.height(); + return result; +} + +/*! \internal + + Returns the font that should be used for drawing text. Returns mFont when the item is not selected + and mSelectedFont when it is. +*/ +QFont QCPItemText::mainFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Returns the color that should be used for drawing text. Returns mColor when the item is not + selected and mSelectedColor when it is. +*/ +QColor QCPItemText::mainColor() const +{ + return mSelected ? mSelectedColor : mColor; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemText::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemText::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemEllipse +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemEllipse + \brief An ellipse + + \image html QCPItemEllipse.png "Ellipse example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rect the ellipse will be drawn in. +*/ + +/*! + Creates an ellipse item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemEllipse::QCPItemEllipse(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + topLeftRim(createAnchor(QLatin1String("topLeftRim"), aiTopLeftRim)), + top(createAnchor(QLatin1String("top"), aiTop)), + topRightRim(createAnchor(QLatin1String("topRightRim"), aiTopRightRim)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottomRightRim(createAnchor(QLatin1String("bottomRightRim"), aiBottomRightRim)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeftRim(createAnchor(QLatin1String("bottomLeftRim"), aiBottomLeftRim)), + left(createAnchor(QLatin1String("left"), aiLeft)), + center(createAnchor(QLatin1String("center"), aiCenter)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPItemEllipse::~QCPItemEllipse() +{ +} + +/*! + Sets the pen that will be used to draw the line of the ellipse + + \see setSelectedPen, setBrush +*/ +void QCPItemEllipse::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the ellipse when selected + + \see setPen, setSelected +*/ +void QCPItemEllipse::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to fill the ellipse. To disable filling, set \a brush to + Qt::NoBrush. + + \see setSelectedBrush, setPen +*/ +void QCPItemEllipse::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to fill the ellipse when selected. To disable filling, set \a + brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemEllipse::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/* inherits documentation from base class */ +double QCPItemEllipse::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + double result = -1; + QPointF p1 = topLeft->pixelPoint(); + QPointF p2 = bottomRight->pixelPoint(); + QPointF center((p1+p2)/2.0); + double a = qAbs(p1.x()-p2.x())/2.0; + double b = qAbs(p1.y()-p2.y())/2.0; + double x = pos.x()-center.x(); + double y = pos.y()-center.y(); + + // distance to border: + double c = 1.0/qSqrt(x*x/(a*a)+y*y/(b*b)); + result = qAbs(c-1)*qSqrt(x*x+y*y); + // filled ellipse, allow click inside to count as hit: + if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) + { + if (x*x/(a*a) + y*y/(b*b) <= 1) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; +} + +/* inherits documentation from base class */ +void QCPItemEllipse::draw(QCPPainter *painter) +{ + QPointF p1 = topLeft->pixelPoint(); + QPointF p2 = bottomRight->pixelPoint(); + if (p1.toPoint() == p2.toPoint()) + return; + QRectF ellipseRect = QRectF(p1, p2).normalized(); + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + if (ellipseRect.intersects(clip)) // only draw if bounding rect of ellipse is visible in cliprect + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); +#ifdef __EXCEPTIONS + try // drawEllipse sometimes throws exceptions if ellipse is too big + { +#endif + painter->drawEllipse(ellipseRect); +#ifdef __EXCEPTIONS + } catch (...) + { + qDebug() << Q_FUNC_INFO << "Item too large for memory, setting invisible"; + setVisible(false); + } +#endif + } +} + +/* inherits documentation from base class */ +QPointF QCPItemEllipse::anchorPixelPoint(int anchorId) const +{ + QRectF rect = QRectF(topLeft->pixelPoint(), bottomRight->pixelPoint()); + switch (anchorId) + { + case aiTopLeftRim: return rect.center()+(rect.topLeft()-rect.center())*1/qSqrt(2); + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRightRim: return rect.center()+(rect.topRight()-rect.center())*1/qSqrt(2); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottomRightRim: return rect.center()+(rect.bottomRight()-rect.center())*1/qSqrt(2); + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeftRim: return rect.center()+(rect.bottomLeft()-rect.center())*1/qSqrt(2); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; + case aiCenter: return (rect.topLeft()+rect.bottomRight())*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemEllipse::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemEllipse::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemPixmap +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemPixmap + \brief An arbitrary pixmap + + \image html QCPItemPixmap.png "Pixmap example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rectangle the pixmap will + be drawn in. Depending on the scale setting (\ref setScaled), the pixmap will be either scaled to + fit the rectangle or be drawn aligned to the topLeft position. + + If scaling is enabled and \a topLeft is further to the bottom/right than \a bottomRight (as shown + on the right side of the example image), the pixmap will be flipped in the respective + orientations. +*/ + +/*! + Creates a rectangle item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemPixmap::QCPItemPixmap(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)), + mScaledPixmapInvalidated(true) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(Qt::NoPen); + setSelectedPen(QPen(Qt::blue)); + setScaled(false, Qt::KeepAspectRatio, Qt::SmoothTransformation); +} + +QCPItemPixmap::~QCPItemPixmap() +{ +} + +/*! + Sets the pixmap that will be displayed. +*/ +void QCPItemPixmap::setPixmap(const QPixmap &pixmap) +{ + mPixmap = pixmap; + mScaledPixmapInvalidated = true; + if (mPixmap.isNull()) + qDebug() << Q_FUNC_INFO << "pixmap is null"; +} + +/*! + Sets whether the pixmap will be scaled to fit the rectangle defined by the \a topLeft and \a + bottomRight positions. +*/ +void QCPItemPixmap::setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformationMode) +{ + mScaled = scaled; + mAspectRatioMode = aspectRatioMode; + mTransformationMode = transformationMode; + mScaledPixmapInvalidated = true; +} + +/*! + Sets the pen that will be used to draw a border around the pixmap. + + \see setSelectedPen, setBrush +*/ +void QCPItemPixmap::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw a border around the pixmap when selected + + \see setPen, setSelected +*/ +void QCPItemPixmap::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/* inherits documentation from base class */ +double QCPItemPixmap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return rectSelectTest(getFinalRect(), pos, true); +} + +/* inherits documentation from base class */ +void QCPItemPixmap::draw(QCPPainter *painter) +{ + bool flipHorz = false; + bool flipVert = false; + QRect rect = getFinalRect(&flipHorz, &flipVert); + double clipPad = mainPen().style() == Qt::NoPen ? 0 : mainPen().widthF(); + QRect boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (boundingRect.intersects(clipRect())) + { + updateScaledPixmap(rect, flipHorz, flipVert); + painter->drawPixmap(rect.topLeft(), mScaled ? mScaledPixmap : mPixmap); + QPen pen = mainPen(); + if (pen.style() != Qt::NoPen) + { + painter->setPen(pen); + painter->setBrush(Qt::NoBrush); + painter->drawRect(rect); + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemPixmap::anchorPixelPoint(int anchorId) const +{ + bool flipHorz; + bool flipVert; + QRect rect = getFinalRect(&flipHorz, &flipVert); + // we actually want denormal rects (negative width/height) here, so restore + // the flipped state: + if (flipHorz) + rect.adjust(rect.width(), 0, -rect.width(), 0); + if (flipVert) + rect.adjust(0, rect.height(), 0, -rect.height()); + + switch (anchorId) + { + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRight: return rect.topRight(); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeft: return rect.bottomLeft(); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5;; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Creates the buffered scaled image (\a mScaledPixmap) to fit the specified \a finalRect. The + parameters \a flipHorz and \a flipVert control whether the resulting image shall be flipped + horizontally or vertically. (This is used when \a topLeft is further to the bottom/right than \a + bottomRight.) + + This function only creates the scaled pixmap when the buffered pixmap has a different size than + the expected result, so calling this function repeatedly, e.g. in the \ref draw function, does + not cause expensive rescaling every time. + + If scaling is disabled, sets mScaledPixmap to a null QPixmap. +*/ +void QCPItemPixmap::updateScaledPixmap(QRect finalRect, bool flipHorz, bool flipVert) +{ + if (mPixmap.isNull()) + return; + + if (mScaled) + { + if (finalRect.isNull()) + finalRect = getFinalRect(&flipHorz, &flipVert); + if (mScaledPixmapInvalidated || finalRect.size() != mScaledPixmap.size()) + { + mScaledPixmap = mPixmap.scaled(finalRect.size(), mAspectRatioMode, mTransformationMode); + if (flipHorz || flipVert) + mScaledPixmap = QPixmap::fromImage(mScaledPixmap.toImage().mirrored(flipHorz, flipVert)); + } + } else if (!mScaledPixmap.isNull()) + mScaledPixmap = QPixmap(); + mScaledPixmapInvalidated = false; +} + +/*! \internal + + Returns the final (tight) rect the pixmap is drawn in, depending on the current item positions + and scaling settings. + + The output parameters \a flippedHorz and \a flippedVert return whether the pixmap should be drawn + flipped horizontally or vertically in the returned rect. (The returned rect itself is always + normalized, i.e. the top left corner of the rect is actually further to the top/left than the + bottom right corner). This is the case when the item position \a topLeft is further to the + bottom/right than \a bottomRight. + + If scaling is disabled, returns a rect with size of the original pixmap and the top left corner + aligned with the item position \a topLeft. The position \a bottomRight is ignored. +*/ +QRect QCPItemPixmap::getFinalRect(bool *flippedHorz, bool *flippedVert) const +{ + QRect result; + bool flipHorz = false; + bool flipVert = false; + QPoint p1 = topLeft->pixelPoint().toPoint(); + QPoint p2 = bottomRight->pixelPoint().toPoint(); + if (p1 == p2) + return QRect(p1, QSize(0, 0)); + if (mScaled) + { + QSize newSize = QSize(p2.x()-p1.x(), p2.y()-p1.y()); + QPoint topLeft = p1; + if (newSize.width() < 0) + { + flipHorz = true; + newSize.rwidth() *= -1; + topLeft.setX(p2.x()); + } + if (newSize.height() < 0) + { + flipVert = true; + newSize.rheight() *= -1; + topLeft.setY(p2.y()); + } + QSize scaledSize = mPixmap.size(); + scaledSize.scale(newSize, mAspectRatioMode); + result = QRect(topLeft, scaledSize); + } else + { + result = QRect(p1, mPixmap.size()); + } + if (flippedHorz) + *flippedHorz = flipHorz; + if (flippedVert) + *flippedVert = flipVert; + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemPixmap::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemTracer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemTracer + \brief Item that sticks to QCPGraph data points + + \image html QCPItemTracer.png "Tracer example. Blue dotted circles are anchors, solid blue discs are positions." + + The tracer can be connected with a QCPGraph via \ref setGraph. Then it will automatically adopt + the coordinate axes of the graph and update its \a position to be on the graph's data. This means + the key stays controllable via \ref setGraphKey, but the value will follow the graph data. If a + QCPGraph is connected, note that setting the coordinates of the tracer item directly via \a + position will have no effect because they will be overriden in the next redraw (this is when the + coordinate update happens). + + If the specified key in \ref setGraphKey is outside the key bounds of the graph, the tracer will + stay at the corresponding end of the graph. + + With \ref setInterpolating you may specify whether the tracer may only stay exactly on data + points or whether it interpolates data points linearly, if given a key that lies between two data + points of the graph. + + The tracer has different visual styles, see \ref setStyle. It is also possible to make the tracer + have no own visual appearance (set the style to \ref tsNone), and just connect other item + positions to the tracer \a position (used as an anchor) via \ref + QCPItemPosition::setParentAnchor. + + \note The tracer position is only automatically updated upon redraws. So when the data of the + graph changes and immediately afterwards (without a redraw) the a position coordinates of the + tracer are retrieved, they will not reflect the updated data of the graph. In this case \ref + updatePosition must be called manually, prior to reading the tracer coordinates. +*/ + +/*! + Creates a tracer item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemTracer::QCPItemTracer(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + mGraph(0) +{ + position->setCoords(0, 0); + + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); + setStyle(tsCrosshair); + setSize(6); + setInterpolating(false); + setGraphKey(0); +} + +QCPItemTracer::~QCPItemTracer() +{ +} + +/*! + Sets the pen that will be used to draw the line of the tracer + + \see setSelectedPen, setBrush +*/ +void QCPItemTracer::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the tracer when selected + + \see setPen, setSelected +*/ +void QCPItemTracer::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to draw any fills of the tracer + + \see setSelectedBrush, setPen +*/ +void QCPItemTracer::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to draw any fills of the tracer, when selected. + + \see setBrush, setSelected +*/ +void QCPItemTracer::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the size of the tracer in pixels, if the style supports setting a size (e.g. \ref tsSquare + does, \ref tsCrosshair does not). +*/ +void QCPItemTracer::setSize(double size) +{ + mSize = size; +} + +/*! + Sets the style/visual appearance of the tracer. + + If you only want to use the tracer \a position as an anchor for other items, set \a style to + \ref tsNone. +*/ +void QCPItemTracer::setStyle(QCPItemTracer::TracerStyle style) +{ + mStyle = style; +} + +/*! + Sets the QCPGraph this tracer sticks to. The tracer \a position will be set to type + QCPItemPosition::ptPlotCoords and the axes will be set to the axes of \a graph. + + To free the tracer from any graph, set \a graph to 0. The tracer \a position can then be placed + freely like any other item position. This is the state the tracer will assume when its graph gets + deleted while still attached to it. + + \see setGraphKey +*/ +void QCPItemTracer::setGraph(QCPGraph *graph) +{ + if (graph) + { + if (graph->parentPlot() == mParentPlot) + { + position->setType(QCPItemPosition::ptPlotCoords); + position->setAxes(graph->keyAxis(), graph->valueAxis()); + mGraph = graph; + updatePosition(); + } else + qDebug() << Q_FUNC_INFO << "graph isn't in same QCustomPlot instance as this item"; + } else + { + mGraph = 0; + } +} + +/*! + Sets the key of the graph's data point the tracer will be positioned at. This is the only free + coordinate of a tracer when attached to a graph. + + Depending on \ref setInterpolating, the tracer will be either positioned on the data point + closest to \a key, or will stay exactly at \a key and interpolate the value linearly. + + \see setGraph, setInterpolating +*/ +void QCPItemTracer::setGraphKey(double key) +{ + mGraphKey = key; +} + +/*! + Sets whether the value of the graph's data points shall be interpolated, when positioning the + tracer. + + If \a enabled is set to false and a key is given with \ref setGraphKey, the tracer is placed on + the data point of the graph which is closest to the key, but which is not necessarily exactly + there. If \a enabled is true, the tracer will be positioned exactly at the specified key, and + the appropriate value will be interpolated from the graph's data points linearly. + + \see setGraph, setGraphKey +*/ +void QCPItemTracer::setInterpolating(bool enabled) +{ + mInterpolating = enabled; +} + +/* inherits documentation from base class */ +double QCPItemTracer::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF center(position->pixelPoint()); + double w = mSize/2.0; + QRect clip = clipRect(); + switch (mStyle) + { + case tsNone: return -1; + case tsPlus: + { + if (clipRect().intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + return qSqrt(qMin(distSqrToLine(center+QPointF(-w, 0), center+QPointF(w, 0), pos), + distSqrToLine(center+QPointF(0, -w), center+QPointF(0, w), pos))); + break; + } + case tsCrosshair: + { + return qSqrt(qMin(distSqrToLine(QPointF(clip.left(), center.y()), QPointF(clip.right(), center.y()), pos), + distSqrToLine(QPointF(center.x(), clip.top()), QPointF(center.x(), clip.bottom()), pos))); + } + case tsCircle: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + // distance to border: + double centerDist = QVector2D(center-pos).length(); + double circleLine = w; + double result = qAbs(centerDist-circleLine); + // filled ellipse, allow click inside to count as hit: + if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) + { + if (centerDist <= circleLine) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; + } + break; + } + case tsSquare: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + QRectF rect = QRectF(center-QPointF(w, w), center+QPointF(w, w)); + bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; + return rectSelectTest(rect, pos, filledRect); + } + break; + } + } + return -1; +} + +/* inherits documentation from base class */ +void QCPItemTracer::draw(QCPPainter *painter) +{ + updatePosition(); + if (mStyle == tsNone) + return; + + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + QPointF center(position->pixelPoint()); + double w = mSize/2.0; + QRect clip = clipRect(); + switch (mStyle) + { + case tsNone: return; + case tsPlus: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + painter->drawLine(QLineF(center+QPointF(-w, 0), center+QPointF(w, 0))); + painter->drawLine(QLineF(center+QPointF(0, -w), center+QPointF(0, w))); + } + break; + } + case tsCrosshair: + { + if (center.y() > clip.top() && center.y() < clip.bottom()) + painter->drawLine(QLineF(clip.left(), center.y(), clip.right(), center.y())); + if (center.x() > clip.left() && center.x() < clip.right()) + painter->drawLine(QLineF(center.x(), clip.top(), center.x(), clip.bottom())); + break; + } + case tsCircle: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + painter->drawEllipse(center, w, w); + break; + } + case tsSquare: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + painter->drawRect(QRectF(center-QPointF(w, w), center+QPointF(w, w))); + break; + } + } +} + +/*! + If the tracer is connected with a graph (\ref setGraph), this function updates the tracer's \a + position to reside on the graph data, depending on the configured key (\ref setGraphKey). + + It is called automatically on every redraw and normally doesn't need to be called manually. One + exception is when you want to read the tracer coordinates via \a position and are not sure that + the graph's data (or the tracer key with \ref setGraphKey) hasn't changed since the last redraw. + In that situation, call this function before accessing \a position, to make sure you don't get + out-of-date coordinates. + + If there is no graph set on this tracer, this function does nothing. +*/ +void QCPItemTracer::updatePosition() +{ + if (mGraph) + { + if (mParentPlot->hasPlottable(mGraph)) + { + if (mGraph->data()->size() > 1) + { + QCPDataMap::const_iterator first = mGraph->data()->constBegin(); + QCPDataMap::const_iterator last = mGraph->data()->constEnd()-1; + if (mGraphKey < first.key()) + position->setCoords(first.key(), first.value().value); + else if (mGraphKey > last.key()) + position->setCoords(last.key(), last.value().value); + else + { + QCPDataMap::const_iterator it = mGraph->data()->lowerBound(mGraphKey); + if (it != first) // mGraphKey is somewhere between iterators + { + QCPDataMap::const_iterator prevIt = it-1; + if (mInterpolating) + { + // interpolate between iterators around mGraphKey: + double slope = 0; + if (!qFuzzyCompare((double)it.key(), (double)prevIt.key())) + slope = (it.value().value-prevIt.value().value)/(it.key()-prevIt.key()); + position->setCoords(mGraphKey, (mGraphKey-prevIt.key())*slope+prevIt.value().value); + } else + { + // find iterator with key closest to mGraphKey: + if (mGraphKey < (prevIt.key()+it.key())*0.5) + it = prevIt; + position->setCoords(it.key(), it.value().value); + } + } else // mGraphKey is exactly on first iterator + position->setCoords(it.key(), it.value().value); + } + } else if (mGraph->data()->size() == 1) + { + QCPDataMap::const_iterator it = mGraph->data()->constBegin(); + position->setCoords(it.key(), it.value().value); + } else + qDebug() << Q_FUNC_INFO << "graph has no data"; + } else + qDebug() << Q_FUNC_INFO << "graph not contained in QCustomPlot instance (anymore)"; + } +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemTracer::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemTracer::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemBracket +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemBracket + \brief A bracket for referencing/highlighting certain parts in the plot. + + \image html QCPItemBracket.png "Bracket example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a left and \a right, which define the span of the bracket. If \a left is + actually farther to the left than \a right, the bracket is opened to the bottom, as shown in the + example image. + + The bracket supports multiple styles via \ref setStyle. The length, i.e. how far the bracket + stretches away from the embraced span, can be controlled with \ref setLength. + + \image html QCPItemBracket-length.png +
Demonstrating the effect of different values for \ref setLength, for styles \ref + bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
+ + It provides an anchor \a center, to allow connection of other items, e.g. an arrow (QCPItemLine + or QCPItemCurve) or a text label (QCPItemText), to the bracket. +*/ + +/*! + Creates a bracket item and sets default values. + + The constructed item can be added to the plot with QCustomPlot::addItem. +*/ +QCPItemBracket::QCPItemBracket(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + left(createPosition(QLatin1String("left"))), + right(createPosition(QLatin1String("right"))), + center(createAnchor(QLatin1String("center"), aiCenter)) +{ + left->setCoords(0, 0); + right->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); + setLength(8); + setStyle(bsCalligraphic); +} + +QCPItemBracket::~QCPItemBracket() +{ +} + +/*! + Sets the pen that will be used to draw the bracket. + + Note that when the style is \ref bsCalligraphic, only the color will be taken from the pen, the + stroke and width are ignored. To change the apparent stroke width of a calligraphic bracket, use + \ref setLength, which has a similar effect. + + \see setSelectedPen +*/ +void QCPItemBracket::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the bracket when selected + + \see setPen, setSelected +*/ +void QCPItemBracket::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the \a length in pixels how far the bracket extends in the direction towards the embraced + span of the bracket (i.e. perpendicular to the left-right-direction) + + \image html QCPItemBracket-length.png +
Demonstrating the effect of different values for \ref setLength, for styles \ref + bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
+*/ +void QCPItemBracket::setLength(double length) +{ + mLength = length; +} + +/*! + Sets the style of the bracket, i.e. the shape/visual appearance. + + \see setPen +*/ +void QCPItemBracket::setStyle(QCPItemBracket::BracketStyle style) +{ + mStyle = style; +} + +/* inherits documentation from base class */ +double QCPItemBracket::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QVector2D leftVec(left->pixelPoint()); + QVector2D rightVec(right->pixelPoint()); + if (leftVec.toPoint() == rightVec.toPoint()) + return -1; + + QVector2D widthVec = (rightVec-leftVec)*0.5f; + QVector2D lengthVec(-widthVec.y(), widthVec.x()); + lengthVec = lengthVec.normalized()*mLength; + QVector2D centerVec = (rightVec+leftVec)*0.5f-lengthVec; + + switch (mStyle) + { + case QCPItemBracket::bsSquare: + case QCPItemBracket::bsRound: + { + double a = distSqrToLine((centerVec-widthVec).toPointF(), (centerVec+widthVec).toPointF(), pos); + double b = distSqrToLine((centerVec-widthVec+lengthVec).toPointF(), (centerVec-widthVec).toPointF(), pos); + double c = distSqrToLine((centerVec+widthVec+lengthVec).toPointF(), (centerVec+widthVec).toPointF(), pos); + return qSqrt(qMin(qMin(a, b), c)); + } + case QCPItemBracket::bsCurly: + case QCPItemBracket::bsCalligraphic: + { + double a = distSqrToLine((centerVec-widthVec*0.75f+lengthVec*0.15f).toPointF(), (centerVec+lengthVec*0.3f).toPointF(), pos); + double b = distSqrToLine((centerVec-widthVec+lengthVec*0.7f).toPointF(), (centerVec-widthVec*0.75f+lengthVec*0.15f).toPointF(), pos); + double c = distSqrToLine((centerVec+widthVec*0.75f+lengthVec*0.15f).toPointF(), (centerVec+lengthVec*0.3f).toPointF(), pos); + double d = distSqrToLine((centerVec+widthVec+lengthVec*0.7f).toPointF(), (centerVec+widthVec*0.75f+lengthVec*0.15f).toPointF(), pos); + return qSqrt(qMin(qMin(a, b), qMin(c, d))); + } + } + return -1; +} + +/* inherits documentation from base class */ +void QCPItemBracket::draw(QCPPainter *painter) +{ + QVector2D leftVec(left->pixelPoint()); + QVector2D rightVec(right->pixelPoint()); + if (leftVec.toPoint() == rightVec.toPoint()) + return; + + QVector2D widthVec = (rightVec-leftVec)*0.5f; + QVector2D lengthVec(-widthVec.y(), widthVec.x()); + lengthVec = lengthVec.normalized()*mLength; + QVector2D centerVec = (rightVec+leftVec)*0.5f-lengthVec; + + QPolygon boundingPoly; + boundingPoly << leftVec.toPoint() << rightVec.toPoint() + << (rightVec-lengthVec).toPoint() << (leftVec-lengthVec).toPoint(); + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + if (clip.intersects(boundingPoly.boundingRect())) + { + painter->setPen(mainPen()); + switch (mStyle) + { + case bsSquare: + { + painter->drawLine((centerVec+widthVec).toPointF(), (centerVec-widthVec).toPointF()); + painter->drawLine((centerVec+widthVec).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); + painter->drawLine((centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + break; + } + case bsRound: + { + painter->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + path.cubicTo((centerVec+widthVec).toPointF(), (centerVec+widthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-widthVec).toPointF(), (centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + painter->drawPath(path); + break; + } + case bsCurly: + { + painter->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + path.cubicTo((centerVec+widthVec-lengthVec*0.8f).toPointF(), (centerVec+0.4f*widthVec+lengthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-0.4f*widthVec+lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8f).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + painter->drawPath(path); + break; + } + case bsCalligraphic: + { + painter->setPen(Qt::NoPen); + painter->setBrush(QBrush(mainPen().color())); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + + path.cubicTo((centerVec+widthVec-lengthVec*0.8f).toPointF(), (centerVec+0.4f*widthVec+0.8f*lengthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-0.4f*widthVec+0.8f*lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8f).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + + path.cubicTo((centerVec-widthVec-lengthVec*0.5f).toPointF(), (centerVec-0.2f*widthVec+1.2f*lengthVec).toPointF(), (centerVec+lengthVec*0.2f).toPointF()); + path.cubicTo((centerVec+0.2f*widthVec+1.2f*lengthVec).toPointF(), (centerVec+widthVec-lengthVec*0.5f).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); + + painter->drawPath(path); + break; + } + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemBracket::anchorPixelPoint(int anchorId) const +{ + QVector2D leftVec(left->pixelPoint()); + QVector2D rightVec(right->pixelPoint()); + if (leftVec.toPoint() == rightVec.toPoint()) + return leftVec.toPointF(); + + QVector2D widthVec = (rightVec-leftVec)*0.5f; + QVector2D lengthVec(-widthVec.y(), widthVec.x()); + lengthVec = lengthVec.normalized()*mLength; + QVector2D centerVec = (rightVec+leftVec)*0.5f-lengthVec; + + switch (anchorId) + { + case aiCenter: + return centerVec.toPointF(); + } + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemBracket::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + diff --git a/Desktop_Interface/ui_elements/qcp1/qcustomplot.cpp.REMOVED.git-id b/Desktop_Interface/ui_elements/qcp1/qcustomplot.cpp.REMOVED.git-id deleted file mode 100644 index dfd82366..00000000 --- a/Desktop_Interface/ui_elements/qcp1/qcustomplot.cpp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -30860827c5f1a7c07a294591ecc63de3066b3ee6 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/qcp1/qcustomplot.h b/Desktop_Interface/ui_elements/qcp1/qcustomplot.h new file mode 100644 index 00000000..bb998f1c --- /dev/null +++ b/Desktop_Interface/ui_elements/qcp1/qcustomplot.h @@ -0,0 +1,3768 @@ +/*************************************************************************** +** ** +** QCustomPlot, an easy to use, modern plotting widget for Qt ** +** Copyright (C) 2011-2015 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.qcustomplot.com/ ** +** Date: 22.12.15 ** +** Version: 1.3.2 ** +****************************************************************************/ + +#ifndef QCUSTOMPLOT_H +#define QCUSTOMPLOT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# include +# include +# include +#else +# include +# include +#endif + +class QCPPainter; +class QCustomPlot; +class QCPLayerable; +class QCPLayoutElement; +class QCPLayout; +class QCPAxis; +class QCPAxisRect; +class QCPAxisPainterPrivate; +class QCPAbstractPlottable; +class QCPGraph; +class QCPAbstractItem; +class QCPItemPosition; +class QCPLayer; +class QCPPlotTitle; +class QCPLegend; +class QCPAbstractLegendItem; +class QCPColorMap; +class QCPColorScale; +class QCPBars; + + +/*! \file */ + + +// decl definitions for shared library compilation/usage: +#if defined(QCUSTOMPLOT_COMPILE_LIBRARY) +# define QCP_LIB_DECL Q_DECL_EXPORT +#elif defined(QCUSTOMPLOT_USE_LIBRARY) +# define QCP_LIB_DECL Q_DECL_IMPORT +#else +# define QCP_LIB_DECL +#endif + +/*! + The QCP Namespace contains general enums and QFlags used throughout the QCustomPlot library +*/ +namespace QCP +{ +/*! + Defines the sides of a rectangular entity to which margins can be applied. + + \see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins +*/ +enum MarginSide { msLeft = 0x01 ///< 0x01 left margin + ,msRight = 0x02 ///< 0x02 right margin + ,msTop = 0x04 ///< 0x04 top margin + ,msBottom = 0x08 ///< 0x08 bottom margin + ,msAll = 0xFF ///< 0xFF all margins + ,msNone = 0x00 ///< 0x00 no margin + }; +Q_DECLARE_FLAGS(MarginSides, MarginSide) + +/*! + Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is + neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective + element how it is drawn. Typically it provides a \a setAntialiased function for this. + + \c AntialiasedElements is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements +*/ +enum AntialiasedElement { aeAxes = 0x0001 ///< 0x0001 Axis base line and tick marks + ,aeGrid = 0x0002 ///< 0x0002 Grid lines + ,aeSubGrid = 0x0004 ///< 0x0004 Sub grid lines + ,aeLegend = 0x0008 ///< 0x0008 Legend box + ,aeLegendItems = 0x0010 ///< 0x0010 Legend items + ,aePlottables = 0x0020 ///< 0x0020 Main lines of plottables (excluding error bars, see element \ref aeErrorBars) + ,aeItems = 0x0040 ///< 0x0040 Main lines of items + ,aeScatters = 0x0080 ///< 0x0080 Scatter symbols of plottables (excluding scatter symbols of type ssPixmap) + ,aeErrorBars = 0x0100 ///< 0x0100 Error bars + ,aeFills = 0x0200 ///< 0x0200 Borders of fills (e.g. under or between graphs) + ,aeZeroLine = 0x0400 ///< 0x0400 Zero-lines, see \ref QCPGrid::setZeroLinePen + ,aeAll = 0xFFFF ///< 0xFFFF All elements + ,aeNone = 0x0000 ///< 0x0000 No elements + }; +Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement) + +/*! + Defines plotting hints that control various aspects of the quality and speed of plotting. + + \see QCustomPlot::setPlottingHints +*/ +enum PlottingHint { phNone = 0x000 ///< 0x000 No hints are set + ,phFastPolylines = 0x001 ///< 0x001 Graph/Curve lines are drawn with a faster method. This reduces the quality + ///< especially of the line segment joins. (Only relevant for solid line pens.) + ,phForceRepaint = 0x002 ///< 0x002 causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpHint. + ///< This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse). + ,phCacheLabels = 0x004 ///< 0x004 axis (tick) labels will be cached as pixmaps, increasing replot performance. + }; +Q_DECLARE_FLAGS(PlottingHints, PlottingHint) + +/*! + Defines the mouse interactions possible with QCustomPlot. + + \c Interactions is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setInteractions +*/ +enum Interaction { iRangeDrag = 0x001 ///< 0x001 Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes) + ,iRangeZoom = 0x002 ///< 0x002 Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes) + ,iMultiSelect = 0x004 ///< 0x004 The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking + ,iSelectPlottables = 0x008 ///< 0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable) + ,iSelectAxes = 0x010 ///< 0x010 Axes are selectable (or parts of them, see QCPAxis::setSelectableParts) + ,iSelectLegend = 0x020 ///< 0x020 Legends are selectable (or their child items, see QCPLegend::setSelectableParts) + ,iSelectItems = 0x040 ///< 0x040 Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem) + ,iSelectOther = 0x080 ///< 0x080 All other objects are selectable (e.g. your own derived layerables, the plot title,...) + }; +Q_DECLARE_FLAGS(Interactions, Interaction) + +/*! \internal + + Returns whether the specified \a value is considered an invalid data value for plottables (i.e. + is \e nan or \e +/-inf). This function is used to check data validity upon replots, when the + compiler flag \c QCUSTOMPLOT_CHECK_DATA is set. +*/ +inline bool isInvalidData(double value) +{ + return qIsNaN(value) || qIsInf(value); +} + +/*! \internal + \overload + + Checks two arguments instead of one. +*/ +inline bool isInvalidData(double value1, double value2) +{ + return isInvalidData(value1) || isInvalidData(value2); +} + +/*! \internal + + Sets the specified \a side of \a margins to \a value + + \see getMarginValue +*/ +inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value) +{ + switch (side) + { + case QCP::msLeft: margins.setLeft(value); break; + case QCP::msRight: margins.setRight(value); break; + case QCP::msTop: margins.setTop(value); break; + case QCP::msBottom: margins.setBottom(value); break; + case QCP::msAll: margins = QMargins(value, value, value, value); break; + default: break; + } +} + +/*! \internal + + Returns the value of the specified \a side of \a margins. If \a side is \ref QCP::msNone or + \ref QCP::msAll, returns 0. + + \see setMarginValue +*/ +inline int getMarginValue(const QMargins &margins, QCP::MarginSide side) +{ + switch (side) + { + case QCP::msLeft: return margins.left(); + case QCP::msRight: return margins.right(); + case QCP::msTop: return margins.top(); + case QCP::msBottom: return margins.bottom(); + default: break; + } + return 0; +} + +} // end of namespace QCP + +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions) + + +class QCP_LIB_DECL QCPScatterStyle +{ + Q_GADGET +public: + /*! + Defines the shape used for scatter points. + + On plottables/items that draw scatters, the sizes of these visualizations (with exception of + \ref ssDot and \ref ssPixmap) can be controlled with the \ref setSize function. Scatters are + drawn with the pen and brush specified with \ref setPen and \ref setBrush. + */ + Q_ENUMS(ScatterShape) + enum ScatterShape { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines) + ,ssDot ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius) + ,ssCross ///< \enumimage{ssCross.png} a cross + ,ssPlus ///< \enumimage{ssPlus.png} a plus + ,ssCircle ///< \enumimage{ssCircle.png} a circle + ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle) + ,ssSquare ///< \enumimage{ssSquare.png} a square + ,ssDiamond ///< \enumimage{ssDiamond.png} a diamond + ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus + ,ssTriangle ///< \enumimage{ssTriangle.png} an equilateral triangle, standing on baseline + ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner + ,ssCrossSquare ///< \enumimage{ssCrossSquare.png} a square with a cross inside + ,ssPlusSquare ///< \enumimage{ssPlusSquare.png} a square with a plus inside + ,ssCrossCircle ///< \enumimage{ssCrossCircle.png} a circle with a cross inside + ,ssPlusCircle ///< \enumimage{ssPlusCircle.png} a circle with a plus inside + ,ssPeace ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines + ,ssPixmap ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates + ,ssCustom ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath) + }; + + QCPScatterStyle(); + QCPScatterStyle(ScatterShape shape, double size=6); + QCPScatterStyle(ScatterShape shape, const QColor &color, double size); + QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size); + QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size); + QCPScatterStyle(const QPixmap &pixmap); + QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6); + + // getters: + double size() const { return mSize; } + ScatterShape shape() const { return mShape; } + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QPixmap pixmap() const { return mPixmap; } + QPainterPath customPath() const { return mCustomPath; } + + // setters: + void setSize(double size); + void setShape(ScatterShape shape); + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setPixmap(const QPixmap &pixmap); + void setCustomPath(const QPainterPath &customPath); + + // non-property methods: + bool isNone() const { return mShape == ssNone; } + bool isPenDefined() const { return mPenDefined; } + void applyTo(QCPPainter *painter, const QPen &defaultPen) const; + void drawShape(QCPPainter *painter, QPointF pos) const; + void drawShape(QCPPainter *painter, double x, double y) const; + +protected: + // property members: + double mSize; + ScatterShape mShape; + QPen mPen; + QBrush mBrush; + QPixmap mPixmap; + QPainterPath mCustomPath; + + // non-property members: + bool mPenDefined; +}; +Q_DECLARE_TYPEINFO(QCPScatterStyle, Q_MOVABLE_TYPE); + + +class QCP_LIB_DECL QCPPainter : public QPainter +{ + Q_GADGET +public: + /*! + Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds, + depending on whether they are wanted on the respective output device. + */ + enum PainterMode { pmDefault = 0x00 ///< 0x00 Default mode for painting on screen devices + ,pmVectorized = 0x01 ///< 0x01 Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes. + ,pmNoCaching = 0x02 ///< 0x02 Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels + ,pmNonCosmetic = 0x04 ///< 0x04 Turns pen widths 0 to 1, i.e. disables cosmetic pens. (A cosmetic pen is always drawn with width 1 pixel in the vector image/pdf viewer, independent of zoom.) + }; + Q_FLAGS(PainterMode PainterModes) + Q_DECLARE_FLAGS(PainterModes, PainterMode) + + QCPPainter(); + QCPPainter(QPaintDevice *device); + ~QCPPainter(); + + // getters: + bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); } + PainterModes modes() const { return mModes; } + + // setters: + void setAntialiasing(bool enabled); + void setMode(PainterMode mode, bool enabled=true); + void setModes(PainterModes modes); + + // methods hiding non-virtual base class functions (QPainter bug workarounds): + bool begin(QPaintDevice *device); + void setPen(const QPen &pen); + void setPen(const QColor &color); + void setPen(Qt::PenStyle penStyle); + void drawLine(const QLineF &line); + void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));} + void save(); + void restore(); + + // non-virtual methods: + void makeNonCosmetic(); + +protected: + // property members: + PainterModes mModes; + bool mIsAntialiasing; + + // non-property members: + QStack mAntialiasingStack; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes) + + +class QCP_LIB_DECL QCPLayer : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) + Q_PROPERTY(QString name READ name) + Q_PROPERTY(int index READ index) + Q_PROPERTY(QList children READ children) + Q_PROPERTY(bool visible READ visible WRITE setVisible) + /// \endcond +public: + QCPLayer(QCustomPlot* parentPlot, const QString &layerName); + ~QCPLayer(); + + // getters: + QCustomPlot *parentPlot() const { return mParentPlot; } + QString name() const { return mName; } + int index() const { return mIndex; } + QList children() const { return mChildren; } + bool visible() const { return mVisible; } + + // setters: + void setVisible(bool visible); + +protected: + // property members: + QCustomPlot *mParentPlot; + QString mName; + int mIndex; + QList mChildren; + bool mVisible; + + // non-virtual methods: + void addChild(QCPLayerable *layerable, bool prepend); + void removeChild(QCPLayerable *layerable); + +private: + Q_DISABLE_COPY(QCPLayer) + + friend class QCustomPlot; + friend class QCPLayerable; +}; + +class QCP_LIB_DECL QCPLayerable : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool visible READ visible WRITE setVisible) + Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) + Q_PROPERTY(QCPLayerable* parentLayerable READ parentLayerable) + Q_PROPERTY(QCPLayer* layer READ layer WRITE setLayer NOTIFY layerChanged) + Q_PROPERTY(bool antialiased READ antialiased WRITE setAntialiased) + /// \endcond +public: + QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=0); + ~QCPLayerable(); + + // getters: + bool visible() const { return mVisible; } + QCustomPlot *parentPlot() const { return mParentPlot; } + QCPLayerable *parentLayerable() const { return mParentLayerable.data(); } + QCPLayer *layer() const { return mLayer; } + bool antialiased() const { return mAntialiased; } + + // setters: + void setVisible(bool on); + Q_SLOT bool setLayer(QCPLayer *layer); + bool setLayer(const QString &layerName); + void setAntialiased(bool enabled); + + // introduced virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // non-property methods: + bool realVisibility() const; + +signals: + void layerChanged(QCPLayer *newLayer); + +protected: + // property members: + bool mVisible; + QCustomPlot *mParentPlot; + QPointer mParentLayerable; + QCPLayer *mLayer; + bool mAntialiased; + + // introduced virtual methods: + virtual void parentPlotInitialized(QCustomPlot *parentPlot); + virtual QCP::Interaction selectionCategory() const; + virtual QRect clipRect() const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const = 0; + virtual void draw(QCPPainter *painter) = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + + // non-property methods: + void initializeParentPlot(QCustomPlot *parentPlot); + void setParentLayerable(QCPLayerable* parentLayerable); + bool moveToLayer(QCPLayer *layer, bool prepend); + void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const; + +private: + Q_DISABLE_COPY(QCPLayerable) + + friend class QCustomPlot; + friend class QCPAxisRect; +}; + + +class QCP_LIB_DECL QCPRange +{ +public: + double lower, upper; + + QCPRange(); + QCPRange(double lower, double upper); + + bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; } + bool operator!=(const QCPRange& other) const { return !(*this == other); } + + QCPRange &operator+=(const double& value) { lower+=value; upper+=value; return *this; } + QCPRange &operator-=(const double& value) { lower-=value; upper-=value; return *this; } + QCPRange &operator*=(const double& value) { lower*=value; upper*=value; return *this; } + QCPRange &operator/=(const double& value) { lower/=value; upper/=value; return *this; } + friend inline const QCPRange operator+(const QCPRange&, double); + friend inline const QCPRange operator+(double, const QCPRange&); + friend inline const QCPRange operator-(const QCPRange& range, double value); + friend inline const QCPRange operator*(const QCPRange& range, double value); + friend inline const QCPRange operator*(double value, const QCPRange& range); + friend inline const QCPRange operator/(const QCPRange& range, double value); + + double size() const; + double center() const; + void normalize(); + void expand(const QCPRange &otherRange); + QCPRange expanded(const QCPRange &otherRange) const; + QCPRange sanitizedForLogScale() const; + QCPRange sanitizedForLinScale() const; + bool contains(double value) const; + + static bool validRange(double lower, double upper); + static bool validRange(const QCPRange &range); + static const double minRange; //1e-280; + static const double maxRange; //1e280; + +}; +Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE); + +/* documentation of inline functions */ + +/*! \fn QCPRange &QCPRange::operator+=(const double& value) + + Adds \a value to both boundaries of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator-=(const double& value) + + Subtracts \a value from both boundaries of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator*=(const double& value) + + Multiplies both boundaries of the range by \a value. +*/ + +/*! \fn QCPRange &QCPRange::operator/=(const double& value) + + Divides both boundaries of the range by \a value. +*/ + +/* end documentation of inline functions */ + +/*! + Adds \a value to both boundaries of the range. +*/ +inline const QCPRange operator+(const QCPRange& range, double value) +{ + QCPRange result(range); + result += value; + return result; +} + +/*! + Adds \a value to both boundaries of the range. +*/ +inline const QCPRange operator+(double value, const QCPRange& range) +{ + QCPRange result(range); + result += value; + return result; +} + +/*! + Subtracts \a value from both boundaries of the range. +*/ +inline const QCPRange operator-(const QCPRange& range, double value) +{ + QCPRange result(range); + result -= value; + return result; +} + +/*! + Multiplies both boundaries of the range by \a value. +*/ +inline const QCPRange operator*(const QCPRange& range, double value) +{ + QCPRange result(range); + result *= value; + return result; +} + +/*! + Multiplies both boundaries of the range by \a value. +*/ +inline const QCPRange operator*(double value, const QCPRange& range) +{ + QCPRange result(range); + result *= value; + return result; +} + +/*! + Divides both boundaries of the range by \a value. +*/ +inline const QCPRange operator/(const QCPRange& range, double value) +{ + QCPRange result(range); + result /= value; + return result; +} + + +class QCP_LIB_DECL QCPMarginGroup : public QObject +{ + Q_OBJECT +public: + QCPMarginGroup(QCustomPlot *parentPlot); + ~QCPMarginGroup(); + + // non-virtual methods: + QList elements(QCP::MarginSide side) const { return mChildren.value(side); } + bool isEmpty() const; + void clear(); + +protected: + // non-property members: + QCustomPlot *mParentPlot; + QHash > mChildren; + + // non-virtual methods: + int commonMargin(QCP::MarginSide side) const; + void addChild(QCP::MarginSide side, QCPLayoutElement *element); + void removeChild(QCP::MarginSide side, QCPLayoutElement *element); + +private: + Q_DISABLE_COPY(QCPMarginGroup) + + friend class QCPLayoutElement; +}; + + +class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPLayout* layout READ layout) + Q_PROPERTY(QRect rect READ rect) + Q_PROPERTY(QRect outerRect READ outerRect WRITE setOuterRect) + Q_PROPERTY(QMargins margins READ margins WRITE setMargins) + Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins) + Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize) + Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize) + /// \endcond +public: + /*! + Defines the phases of the update process, that happens just before a replot. At each phase, + \ref update is called with the according UpdatePhase value. + */ + enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout + ,upMargins ///< Phase in which the margins are calculated and set + ,upLayout ///< Final phase in which the layout system places the rects of the elements + }; + Q_ENUMS(UpdatePhase) + + explicit QCPLayoutElement(QCustomPlot *parentPlot=0); + virtual ~QCPLayoutElement(); + + // getters: + QCPLayout *layout() const { return mParentLayout; } + QRect rect() const { return mRect; } + QRect outerRect() const { return mOuterRect; } + QMargins margins() const { return mMargins; } + QMargins minimumMargins() const { return mMinimumMargins; } + QCP::MarginSides autoMargins() const { return mAutoMargins; } + QSize minimumSize() const { return mMinimumSize; } + QSize maximumSize() const { return mMaximumSize; } + QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, (QCPMarginGroup*)0); } + QHash marginGroups() const { return mMarginGroups; } + + // setters: + void setOuterRect(const QRect &rect); + void setMargins(const QMargins &margins); + void setMinimumMargins(const QMargins &margins); + void setAutoMargins(QCP::MarginSides sides); + void setMinimumSize(const QSize &size); + void setMinimumSize(int width, int height); + void setMaximumSize(const QSize &size); + void setMaximumSize(int width, int height); + void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group); + + // introduced virtual methods: + virtual void update(UpdatePhase phase); + virtual QSize minimumSizeHint() const; + virtual QSize maximumSizeHint() const; + virtual QList elements(bool recursive) const; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + +protected: + // property members: + QCPLayout *mParentLayout; + QSize mMinimumSize, mMaximumSize; + QRect mRect, mOuterRect; + QMargins mMargins, mMinimumMargins; + QCP::MarginSides mAutoMargins; + QHash mMarginGroups; + + // introduced virtual methods: + virtual int calculateAutoMargin(QCP::MarginSide side); + // events: + virtual void mousePressEvent(QMouseEvent *event) {Q_UNUSED(event)} + virtual void mouseMoveEvent(QMouseEvent *event) {Q_UNUSED(event)} + virtual void mouseReleaseEvent(QMouseEvent *event) {Q_UNUSED(event)} + virtual void mouseDoubleClickEvent(QMouseEvent *event) {Q_UNUSED(event)} + virtual void wheelEvent(QWheelEvent *event) {Q_UNUSED(event)} + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const { Q_UNUSED(painter) } + virtual void draw(QCPPainter *painter) { Q_UNUSED(painter) } + virtual void parentPlotInitialized(QCustomPlot *parentPlot); + +private: + Q_DISABLE_COPY(QCPLayoutElement) + + friend class QCustomPlot; + friend class QCPLayout; + friend class QCPMarginGroup; +}; + + +class QCP_LIB_DECL QCPLayout : public QCPLayoutElement +{ + Q_OBJECT +public: + explicit QCPLayout(); + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase); + virtual QList elements(bool recursive) const; + + // introduced virtual methods: + virtual int elementCount() const = 0; + virtual QCPLayoutElement* elementAt(int index) const = 0; + virtual QCPLayoutElement* takeAt(int index) = 0; + virtual bool take(QCPLayoutElement* element) = 0; + virtual void simplify(); + + // non-virtual methods: + bool removeAt(int index); + bool remove(QCPLayoutElement* element); + void clear(); + +protected: + // introduced virtual methods: + virtual void updateLayout(); + + // non-virtual methods: + void sizeConstraintsChanged() const; + void adoptElement(QCPLayoutElement *el); + void releaseElement(QCPLayoutElement *el); + QVector getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const; + +private: + Q_DISABLE_COPY(QCPLayout) + friend class QCPLayoutElement; +}; + + +class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(int rowCount READ rowCount) + Q_PROPERTY(int columnCount READ columnCount) + Q_PROPERTY(QList columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors) + Q_PROPERTY(QList rowStretchFactors READ rowStretchFactors WRITE setRowStretchFactors) + Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing) + Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing) + /// \endcond +public: + explicit QCPLayoutGrid(); + virtual ~QCPLayoutGrid(); + + // getters: + int rowCount() const; + int columnCount() const; + QList columnStretchFactors() const { return mColumnStretchFactors; } + QList rowStretchFactors() const { return mRowStretchFactors; } + int columnSpacing() const { return mColumnSpacing; } + int rowSpacing() const { return mRowSpacing; } + + // setters: + void setColumnStretchFactor(int column, double factor); + void setColumnStretchFactors(const QList &factors); + void setRowStretchFactor(int row, double factor); + void setRowStretchFactors(const QList &factors); + void setColumnSpacing(int pixels); + void setRowSpacing(int pixels); + + // reimplemented virtual methods: + virtual void updateLayout(); + virtual int elementCount() const; + virtual QCPLayoutElement* elementAt(int index) const; + virtual QCPLayoutElement* takeAt(int index); + virtual bool take(QCPLayoutElement* element); + virtual QList elements(bool recursive) const; + virtual void simplify(); + virtual QSize minimumSizeHint() const; + virtual QSize maximumSizeHint() const; + + // non-virtual methods: + QCPLayoutElement *element(int row, int column) const; + bool addElement(int row, int column, QCPLayoutElement *element); + bool hasElement(int row, int column); + void expandTo(int newRowCount, int newColumnCount); + void insertRow(int newIndex); + void insertColumn(int newIndex); + +protected: + // property members: + QList > mElements; + QList mColumnStretchFactors; + QList mRowStretchFactors; + int mColumnSpacing, mRowSpacing; + + // non-virtual methods: + void getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const; + void getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const; + +private: + Q_DISABLE_COPY(QCPLayoutGrid) +}; + + +class QCP_LIB_DECL QCPLayoutInset : public QCPLayout +{ + Q_OBJECT +public: + /*! + Defines how the placement and sizing is handled for a certain element in a QCPLayoutInset. + */ + enum InsetPlacement { ipFree ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect + ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment + }; + + explicit QCPLayoutInset(); + virtual ~QCPLayoutInset(); + + // getters: + InsetPlacement insetPlacement(int index) const; + Qt::Alignment insetAlignment(int index) const; + QRectF insetRect(int index) const; + + // setters: + void setInsetPlacement(int index, InsetPlacement placement); + void setInsetAlignment(int index, Qt::Alignment alignment); + void setInsetRect(int index, const QRectF &rect); + + // reimplemented virtual methods: + virtual void updateLayout(); + virtual int elementCount() const; + virtual QCPLayoutElement* elementAt(int index) const; + virtual QCPLayoutElement* takeAt(int index); + virtual bool take(QCPLayoutElement* element); + virtual void simplify() {} + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // non-virtual methods: + void addElement(QCPLayoutElement *element, Qt::Alignment alignment); + void addElement(QCPLayoutElement *element, const QRectF &rect); + +protected: + // property members: + QList mElements; + QList mInsetPlacement; + QList mInsetAlignment; + QList mInsetRect; + +private: + Q_DISABLE_COPY(QCPLayoutInset) +}; + + +class QCP_LIB_DECL QCPLineEnding +{ + Q_GADGET +public: + /*! + Defines the type of ending decoration for line-like items, e.g. an arrow. + + \image html QCPLineEnding.png + + The width and length of these decorations can be controlled with the functions \ref setWidth + and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only + support a width, the length property is ignored. + + \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding + */ + Q_ENUMS(EndingStyle) + enum EndingStyle { esNone ///< No ending decoration + ,esFlatArrow ///< A filled arrow head with a straight/flat back (a triangle) + ,esSpikeArrow ///< A filled arrow head with an indented back + ,esLineArrow ///< A non-filled arrow head with open back + ,esDisc ///< A filled circle + ,esSquare ///< A filled square + ,esDiamond ///< A filled diamond (45° rotated square) + ,esBar ///< A bar perpendicular to the line + ,esHalfBar ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted) + ,esSkewedBar ///< A bar that is skewed (skew controllable via \ref setLength) + }; + + QCPLineEnding(); + QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false); + + // getters: + EndingStyle style() const { return mStyle; } + double width() const { return mWidth; } + double length() const { return mLength; } + bool inverted() const { return mInverted; } + + // setters: + void setStyle(EndingStyle style); + void setWidth(double width); + void setLength(double length); + void setInverted(bool inverted); + + // non-property methods: + double boundingDistance() const; + double realLength() const; + void draw(QCPPainter *painter, const QVector2D &pos, const QVector2D &dir) const; + void draw(QCPPainter *painter, const QVector2D &pos, double angle) const; + +protected: + // property members: + EndingStyle mStyle; + double mWidth, mLength; + bool mInverted; +}; +Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE); + + +class QCP_LIB_DECL QCPGrid :public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool subGridVisible READ subGridVisible WRITE setSubGridVisible) + Q_PROPERTY(bool antialiasedSubGrid READ antialiasedSubGrid WRITE setAntialiasedSubGrid) + Q_PROPERTY(bool antialiasedZeroLine READ antialiasedZeroLine WRITE setAntialiasedZeroLine) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen subGridPen READ subGridPen WRITE setSubGridPen) + Q_PROPERTY(QPen zeroLinePen READ zeroLinePen WRITE setZeroLinePen) + /// \endcond +public: + QCPGrid(QCPAxis *parentAxis); + + // getters: + bool subGridVisible() const { return mSubGridVisible; } + bool antialiasedSubGrid() const { return mAntialiasedSubGrid; } + bool antialiasedZeroLine() const { return mAntialiasedZeroLine; } + QPen pen() const { return mPen; } + QPen subGridPen() const { return mSubGridPen; } + QPen zeroLinePen() const { return mZeroLinePen; } + + // setters: + void setSubGridVisible(bool visible); + void setAntialiasedSubGrid(bool enabled); + void setAntialiasedZeroLine(bool enabled); + void setPen(const QPen &pen); + void setSubGridPen(const QPen &pen); + void setZeroLinePen(const QPen &pen); + +protected: + // property members: + bool mSubGridVisible; + bool mAntialiasedSubGrid, mAntialiasedZeroLine; + QPen mPen, mSubGridPen, mZeroLinePen; + // non-property members: + QCPAxis *mParentAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter); + + // non-virtual methods: + void drawGridLines(QCPPainter *painter) const; + void drawSubGridLines(QCPPainter *painter) const; + + friend class QCPAxis; +}; + + +class QCP_LIB_DECL QCPAxis : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(AxisType axisType READ axisType) + Q_PROPERTY(QCPAxisRect* axisRect READ axisRect) + Q_PROPERTY(ScaleType scaleType READ scaleType WRITE setScaleType NOTIFY scaleTypeChanged) + Q_PROPERTY(double scaleLogBase READ scaleLogBase WRITE setScaleLogBase) + Q_PROPERTY(QCPRange range READ range WRITE setRange NOTIFY rangeChanged) + Q_PROPERTY(bool rangeReversed READ rangeReversed WRITE setRangeReversed) + Q_PROPERTY(bool autoTicks READ autoTicks WRITE setAutoTicks) + Q_PROPERTY(int autoTickCount READ autoTickCount WRITE setAutoTickCount) + Q_PROPERTY(bool autoTickLabels READ autoTickLabels WRITE setAutoTickLabels) + Q_PROPERTY(bool autoTickStep READ autoTickStep WRITE setAutoTickStep) + Q_PROPERTY(bool autoSubTicks READ autoSubTicks WRITE setAutoSubTicks) + Q_PROPERTY(bool ticks READ ticks WRITE setTicks) + Q_PROPERTY(bool tickLabels READ tickLabels WRITE setTickLabels) + Q_PROPERTY(int tickLabelPadding READ tickLabelPadding WRITE setTickLabelPadding) + Q_PROPERTY(LabelType tickLabelType READ tickLabelType WRITE setTickLabelType) + Q_PROPERTY(QFont tickLabelFont READ tickLabelFont WRITE setTickLabelFont) + Q_PROPERTY(QColor tickLabelColor READ tickLabelColor WRITE setTickLabelColor) + Q_PROPERTY(double tickLabelRotation READ tickLabelRotation WRITE setTickLabelRotation) + Q_PROPERTY(LabelSide tickLabelSide READ tickLabelSide WRITE setTickLabelSide) + Q_PROPERTY(QString dateTimeFormat READ dateTimeFormat WRITE setDateTimeFormat) + Q_PROPERTY(Qt::TimeSpec dateTimeSpec READ dateTimeSpec WRITE setDateTimeSpec) + Q_PROPERTY(QString numberFormat READ numberFormat WRITE setNumberFormat) + Q_PROPERTY(int numberPrecision READ numberPrecision WRITE setNumberPrecision) + Q_PROPERTY(double tickStep READ tickStep WRITE setTickStep) + Q_PROPERTY(QVector tickVector READ tickVector WRITE setTickVector) + Q_PROPERTY(QVector tickVectorLabels READ tickVectorLabels WRITE setTickVectorLabels) + Q_PROPERTY(int tickLengthIn READ tickLengthIn WRITE setTickLengthIn) + Q_PROPERTY(int tickLengthOut READ tickLengthOut WRITE setTickLengthOut) + Q_PROPERTY(int subTickCount READ subTickCount WRITE setSubTickCount) + Q_PROPERTY(int subTickLengthIn READ subTickLengthIn WRITE setSubTickLengthIn) + Q_PROPERTY(int subTickLengthOut READ subTickLengthOut WRITE setSubTickLengthOut) + Q_PROPERTY(QPen basePen READ basePen WRITE setBasePen) + Q_PROPERTY(QPen tickPen READ tickPen WRITE setTickPen) + Q_PROPERTY(QPen subTickPen READ subTickPen WRITE setSubTickPen) + Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont) + Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int labelPadding READ labelPadding WRITE setLabelPadding) + Q_PROPERTY(int padding READ padding WRITE setPadding) + Q_PROPERTY(int offset READ offset WRITE setOffset) + Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged) + Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged) + Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont) + Q_PROPERTY(QFont selectedLabelFont READ selectedLabelFont WRITE setSelectedLabelFont) + Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor) + Q_PROPERTY(QColor selectedLabelColor READ selectedLabelColor WRITE setSelectedLabelColor) + Q_PROPERTY(QPen selectedBasePen READ selectedBasePen WRITE setSelectedBasePen) + Q_PROPERTY(QPen selectedTickPen READ selectedTickPen WRITE setSelectedTickPen) + Q_PROPERTY(QPen selectedSubTickPen READ selectedSubTickPen WRITE setSelectedSubTickPen) + Q_PROPERTY(QCPLineEnding lowerEnding READ lowerEnding WRITE setLowerEnding) + Q_PROPERTY(QCPLineEnding upperEnding READ upperEnding WRITE setUpperEnding) + Q_PROPERTY(QCPGrid* grid READ grid) + /// \endcond +public: + /*! + Defines at which side of the axis rect the axis will appear. This also affects how the tick + marks are drawn, on which side the labels are placed etc. + */ + enum AxisType { atLeft = 0x01 ///< 0x01 Axis is vertical and on the left side of the axis rect + ,atRight = 0x02 ///< 0x02 Axis is vertical and on the right side of the axis rect + ,atTop = 0x04 ///< 0x04 Axis is horizontal and on the top side of the axis rect + ,atBottom = 0x08 ///< 0x08 Axis is horizontal and on the bottom side of the axis rect + }; + Q_FLAGS(AxisType AxisTypes) + Q_DECLARE_FLAGS(AxisTypes, AxisType) + /*! + When automatic tick label generation is enabled (\ref setAutoTickLabels), defines how the + coordinate of the tick is interpreted, i.e. translated into a string. + + \see setTickLabelType + */ + enum LabelType { ltNumber ///< Tick coordinate is regarded as normal number and will be displayed as such. (see \ref setNumberFormat) + ,ltDateTime ///< Tick coordinate is regarded as a date/time (seconds since 1970-01-01T00:00:00 UTC) and will be displayed and formatted as such. (for details, see \ref setDateTimeFormat) + }; + Q_ENUMS(LabelType) + /*! + Defines on which side of the axis the tick labels (numbers) shall appear. + + \see setTickLabelSide + */ + enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect + ,lsOutside ///< Tick labels will be displayed outside the axis rect + }; + Q_ENUMS(LabelSide) + /*! + Defines the scale of an axis. + \see setScaleType + */ + enum ScaleType { stLinear ///< Linear scaling + ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed plots and (major) tick marks at every base power (see \ref setScaleLogBase). + }; + Q_ENUMS(ScaleType) + /*! + Defines the selectable parts of an axis. + \see setSelectableParts, setSelectedParts + */ + enum SelectablePart { spNone = 0 ///< None of the selectable parts + ,spAxis = 0x001 ///< The axis backbone and tick marks + ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually) + ,spAxisLabel = 0x004 ///< The axis label + }; + Q_FLAGS(SelectablePart SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPAxis(QCPAxisRect *parent, AxisType type); + virtual ~QCPAxis(); + + // getters: + AxisType axisType() const { return mAxisType; } + QCPAxisRect *axisRect() const { return mAxisRect; } + ScaleType scaleType() const { return mScaleType; } + double scaleLogBase() const { return mScaleLogBase; } + const QCPRange range() const { return mRange; } + bool rangeReversed() const { return mRangeReversed; } + bool autoTicks() const { return mAutoTicks; } + int autoTickCount() const { return mAutoTickCount; } + bool autoTickLabels() const { return mAutoTickLabels; } + bool autoTickStep() const { return mAutoTickStep; } + bool autoSubTicks() const { return mAutoSubTicks; } + bool ticks() const { return mTicks; } + bool tickLabels() const { return mTickLabels; } + int tickLabelPadding() const; + LabelType tickLabelType() const { return mTickLabelType; } + QFont tickLabelFont() const { return mTickLabelFont; } + QColor tickLabelColor() const { return mTickLabelColor; } + double tickLabelRotation() const; + LabelSide tickLabelSide() const; + QString dateTimeFormat() const { return mDateTimeFormat; } + Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; } + QString numberFormat() const; + int numberPrecision() const { return mNumberPrecision; } + double tickStep() const { return mTickStep; } + QVector tickVector() const { return mTickVector; } + QVector tickVectorLabels() const { return mTickVectorLabels; } + int tickLengthIn() const; + int tickLengthOut() const; + int subTickCount() const { return mSubTickCount; } + int subTickLengthIn() const; + int subTickLengthOut() const; + QPen basePen() const { return mBasePen; } + QPen tickPen() const { return mTickPen; } + QPen subTickPen() const { return mSubTickPen; } + QFont labelFont() const { return mLabelFont; } + QColor labelColor() const { return mLabelColor; } + QString label() const { return mLabel; } + int labelPadding() const; + int padding() const { return mPadding; } + int offset() const; + SelectableParts selectedParts() const { return mSelectedParts; } + SelectableParts selectableParts() const { return mSelectableParts; } + QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; } + QFont selectedLabelFont() const { return mSelectedLabelFont; } + QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; } + QColor selectedLabelColor() const { return mSelectedLabelColor; } + QPen selectedBasePen() const { return mSelectedBasePen; } + QPen selectedTickPen() const { return mSelectedTickPen; } + QPen selectedSubTickPen() const { return mSelectedSubTickPen; } + QCPLineEnding lowerEnding() const; + QCPLineEnding upperEnding() const; + QCPGrid *grid() const { return mGrid; } + + // setters: + Q_SLOT void setScaleType(QCPAxis::ScaleType type); + void setScaleLogBase(double base); + Q_SLOT void setRange(const QCPRange &range); + void setRange(double lower, double upper); + void setRange(double position, double size, Qt::AlignmentFlag alignment); + void setRangeLower(double lower); + void setRangeUpper(double upper); + void setRangeReversed(bool reversed); + void setAutoTicks(bool on); + void setAutoTickCount(int approximateCount); + void setAutoTickLabels(bool on); + void setAutoTickStep(bool on); + void setAutoSubTicks(bool on); + void setTicks(bool show); + void setTickLabels(bool show); + void setTickLabelPadding(int padding); + void setTickLabelType(LabelType type); + void setTickLabelFont(const QFont &font); + void setTickLabelColor(const QColor &color); + void setTickLabelRotation(double degrees); + void setTickLabelSide(LabelSide side); + void setDateTimeFormat(const QString &format); + void setDateTimeSpec(const Qt::TimeSpec &timeSpec); + void setNumberFormat(const QString &formatCode); + void setNumberPrecision(int precision); + void setTickStep(double step); + void setTickVector(const QVector &vec); + void setTickVectorLabels(const QVector &vec); + void setTickLength(int inside, int outside=0); + void setTickLengthIn(int inside); + void setTickLengthOut(int outside); + void setSubTickCount(int count); + void setSubTickLength(int inside, int outside=0); + void setSubTickLengthIn(int inside); + void setSubTickLengthOut(int outside); + void setBasePen(const QPen &pen); + void setTickPen(const QPen &pen); + void setSubTickPen(const QPen &pen); + void setLabelFont(const QFont &font); + void setLabelColor(const QColor &color); + void setLabel(const QString &str); + void setLabelPadding(int padding); + void setPadding(int padding); + void setOffset(int offset); + void setSelectedTickLabelFont(const QFont &font); + void setSelectedLabelFont(const QFont &font); + void setSelectedTickLabelColor(const QColor &color); + void setSelectedLabelColor(const QColor &color); + void setSelectedBasePen(const QPen &pen); + void setSelectedTickPen(const QPen &pen); + void setSelectedSubTickPen(const QPen &pen); + Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts); + void setLowerEnding(const QCPLineEnding &ending); + void setUpperEnding(const QCPLineEnding &ending); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // non-property methods: + Qt::Orientation orientation() const { return mOrientation; } + void moveRange(double diff); + void scaleRange(double factor, double center); + void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0); + void rescale(bool onlyVisiblePlottables=false); + double pixelToCoord(double value) const; + double coordToPixel(double value) const; + SelectablePart getPartAt(const QPointF &pos) const; + QList plottables() const; + QList graphs() const; + QList items() const; + + static AxisType marginSideToAxisType(QCP::MarginSide side); + static Qt::Orientation orientation(AxisType type) { return type==atBottom||type==atTop ? Qt::Horizontal : Qt::Vertical; } + static AxisType opposite(AxisType type); + +signals: + void ticksRequest(); + void rangeChanged(const QCPRange &newRange); + void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); + void scaleTypeChanged(QCPAxis::ScaleType scaleType); + void selectionChanged(const QCPAxis::SelectableParts &parts); + void selectableChanged(const QCPAxis::SelectableParts &parts); + +protected: + // property members: + // axis base: + AxisType mAxisType; + QCPAxisRect *mAxisRect; + //int mOffset; // in QCPAxisPainter + int mPadding; + Qt::Orientation mOrientation; + SelectableParts mSelectableParts, mSelectedParts; + QPen mBasePen, mSelectedBasePen; + //QCPLineEnding mLowerEnding, mUpperEnding; // in QCPAxisPainter + // axis label: + //int mLabelPadding; // in QCPAxisPainter + QString mLabel; + QFont mLabelFont, mSelectedLabelFont; + QColor mLabelColor, mSelectedLabelColor; + // tick labels: + //int mTickLabelPadding; // in QCPAxisPainter + bool mTickLabels, mAutoTickLabels; + //double mTickLabelRotation; // in QCPAxisPainter + LabelType mTickLabelType; + QFont mTickLabelFont, mSelectedTickLabelFont; + QColor mTickLabelColor, mSelectedTickLabelColor; + QString mDateTimeFormat; + Qt::TimeSpec mDateTimeSpec; + int mNumberPrecision; + QLatin1Char mNumberFormatChar; + bool mNumberBeautifulPowers; + //bool mNumberMultiplyCross; // QCPAxisPainter + // ticks and subticks: + bool mTicks; + double mTickStep; + int mSubTickCount, mAutoTickCount; + bool mAutoTicks, mAutoTickStep, mAutoSubTicks; + //int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; // QCPAxisPainter + QPen mTickPen, mSelectedTickPen; + QPen mSubTickPen, mSelectedSubTickPen; + // scale and range: + QCPRange mRange; + bool mRangeReversed; + ScaleType mScaleType; + double mScaleLogBase, mScaleLogBaseLogInv; + + // non-property members: + QCPGrid *mGrid; + QCPAxisPainterPrivate *mAxisPainter; + int mLowestVisibleTick, mHighestVisibleTick; + QVector mTickVector; + QVector mTickVectorLabels; + QVector mSubTickVector; + bool mCachedMarginValid; + int mCachedMargin; + + // introduced virtual methods: + virtual void setupTickVectors(); + virtual void generateAutoTicks(); + virtual int calculateAutoSubTickCount(double tickStep) const; + virtual int calculateMargin(); + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter); + virtual QCP::Interaction selectionCategory() const; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + + // non-virtual methods: + void visibleTickBounds(int &lowIndex, int &highIndex) const; + double baseLog(double value) const; + double basePow(double value) const; + QPen getBasePen() const; + QPen getTickPen() const; + QPen getSubTickPen() const; + QFont getTickLabelFont() const; + QFont getLabelFont() const; + QColor getTickLabelColor() const; + QColor getLabelColor() const; + +private: + Q_DISABLE_COPY(QCPAxis) + + friend class QCustomPlot; + friend class QCPGrid; + friend class QCPAxisRect; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::SelectableParts) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::AxisTypes) +Q_DECLARE_METATYPE(QCPAxis::SelectablePart) + + +class QCPAxisPainterPrivate +{ +public: + explicit QCPAxisPainterPrivate(QCustomPlot *parentPlot); + virtual ~QCPAxisPainterPrivate(); + + virtual void draw(QCPPainter *painter); + virtual int size() const; + void clearCache(); + + QRect axisSelectionBox() const { return mAxisSelectionBox; } + QRect tickLabelsSelectionBox() const { return mTickLabelsSelectionBox; } + QRect labelSelectionBox() const { return mLabelSelectionBox; } + + // public property members: + QCPAxis::AxisType type; + QPen basePen; + QCPLineEnding lowerEnding, upperEnding; // directly accessed by QCPAxis setters/getters + int labelPadding; // directly accessed by QCPAxis setters/getters + QFont labelFont; + QColor labelColor; + QString label; + int tickLabelPadding; // directly accessed by QCPAxis setters/getters + double tickLabelRotation; // directly accessed by QCPAxis setters/getters + QCPAxis::LabelSide tickLabelSide; // directly accessed by QCPAxis setters/getters + bool substituteExponent; + bool numberMultiplyCross; // directly accessed by QCPAxis setters/getters + int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters + QPen tickPen, subTickPen; + QFont tickLabelFont; + QColor tickLabelColor; + QRect axisRect, viewportRect; + double offset; // directly accessed by QCPAxis setters/getters + bool abbreviateDecimalPowers; + bool reversedEndings; + + QVector subTickPositions; + QVector tickPositions; + QVector tickLabels; + +protected: + struct CachedLabel + { + QPointF offset; + QPixmap pixmap; + }; + struct TickLabelData + { + QString basePart, expPart; + QRect baseBounds, expBounds, totalBounds, rotatedTotalBounds; + QFont baseFont, expFont; + }; + QCustomPlot *mParentPlot; + QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters + QCache mLabelCache; + QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox; + + virtual QByteArray generateLabelParameterHash() const; + + virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize); + virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const; + virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const; + virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const; + virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const; +}; + + +class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(bool antialiasedFill READ antialiasedFill WRITE setAntialiasedFill) + Q_PROPERTY(bool antialiasedScatters READ antialiasedScatters WRITE setAntialiasedScatters) + Q_PROPERTY(bool antialiasedErrorBars READ antialiasedErrorBars WRITE setAntialiasedErrorBars) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QCPAxis* keyAxis READ keyAxis WRITE setKeyAxis) + Q_PROPERTY(QCPAxis* valueAxis READ valueAxis WRITE setValueAxis) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis); + + // getters: + QString name() const { return mName; } + bool antialiasedFill() const { return mAntialiasedFill; } + bool antialiasedScatters() const { return mAntialiasedScatters; } + bool antialiasedErrorBars() const { return mAntialiasedErrorBars; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + QCPAxis *keyAxis() const { return mKeyAxis.data(); } + QCPAxis *valueAxis() const { return mValueAxis.data(); } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setName(const QString &name); + void setAntialiasedFill(bool enabled); + void setAntialiasedScatters(bool enabled); + void setAntialiasedErrorBars(bool enabled); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setKeyAxis(QCPAxis *axis); + void setValueAxis(QCPAxis *axis); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // introduced virtual methods: + virtual void clearData() = 0; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const = 0; + virtual bool addToLegend(); + virtual bool removeFromLegend() const; + + // non-property methods: + void rescaleAxes(bool onlyEnlarge=false) const; + void rescaleKeyAxis(bool onlyEnlarge=false) const; + void rescaleValueAxis(bool onlyEnlarge=false) const; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + /*! + Represents negative and positive sign domain for passing to \ref getKeyRange and \ref getValueRange. + */ + enum SignDomain { sdNegative ///< The negative sign domain, i.e. numbers smaller than zero + ,sdBoth ///< Both sign domains, including zero, i.e. all (rational) numbers + ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero + }; + + // property members: + QString mName; + bool mAntialiasedFill, mAntialiasedScatters, mAntialiasedErrorBars; + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + QPointer mKeyAxis, mValueAxis; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QRect clipRect() const; + virtual void draw(QCPPainter *painter) = 0; + virtual QCP::Interaction selectionCategory() const; + void applyDefaultAntialiasingHint(QCPPainter *painter) const; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + + // introduced virtual methods: + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const = 0; + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const = 0; + + // non-virtual methods: + void coordsToPixels(double key, double value, double &x, double &y) const; + const QPointF coordsToPixels(double key, double value) const; + void pixelsToCoords(double x, double y, double &key, double &value) const; + void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const; + QPen mainPen() const; + QBrush mainBrush() const; + void applyFillAntialiasingHint(QCPPainter *painter) const; + void applyScattersAntialiasingHint(QCPPainter *painter) const; + void applyErrorBarsAntialiasingHint(QCPPainter *painter) const; + double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const; + +private: + Q_DISABLE_COPY(QCPAbstractPlottable) + + friend class QCustomPlot; + friend class QCPAxis; + friend class QCPPlottableLegendItem; +}; + + +class QCP_LIB_DECL QCPItemAnchor +{ +public: + QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name, int anchorId=-1); + virtual ~QCPItemAnchor(); + + // getters: + QString name() const { return mName; } + virtual QPointF pixelPoint() const; + +protected: + // property members: + QString mName; + + // non-property members: + QCustomPlot *mParentPlot; + QCPAbstractItem *mParentItem; + int mAnchorId; + QSet mChildrenX, mChildrenY; + + // introduced virtual methods: + virtual QCPItemPosition *toQCPItemPosition() { return 0; } + + // non-virtual methods: + void addChildX(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + void addChildY(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + +private: + Q_DISABLE_COPY(QCPItemAnchor) + + friend class QCPItemPosition; +}; + + + +class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor +{ +public: + /*! + Defines the ways an item position can be specified. Thus it defines what the numbers passed to + \ref setCoords actually mean. + + \see setType + */ + enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget. + ,ptViewportRatio ///< Static positioning given by a fraction of the viewport size. For example, if you call setCoords(0, 0), the position will be at the top + ///< left corner of the viewport/widget. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and + ///< vertically at the top of the viewport/widget, etc. + ,ptAxisRectRatio ///< Static positioning given by a fraction of the axis rect size (see \ref setAxisRect). For example, if you call setCoords(0, 0), the position will be at the top + ///< left corner of the axis rect. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and + ///< vertically at the top of the axis rect, etc. You can also go beyond the axis rect by providing negative coordinates or coordinates larger than 1. + ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes). + }; + + QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name); + virtual ~QCPItemPosition(); + + // getters: + PositionType type() const { return typeX(); } + PositionType typeX() const { return mPositionTypeX; } + PositionType typeY() const { return mPositionTypeY; } + QCPItemAnchor *parentAnchor() const { return parentAnchorX(); } + QCPItemAnchor *parentAnchorX() const { return mParentAnchorX; } + QCPItemAnchor *parentAnchorY() const { return mParentAnchorY; } + double key() const { return mKey; } + double value() const { return mValue; } + QPointF coords() const { return QPointF(mKey, mValue); } + QCPAxis *keyAxis() const { return mKeyAxis.data(); } + QCPAxis *valueAxis() const { return mValueAxis.data(); } + QCPAxisRect *axisRect() const; + virtual QPointF pixelPoint() const; + + // setters: + void setType(PositionType type); + void setTypeX(PositionType type); + void setTypeY(PositionType type); + bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + void setCoords(double key, double value); + void setCoords(const QPointF &coords); + void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis); + void setAxisRect(QCPAxisRect *axisRect); + void setPixelPoint(const QPointF &pixelPoint); + +protected: + // property members: + PositionType mPositionTypeX, mPositionTypeY; + QPointer mKeyAxis, mValueAxis; + QPointer mAxisRect; + double mKey, mValue; + QCPItemAnchor *mParentAnchorX, *mParentAnchorY; + + // reimplemented virtual methods: + virtual QCPItemPosition *toQCPItemPosition() { return this; } + +private: + Q_DISABLE_COPY(QCPItemPosition) + +}; + + +class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool clipToAxisRect READ clipToAxisRect WRITE setClipToAxisRect) + Q_PROPERTY(QCPAxisRect* clipAxisRect READ clipAxisRect WRITE setClipAxisRect) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + QCPAbstractItem(QCustomPlot *parentPlot); + virtual ~QCPAbstractItem(); + + // getters: + bool clipToAxisRect() const { return mClipToAxisRect; } + QCPAxisRect *clipAxisRect() const; + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setClipToAxisRect(bool clip); + void setClipAxisRect(QCPAxisRect *rect); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const = 0; + + // non-virtual methods: + QList positions() const { return mPositions; } + QList anchors() const { return mAnchors; } + QCPItemPosition *position(const QString &name) const; + QCPItemAnchor *anchor(const QString &name) const; + bool hasAnchor(const QString &name) const; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + bool mClipToAxisRect; + QPointer mClipAxisRect; + QList mPositions; + QList mAnchors; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QCP::Interaction selectionCategory() const; + virtual QRect clipRect() const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter) = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + + // introduced virtual methods: + virtual QPointF anchorPixelPoint(int anchorId) const; + + // non-virtual methods: + double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const; + double rectSelectTest(const QRectF &rect, const QPointF &pos, bool filledRect) const; + QCPItemPosition *createPosition(const QString &name); + QCPItemAnchor *createAnchor(const QString &name, int anchorId); + +private: + Q_DISABLE_COPY(QCPAbstractItem) + + friend class QCustomPlot; + friend class QCPItemAnchor; +}; + + +class QCP_LIB_DECL QCustomPlot : public QWidget +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QRect viewport READ viewport WRITE setViewport) + Q_PROPERTY(QPixmap background READ background WRITE setBackground) + Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) + Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) + Q_PROPERTY(QCPLayoutGrid* plotLayout READ plotLayout) + Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend) + Q_PROPERTY(int selectionTolerance READ selectionTolerance WRITE setSelectionTolerance) + Q_PROPERTY(bool noAntialiasingOnDrag READ noAntialiasingOnDrag WRITE setNoAntialiasingOnDrag) + Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier) + /// \endcond +public: + /*! + Defines how a layer should be inserted relative to an other layer. + + \see addLayer, moveLayer + */ + enum LayerInsertMode { limBelow ///< Layer is inserted below other layer + ,limAbove ///< Layer is inserted above other layer + }; + Q_ENUMS(LayerInsertMode) + + /*! + Defines with what timing the QCustomPlot surface is refreshed after a replot. + + \see replot + */ + enum RefreshPriority { rpImmediate ///< The QCustomPlot surface is immediately refreshed, by calling QWidget::repaint() after the replot + ,rpQueued ///< Queues the refresh such that it is performed at a slightly delayed point in time after the replot, by calling QWidget::update() after the replot + ,rpHint ///< Whether to use immediate repaint or queued update depends on whether the plotting hint \ref QCP::phForceRepaint is set, see \ref setPlottingHints. + }; + + explicit QCustomPlot(QWidget *parent = 0); + virtual ~QCustomPlot(); + + // getters: + QRect viewport() const { return mViewport; } + QPixmap background() const { return mBackgroundPixmap; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + QCPLayoutGrid *plotLayout() const { return mPlotLayout; } + QCP::AntialiasedElements antialiasedElements() const { return mAntialiasedElements; } + QCP::AntialiasedElements notAntialiasedElements() const { return mNotAntialiasedElements; } + bool autoAddPlottableToLegend() const { return mAutoAddPlottableToLegend; } + const QCP::Interactions interactions() const { return mInteractions; } + int selectionTolerance() const { return mSelectionTolerance; } + bool noAntialiasingOnDrag() const { return mNoAntialiasingOnDrag; } + QCP::PlottingHints plottingHints() const { return mPlottingHints; } + Qt::KeyboardModifier multiSelectModifier() const { return mMultiSelectModifier; } + + // setters: + void setViewport(const QRect &rect); + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements); + void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true); + void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements); + void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true); + void setAutoAddPlottableToLegend(bool on); + void setInteractions(const QCP::Interactions &interactions); + void setInteraction(const QCP::Interaction &interaction, bool enabled=true); + void setSelectionTolerance(int pixels); + void setNoAntialiasingOnDrag(bool enabled); + void setPlottingHints(const QCP::PlottingHints &hints); + void setPlottingHint(QCP::PlottingHint hint, bool enabled=true); + void setMultiSelectModifier(Qt::KeyboardModifier modifier); + + // non-property methods: + // plottable interface: + QCPAbstractPlottable *plottable(int index); + QCPAbstractPlottable *plottable(); + bool addPlottable(QCPAbstractPlottable *plottable); + bool removePlottable(QCPAbstractPlottable *plottable); + bool removePlottable(int index); + int clearPlottables(); + int plottableCount() const; + QList selectedPlottables() const; + QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false) const; + bool hasPlottable(QCPAbstractPlottable *plottable) const; + + // specialized interface for QCPGraph: + QCPGraph *graph(int index) const; + QCPGraph *graph() const; + QCPGraph *addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0); + bool removeGraph(QCPGraph *graph); + bool removeGraph(int index); + int clearGraphs(); + int graphCount() const; + QList selectedGraphs() const; + + // item interface: + QCPAbstractItem *item(int index) const; + QCPAbstractItem *item() const; + bool addItem(QCPAbstractItem* item); + bool removeItem(QCPAbstractItem *item); + bool removeItem(int index); + int clearItems(); + int itemCount() const; + QList selectedItems() const; + QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const; + bool hasItem(QCPAbstractItem *item) const; + + // layer interface: + QCPLayer *layer(const QString &name) const; + QCPLayer *layer(int index) const; + QCPLayer *currentLayer() const; + bool setCurrentLayer(const QString &name); + bool setCurrentLayer(QCPLayer *layer); + int layerCount() const; + bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove); + bool removeLayer(QCPLayer *layer); + bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove); + + // axis rect/layout interface: + int axisRectCount() const; + QCPAxisRect* axisRect(int index=0) const; + QList axisRects() const; + QCPLayoutElement* layoutElementAt(const QPointF &pos) const; + Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false); + + QList selectedAxes() const; + QList selectedLegends() const; + Q_SLOT void deselectAll(); + + bool savePdf(const QString &fileName, bool noCosmeticPen=false, int width=0, int height=0, const QString &pdfCreator=QString(), const QString &pdfTitle=QString()); + bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1); + bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1); + bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0); + bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1); + QPixmap toPixmap(int width=0, int height=0, double scale=1.0); + void toPainter(QCPPainter *painter, int width=0, int height=0); + Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpHint); + + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; + QCPLegend *legend; + +signals: + void mouseDoubleClick(QMouseEvent *event); + void mousePress(QMouseEvent *event); + void mouseMove(QMouseEvent *event); + void mouseRelease(QMouseEvent *event); + void mouseWheel(QWheelEvent *event); + + void plottableClick(QCPAbstractPlottable *plottable, QMouseEvent *event); + void plottableDoubleClick(QCPAbstractPlottable *plottable, QMouseEvent *event); + void itemClick(QCPAbstractItem *item, QMouseEvent *event); + void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event); + void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + void titleClick(QMouseEvent *event, QCPPlotTitle *title); + void titleDoubleClick(QMouseEvent *event, QCPPlotTitle *title); + + void selectionChangedByUser(); + void beforeReplot(); + void afterReplot(); + +protected: + // property members: + QRect mViewport; + QCPLayoutGrid *mPlotLayout; + bool mAutoAddPlottableToLegend; + QList mPlottables; + QList mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph + QList mItems; + QList mLayers; + QCP::AntialiasedElements mAntialiasedElements, mNotAntialiasedElements; + QCP::Interactions mInteractions; + int mSelectionTolerance; + bool mNoAntialiasingOnDrag; + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayer *mCurrentLayer; + QCP::PlottingHints mPlottingHints; + Qt::KeyboardModifier mMultiSelectModifier; + + // non-property members: + QPixmap mPaintBuffer; + QPoint mMousePressPos; + QPointer mMouseEventElement; + bool mReplotting; + + // reimplemented virtual methods: + virtual QSize minimumSizeHint() const; + virtual QSize sizeHint() const; + virtual void paintEvent(QPaintEvent *event); + virtual void resizeEvent(QResizeEvent *event); + virtual void mouseDoubleClickEvent(QMouseEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void wheelEvent(QWheelEvent *event); + + // introduced virtual methods: + virtual void draw(QCPPainter *painter); + virtual void axisRemoved(QCPAxis *axis); + virtual void legendRemoved(QCPLegend *legend); + + // non-virtual methods: + void updateLayerIndices() const; + QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=0) const; + void drawBackground(QCPPainter *painter); + + friend class QCPLegend; + friend class QCPAxis; + friend class QCPLayer; + friend class QCPAxisRect; +}; + + +class QCP_LIB_DECL QCPColorGradient +{ + Q_GADGET +public: + /*! + Defines the color spaces in which color interpolation between gradient stops can be performed. + + \see setColorInterpolation + */ + enum ColorInterpolation { ciRGB ///< Color channels red, green and blue are linearly interpolated + ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance) + }; + Q_ENUMS(ColorInterpolation) + + /*! + Defines the available presets that can be loaded with \ref loadPreset. See the documentation + there for an image of the presets. + */ + enum GradientPreset { gpGrayscale ///< Continuous lightness from black to white (suited for non-biased data representation) + ,gpHot ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation) + ,gpCold ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation) + ,gpNight ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation) + ,gpCandy ///< Blue over pink to white + ,gpGeography ///< Colors suitable to represent different elevations on geographical maps + ,gpIon ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates) + ,gpThermal ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white + ,gpPolar ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values + ,gpSpectrum ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates) + ,gpJet ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates) + ,gpHues ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic) + }; + Q_ENUMS(GradientPreset) + + QCPColorGradient(GradientPreset preset=gpCold); + bool operator==(const QCPColorGradient &other) const; + bool operator!=(const QCPColorGradient &other) const { return !(*this == other); } + + // getters: + int levelCount() const { return mLevelCount; } + QMap colorStops() const { return mColorStops; } + ColorInterpolation colorInterpolation() const { return mColorInterpolation; } + bool periodic() const { return mPeriodic; } + + // setters: + void setLevelCount(int n); + void setColorStops(const QMap &colorStops); + void setColorStopAt(double position, const QColor &color); + void setColorInterpolation(ColorInterpolation interpolation); + void setPeriodic(bool enabled); + + // non-property methods: + void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); + QRgb color(double position, const QCPRange &range, bool logarithmic=false); + void loadPreset(GradientPreset preset); + void clearColorStops(); + QCPColorGradient inverted() const; + +protected: + void updateColorBuffer(); + + // property members: + int mLevelCount; + QMap mColorStops; + ColorInterpolation mColorInterpolation; + bool mPeriodic; + + // non-property members: + QVector mColorBuffer; + bool mColorBufferInvalidated; +}; + + +class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPixmap background READ background WRITE setBackground) + Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) + Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) + Q_PROPERTY(Qt::Orientations rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(Qt::Orientations rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + explicit QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true); + virtual ~QCPAxisRect(); + + // getters: + QPixmap background() const { return mBackgroundPixmap; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + Qt::Orientations rangeDrag() const { return mRangeDrag; } + Qt::Orientations rangeZoom() const { return mRangeZoom; } + QCPAxis *rangeDragAxis(Qt::Orientation orientation); + QCPAxis *rangeZoomAxis(Qt::Orientation orientation); + double rangeZoomFactor(Qt::Orientation orientation); + + // setters: + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setRangeDrag(Qt::Orientations orientations); + void setRangeZoom(Qt::Orientations orientations); + void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeZoomFactor(double horizontalFactor, double verticalFactor); + void setRangeZoomFactor(double factor); + + // non-property methods: + int axisCount(QCPAxis::AxisType type) const; + QCPAxis *axis(QCPAxis::AxisType type, int index=0) const; + QList axes(QCPAxis::AxisTypes types) const; + QList axes() const; + QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=0); + QList addAxes(QCPAxis::AxisTypes types); + bool removeAxis(QCPAxis *axis); + QCPLayoutInset *insetLayout() const { return mInsetLayout; } + + void setupFullAxesBox(bool connectRanges=false); + QList plottables() const; + QList graphs() const; + QList items() const; + + // read-only interface imitating a QRect: + int left() const { return mRect.left(); } + int right() const { return mRect.right(); } + int top() const { return mRect.top(); } + int bottom() const { return mRect.bottom(); } + int width() const { return mRect.width(); } + int height() const { return mRect.height(); } + QSize size() const { return mRect.size(); } + QPoint topLeft() const { return mRect.topLeft(); } + QPoint topRight() const { return mRect.topRight(); } + QPoint bottomLeft() const { return mRect.bottomLeft(); } + QPoint bottomRight() const { return mRect.bottomRight(); } + QPoint center() const { return mRect.center(); } + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase); + virtual QList elements(bool recursive) const; + +protected: + // property members: + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayoutInset *mInsetLayout; + Qt::Orientations mRangeDrag, mRangeZoom; + QPointer mRangeDragHorzAxis, mRangeDragVertAxis, mRangeZoomHorzAxis, mRangeZoomVertAxis; + double mRangeZoomFactorHorz, mRangeZoomFactorVert; + // non-property members: + QCPRange mDragStartHorzRange, mDragStartVertRange; + QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; + QPoint mDragStart; + bool mDragging; + QHash > mAxes; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter); + virtual int calculateAutoMargin(QCP::MarginSide side); + // events: + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void wheelEvent(QWheelEvent *event); + + // non-property methods: + void drawBackground(QCPPainter *painter); + void updateAxesOffset(QCPAxis::AxisType type); + +private: + Q_DISABLE_COPY(QCPAxisRect) + + friend class QCustomPlot; +}; + + +class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPLegend* parentLegend READ parentLegend) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectionChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectableChanged) + /// \endcond +public: + explicit QCPAbstractLegendItem(QCPLegend *parent); + + // getters: + QCPLegend *parentLegend() const { return mParentLegend; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + QCPLegend *mParentLegend; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QCP::Interaction selectionCategory() const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual QRect clipRect() const; + virtual void draw(QCPPainter *painter) = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + +private: + Q_DISABLE_COPY(QCPAbstractLegendItem) + + friend class QCPLegend; +}; + + +class QCP_LIB_DECL QCPPlottableLegendItem : public QCPAbstractLegendItem +{ + Q_OBJECT +public: + QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable); + + // getters: + QCPAbstractPlottable *plottable() { return mPlottable; } + +protected: + // property members: + QCPAbstractPlottable *mPlottable; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual QSize minimumSizeHint() const; + + // non-virtual methods: + QPen getIconBorderPen() const; + QColor getTextColor() const; + QFont getFont() const; +}; + + +class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen borderPen READ borderPen WRITE setBorderPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) + Q_PROPERTY(int iconTextPadding READ iconTextPadding WRITE setIconTextPadding) + Q_PROPERTY(QPen iconBorderPen READ iconBorderPen WRITE setIconBorderPen) + Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectionChanged) + Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectableChanged) + Q_PROPERTY(QPen selectedBorderPen READ selectedBorderPen WRITE setSelectedBorderPen) + Q_PROPERTY(QPen selectedIconBorderPen READ selectedIconBorderPen WRITE setSelectedIconBorderPen) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + /// \endcond +public: + /*! + Defines the selectable parts of a legend + + \see setSelectedParts, setSelectableParts + */ + enum SelectablePart { spNone = 0x000 ///< 0x000 None + ,spLegendBox = 0x001 ///< 0x001 The legend box (frame) + ,spItems = 0x002 ///< 0x002 Legend items individually (see \ref selectedItems) + }; + Q_FLAGS(SelectablePart SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPLegend(); + virtual ~QCPLegend(); + + // getters: + QPen borderPen() const { return mBorderPen; } + QBrush brush() const { return mBrush; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QSize iconSize() const { return mIconSize; } + int iconTextPadding() const { return mIconTextPadding; } + QPen iconBorderPen() const { return mIconBorderPen; } + SelectableParts selectableParts() const { return mSelectableParts; } + SelectableParts selectedParts() const; + QPen selectedBorderPen() const { return mSelectedBorderPen; } + QPen selectedIconBorderPen() const { return mSelectedIconBorderPen; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + + // setters: + void setBorderPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setIconSize(const QSize &size); + void setIconSize(int width, int height); + void setIconTextPadding(int padding); + void setIconBorderPen(const QPen &pen); + Q_SLOT void setSelectableParts(const SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const SelectableParts &selectedParts); + void setSelectedBorderPen(const QPen &pen); + void setSelectedIconBorderPen(const QPen &pen); + void setSelectedBrush(const QBrush &brush); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // non-virtual methods: + QCPAbstractLegendItem *item(int index) const; + QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const; + int itemCount() const; + bool hasItem(QCPAbstractLegendItem *item) const; + bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const; + bool addItem(QCPAbstractLegendItem *item); + bool removeItem(int index); + bool removeItem(QCPAbstractLegendItem *item); + void clearItems(); + QList selectedItems() const; + +signals: + void selectionChanged(QCPLegend::SelectableParts parts); + void selectableChanged(QCPLegend::SelectableParts parts); + +protected: + // property members: + QPen mBorderPen, mIconBorderPen; + QBrush mBrush; + QFont mFont; + QColor mTextColor; + QSize mIconSize; + int mIconTextPadding; + SelectableParts mSelectedParts, mSelectableParts; + QPen mSelectedBorderPen, mSelectedIconBorderPen; + QBrush mSelectedBrush; + QFont mSelectedFont; + QColor mSelectedTextColor; + + // reimplemented virtual methods: + virtual void parentPlotInitialized(QCustomPlot *parentPlot); + virtual QCP::Interaction selectionCategory() const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter); + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + + // non-virtual methods: + QPen getBorderPen() const; + QBrush getBrush() const; + +private: + Q_DISABLE_COPY(QCPLegend) + + friend class QCustomPlot; + friend class QCPAbstractLegendItem; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPLegend::SelectableParts) +Q_DECLARE_METATYPE(QCPLegend::SelectablePart) + + +class QCP_LIB_DECL QCPPlotTitle : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + explicit QCPPlotTitle(QCustomPlot *parentPlot); + explicit QCPPlotTitle(QCustomPlot *parentPlot, const QString &text); + + // getters: + QString text() const { return mText; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setText(const QString &text); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + QString mText; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + QRect mTextBoundingRect; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter); + virtual QSize minimumSizeHint() const; + virtual QSize maximumSizeHint() const; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + + // non-virtual methods: + QFont mainFont() const; + QColor mainTextColor() const; + +private: + Q_DISABLE_COPY(QCPPlotTitle) +}; + + +class QCPColorScaleAxisRectPrivate : public QCPAxisRect +{ + Q_OBJECT +public: + explicit QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale); +protected: + QCPColorScale *mParentColorScale; + QImage mGradientImage; + bool mGradientImageInvalidated; + // re-using some methods of QCPAxisRect to make them available to friend class QCPColorScale + using QCPAxisRect::calculateAutoMargin; + using QCPAxisRect::mousePressEvent; + using QCPAxisRect::mouseMoveEvent; + using QCPAxisRect::mouseReleaseEvent; + using QCPAxisRect::wheelEvent; + using QCPAxisRect::update; + virtual void draw(QCPPainter *painter); + void updateGradientImage(); + Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts); + Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts); + friend class QCPColorScale; +}; + + +class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPAxis::AxisType type READ type WRITE setType) + Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) + Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) + Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int barWidth READ barWidth WRITE setBarWidth) + Q_PROPERTY(bool rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(bool rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + explicit QCPColorScale(QCustomPlot *parentPlot); + virtual ~QCPColorScale(); + + // getters: + QCPAxis *axis() const { return mColorAxis.data(); } + QCPAxis::AxisType type() const { return mType; } + QCPRange dataRange() const { return mDataRange; } + QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } + QCPColorGradient gradient() const { return mGradient; } + QString label() const; + int barWidth () const { return mBarWidth; } + bool rangeDrag() const; + bool rangeZoom() const; + + // setters: + void setType(QCPAxis::AxisType type); + Q_SLOT void setDataRange(const QCPRange &dataRange); + Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); + Q_SLOT void setGradient(const QCPColorGradient &gradient); + void setLabel(const QString &str); + void setBarWidth(int width); + void setRangeDrag(bool enabled); + void setRangeZoom(bool enabled); + + // non-property methods: + QList colorMaps() const; + void rescaleDataRange(bool onlyVisibleMaps); + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase); + +signals: + void dataRangeChanged(QCPRange newRange); + void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + void gradientChanged(QCPColorGradient newGradient); + +protected: + // property members: + QCPAxis::AxisType mType; + QCPRange mDataRange; + QCPAxis::ScaleType mDataScaleType; + QCPColorGradient mGradient; + int mBarWidth; + + // non-property members: + QPointer mAxisRect; + QPointer mColorAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + // events: + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void wheelEvent(QWheelEvent *event); + +private: + Q_DISABLE_COPY(QCPColorScale) + + friend class QCPColorScaleAxisRectPrivate; +}; + + +/*! \file */ + + + +class QCP_LIB_DECL QCPData +{ +public: + QCPData(); + QCPData(double key, double value); + double key, value; + double keyErrorPlus, keyErrorMinus; + double valueErrorPlus, valueErrorMinus; +}; +Q_DECLARE_TYPEINFO(QCPData, Q_MOVABLE_TYPE); + +/*! \typedef QCPDataMap + Container for storing \ref QCPData items in a sorted fashion. The key of the map + is the key member of the QCPData instance. + + This is the container in which QCPGraph holds its data. + \see QCPData, QCPGraph::setData +*/ +typedef QMap QCPDataMap; +typedef QMapIterator QCPDataMapIterator; +typedef QMutableMapIterator QCPDataMutableMapIterator; + + +class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) + Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) + Q_PROPERTY(ErrorType errorType READ errorType WRITE setErrorType) + Q_PROPERTY(QPen errorPen READ errorPen WRITE setErrorPen) + Q_PROPERTY(double errorBarSize READ errorBarSize WRITE setErrorBarSize) + Q_PROPERTY(bool errorBarSkipSymbol READ errorBarSkipSymbol WRITE setErrorBarSkipSymbol) + Q_PROPERTY(QCPGraph* channelFillGraph READ channelFillGraph WRITE setChannelFillGraph) + Q_PROPERTY(bool adaptiveSampling READ adaptiveSampling WRITE setAdaptiveSampling) + /// \endcond +public: + /*! + Defines how the graph's line is represented visually in the plot. The line is drawn with the + current pen of the graph (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< data points are not connected with any lines (e.g. data only represented + ///< with symbols according to the scatter style, see \ref setScatterStyle) + ,lsLine ///< data points are connected by a straight line + ,lsStepLeft ///< line is drawn as steps where the step height is the value of the left data point + ,lsStepRight ///< line is drawn as steps where the step height is the value of the right data point + ,lsStepCenter ///< line is drawn as steps where the step is in between two data points + ,lsImpulse ///< each data point is represented by a line parallel to the value axis, which reaches from the data point to the zero-value-line + }; + Q_ENUMS(LineStyle) + /*! + Defines what kind of error bars are drawn for each data point + */ + enum ErrorType { etNone ///< No error bars are shown + ,etKey ///< Error bars for the key dimension of the data point are shown + ,etValue ///< Error bars for the value dimension of the data point are shown + ,etBoth ///< Error bars for both key and value dimensions of the data point are shown + }; + Q_ENUMS(ErrorType) + + explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPGraph(); + + // getters: + QCPDataMap *data() const { return mData; } + LineStyle lineStyle() const { return mLineStyle; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + ErrorType errorType() const { return mErrorType; } + QPen errorPen() const { return mErrorPen; } + double errorBarSize() const { return mErrorBarSize; } + bool errorBarSkipSymbol() const { return mErrorBarSkipSymbol; } + QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); } + bool adaptiveSampling() const { return mAdaptiveSampling; } + + // setters: + void setData(QCPDataMap *data, bool copy=false); + void setData(const QVector &key, const QVector &value); + void setDataKeyError(const QVector &key, const QVector &value, const QVector &keyError); + void setDataKeyError(const QVector &key, const QVector &value, const QVector &keyErrorMinus, const QVector &keyErrorPlus); + void setDataValueError(const QVector &key, const QVector &value, const QVector &valueError); + void setDataValueError(const QVector &key, const QVector &value, const QVector &valueErrorMinus, const QVector &valueErrorPlus); + void setDataBothError(const QVector &key, const QVector &value, const QVector &keyError, const QVector &valueError); + void setDataBothError(const QVector &key, const QVector &value, const QVector &keyErrorMinus, const QVector &keyErrorPlus, const QVector &valueErrorMinus, const QVector &valueErrorPlus); + void setLineStyle(LineStyle ls); + void setScatterStyle(const QCPScatterStyle &style); + void setErrorType(ErrorType errorType); + void setErrorPen(const QPen &pen); + void setErrorBarSize(double size); + void setErrorBarSkipSymbol(bool enabled); + void setChannelFillGraph(QCPGraph *targetGraph); + void setAdaptiveSampling(bool enabled); + + // non-property methods: + void addData(const QCPDataMap &dataMap); + void addData(const QCPData &data); + void addData(double key, double value); + void addData(const QVector &keys, const QVector &values); + void removeDataBefore(double key); + void removeDataAfter(double key); + void removeData(double fromKey, double toKey); + void removeData(double key); + + // reimplemented virtual methods: + virtual void clearData(); + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + using QCPAbstractPlottable::rescaleAxes; + using QCPAbstractPlottable::rescaleKeyAxis; + using QCPAbstractPlottable::rescaleValueAxis; + void rescaleAxes(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface + void rescaleKeyAxis(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface + void rescaleValueAxis(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface + +protected: + // property members: + QCPDataMap *mData; + QPen mErrorPen; + LineStyle mLineStyle; + QCPScatterStyle mScatterStyle; + ErrorType mErrorType; + double mErrorBarSize; + bool mErrorBarSkipSymbol; + QPointer mChannelFillGraph; + bool mAdaptiveSampling; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface + + // introduced virtual methods: + virtual void drawFill(QCPPainter *painter, QVector *lineData) const; + virtual void drawScatterPlot(QCPPainter *painter, QVector *scatterData) const; + virtual void drawLinePlot(QCPPainter *painter, QVector *lineData) const; + virtual void drawImpulsePlot(QCPPainter *painter, QVector *lineData) const; + + // non-virtual methods: + void getPreparedData(QVector *lineData, QVector *scatterData) const; + void getPlotData(QVector *lineData, QVector *scatterData) const; + void getScatterPlotData(QVector *scatterData) const; + void getLinePlotData(QVector *linePixelData, QVector *scatterData) const; + void getStepLeftPlotData(QVector *linePixelData, QVector *scatterData) const; + void getStepRightPlotData(QVector *linePixelData, QVector *scatterData) const; + void getStepCenterPlotData(QVector *linePixelData, QVector *scatterData) const; + void getImpulsePlotData(QVector *linePixelData, QVector *scatterData) const; + void drawError(QCPPainter *painter, double x, double y, const QCPData &data) const; + void getVisibleDataBounds(QCPDataMap::const_iterator &lower, QCPDataMap::const_iterator &upper) const; + int countDataInBounds(const QCPDataMap::const_iterator &lower, const QCPDataMap::const_iterator &upper, int maxCount) const; + void addFillBasePoints(QVector *lineData) const; + void removeFillBasePoints(QVector *lineData) const; + QPointF lowerFillBasePoint(double lowerKey) const; + QPointF upperFillBasePoint(double upperKey) const; + const QPolygonF getChannelFillPolygon(const QVector *lineData) const; + int findIndexBelowX(const QVector *data, double x) const; + int findIndexAboveX(const QVector *data, double x) const; + int findIndexBelowY(const QVector *data, double y) const; + int findIndexAboveY(const QVector *data, double y) const; + double pointDistance(const QPointF &pixelPoint) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + + +/*! \file */ + + + +class QCP_LIB_DECL QCPCurveData +{ +public: + QCPCurveData(); + QCPCurveData(double t, double key, double value); + double t, key, value; +}; +Q_DECLARE_TYPEINFO(QCPCurveData, Q_MOVABLE_TYPE); + +/*! \typedef QCPCurveDataMap + Container for storing \ref QCPCurveData items in a sorted fashion. The key of the map + is the t member of the QCPCurveData instance. + + This is the container in which QCPCurve holds its data. + \see QCPCurveData, QCPCurve::setData +*/ + +typedef QMap QCPCurveDataMap; +typedef QMapIterator QCPCurveDataMapIterator; +typedef QMutableMapIterator QCPCurveDataMutableMapIterator; + + +class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) + Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) + /// \endcond +public: + /*! + Defines how the curve's line is represented visually in the plot. The line is drawn with the + current pen of the curve (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< No line is drawn between data points (e.g. only scatters) + ,lsLine ///< Data points are connected with a straight line + }; + explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPCurve(); + + // getters: + QCPCurveDataMap *data() const { return mData; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + LineStyle lineStyle() const { return mLineStyle; } + + // setters: + void setData(QCPCurveDataMap *data, bool copy=false); + void setData(const QVector &t, const QVector &key, const QVector &value); + void setData(const QVector &key, const QVector &value); + void setScatterStyle(const QCPScatterStyle &style); + void setLineStyle(LineStyle style); + + // non-property methods: + void addData(const QCPCurveDataMap &dataMap); + void addData(const QCPCurveData &data); + void addData(double t, double key, double value); + void addData(double key, double value); + void addData(const QVector &ts, const QVector &keys, const QVector &values); + void removeDataBefore(double t); + void removeDataAfter(double t); + void removeData(double fromt, double tot); + void removeData(double t); + + // reimplemented virtual methods: + virtual void clearData(); + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + +protected: + // property members: + QCPCurveDataMap *mData; + QCPScatterStyle mScatterStyle; + LineStyle mLineStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + + // introduced virtual methods: + virtual void drawScatterPlot(QCPPainter *painter, const QVector *pointData) const; + + // non-virtual methods: + void getCurveData(QVector *lineData) const; + int getRegion(double x, double y, double rectLeft, double rectTop, double rectRight, double rectBottom) const; + QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom) const; + QVector getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom) const; + bool mayTraverse(int prevRegion, int currentRegion) const; + bool getTraverse(double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom, QPointF &crossA, QPointF &crossB) const; + void getTraverseCornerPoints(int prevRegion, int currentRegion, double rectLeft, double rectTop, double rectRight, double rectBottom, QVector &beforeTraverse, QVector &afterTraverse) const; + double pointDistance(const QPointF &pixelPoint) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + + +/*! \file */ + + + +class QCP_LIB_DECL QCPBarsGroup : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(SpacingType spacingType READ spacingType WRITE setSpacingType) + Q_PROPERTY(double spacing READ spacing WRITE setSpacing) + /// \endcond +public: + /*! + Defines the ways the spacing between bars in the group can be specified. Thus it defines what + the number passed to \ref setSpacing actually means. + + \see setSpacingType, setSpacing + */ + enum SpacingType { stAbsolute ///< Bar spacing is in absolute pixels + ,stAxisRectRatio ///< Bar spacing is given by a fraction of the axis rect size + ,stPlotCoords ///< Bar spacing is in key coordinates and thus scales with the key axis range + }; + QCPBarsGroup(QCustomPlot *parentPlot); + ~QCPBarsGroup(); + + // getters: + SpacingType spacingType() const { return mSpacingType; } + double spacing() const { return mSpacing; } + + // setters: + void setSpacingType(SpacingType spacingType); + void setSpacing(double spacing); + + // non-virtual methods: + QList bars() const { return mBars; } + QCPBars* bars(int index) const; + int size() const { return mBars.size(); } + bool isEmpty() const { return mBars.isEmpty(); } + void clear(); + bool contains(QCPBars *bars) const { return mBars.contains(bars); } + void append(QCPBars *bars); + void insert(int i, QCPBars *bars); + void remove(QCPBars *bars); + +protected: + // non-property members: + QCustomPlot *mParentPlot; + SpacingType mSpacingType; + double mSpacing; + QList mBars; + + // non-virtual methods: + void registerBars(QCPBars *bars); + void unregisterBars(QCPBars *bars); + + // virtual methods: + double keyPixelOffset(const QCPBars *bars, double keyCoord); + double getPixelSpacing(const QCPBars *bars, double keyCoord); + +private: + Q_DISABLE_COPY(QCPBarsGroup) + + friend class QCPBars; +}; + + +class QCP_LIB_DECL QCPBarData +{ +public: + QCPBarData(); + QCPBarData(double key, double value); + double key, value; +}; +Q_DECLARE_TYPEINFO(QCPBarData, Q_MOVABLE_TYPE); + +/*! \typedef QCPBarDataMap + Container for storing \ref QCPBarData items in a sorted fashion. The key of the map + is the key member of the QCPBarData instance. + + This is the container in which QCPBars holds its data. + \see QCPBarData, QCPBars::setData +*/ +typedef QMap QCPBarDataMap; +typedef QMapIterator QCPBarDataMapIterator; +typedef QMutableMapIterator QCPBarDataMutableMapIterator; + + +class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) + Q_PROPERTY(QCPBarsGroup* barsGroup READ barsGroup WRITE setBarsGroup) + Q_PROPERTY(double baseValue READ baseValue WRITE setBaseValue) + Q_PROPERTY(QCPBars* barBelow READ barBelow) + Q_PROPERTY(QCPBars* barAbove READ barAbove) + /// \endcond +public: + /*! + Defines the ways the width of the bar can be specified. Thus it defines what the number passed + to \ref setWidth actually means. + + \see setWidthType, setWidth + */ + enum WidthType { wtAbsolute ///< Bar width is in absolute pixels + ,wtAxisRectRatio ///< Bar width is given by a fraction of the axis rect size + ,wtPlotCoords ///< Bar width is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(WidthType) + + explicit QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPBars(); + + // getters: + double width() const { return mWidth; } + WidthType widthType() const { return mWidthType; } + QCPBarsGroup *barsGroup() const { return mBarsGroup; } + double baseValue() const { return mBaseValue; } + QCPBars *barBelow() const { return mBarBelow.data(); } + QCPBars *barAbove() const { return mBarAbove.data(); } + QCPBarDataMap *data() const { return mData; } + + // setters: + void setWidth(double width); + void setWidthType(WidthType widthType); + void setBarsGroup(QCPBarsGroup *barsGroup); + void setBaseValue(double baseValue); + void setData(QCPBarDataMap *data, bool copy=false); + void setData(const QVector &key, const QVector &value); + + // non-property methods: + void moveBelow(QCPBars *bars); + void moveAbove(QCPBars *bars); + void addData(const QCPBarDataMap &dataMap); + void addData(const QCPBarData &data); + void addData(double key, double value); + void addData(const QVector &keys, const QVector &values); + void removeDataBefore(double key); + void removeDataAfter(double key); + void removeData(double fromKey, double toKey); + void removeData(double key); + + // reimplemented virtual methods: + virtual void clearData(); + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + +protected: + // property members: + QCPBarDataMap *mData; + double mWidth; + WidthType mWidthType; + QCPBarsGroup *mBarsGroup; + double mBaseValue; + QPointer mBarBelow, mBarAbove; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + + // non-virtual methods: + void getVisibleDataBounds(QCPBarDataMap::const_iterator &lower, QCPBarDataMap::const_iterator &upperEnd) const; + QPolygonF getBarPolygon(double key, double value) const; + void getPixelWidth(double key, double &lower, double &upper) const; + double getStackedBaseValue(double key, bool positive) const; + static void connectBars(QCPBars* lower, QCPBars* upper); + + friend class QCustomPlot; + friend class QCPLegend; + friend class QCPBarsGroup; +}; + + +/*! \file */ + + + +class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(double key READ key WRITE setKey) + Q_PROPERTY(double minimum READ minimum WRITE setMinimum) + Q_PROPERTY(double lowerQuartile READ lowerQuartile WRITE setLowerQuartile) + Q_PROPERTY(double median READ median WRITE setMedian) + Q_PROPERTY(double upperQuartile READ upperQuartile WRITE setUpperQuartile) + Q_PROPERTY(double maximum READ maximum WRITE setMaximum) + Q_PROPERTY(QVector outliers READ outliers WRITE setOutliers) + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) + Q_PROPERTY(QPen whiskerPen READ whiskerPen WRITE setWhiskerPen) + Q_PROPERTY(QPen whiskerBarPen READ whiskerBarPen WRITE setWhiskerBarPen) + Q_PROPERTY(QPen medianPen READ medianPen WRITE setMedianPen) + Q_PROPERTY(QCPScatterStyle outlierStyle READ outlierStyle WRITE setOutlierStyle) + /// \endcond +public: + explicit QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis); + + // getters: + double key() const { return mKey; } + double minimum() const { return mMinimum; } + double lowerQuartile() const { return mLowerQuartile; } + double median() const { return mMedian; } + double upperQuartile() const { return mUpperQuartile; } + double maximum() const { return mMaximum; } + QVector outliers() const { return mOutliers; } + double width() const { return mWidth; } + double whiskerWidth() const { return mWhiskerWidth; } + QPen whiskerPen() const { return mWhiskerPen; } + QPen whiskerBarPen() const { return mWhiskerBarPen; } + QPen medianPen() const { return mMedianPen; } + QCPScatterStyle outlierStyle() const { return mOutlierStyle; } + + // setters: + void setKey(double key); + void setMinimum(double value); + void setLowerQuartile(double value); + void setMedian(double value); + void setUpperQuartile(double value); + void setMaximum(double value); + void setOutliers(const QVector &values); + void setData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum); + void setWidth(double width); + void setWhiskerWidth(double width); + void setWhiskerPen(const QPen &pen); + void setWhiskerBarPen(const QPen &pen); + void setMedianPen(const QPen &pen); + void setOutlierStyle(const QCPScatterStyle &style); + + // non-property methods: + virtual void clearData(); + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + +protected: + // property members: + QVector mOutliers; + double mKey, mMinimum, mLowerQuartile, mMedian, mUpperQuartile, mMaximum; + double mWidth; + double mWhiskerWidth; + QPen mWhiskerPen, mWhiskerBarPen, mMedianPen; + QCPScatterStyle mOutlierStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + + // introduced virtual methods: + virtual void drawQuartileBox(QCPPainter *painter, QRectF *quartileBox=0) const; + virtual void drawMedian(QCPPainter *painter) const; + virtual void drawWhiskers(QCPPainter *painter) const; + virtual void drawOutliers(QCPPainter *painter) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + + +class QCP_LIB_DECL QCPColorMapData +{ +public: + QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange); + ~QCPColorMapData(); + QCPColorMapData(const QCPColorMapData &other); + QCPColorMapData &operator=(const QCPColorMapData &other); + + // getters: + int keySize() const { return mKeySize; } + int valueSize() const { return mValueSize; } + QCPRange keyRange() const { return mKeyRange; } + QCPRange valueRange() const { return mValueRange; } + QCPRange dataBounds() const { return mDataBounds; } + double data(double key, double value); + double cell(int keyIndex, int valueIndex); + + // setters: + void setSize(int keySize, int valueSize); + void setKeySize(int keySize); + void setValueSize(int valueSize); + void setRange(const QCPRange &keyRange, const QCPRange &valueRange); + void setKeyRange(const QCPRange &keyRange); + void setValueRange(const QCPRange &valueRange); + void setData(double key, double value, double z); + void setCell(int keyIndex, int valueIndex, double z); + + // non-property methods: + void recalculateDataBounds(); + void clear(); + void fill(double z); + bool isEmpty() const { return mIsEmpty; } + void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const; + void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const; + +protected: + // property members: + int mKeySize, mValueSize; + QCPRange mKeyRange, mValueRange; + bool mIsEmpty; + // non-property members: + double *mData; + QCPRange mDataBounds; + bool mDataModified; + + friend class QCPColorMap; +}; + + +class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) + Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) + Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) + Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate) + Q_PROPERTY(bool tightBoundary READ tightBoundary WRITE setTightBoundary) + Q_PROPERTY(QCPColorScale* colorScale READ colorScale WRITE setColorScale) + /// \endcond +public: + explicit QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPColorMap(); + + // getters: + QCPColorMapData *data() const { return mMapData; } + QCPRange dataRange() const { return mDataRange; } + QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } + bool interpolate() const { return mInterpolate; } + bool tightBoundary() const { return mTightBoundary; } + QCPColorGradient gradient() const { return mGradient; } + QCPColorScale *colorScale() const { return mColorScale.data(); } + + // setters: + void setData(QCPColorMapData *data, bool copy=false); + Q_SLOT void setDataRange(const QCPRange &dataRange); + Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); + Q_SLOT void setGradient(const QCPColorGradient &gradient); + void setInterpolate(bool enabled); + void setTightBoundary(bool enabled); + void setColorScale(QCPColorScale *colorScale); + + // non-property methods: + void rescaleDataRange(bool recalculateDataBounds=false); + Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18)); + + // reimplemented virtual methods: + virtual void clearData(); + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + +signals: + void dataRangeChanged(QCPRange newRange); + void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + void gradientChanged(QCPColorGradient newGradient); + +protected: + // property members: + QCPRange mDataRange; + QCPAxis::ScaleType mDataScaleType; + QCPColorMapData *mMapData; + QCPColorGradient mGradient; + bool mInterpolate; + bool mTightBoundary; + QPointer mColorScale; + // non-property members: + QImage mMapImage, mUndersampledMapImage; + QPixmap mLegendIcon; + bool mMapImageInvalidated; + + // introduced virtual methods: + virtual void updateMapImage(); + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + + +/*! \file */ + + + +class QCP_LIB_DECL QCPFinancialData +{ +public: + QCPFinancialData(); + QCPFinancialData(double key, double open, double high, double low, double close); + double key, open, high, low, close; +}; +Q_DECLARE_TYPEINFO(QCPFinancialData, Q_MOVABLE_TYPE); + +/*! \typedef QCPFinancialDataMap + Container for storing \ref QCPFinancialData items in a sorted fashion. The key of the map + is the key member of the QCPFinancialData instance. + + This is the container in which QCPFinancial holds its data. + \see QCPFinancial, QCPFinancial::setData +*/ +typedef QMap QCPFinancialDataMap; +typedef QMapIterator QCPFinancialDataMapIterator; +typedef QMutableMapIterator QCPFinancialDataMutableMapIterator; + + +class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(ChartStyle chartStyle READ chartStyle WRITE setChartStyle) + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(bool twoColored READ twoColored WRITE setTwoColored) + Q_PROPERTY(QBrush brushPositive READ brushPositive WRITE setBrushPositive) + Q_PROPERTY(QBrush brushNegative READ brushNegative WRITE setBrushNegative) + Q_PROPERTY(QPen penPositive READ penPositive WRITE setPenPositive) + Q_PROPERTY(QPen penNegative READ penNegative WRITE setPenNegative) + /// \endcond +public: + /*! + Defines the possible representations of OHLC data in the plot. + + \see setChartStyle + */ + enum ChartStyle { csOhlc ///< Open-High-Low-Close bar representation + ,csCandlestick ///< Candlestick representation + }; + Q_ENUMS(ChartStyle) + + explicit QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPFinancial(); + + // getters: + QCPFinancialDataMap *data() const { return mData; } + ChartStyle chartStyle() const { return mChartStyle; } + double width() const { return mWidth; } + bool twoColored() const { return mTwoColored; } + QBrush brushPositive() const { return mBrushPositive; } + QBrush brushNegative() const { return mBrushNegative; } + QPen penPositive() const { return mPenPositive; } + QPen penNegative() const { return mPenNegative; } + + + // setters: + void setData(QCPFinancialDataMap *data, bool copy=false); + void setData(const QVector &key, const QVector &open, const QVector &high, const QVector &low, const QVector &close); + void setChartStyle(ChartStyle style); + void setWidth(double width); + void setTwoColored(bool twoColored); + void setBrushPositive(const QBrush &brush); + void setBrushNegative(const QBrush &brush); + void setPenPositive(const QPen &pen); + void setPenNegative(const QPen &pen); + + // non-property methods: + void addData(const QCPFinancialDataMap &dataMap); + void addData(const QCPFinancialData &data); + void addData(double key, double open, double high, double low, double close); + void addData(const QVector &key, const QVector &open, const QVector &high, const QVector &low, const QVector &close); + void removeDataBefore(double key); + void removeDataAfter(double key); + void removeData(double fromKey, double toKey); + void removeData(double key); + + // reimplemented virtual methods: + virtual void clearData(); + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // static methods: + static QCPFinancialDataMap timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset = 0); + +protected: + // property members: + QCPFinancialDataMap *mData; + ChartStyle mChartStyle; + double mWidth; + bool mTwoColored; + QBrush mBrushPositive, mBrushNegative; + QPen mPenPositive, mPenNegative; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + + // non-virtual methods: + void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end); + void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end); + double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) const; + double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) const; + void getVisibleDataBounds(QCPFinancialDataMap::const_iterator &lower, QCPFinancialDataMap::const_iterator &upper) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + + +class QCP_LIB_DECL QCPItemStraightLine : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + /// \endcond +public: + QCPItemStraightLine(QCustomPlot *parentPlot); + virtual ~QCPItemStraightLine(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const point1; + QCPItemPosition * const point2; + +protected: + // property members: + QPen mPen, mSelectedPen; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + + // non-virtual methods: + double distToStraightLine(const QVector2D &point1, const QVector2D &vec, const QVector2D &point) const; + QLineF getRectClippedStraightLine(const QVector2D &point1, const QVector2D &vec, const QRect &rect) const; + QPen mainPen() const; +}; + + +class QCP_LIB_DECL QCPItemLine : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) + Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) + /// \endcond +public: + QCPItemLine(QCustomPlot *parentPlot); + virtual ~QCPItemLine(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const start; + QCPItemPosition * const end; + +protected: + // property members: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + + // non-virtual methods: + QLineF getRectClippedLine(const QVector2D &start, const QVector2D &end, const QRect &rect) const; + QPen mainPen() const; +}; + + +class QCP_LIB_DECL QCPItemCurve : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) + Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) + /// \endcond +public: + QCPItemCurve(QCustomPlot *parentPlot); + virtual ~QCPItemCurve(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const start; + QCPItemPosition * const startDir; + QCPItemPosition * const endDir; + QCPItemPosition * const end; + +protected: + // property members: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + + // non-virtual methods: + QPen mainPen() const; +}; + + +class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + /// \endcond +public: + QCPItemRect(QCustomPlot *parentPlot); + virtual ~QCPItemRect(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + + +class QCP_LIB_DECL QCPItemText : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QColor color READ color WRITE setColor) + Q_PROPERTY(QColor selectedColor READ selectedColor WRITE setSelectedColor) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(Qt::Alignment positionAlignment READ positionAlignment WRITE setPositionAlignment) + Q_PROPERTY(Qt::Alignment textAlignment READ textAlignment WRITE setTextAlignment) + Q_PROPERTY(double rotation READ rotation WRITE setRotation) + Q_PROPERTY(QMargins padding READ padding WRITE setPadding) + /// \endcond +public: + QCPItemText(QCustomPlot *parentPlot); + virtual ~QCPItemText(); + + // getters: + QColor color() const { return mColor; } + QColor selectedColor() const { return mSelectedColor; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont font() const { return mFont; } + QFont selectedFont() const { return mSelectedFont; } + QString text() const { return mText; } + Qt::Alignment positionAlignment() const { return mPositionAlignment; } + Qt::Alignment textAlignment() const { return mTextAlignment; } + double rotation() const { return mRotation; } + QMargins padding() const { return mPadding; } + + // setters; + void setColor(const QColor &color); + void setSelectedColor(const QColor &color); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setFont(const QFont &font); + void setSelectedFont(const QFont &font); + void setText(const QString &text); + void setPositionAlignment(Qt::Alignment alignment); + void setTextAlignment(Qt::Alignment alignment); + void setRotation(double degrees); + void setPadding(const QMargins &padding); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const position; + QCPItemAnchor * const topLeft; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRight; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTopLeft, aiTop, aiTopRight, aiRight, aiBottomRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QColor mColor, mSelectedColor; + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + QFont mFont, mSelectedFont; + QString mText; + Qt::Alignment mPositionAlignment; + Qt::Alignment mTextAlignment; + double mRotation; + QMargins mPadding; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // non-virtual methods: + QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const; + QFont mainFont() const; + QColor mainColor() const; + QPen mainPen() const; + QBrush mainBrush() const; +}; + + +class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + /// \endcond +public: + QCPItemEllipse(QCustomPlot *parentPlot); + virtual ~QCPItemEllipse(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const topLeftRim; + QCPItemAnchor * const top; + QCPItemAnchor * const topRightRim; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRightRim; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeftRim; + QCPItemAnchor * const left; + QCPItemAnchor * const center; + +protected: + enum AnchorIndex {aiTopLeftRim, aiTop, aiTopRightRim, aiRight, aiBottomRightRim, aiBottom, aiBottomLeftRim, aiLeft, aiCenter}; + + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + + +class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) + Q_PROPERTY(bool scaled READ scaled WRITE setScaled) + Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode) + Q_PROPERTY(Qt::TransformationMode transformationMode READ transformationMode) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + /// \endcond +public: + QCPItemPixmap(QCustomPlot *parentPlot); + virtual ~QCPItemPixmap(); + + // getters: + QPixmap pixmap() const { return mPixmap; } + bool scaled() const { return mScaled; } + Qt::AspectRatioMode aspectRatioMode() const { return mAspectRatioMode; } + Qt::TransformationMode transformationMode() const { return mTransformationMode; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPixmap(const QPixmap &pixmap); + void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QPixmap mPixmap; + QPixmap mScaledPixmap; + bool mScaled; + bool mScaledPixmapInvalidated; + Qt::AspectRatioMode mAspectRatioMode; + Qt::TransformationMode mTransformationMode; + QPen mPen, mSelectedPen; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // non-virtual methods: + void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false); + QRect getFinalRect(bool *flippedHorz=0, bool *flippedVert=0) const; + QPen mainPen() const; +}; + + +class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(double size READ size WRITE setSize) + Q_PROPERTY(TracerStyle style READ style WRITE setStyle) + Q_PROPERTY(QCPGraph* graph READ graph WRITE setGraph) + Q_PROPERTY(double graphKey READ graphKey WRITE setGraphKey) + Q_PROPERTY(bool interpolating READ interpolating WRITE setInterpolating) + /// \endcond +public: + /*! + The different visual appearances a tracer item can have. Some styles size may be controlled with \ref setSize. + + \see setStyle + */ + enum TracerStyle { tsNone ///< The tracer is not visible + ,tsPlus ///< A plus shaped crosshair with limited size + ,tsCrosshair ///< A plus shaped crosshair which spans the complete axis rect + ,tsCircle ///< A circle + ,tsSquare ///< A square + }; + Q_ENUMS(TracerStyle) + + QCPItemTracer(QCustomPlot *parentPlot); + virtual ~QCPItemTracer(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + double size() const { return mSize; } + TracerStyle style() const { return mStyle; } + QCPGraph *graph() const { return mGraph; } + double graphKey() const { return mGraphKey; } + bool interpolating() const { return mInterpolating; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setSize(double size); + void setStyle(TracerStyle style); + void setGraph(QCPGraph *graph); + void setGraphKey(double key); + void setInterpolating(bool enabled); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // non-virtual methods: + void updatePosition(); + + QCPItemPosition * const position; + +protected: + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + double mSize; + TracerStyle mStyle; + QCPGraph *mGraph; + double mGraphKey; + bool mInterpolating; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + + +class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(double length READ length WRITE setLength) + Q_PROPERTY(BracketStyle style READ style WRITE setStyle) + /// \endcond +public: + enum BracketStyle { bsSquare ///< A brace with angled edges + ,bsRound ///< A brace with round edges + ,bsCurly ///< A curly brace + ,bsCalligraphic ///< A curly brace with varying stroke width giving a calligraphic impression + }; + + QCPItemBracket(QCustomPlot *parentPlot); + virtual ~QCPItemBracket(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + double length() const { return mLength; } + BracketStyle style() const { return mStyle; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setLength(double length); + void setStyle(BracketStyle style); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const left; + QCPItemPosition * const right; + QCPItemAnchor * const center; + +protected: + // property members: + enum AnchorIndex {aiCenter}; + QPen mPen, mSelectedPen; + double mLength; + BracketStyle mStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // non-virtual methods: + QPen mainPen() const; +}; + +#endif // QCUSTOMPLOT_H + diff --git a/Desktop_Interface/ui_elements/qcp1/qcustomplot.h.REMOVED.git-id b/Desktop_Interface/ui_elements/qcp1/qcustomplot.h.REMOVED.git-id deleted file mode 100644 index 8ca181cd..00000000 --- a/Desktop_Interface/ui_elements/qcp1/qcustomplot.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bb998f1c50a6c4b0c0635465c1fd522367a84ed3 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/qcp2/qcustomplot.cpp b/Desktop_Interface/ui_elements/qcp2/qcustomplot.cpp new file mode 100644 index 00000000..e55d10a3 --- /dev/null +++ b/Desktop_Interface/ui_elements/qcp2/qcustomplot.cpp @@ -0,0 +1,29757 @@ +/*************************************************************************** +** ** +** QCustomPlot, an easy to use, modern plotting widget for Qt ** +** Copyright (C) 2011-2016 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.qcustomplot.com/ ** +** Date: 13.09.16 ** +** Version: 2.0.0-beta ** +****************************************************************************/ + +#include "qcustomplot.h" + + +/* including file 'src/vector2d.cpp', size 7340 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPVector2D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPVector2D + \brief Represents two doubles as a mathematical 2D vector + + This class acts as a replacement for QVector2D with the advantage of double precision instead of + single, and some convenience methods tailored for the QCustomPlot library. +*/ + +/* start documentation of inline functions */ + +/*! \fn void QCPVector2D::setX(double x) + + Sets the x coordinate of this vector to \a x. + + \see setY +*/ + +/*! \fn void QCPVector2D::setY(double y) + + Sets the y coordinate of this vector to \a y. + + \see setX +*/ + +/*! \fn double QCPVector2D::length() const + + Returns the length of this vector. + + \see lengthSquared +*/ + +/*! \fn double QCPVector2D::lengthSquared() const + + Returns the squared length of this vector. In some situations, e.g. when just trying to find the + shortest vector of a group, this is faster than calculating \ref length, because it avoids + calculation of a square root. + + \see length +*/ + +/*! \fn QPoint QCPVector2D::toPoint() const + + Returns a QPoint which has the x and y coordinates of this vector, truncating any floating point + information. + + \see toPointF +*/ + +/*! \fn QPointF QCPVector2D::toPointF() const + + Returns a QPointF which has the x and y coordinates of this vector. + + \see toPoint +*/ + +/*! \fn bool QCPVector2D::isNull() const + + Returns whether this vector is null. A vector is null if \c qIsNull returns true for both x and y + coordinates, i.e. if both are binary equal to 0. +*/ + +/*! \fn QCPVector2D QCPVector2D::perpendicular() const + + Returns a vector perpendicular to this vector, with the same length. +*/ + +/*! \fn double QCPVector2D::dot() const + + Returns the dot/scalar product of this vector with the specified vector \a vec. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates to 0. +*/ +QCPVector2D::QCPVector2D() : + mX(0), + mY(0) +{ +} + +/*! + Creates a QCPVector2D object and initializes the \a x and \a y coordinates with the specified + values. +*/ +QCPVector2D::QCPVector2D(double x, double y) : + mX(x), + mY(y) +{ +} + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates respective coordinates of + the specified \a point. +*/ +QCPVector2D::QCPVector2D(const QPoint &point) : + mX(point.x()), + mY(point.y()) +{ +} + +/*! + Creates a QCPVector2D object and initializes the x and y coordinates respective coordinates of + the specified \a point. +*/ +QCPVector2D::QCPVector2D(const QPointF &point) : + mX(point.x()), + mY(point.y()) +{ +} + +/*! + Normalizes this vector. After this operation, the length of the vector is equal to 1. + + \see normalized, length, lengthSquared +*/ +void QCPVector2D::normalize() +{ + double len = length(); + mX /= len; + mY /= len; +} + +/*! + Returns a normalized version of this vector. The length of the returned vector is equal to 1. + + \see normalize, length, lengthSquared +*/ +QCPVector2D QCPVector2D::normalized() const +{ + QCPVector2D result(mX, mY); + result.normalize(); + return result; +} + +/*! \overload + + Returns the squared shortest distance of this vector (interpreted as a point) to the finite line + segment given by \a start and \a end. + + \see distanceToStraightLine +*/ +double QCPVector2D::distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const +{ + QCPVector2D v(end-start); + double vLengthSqr = v.lengthSquared(); + if (!qFuzzyIsNull(vLengthSqr)) + { + double mu = v.dot(*this-start)/vLengthSqr; + if (mu < 0) + return (*this-start).lengthSquared(); + else if (mu > 1) + return (*this-end).lengthSquared(); + else + return ((start + mu*v)-*this).lengthSquared(); + } else + return (*this-start).lengthSquared(); +} + +/*! \overload + + Returns the squared shortest distance of this vector (interpreted as a point) to the finite line + segment given by \a line. + + \see distanceToStraightLine +*/ +double QCPVector2D::distanceSquaredToLine(const QLineF &line) const +{ + return distanceSquaredToLine(QCPVector2D(line.p1()), QCPVector2D(line.p2())); +} + +/*! + Returns the shortest distance of this vector (interpreted as a point) to the infinite straight + line given by a \a base point and a \a direction vector. + + \see distanceSquaredToLine +*/ +double QCPVector2D::distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const +{ + return qAbs((*this-base).dot(direction.perpendicular()))/direction.length(); +} + +/*! + Scales this vector by the given \a factor, i.e. the x and y components are multiplied by \a + factor. +*/ +QCPVector2D &QCPVector2D::operator*=(double factor) +{ + mX *= factor; + mY *= factor; + return *this; +} + +/*! + Scales this vector by the given \a divisor, i.e. the x and y components are divided by \a + divisor. +*/ +QCPVector2D &QCPVector2D::operator/=(double divisor) +{ + mX /= divisor; + mY /= divisor; + return *this; +} + +/*! + Adds the given \a vector to this vector component-wise. +*/ +QCPVector2D &QCPVector2D::operator+=(const QCPVector2D &vector) +{ + mX += vector.mX; + mY += vector.mY; + return *this; +} + +/*! + subtracts the given \a vector from this vector component-wise. +*/ +QCPVector2D &QCPVector2D::operator-=(const QCPVector2D &vector) +{ + mX -= vector.mX; + mY -= vector.mY; + return *this; +} +/* end of 'src/vector2d.cpp' */ + + +/* including file 'src/painter.cpp', size 8670 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPainter +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPainter + \brief QPainter subclass used internally + + This QPainter subclass is used to provide some extended functionality e.g. for tweaking position + consistency between antialiased and non-antialiased painting. Further it provides workarounds + for QPainter quirks. + + \warning This class intentionally hides non-virtual functions of QPainter, e.g. setPen, save and + restore. So while it is possible to pass a QCPPainter instance to a function that expects a + QPainter pointer, some of the workarounds and tweaks will be unavailable to the function (because + it will call the base class implementations of the functions actually hidden by QCPPainter). +*/ + +/*! + Creates a new QCPPainter instance and sets default values +*/ +QCPPainter::QCPPainter() : + QPainter(), + mModes(pmDefault), + mIsAntialiasing(false) +{ + // don't setRenderHint(QPainter::NonCosmeticDefautPen) here, because painter isn't active yet and + // a call to begin() will follow +} + +/*! + Creates a new QCPPainter instance on the specified paint \a device and sets default values. Just + like the analogous QPainter constructor, begins painting on \a device immediately. + + Like \ref begin, this method sets QPainter::NonCosmeticDefaultPen in Qt versions before Qt5. +*/ +QCPPainter::QCPPainter(QPaintDevice *device) : + QPainter(device), + mModes(pmDefault), + mIsAntialiasing(false) +{ +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. + if (isActive()) + setRenderHint(QPainter::NonCosmeticDefaultPen); +#endif +} + +/*! + Sets the pen of the painter and applies certain fixes to it, depending on the mode of this + QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(const QPen &pen) +{ + QPainter::setPen(pen); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Sets the pen (by color) of the painter and applies certain fixes to it, depending on the mode of + this QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(const QColor &color) +{ + QPainter::setPen(color); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Sets the pen (by style) of the painter and applies certain fixes to it, depending on the mode of + this QCPPainter. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::setPen(Qt::PenStyle penStyle) +{ + QPainter::setPen(penStyle); + if (mModes.testFlag(pmNonCosmetic)) + makeNonCosmetic(); +} + +/*! \overload + + Works around a Qt bug introduced with Qt 4.8 which makes drawing QLineF unpredictable when + antialiasing is disabled. Thus when antialiasing is disabled, it rounds the \a line to + integer coordinates and then passes it to the original drawLine. + + \note this function hides the non-virtual base class implementation. +*/ +void QCPPainter::drawLine(const QLineF &line) +{ + if (mIsAntialiasing || mModes.testFlag(pmVectorized)) + QPainter::drawLine(line); + else + QPainter::drawLine(line.toLine()); +} + +/*! + Sets whether painting uses antialiasing or not. Use this method instead of using setRenderHint + with QPainter::Antialiasing directly, as it allows QCPPainter to regain pixel exactness between + antialiased and non-antialiased painting (Since Qt < 5.0 uses slightly different coordinate systems for + AA/Non-AA painting). +*/ +void QCPPainter::setAntialiasing(bool enabled) +{ + setRenderHint(QPainter::Antialiasing, enabled); + if (mIsAntialiasing != enabled) + { + mIsAntialiasing = enabled; + if (!mModes.testFlag(pmVectorized)) // antialiasing half-pixel shift only needed for rasterized outputs + { + if (mIsAntialiasing) + translate(0.5, 0.5); + else + translate(-0.5, -0.5); + } + } +} + +/*! + Sets the mode of the painter. This controls whether the painter shall adjust its + fixes/workarounds optimized for certain output devices. +*/ +void QCPPainter::setModes(QCPPainter::PainterModes modes) +{ + mModes = modes; +} + +/*! + Sets the QPainter::NonCosmeticDefaultPen in Qt versions before Qt5 after beginning painting on \a + device. This is necessary to get cosmetic pen consistency across Qt versions, because since Qt5, + all pens are non-cosmetic by default, and in Qt4 this render hint must be set to get that + behaviour. + + The Constructor \ref QCPPainter(QPaintDevice *device) which directly starts painting also sets + the render hint as appropriate. + + \note this function hides the non-virtual base class implementation. +*/ +bool QCPPainter::begin(QPaintDevice *device) +{ + bool result = QPainter::begin(device); +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. + if (result) + setRenderHint(QPainter::NonCosmeticDefaultPen); +#endif + return result; +} + +/*! \overload + + Sets the mode of the painter. This controls whether the painter shall adjust its + fixes/workarounds optimized for certain output devices. +*/ +void QCPPainter::setMode(QCPPainter::PainterMode mode, bool enabled) +{ + if (!enabled && mModes.testFlag(mode)) + mModes &= ~mode; + else if (enabled && !mModes.testFlag(mode)) + mModes |= mode; +} + +/*! + Saves the painter (see QPainter::save). Since QCPPainter adds some new internal state to + QPainter, the save/restore functions are reimplemented to also save/restore those members. + + \note this function hides the non-virtual base class implementation. + + \see restore +*/ +void QCPPainter::save() +{ + mAntialiasingStack.push(mIsAntialiasing); + QPainter::save(); +} + +/*! + Restores the painter (see QPainter::restore). Since QCPPainter adds some new internal state to + QPainter, the save/restore functions are reimplemented to also save/restore those members. + + \note this function hides the non-virtual base class implementation. + + \see save +*/ +void QCPPainter::restore() +{ + if (!mAntialiasingStack.isEmpty()) + mIsAntialiasing = mAntialiasingStack.pop(); + else + qDebug() << Q_FUNC_INFO << "Unbalanced save/restore"; + QPainter::restore(); +} + +/*! + Changes the pen width to 1 if it currently is 0. This function is called in the \ref setPen + overrides when the \ref pmNonCosmetic mode is set. +*/ +void QCPPainter::makeNonCosmetic() +{ + if (qFuzzyIsNull(pen().widthF())) + { + QPen p = pen(); + p.setWidth(1); + QPainter::setPen(p); + } +} +/* end of 'src/painter.cpp' */ + + +/* including file 'src/paintbuffer.cpp', size 18502 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPaintBuffer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPaintBuffer + \brief The abstract base class for paint buffers, which define the rendering backend + + This abstract base class defines the basic interface that a paint buffer needs to provide in + order to be usable by QCustomPlot. + + A paint buffer manages both a surface to draw onto, and the matching paint device. The size of + the surface can be changed via \ref setSize. External classes (\ref QCustomPlot and \ref + QCPLayer) request a painter via \ref startPainting and then perform the draw calls. Once the + painting is complete, \ref donePainting is called, so the paint buffer implementation can do + clean up if necessary. Before rendering a frame, each paint buffer is usually filled with a color + using \ref clear (usually the color is \c Qt::transparent), to remove the contents of the + previous frame. + + The simplest paint buffer implementation is \ref QCPPaintBufferPixmap which allows regular + software rendering via the raster engine. Hardware accelerated rendering via pixel buffers and + frame buffer objects is provided by \ref QCPPaintBufferGlPbuffer and \ref QCPPaintBufferGlFbo. + They are used automatically if \ref QCustomPlot::setOpenGl is enabled. +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual QCPPainter *QCPAbstractPaintBuffer::startPainting() = 0 + + Returns a \ref QCPPainter which is ready to draw to this buffer. The ownership and thus the + responsibility to delete the painter after the painting operations are complete is given to the + caller of this method. + + Once you are done using the painter, delete the painter and call \ref donePainting. + + While a painter generated with this method is active, you must not call \ref setSize, \ref + setDevicePixelRatio or \ref clear. + + This method may return 0, if a painter couldn't be activated on the buffer. This usually + indicates a problem with the respective painting backend. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::draw(QCPPainter *painter) const = 0 + + Draws the contents of this buffer with the provided \a painter. This is the method that is used + to finally join all paint buffers and draw them onto the screen. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::clear(const QColor &color) = 0 + + Fills the entire buffer with the provided \a color. To have an empty transparent buffer, use the + named color \c Qt::transparent. + + This method must not be called if there is currently a painter (acquired with \ref startPainting) + active. +*/ + +/*! \fn virtual void QCPAbstractPaintBuffer::reallocateBuffer() = 0 + + Reallocates the internal buffer with the currently configured size (\ref setSize) and device + pixel ratio, if applicable (\ref setDevicePixelRatio). It is called as soon as any of those + properties are changed on this paint buffer. + + \note Subclasses of \ref QCPAbstractPaintBuffer must call their reimplementation of this method + in their constructor, to perform the first allocation (this can not be done by the base class + because calling pure virtual methods in base class constructors is not possible). +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of inline functions */ + +/*! \fn virtual void QCPAbstractPaintBuffer::donePainting() + + If you have acquired a \ref QCPPainter to paint onto this paint buffer via \ref startPainting, + call this method as soon as you are done with the painting operations and have deleted the + painter. + + paint buffer subclasses may use this method to perform any type of cleanup that is necessary. The + default implementation does nothing. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a paint buffer and initializes it with the provided \a size and \a devicePixelRatio. + + Subclasses must call their \ref reallocateBuffer implementation in their respective constructors. +*/ +QCPAbstractPaintBuffer::QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio) : + mSize(size), + mDevicePixelRatio(devicePixelRatio), + mInvalidated(true) +{ +} + +QCPAbstractPaintBuffer::~QCPAbstractPaintBuffer() +{ +} + +/*! + Sets the paint buffer size. + + The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained + by \ref startPainting are invalidated and must not be used after calling this method. + + If \a size is already the current buffer size, this method does nothing. +*/ +void QCPAbstractPaintBuffer::setSize(const QSize &size) +{ + if (mSize != size) + { + mSize = size; + reallocateBuffer(); + } +} + +/*! + Sets the invalidated flag to \a invalidated. + + This mechanism is used internally in conjunction with isolated replotting of \ref QCPLayer + instances (in \ref QCPLayer::lmBuffered mode). If \ref QCPLayer::replot is called on a buffered + layer, i.e. an isolated repaint of only that layer (and its dedicated paint buffer) is requested, + QCustomPlot will decide depending on the invalidated flags of other paint buffers whether it also + replots them, instead of only the layer on which the replot was called. + + The invalidated flag is set to true when \ref QCPLayer association has changed, i.e. if layers + were added or removed from this buffer, or if they were reordered. It is set to false as soon as + all associated \ref QCPLayer instances are drawn onto the buffer. + + Under normal circumstances, it is not necessary to manually call this method. +*/ +void QCPAbstractPaintBuffer::setInvalidated(bool invalidated) +{ + mInvalidated = invalidated; +} + +/*! + Sets the the device pixel ratio to \a ratio. This is useful to render on high-DPI output devices. + The ratio is automatically set to the device pixel ratio used by the parent QCustomPlot instance. + + The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained + by \ref startPainting are invalidated and must not be used after calling this method. + + \note This method is only available for Qt versions 5.4 and higher. +*/ +void QCPAbstractPaintBuffer::setDevicePixelRatio(double ratio) +{ + if (!qFuzzyCompare(ratio, mDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mDevicePixelRatio = ratio; + reallocateBuffer(); +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mDevicePixelRatio = 1.0; +#endif + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferPixmap +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferPixmap + \brief A paint buffer based on QPixmap, using software raster rendering + + This paint buffer is the default and fall-back paint buffer which uses software rendering and + QPixmap as internal buffer. It is used if \ref QCustomPlot::setOpenGl is false. +*/ + +/*! + Creates a pixmap paint buffer instancen with the specified \a size and \a devicePixelRatio, if + applicable. +*/ +QCPPaintBufferPixmap::QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio) : + QCPAbstractPaintBuffer(size, devicePixelRatio) +{ + QCPPaintBufferPixmap::reallocateBuffer(); +} + +QCPPaintBufferPixmap::~QCPPaintBufferPixmap() +{ +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferPixmap::startPainting() +{ + QCPPainter *result = new QCPPainter(&mBuffer); + result->setRenderHint(QPainter::HighQualityAntialiasing); + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::draw(QCPPainter *painter) const +{ + if (painter && painter->isActive()) + painter->drawPixmap(0, 0, mBuffer); + else + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::clear(const QColor &color) +{ + mBuffer.fill(color); +} + +/* inherits documentation from base class */ +void QCPPaintBufferPixmap::reallocateBuffer() +{ + setInvalidated(); + if (!qFuzzyCompare(1.0, mDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mBuffer = QPixmap(mSize*mDevicePixelRatio); + mBuffer.setDevicePixelRatio(mDevicePixelRatio); +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mDevicePixelRatio = 1.0; + mBuffer = QPixmap(mSize); +#endif + } else + { + mBuffer = QPixmap(mSize); + } +} + + +#ifdef QCP_OPENGL_PBUFFER +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferGlPbuffer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferGlPbuffer + \brief A paint buffer based on OpenGL pixel buffers, using hardware accelerated rendering + + This paint buffer is one of the OpenGL paint buffers which facilitate hardware accelerated plot + rendering. It is based on OpenGL pixel buffers (pbuffer) and is used in Qt versions before 5.0. + (See \ref QCPPaintBufferGlFbo used in newer Qt versions.) + + The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are + supported by the system. +*/ + +/*! + Creates a \ref QCPPaintBufferGlPbuffer instance with the specified \a size and \a + devicePixelRatio, if applicable. + + The parameter \a multisamples defines how many samples are used per pixel. Higher values thus + result in higher quality antialiasing. If the specified \a multisamples value exceeds the + capability of the graphics hardware, the highest supported multisampling is used. +*/ +QCPPaintBufferGlPbuffer::QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples) : + QCPAbstractPaintBuffer(size, devicePixelRatio), + mGlPBuffer(0), + mMultisamples(qMax(0, multisamples)) +{ + QCPPaintBufferGlPbuffer::reallocateBuffer(); +} + +QCPPaintBufferGlPbuffer::~QCPPaintBufferGlPbuffer() +{ + if (mGlPBuffer) + delete mGlPBuffer; +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferGlPbuffer::startPainting() +{ + if (!mGlPBuffer->isValid()) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return 0; + } + + QCPPainter *result = new QCPPainter(mGlPBuffer); + result->setRenderHint(QPainter::HighQualityAntialiasing); + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::draw(QCPPainter *painter) const +{ + if (!painter || !painter->isActive()) + { + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; + return; + } + if (!mGlPBuffer->isValid()) + { + qDebug() << Q_FUNC_INFO << "OpenGL pbuffer isn't valid, reallocateBuffer was not called?"; + return; + } + painter->drawImage(0, 0, mGlPBuffer->toImage()); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::clear(const QColor &color) +{ + if (mGlPBuffer->isValid()) + { + mGlPBuffer->makeCurrent(); + glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + mGlPBuffer->doneCurrent(); + } else + qDebug() << Q_FUNC_INFO << "OpenGL pbuffer invalid or context not current"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlPbuffer::reallocateBuffer() +{ + if (mGlPBuffer) + delete mGlPBuffer; + + QGLFormat format; + format.setAlpha(true); + format.setSamples(mMultisamples); + mGlPBuffer = new QGLPixelBuffer(mSize, format); +} +#endif // QCP_OPENGL_PBUFFER + + +#ifdef QCP_OPENGL_FBO +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPaintBufferGlFbo +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPaintBufferGlFbo + \brief A paint buffer based on OpenGL frame buffers objects, using hardware accelerated rendering + + This paint buffer is one of the OpenGL paint buffers which facilitate hardware accelerated plot + rendering. It is based on OpenGL frame buffer objects (fbo) and is used in Qt versions 5.0 and + higher. (See \ref QCPPaintBufferGlPbuffer used in older Qt versions.) + + The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are + supported by the system. +*/ + +/*! + Creates a \ref QCPPaintBufferGlFbo instance with the specified \a size and \a devicePixelRatio, + if applicable. + + All frame buffer objects shall share one OpenGL context and paint device, which need to be set up + externally and passed via \a glContext and \a glPaintDevice. The set-up is done in \ref + QCustomPlot::setupOpenGl and the context and paint device are managed by the parent QCustomPlot + instance. +*/ +QCPPaintBufferGlFbo::QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice) : + QCPAbstractPaintBuffer(size, devicePixelRatio), + mGlContext(glContext), + mGlPaintDevice(glPaintDevice), + mGlFrameBuffer(0) +{ + initializeOpenGLFunctions(); + QCPPaintBufferGlFbo::reallocateBuffer(); +} + +QCPPaintBufferGlFbo::~QCPPaintBufferGlFbo() +{ + if (mGlFrameBuffer) + delete mGlFrameBuffer; +} + +/* inherits documentation from base class */ +QCPPainter *QCPPaintBufferGlFbo::startPainting() +{ + if (mGlPaintDevice.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL paint device doesn't exist"; + return 0; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return 0; + } + + if (QOpenGLContext::currentContext() != mGlContext.data()) + mGlContext.data()->makeCurrent(mGlContext.data()->surface()); + mGlFrameBuffer->bind(); + QCPPainter *result = new QCPPainter(mGlPaintDevice.data()); + result->setRenderHint(QPainter::HighQualityAntialiasing); + return result; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::donePainting() +{ + if (mGlFrameBuffer && mGlFrameBuffer->isBound()) + mGlFrameBuffer->release(); + else + qDebug() << Q_FUNC_INFO << "Either OpenGL frame buffer not valid or was not bound"; +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::draw(QCPPainter *painter) const +{ + if (!painter || !painter->isActive()) + { + qDebug() << Q_FUNC_INFO << "invalid or inactive painter passed"; + return; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return; + } + painter->drawImage(0, 0, mGlFrameBuffer->toImage()); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::clear(const QColor &color) +{ + if (mGlContext.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; + return; + } + if (!mGlFrameBuffer) + { + qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?"; + return; + } + + if (QOpenGLContext::currentContext() != mGlContext.data()) + mGlContext.data()->makeCurrent(mGlContext.data()->surface()); + mGlFrameBuffer->bind(); + glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + mGlFrameBuffer->release(); +} + +/* inherits documentation from base class */ +void QCPPaintBufferGlFbo::reallocateBuffer() +{ + // release and delete possibly existing framebuffer: + if (mGlFrameBuffer) + { + if (mGlFrameBuffer->isBound()) + mGlFrameBuffer->release(); + delete mGlFrameBuffer; + mGlFrameBuffer = 0; + } + + if (mGlContext.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL context doesn't exist"; + return; + } + if (mGlPaintDevice.isNull()) + { + qDebug() << Q_FUNC_INFO << "OpenGL paint device doesn't exist"; + return; + } + + // create new fbo with appropriate size: + mGlContext.data()->makeCurrent(mGlContext.data()->surface()); + QOpenGLFramebufferObjectFormat frameBufferFormat; + frameBufferFormat.setSamples(mGlContext.data()->format().samples()); + frameBufferFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + mGlFrameBuffer = new QOpenGLFramebufferObject(mSize*mDevicePixelRatio, frameBufferFormat); + if (mGlPaintDevice.data()->size() != mSize*mDevicePixelRatio) + mGlPaintDevice.data()->setSize(mSize*mDevicePixelRatio); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mGlPaintDevice.data()->setDevicePixelRatio(mDevicePixelRatio); +#endif +} +#endif // QCP_OPENGL_FBO +/* end of 'src/paintbuffer.cpp' */ + + +/* including file 'src/layer.cpp', size 37064 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayer + \brief A layer that may contain objects, to control the rendering order + + The Layering system of QCustomPlot is the mechanism to control the rendering order of the + elements inside the plot. + + It is based on the two classes QCPLayer and QCPLayerable. QCustomPlot holds an ordered list of + one or more instances of QCPLayer (see QCustomPlot::addLayer, QCustomPlot::layer, + QCustomPlot::moveLayer, etc.). When replotting, QCustomPlot goes through the list of layers + bottom to top and successively draws the layerables of the layers into the paint buffer(s). + + A QCPLayer contains an ordered list of QCPLayerable instances. QCPLayerable is an abstract base + class from which almost all visible objects derive, like axes, grids, graphs, items, etc. + + \section qcplayer-defaultlayers Default layers + + Initially, QCustomPlot has six layers: "background", "grid", "main", "axes", "legend" and + "overlay" (in that order). On top is the "overlay" layer, which only contains the QCustomPlot's + selection rect (\ref QCustomPlot::selectionRect). The next two layers "axes" and "legend" contain + the default axes and legend, so they will be drawn above plottables. In the middle, there is the + "main" layer. It is initially empty and set as the current layer (see + QCustomPlot::setCurrentLayer). This means, all new plottables, items etc. are created on this + layer by default. Then comes the "grid" layer which contains the QCPGrid instances (which belong + tightly to QCPAxis, see \ref QCPAxis::grid). The Axis rect background shall be drawn behind + everything else, thus the default QCPAxisRect instance is placed on the "background" layer. Of + course, the layer affiliation of the individual objects can be changed as required (\ref + QCPLayerable::setLayer). + + \section qcplayer-ordering Controlling the rendering order via layers + + Controlling the ordering of layerables in the plot is easy: Create a new layer in the position + you want the layerable to be in, e.g. above "main", with \ref QCustomPlot::addLayer. Then set the + current layer with \ref QCustomPlot::setCurrentLayer to that new layer and finally create the + objects normally. They will be placed on the new layer automatically, due to the current layer + setting. Alternatively you could have also ignored the current layer setting and just moved the + objects with \ref QCPLayerable::setLayer to the desired layer after creating them. + + It is also possible to move whole layers. For example, If you want the grid to be shown in front + of all plottables/items on the "main" layer, just move it above "main" with + QCustomPlot::moveLayer. + + The rendering order within one layer is simply by order of creation or insertion. The item + created last (or added last to the layer), is drawn on top of all other objects on that layer. + + When a layer is deleted, the objects on it are not deleted with it, but fall on the layer below + the deleted layer, see QCustomPlot::removeLayer. + + \section qcplayer-buffering Replotting only a specific layer + + If the layer mode (\ref setMode) is set to \ref lmBuffered, you can replot only this specific + layer by calling \ref replot. In certain situations this can provide better replot performance, + compared with a full replot of all layers. Upon creation of a new layer, the layer mode is + initialized to \ref lmLogical. The only layer that is set to \ref lmBuffered in a new \ref + QCustomPlot instance is the "overlay" layer, containing the selection rect. +*/ + +/* start documentation of inline functions */ + +/*! \fn QList QCPLayer::children() const + + Returns a list of all layerables on this layer. The order corresponds to the rendering order: + layerables with higher indices are drawn above layerables with lower indices. +*/ + +/*! \fn int QCPLayer::index() const + + Returns the index this layer has in the QCustomPlot. The index is the integer number by which this layer can be + accessed via \ref QCustomPlot::layer. + + Layers with higher indices will be drawn above layers with lower indices. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPLayer instance. + + Normally you shouldn't directly instantiate layers, use \ref QCustomPlot::addLayer instead. + + \warning It is not checked that \a layerName is actually a unique layer name in \a parentPlot. + This check is only performed by \ref QCustomPlot::addLayer. +*/ +QCPLayer::QCPLayer(QCustomPlot *parentPlot, const QString &layerName) : + QObject(parentPlot), + mParentPlot(parentPlot), + mName(layerName), + mIndex(-1), // will be set to a proper value by the QCustomPlot layer creation function + mVisible(true), + mMode(lmLogical) +{ + // Note: no need to make sure layerName is unique, because layer + // management is done with QCustomPlot functions. +} + +QCPLayer::~QCPLayer() +{ + // If child layerables are still on this layer, detach them, so they don't try to reach back to this + // then invalid layer once they get deleted/moved themselves. This only happens when layers are deleted + // directly, like in the QCustomPlot destructor. (The regular layer removal procedure for the user is to + // call QCustomPlot::removeLayer, which moves all layerables off this layer before deleting it.) + + while (!mChildren.isEmpty()) + mChildren.last()->setLayer(0); // removes itself from mChildren via removeChild() + + if (mParentPlot->currentLayer() == this) + qDebug() << Q_FUNC_INFO << "The parent plot's mCurrentLayer will be a dangling pointer. Should have been set to a valid layer or 0 beforehand."; +} + +/*! + Sets whether this layer is visible or not. If \a visible is set to false, all layerables on this + layer will be invisible. + + This function doesn't change the visibility property of the layerables (\ref + QCPLayerable::setVisible), but the \ref QCPLayerable::realVisibility of each layerable takes the + visibility of the parent layer into account. +*/ +void QCPLayer::setVisible(bool visible) +{ + mVisible = visible; +} + +/*! + Sets the rendering mode of this layer. + + If \a mode is set to \ref lmBuffered for a layer, it will be given a dedicated paint buffer by + the parent QCustomPlot instance. This means it may be replotted individually by calling \ref + QCPLayer::replot, without needing to replot all other layers. + + Layers which are set to \ref lmLogical (the default) are used only to define the rendering order + and can't be replotted individually. + + Note that each layer which is set to \ref lmBuffered requires additional paint buffers for the + layers below, above and for the layer itself. This increases the memory consumption and + (slightly) decreases the repainting speed because multiple paint buffers need to be joined. So + you should carefully choose which layers benefit from having their own paint buffer. A typical + example would be a layer which contains certain layerables (e.g. items) that need to be changed + and thus replotted regularly, while all other layerables on other layers stay static. By default, + only the topmost layer called "overlay" is in mode \ref lmBuffered, and contains the selection + rect. + + \see replot +*/ +void QCPLayer::setMode(QCPLayer::LayerMode mode) +{ + if (mMode != mode) + { + mMode = mode; + if (!mPaintBuffer.isNull()) + mPaintBuffer.data()->setInvalidated(); + } +} + +/*! \internal + + Draws the contents of this layer with the provided \a painter. + + \see replot, drawToPaintBuffer +*/ +void QCPLayer::draw(QCPPainter *painter) +{ + foreach (QCPLayerable *child, mChildren) + { + if (child->realVisibility()) + { + painter->save(); + painter->setClipRect(child->clipRect().translated(0, -1)); + child->applyDefaultAntialiasingHint(painter); + child->draw(painter); + painter->restore(); + } + } +} + +/*! \internal + + Draws the contents of this layer into the paint buffer which is associated with this layer. The + association is established by the parent QCustomPlot, which manages all paint buffers (see \ref + QCustomPlot::setupPaintBuffers). + + \see draw +*/ +void QCPLayer::drawToPaintBuffer() +{ + if (!mPaintBuffer.isNull()) + { + if (QCPPainter *painter = mPaintBuffer.data()->startPainting()) + { + if (painter->isActive()) + draw(painter); + else + qDebug() << Q_FUNC_INFO << "paint buffer returned inactive painter"; + delete painter; + mPaintBuffer.data()->donePainting(); + } else + qDebug() << Q_FUNC_INFO << "paint buffer returned zero painter"; + } else + qDebug() << Q_FUNC_INFO << "no valid paint buffer associated with this layer"; +} + +/*! + If the layer mode (\ref setMode) is set to \ref lmBuffered, this method allows replotting only + the layerables on this specific layer, without the need to replot all other layers (as a call to + \ref QCustomPlot::replot would do). + + If the layer mode is \ref lmLogical however, this method simply calls \ref QCustomPlot::replot on + the parent QCustomPlot instance. + + QCustomPlot also makes sure to replot all layers instead of only this one, if the layer ordering + has changed since the last full replot and the other paint buffers were thus invalidated. + + \see draw +*/ +void QCPLayer::replot() +{ + if (mMode == lmBuffered && !mParentPlot->hasInvalidatedPaintBuffers()) + { + if (!mPaintBuffer.isNull()) + { + mPaintBuffer.data()->clear(Qt::transparent); + drawToPaintBuffer(); + mPaintBuffer.data()->setInvalidated(false); + mParentPlot->update(); + } else + qDebug() << Q_FUNC_INFO << "no valid paint buffer associated with this layer"; + } else if (mMode == lmLogical) + mParentPlot->replot(); +} + +/*! \internal + + Adds the \a layerable to the list of this layer. If \a prepend is set to true, the layerable will + be prepended to the list, i.e. be drawn beneath the other layerables already in the list. + + This function does not change the \a mLayer member of \a layerable to this layer. (Use + QCPLayerable::setLayer to change the layer of an object, not this function.) + + \see removeChild +*/ +void QCPLayer::addChild(QCPLayerable *layerable, bool prepend) +{ + if (!mChildren.contains(layerable)) + { + if (prepend) + mChildren.prepend(layerable); + else + mChildren.append(layerable); + if (!mPaintBuffer.isNull()) + mPaintBuffer.data()->setInvalidated(); + } else + qDebug() << Q_FUNC_INFO << "layerable is already child of this layer" << reinterpret_cast(layerable); +} + +/*! \internal + + Removes the \a layerable from the list of this layer. + + This function does not change the \a mLayer member of \a layerable. (Use QCPLayerable::setLayer + to change the layer of an object, not this function.) + + \see addChild +*/ +void QCPLayer::removeChild(QCPLayerable *layerable) +{ + if (mChildren.removeOne(layerable)) + { + if (!mPaintBuffer.isNull()) + mPaintBuffer.data()->setInvalidated(); + } else + qDebug() << Q_FUNC_INFO << "layerable is not child of this layer" << reinterpret_cast(layerable); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayerable +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayerable + \brief Base class for all drawable objects + + This is the abstract base class most visible objects derive from, e.g. plottables, axes, grid + etc. + + Every layerable is on a layer (QCPLayer) which allows controlling the rendering order by stacking + the layers accordingly. + + For details about the layering mechanism, see the QCPLayer documentation. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayerable *QCPLayerable::parentLayerable() const + + Returns the parent layerable of this layerable. The parent layerable is used to provide + visibility hierarchies in conjunction with the method \ref realVisibility. This way, layerables + only get drawn if their parent layerables are visible, too. + + Note that a parent layerable is not necessarily also the QObject parent for memory management. + Further, a layerable doesn't always have a parent layerable, so this function may return 0. + + A parent layerable is set implicitly when placed inside layout elements and doesn't need to be + set manually by the user. +*/ + +/* end documentation of inline functions */ +/* start documentation of pure virtual functions */ + +/*! \fn virtual void QCPLayerable::applyDefaultAntialiasingHint(QCPPainter *painter) const = 0 + \internal + + This function applies the default antialiasing setting to the specified \a painter, using the + function \ref applyAntialiasingHint. It is the antialiasing state the painter is put in, when + \ref draw is called on the layerable. If the layerable has multiple entities whose antialiasing + setting may be specified individually, this function should set the antialiasing state of the + most prominent entity. In this case however, the \ref draw function usually calls the specialized + versions of this function before drawing each entity, effectively overriding the setting of the + default antialiasing hint. + + First example: QCPGraph has multiple entities that have an antialiasing setting: The graph + line, fills and scatters. Those can be configured via QCPGraph::setAntialiased, + QCPGraph::setAntialiasedFill and QCPGraph::setAntialiasedScatters. Consequently, there isn't only + the QCPGraph::applyDefaultAntialiasingHint function (which corresponds to the graph line's + antialiasing), but specialized ones like QCPGraph::applyFillAntialiasingHint and + QCPGraph::applyScattersAntialiasingHint. So before drawing one of those entities, QCPGraph::draw + calls the respective specialized applyAntialiasingHint function. + + Second example: QCPItemLine consists only of a line so there is only one antialiasing + setting which can be controlled with QCPItemLine::setAntialiased. (This function is inherited by + all layerables. The specialized functions, as seen on QCPGraph, must be added explicitly to the + respective layerable subclass.) Consequently it only has the normal + QCPItemLine::applyDefaultAntialiasingHint. The \ref QCPItemLine::draw function doesn't need to + care about setting any antialiasing states, because the default antialiasing hint is already set + on the painter when the \ref draw function is called, and that's the state it wants to draw the + line with. +*/ + +/*! \fn virtual void QCPLayerable::draw(QCPPainter *painter) const = 0 + \internal + + This function draws the layerable with the specified \a painter. It is only called by + QCustomPlot, if the layerable is visible (\ref setVisible). + + Before this function is called, the painter's antialiasing state is set via \ref + applyDefaultAntialiasingHint, see the documentation there. Further, the clipping rectangle was + set to \ref clipRect. +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of signals */ + +/*! \fn void QCPLayerable::layerChanged(QCPLayer *newLayer); + + This signal is emitted when the layer of this layerable changes, i.e. this layerable is moved to + a different layer. + + \see setLayer +*/ + +/* end documentation of signals */ + +/*! + Creates a new QCPLayerable instance. + + Since QCPLayerable is an abstract base class, it can't be instantiated directly. Use one of the + derived classes. + + If \a plot is provided, it automatically places itself on the layer named \a targetLayer. If \a + targetLayer is an empty string, it places itself on the current layer of the plot (see \ref + QCustomPlot::setCurrentLayer). + + It is possible to provide 0 as \a plot. In that case, you should assign a parent plot at a later + time with \ref initializeParentPlot. + + The layerable's parent layerable is set to \a parentLayerable, if provided. Direct layerable + parents are mainly used to control visibility in a hierarchy of layerables. This means a + layerable is only drawn, if all its ancestor layerables are also visible. Note that \a + parentLayerable does not become the QObject-parent (for memory management) of this layerable, \a + plot does. It is not uncommon to set the QObject-parent to something else in the constructors of + QCPLayerable subclasses, to guarantee a working destruction hierarchy. +*/ +QCPLayerable::QCPLayerable(QCustomPlot *plot, QString targetLayer, QCPLayerable *parentLayerable) : + QObject(plot), + mVisible(true), + mParentPlot(plot), + mParentLayerable(parentLayerable), + mLayer(0), + mAntialiased(true) +{ + if (mParentPlot) + { + if (targetLayer.isEmpty()) + setLayer(mParentPlot->currentLayer()); + else if (!setLayer(targetLayer)) + qDebug() << Q_FUNC_INFO << "setting QCPlayerable initial layer to" << targetLayer << "failed."; + } +} + +QCPLayerable::~QCPLayerable() +{ + if (mLayer) + { + mLayer->removeChild(this); + mLayer = 0; + } +} + +/*! + Sets the visibility of this layerable object. If an object is not visible, it will not be drawn + on the QCustomPlot surface, and user interaction with it (e.g. click and selection) is not + possible. +*/ +void QCPLayerable::setVisible(bool on) +{ + mVisible = on; +} + +/*! + Sets the \a layer of this layerable object. The object will be placed on top of the other objects + already on \a layer. + + If \a layer is 0, this layerable will not be on any layer and thus not appear in the plot (or + interact/receive events). + + Returns true if the layer of this layerable was successfully changed to \a layer. +*/ +bool QCPLayerable::setLayer(QCPLayer *layer) +{ + return moveToLayer(layer, false); +} + +/*! \overload + Sets the layer of this layerable object by name + + Returns true on success, i.e. if \a layerName is a valid layer name. +*/ +bool QCPLayerable::setLayer(const QString &layerName) +{ + if (!mParentPlot) + { + qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; + return false; + } + if (QCPLayer *layer = mParentPlot->layer(layerName)) + { + return setLayer(layer); + } else + { + qDebug() << Q_FUNC_INFO << "there is no layer with name" << layerName; + return false; + } +} + +/*! + Sets whether this object will be drawn antialiased or not. + + Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPLayerable::setAntialiased(bool enabled) +{ + mAntialiased = enabled; +} + +/*! + Returns whether this layerable is visible, taking the visibility of the layerable parent and the + visibility of this layerable's layer into account. This is the method that is consulted to decide + whether a layerable shall be drawn or not. + + If this layerable has a direct layerable parent (usually set via hierarchies implemented in + subclasses, like in the case of \ref QCPLayoutElement), this function returns true only if this + layerable has its visibility set to true and the parent layerable's \ref realVisibility returns + true. +*/ +bool QCPLayerable::realVisibility() const +{ + return mVisible && (!mLayer || mLayer->visible()) && (!mParentLayerable || mParentLayerable.data()->realVisibility()); +} + +/*! + This function is used to decide whether a click hits a layerable object or not. + + \a pos is a point in pixel coordinates on the QCustomPlot surface. This function returns the + shortest pixel distance of this point to the object. If the object is either invisible or the + distance couldn't be determined, -1.0 is returned. Further, if \a onlySelectable is true and the + object is not selectable, -1.0 is returned, too. + + If the object is represented not by single lines but by an area like a \ref QCPItemText or the + bars of a \ref QCPBars plottable, a click inside the area should also be considered a hit. In + these cases this function thus returns a constant value greater zero but still below the parent + plot's selection tolerance. (typically the selectionTolerance multiplied by 0.99). + + Providing a constant value for area objects allows selecting line objects even when they are + obscured by such area objects, by clicking close to the lines (i.e. closer than + 0.99*selectionTolerance). + + The actual setting of the selection state is not done by this function. This is handled by the + parent QCustomPlot when the mouseReleaseEvent occurs, and the finally selected object is notified + via the \ref selectEvent/\ref deselectEvent methods. + + \a details is an optional output parameter. Every layerable subclass may place any information + in \a details. This information will be passed to \ref selectEvent when the parent QCustomPlot + decides on the basis of this selectTest call, that the object was successfully selected. The + subsequent call to \ref selectEvent will carry the \a details. This is useful for multi-part + objects (like QCPAxis). This way, a possibly complex calculation to decide which part was clicked + is only done once in \ref selectTest. The result (i.e. the actually clicked part) can then be + placed in \a details. So in the subsequent \ref selectEvent, the decision which part was + selected doesn't have to be done a second time for a single selection operation. + + You may pass 0 as \a details to indicate that you are not interested in those selection details. + + \see selectEvent, deselectEvent, mousePressEvent, wheelEvent, QCustomPlot::setInteractions +*/ +double QCPLayerable::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(pos) + Q_UNUSED(onlySelectable) + Q_UNUSED(details) + return -1.0; +} + +/*! \internal + + Sets the parent plot of this layerable. Use this function once to set the parent plot if you have + passed 0 in the constructor. It can not be used to move a layerable from one QCustomPlot to + another one. + + Note that, unlike when passing a non-null parent plot in the constructor, this function does not + make \a parentPlot the QObject-parent of this layerable. If you want this, call + QObject::setParent(\a parentPlot) in addition to this function. + + Further, you will probably want to set a layer (\ref setLayer) after calling this function, to + make the layerable appear on the QCustomPlot. + + The parent plot change will be propagated to subclasses via a call to \ref parentPlotInitialized + so they can react accordingly (e.g. also initialize the parent plot of child layerables, like + QCPLayout does). +*/ +void QCPLayerable::initializeParentPlot(QCustomPlot *parentPlot) +{ + if (mParentPlot) + { + qDebug() << Q_FUNC_INFO << "called with mParentPlot already initialized"; + return; + } + + if (!parentPlot) + qDebug() << Q_FUNC_INFO << "called with parentPlot zero"; + + mParentPlot = parentPlot; + parentPlotInitialized(mParentPlot); +} + +/*! \internal + + Sets the parent layerable of this layerable to \a parentLayerable. Note that \a parentLayerable does not + become the QObject-parent (for memory management) of this layerable. + + The parent layerable has influence on the return value of the \ref realVisibility method. Only + layerables with a fully visible parent tree will return true for \ref realVisibility, and thus be + drawn. + + \see realVisibility +*/ +void QCPLayerable::setParentLayerable(QCPLayerable *parentLayerable) +{ + mParentLayerable = parentLayerable; +} + +/*! \internal + + Moves this layerable object to \a layer. If \a prepend is true, this object will be prepended to + the new layer's list, i.e. it will be drawn below the objects already on the layer. If it is + false, the object will be appended. + + Returns true on success, i.e. if \a layer is a valid layer. +*/ +bool QCPLayerable::moveToLayer(QCPLayer *layer, bool prepend) +{ + if (layer && !mParentPlot) + { + qDebug() << Q_FUNC_INFO << "no parent QCustomPlot set"; + return false; + } + if (layer && layer->parentPlot() != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "layer" << layer->name() << "is not in same QCustomPlot as this layerable"; + return false; + } + + QCPLayer *oldLayer = mLayer; + if (mLayer) + mLayer->removeChild(this); + mLayer = layer; + if (mLayer) + mLayer->addChild(this, prepend); + if (mLayer != oldLayer) + emit layerChanged(mLayer); + return true; +} + +/*! \internal + + Sets the QCPainter::setAntialiasing state on the provided \a painter, depending on the \a + localAntialiased value as well as the overrides \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. Which override enum this function takes into account is + controlled via \a overrideElement. +*/ +void QCPLayerable::applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const +{ + if (mParentPlot && mParentPlot->notAntialiasedElements().testFlag(overrideElement)) + painter->setAntialiasing(false); + else if (mParentPlot && mParentPlot->antialiasedElements().testFlag(overrideElement)) + painter->setAntialiasing(true); + else + painter->setAntialiasing(localAntialiased); +} + +/*! \internal + + This function is called by \ref initializeParentPlot, to allow subclasses to react on the setting + of a parent plot. This is the case when 0 was passed as parent plot in the constructor, and the + parent plot is set at a later time. + + For example, QCPLayoutElement/QCPLayout hierarchies may be created independently of any + QCustomPlot at first. When they are then added to a layout inside the QCustomPlot, the top level + element of the hierarchy gets its parent plot initialized with \ref initializeParentPlot. To + propagate the parent plot to all the children of the hierarchy, the top level element then uses + this function to pass the parent plot on to its child elements. + + The default implementation does nothing. + + \see initializeParentPlot +*/ +void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot) +{ + Q_UNUSED(parentPlot) +} + +/*! \internal + + Returns the selection category this layerable shall belong to. The selection category is used in + conjunction with \ref QCustomPlot::setInteractions to control which objects are selectable and + which aren't. + + Subclasses that don't fit any of the normal \ref QCP::Interaction values can use \ref + QCP::iSelectOther. This is what the default implementation returns. + + \see QCustomPlot::setInteractions +*/ +QCP::Interaction QCPLayerable::selectionCategory() const +{ + return QCP::iSelectOther; +} + +/*! \internal + + Returns the clipping rectangle of this layerable object. By default, this is the viewport of the + parent QCustomPlot. Specific subclasses may reimplement this function to provide different + clipping rects. + + The returned clipping rect is set on the painter before the draw function of the respective + object is called. +*/ +QRect QCPLayerable::clipRect() const +{ + if (mParentPlot) + return mParentPlot->viewport(); + else + return QRect(); +} + +/*! \internal + + This event is called when the layerable shall be selected, as a consequence of a click by the + user. Subclasses should react to it by setting their selection state appropriately. The default + implementation does nothing. + + \a event is the mouse event that caused the selection. \a additive indicates, whether the user + was holding the multi-select-modifier while performing the selection (see \ref + QCustomPlot::setMultiSelectModifier). if \a additive is true, the selection state must be toggled + (i.e. become selected when unselected and unselected when selected). + + Every selectEvent is preceded by a call to \ref selectTest, which has returned positively (i.e. + returned a value greater than 0 and less than the selection tolerance of the parent QCustomPlot). + The \a details data you output from \ref selectTest is fed back via \a details here. You may + use it to transport any kind of information from the selectTest to the possibly subsequent + selectEvent. Usually \a details is used to transfer which part was clicked, if it is a layerable + that has multiple individually selectable parts (like QCPAxis). This way selectEvent doesn't need + to do the calculation again to find out which part was actually clicked. + + \a selectionStateChanged is an output parameter. If the pointer is non-null, this function must + set the value either to true or false, depending on whether the selection state of this layerable + was actually changed. For layerables that only are selectable as a whole and not in parts, this + is simple: if \a additive is true, \a selectionStateChanged must also be set to true, because the + selection toggles. If \a additive is false, \a selectionStateChanged is only set to true, if the + layerable was previously unselected and now is switched to the selected state. + + \see selectTest, deselectEvent +*/ +void QCPLayerable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(additive) + Q_UNUSED(details) + Q_UNUSED(selectionStateChanged) +} + +/*! \internal + + This event is called when the layerable shall be deselected, either as consequence of a user + interaction or a call to \ref QCustomPlot::deselectAll. Subclasses should react to it by + unsetting their selection appropriately. + + just as in \ref selectEvent, the output parameter \a selectionStateChanged (if non-null), must + return true or false when the selection state of this layerable has changed or not changed, + respectively. + + \see selectTest, selectEvent +*/ +void QCPLayerable::deselectEvent(bool *selectionStateChanged) +{ + Q_UNUSED(selectionStateChanged) +} + +/*! + This event gets called when the user presses a mouse button while the cursor is over the + layerable. Whether a cursor is over the layerable is decided by a preceding call to \ref + selectTest. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a details contains layerable-specific details about the hit, which + were generated in the previous call to \ref selectTest. For example, One-dimensional plottables + like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as + \ref QCPDataSelection packed as QVariant. Multi-part objects convey the specific \c + SelectablePart that was hit (e.g. \ref QCPAxis::SelectablePart in the case of axes). + + QCustomPlot uses an event propagation system that works the same as Qt's system. If your + layerable doesn't reimplement the \ref mousePressEvent or explicitly calls \c event->ignore() in + its reimplementation, the event will be propagated to the next layerable in the stacking order. + + Once a layerable has accepted the \ref mousePressEvent, it is considered the mouse grabber and + will receive all following calls to \ref mouseMoveEvent or \ref mouseReleaseEvent for this mouse + interaction (a "mouse interaction" in this context ends with the release). + + The default implementation does nothing except explicitly ignoring the event with \c + event->ignore(). + + \see mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->ignore(); +} + +/*! + This event gets called when the user moves the mouse while holding a mouse button, after this + layerable has become the mouse grabber by accepting the preceding \ref mousePressEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a startPos indicates the position where the initial \ref + mousePressEvent occured, that started the mouse interaction. + + The default implementation does nothing. + + \see mousePressEvent, mouseReleaseEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + event->ignore(); +} + +/*! + This event gets called when the user releases the mouse button, after this layerable has become + the mouse grabber by accepting the preceding \ref mousePressEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a startPos indicates the position where the initial \ref + mousePressEvent occured, that started the mouse interaction. + + The default implementation does nothing. + + \see mousePressEvent, mouseMoveEvent, mouseDoubleClickEvent, wheelEvent +*/ +void QCPLayerable::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + event->ignore(); +} + +/*! + This event gets called when the user presses the mouse button a second time in a double-click, + while the cursor is over the layerable. Whether a cursor is over the layerable is decided by a + preceding call to \ref selectTest. + + The \ref mouseDoubleClickEvent is called instead of the second \ref mousePressEvent. So in the + case of a double-click, the event succession is + pressEvent – releaseEvent – doubleClickEvent – releaseEvent. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). The parameter \a details contains layerable-specific details about the hit, which + were generated in the previous call to \ref selectTest. For example, One-dimensional plottables + like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as + \ref QCPDataSelection packed as QVariant. Multi-part objects convey the specific \c + SelectablePart that was hit (e.g. \ref QCPAxis::SelectablePart in the case of axes). + + Similarly to \ref mousePressEvent, once a layerable has accepted the \ref mouseDoubleClickEvent, + it is considered the mouse grabber and will receive all following calls to \ref mouseMoveEvent + and \ref mouseReleaseEvent for this mouse interaction (a "mouse interaction" in this context ends + with the release). + + The default implementation does nothing except explicitly ignoring the event with \c + event->ignore(). + + \see mousePressEvent, mouseMoveEvent, mouseReleaseEvent, wheelEvent +*/ +void QCPLayerable::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->ignore(); +} + +/*! + This event gets called when the user turns the mouse scroll wheel while the cursor is over the + layerable. Whether a cursor is over the layerable is decided by a preceding call to \ref + selectTest. + + The current pixel position of the cursor on the QCustomPlot widget is accessible via \c + event->pos(). + + The \c event->delta() indicates how far the mouse wheel was turned, which is usually +/- 120 for + single rotation steps. However, if the mouse wheel is turned rapidly, multiple steps may + accumulate to one event, making \c event->delta() larger. On the other hand, if the wheel has + very smooth steps or none at all, the delta may be smaller. + + The default implementation does nothing. + + \see mousePressEvent, mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent +*/ +void QCPLayerable::wheelEvent(QWheelEvent *event) +{ + event->ignore(); +} +/* end of 'src/layer.cpp' */ + + +/* including file 'src/axis/range.cpp', size 12221 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPRange +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPRange + \brief Represents the range an axis is encompassing. + + contains a \a lower and \a upper double value and provides convenience input, output and + modification functions. + + \see QCPAxis::setRange +*/ + +/* start of documentation of inline functions */ + +/*! \fn double QCPRange::size() const + + Returns the size of the range, i.e. \a upper-\a lower +*/ + +/*! \fn double QCPRange::center() const + + Returns the center of the range, i.e. (\a upper+\a lower)*0.5 +*/ + +/*! \fn void QCPRange::normalize() + + Makes sure \a lower is numerically smaller than \a upper. If this is not the case, the values are + swapped. +*/ + +/*! \fn bool QCPRange::contains(double value) const + + Returns true when \a value lies within or exactly on the borders of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator+=(const double& value) + + Adds \a value to both boundaries of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator-=(const double& value) + + Subtracts \a value from both boundaries of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator*=(const double& value) + + Multiplies both boundaries of the range by \a value. +*/ + +/*! \fn QCPRange &QCPRange::operator/=(const double& value) + + Divides both boundaries of the range by \a value. +*/ + +/* end of documentation of inline functions */ + +/*! + Minimum range size (\a upper - \a lower) the range changing functions will accept. Smaller + intervals would cause errors due to the 11-bit exponent of double precision numbers, + corresponding to a minimum magnitude of roughly 1e-308. + + \warning Do not use this constant to indicate "arbitrarily small" values in plotting logic (as + values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to + prevent axis ranges from obtaining underflowing ranges. + + \see validRange, maxRange +*/ +const double QCPRange::minRange = 1e-280; + +/*! + Maximum values (negative and positive) the range will accept in range-changing functions. + Larger absolute values would cause errors due to the 11-bit exponent of double precision numbers, + corresponding to a maximum magnitude of roughly 1e308. + + \warning Do not use this constant to indicate "arbitrarily large" values in plotting logic (as + values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to + prevent axis ranges from obtaining overflowing ranges. + + \see validRange, minRange +*/ +const double QCPRange::maxRange = 1e250; + +/*! + Constructs a range with \a lower and \a upper set to zero. +*/ +QCPRange::QCPRange() : + lower(0), + upper(0) +{ +} + +/*! \overload + + Constructs a range with the specified \a lower and \a upper values. + + The resulting range will be normalized (see \ref normalize), so if \a lower is not numerically + smaller than \a upper, they will be swapped. +*/ +QCPRange::QCPRange(double lower, double upper) : + lower(lower), + upper(upper) +{ + normalize(); +} + +/*! \overload + + Expands this range such that \a otherRange is contained in the new range. It is assumed that both + this range and \a otherRange are normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, it will be replaced by the respective bound + of \a otherRange. + + If \a otherRange is already inside the current range, this function does nothing. + + \see expanded +*/ +void QCPRange::expand(const QCPRange &otherRange) +{ + if (lower > otherRange.lower || qIsNaN(lower)) + lower = otherRange.lower; + if (upper < otherRange.upper || qIsNaN(upper)) + upper = otherRange.upper; +} + +/*! \overload + + Expands this range such that \a includeCoord is contained in the new range. It is assumed that + this range is normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the respective bound will be set to \a + includeCoord. + + If \a includeCoord is already inside the current range, this function does nothing. + + \see expand +*/ +void QCPRange::expand(double includeCoord) +{ + if (lower > includeCoord || qIsNaN(lower)) + lower = includeCoord; + if (upper < includeCoord || qIsNaN(upper)) + upper = includeCoord; +} + + +/*! \overload + + Returns an expanded range that contains this and \a otherRange. It is assumed that both this + range and \a otherRange are normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the returned range's bound will be taken from + \a otherRange. + + \see expand +*/ +QCPRange QCPRange::expanded(const QCPRange &otherRange) const +{ + QCPRange result = *this; + result.expand(otherRange); + return result; +} + +/*! \overload + + Returns an expanded range that includes the specified \a includeCoord. It is assumed that this + range is normalized (see \ref normalize). + + If this range contains NaN as lower or upper bound, the returned range's bound will be set to \a + includeCoord. + + \see expand +*/ +QCPRange QCPRange::expanded(double includeCoord) const +{ + QCPRange result = *this; + result.expand(includeCoord); + return result; +} + +/*! + Returns this range, possibly modified to not exceed the bounds provided as \a lowerBound and \a + upperBound. If possible, the size of the current range is preserved in the process. + + If the range shall only be bounded at the lower side, you can set \a upperBound to \ref + QCPRange::maxRange. If it shall only be bounded at the upper side, set \a lowerBound to -\ref + QCPRange::maxRange. +*/ +QCPRange QCPRange::bounded(double lowerBound, double upperBound) const +{ + if (lowerBound > upperBound) + qSwap(lowerBound, upperBound); + + QCPRange result(lower, upper); + if (result.lower < lowerBound) + { + result.lower = lowerBound; + result.upper = lowerBound + size(); + if (result.upper > upperBound || qFuzzyCompare(size(), upperBound-lowerBound)) + result.upper = upperBound; + } else if (result.upper > upperBound) + { + result.upper = upperBound; + result.lower = upperBound - size(); + if (result.lower < lowerBound || qFuzzyCompare(size(), upperBound-lowerBound)) + result.lower = lowerBound; + } + + return result; +} + +/*! + Returns a sanitized version of the range. Sanitized means for logarithmic scales, that + the range won't span the positive and negative sign domain, i.e. contain zero. Further + \a lower will always be numerically smaller (or equal) to \a upper. + + If the original range does span positive and negative sign domains or contains zero, + the returned range will try to approximate the original range as good as possible. + If the positive interval of the original range is wider than the negative interval, the + returned range will only contain the positive interval, with lower bound set to \a rangeFac or + \a rangeFac *\a upper, whichever is closer to zero. Same procedure is used if the negative interval + is wider than the positive interval, this time by changing the \a upper bound. +*/ +QCPRange QCPRange::sanitizedForLogScale() const +{ + double rangeFac = 1e-3; + QCPRange sanitizedRange(lower, upper); + sanitizedRange.normalize(); + // can't have range spanning negative and positive values in log plot, so change range to fix it + //if (qFuzzyCompare(sanitizedRange.lower+1, 1) && !qFuzzyCompare(sanitizedRange.upper+1, 1)) + if (sanitizedRange.lower == 0.0 && sanitizedRange.upper != 0.0) + { + // case lower is 0 + if (rangeFac < sanitizedRange.upper*rangeFac) + sanitizedRange.lower = rangeFac; + else + sanitizedRange.lower = sanitizedRange.upper*rangeFac; + } //else if (!qFuzzyCompare(lower+1, 1) && qFuzzyCompare(upper+1, 1)) + else if (sanitizedRange.lower != 0.0 && sanitizedRange.upper == 0.0) + { + // case upper is 0 + if (-rangeFac > sanitizedRange.lower*rangeFac) + sanitizedRange.upper = -rangeFac; + else + sanitizedRange.upper = sanitizedRange.lower*rangeFac; + } else if (sanitizedRange.lower < 0 && sanitizedRange.upper > 0) + { + // find out whether negative or positive interval is wider to decide which sign domain will be chosen + if (-sanitizedRange.lower > sanitizedRange.upper) + { + // negative is wider, do same as in case upper is 0 + if (-rangeFac > sanitizedRange.lower*rangeFac) + sanitizedRange.upper = -rangeFac; + else + sanitizedRange.upper = sanitizedRange.lower*rangeFac; + } else + { + // positive is wider, do same as in case lower is 0 + if (rangeFac < sanitizedRange.upper*rangeFac) + sanitizedRange.lower = rangeFac; + else + sanitizedRange.lower = sanitizedRange.upper*rangeFac; + } + } + // due to normalization, case lower>0 && upper<0 should never occur, because that implies upper -maxRange && + upper < maxRange && + qAbs(lower-upper) > minRange && + qAbs(lower-upper) < maxRange && + !(lower > 0 && qIsInf(upper/lower)) && + !(upper < 0 && qIsInf(lower/upper))); +} + +/*! + \overload + Checks, whether the specified range is within valid bounds, which are defined + as QCPRange::maxRange and QCPRange::minRange. + A valid range means: + \li range bounds within -maxRange and maxRange + \li range size above minRange + \li range size below maxRange +*/ +bool QCPRange::validRange(const QCPRange &range) +{ + return (range.lower > -maxRange && + range.upper < maxRange && + qAbs(range.lower-range.upper) > minRange && + qAbs(range.lower-range.upper) < maxRange && + !(range.lower > 0 && qIsInf(range.upper/range.lower)) && + !(range.upper < 0 && qIsInf(range.lower/range.upper))); +} +/* end of 'src/axis/range.cpp' */ + + +/* including file 'src/selection.cpp', size 21898 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataRange +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataRange + \brief Describes a data range given by begin and end index + + QCPDataRange holds two integers describing the begin (\ref setBegin) and end (\ref setEnd) index + of a contiguous set of data points. The end index points to the data point above the last data point that's part of + the data range, similarly to the nomenclature used in standard iterators. + + Data Ranges are not bound to a certain plottable, thus they can be freely exchanged, created and + modified. If a non-contiguous data set shall be described, the class \ref QCPDataSelection is + used, which holds and manages multiple instances of \ref QCPDataRange. In most situations, \ref + QCPDataSelection is thus used. + + Both \ref QCPDataRange and \ref QCPDataSelection offer convenience methods to work with them, + e.g. \ref bounded, \ref expanded, \ref intersects, \ref intersection, \ref adjusted, \ref + contains. Further, addition and subtraction operators (defined in \ref QCPDataSelection) can be + used to join/subtract data ranges and data selections (or mixtures), to retrieve a corresponding + \ref QCPDataSelection. + + %QCustomPlot's \ref dataselection "data selection mechanism" is based on \ref QCPDataSelection and + QCPDataRange. + + \note Do not confuse \ref QCPDataRange with \ref QCPRange. A \ref QCPRange describes an interval + in floating point plot coordinates, e.g. the current axis range. +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataRange::size() const + + Returns the number of data points described by this data range. This is equal to the end index + minus the begin index. + + \see length +*/ + +/*! \fn int QCPDataRange::length() const + + Returns the number of data points described by this data range. Equivalent to \ref size. +*/ + +/*! \fn void QCPDataRange::setBegin(int begin) + + Sets the begin of this data range. The \a begin index points to the first data point that is part + of the data range. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). + + \see setEnd +*/ + +/*! \fn void QCPDataRange::setEnd(int end) + + Sets the end of this data range. The \a end index points to the data point just above the last + data point that is part of the data range. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). + + \see setBegin +*/ + +/*! \fn bool QCPDataRange::isValid() const + + Returns whether this range is valid. A valid range has a begin index greater or equal to 0, and + an end index greater or equal to the begin index. + + \note Invalid ranges should be avoided and are never the result of any of QCustomPlot's methods + (unless they are themselves fed with invalid ranges). Do not pass invalid ranges to QCustomPlot's + methods. The invalid range is not inherently prevented in QCPDataRange, to allow temporary + invalid begin/end values while manipulating the range. An invalid range is not necessarily empty + (\ref isEmpty), since its \ref length can be negative and thus non-zero. +*/ + +/*! \fn bool QCPDataRange::isEmpty() const + + Returns whether this range is empty, i.e. whether its begin index equals its end index. + + \see size, length +*/ + +/*! \fn QCPDataRange QCPDataRange::adjusted(int changeBegin, int changeEnd) const + + Returns a data range where \a changeBegin and \a changeEnd were added to the begin and end + indices, respectively. +*/ + +/* end documentation of inline functions */ + +/*! + Creates an empty QCPDataRange, with begin and end set to 0. +*/ +QCPDataRange::QCPDataRange() : + mBegin(0), + mEnd(0) +{ +} + +/*! + Creates a QCPDataRange, initialized with the specified \a begin and \a end. + + No checks or corrections are made to ensure the resulting range is valid (\ref isValid). +*/ +QCPDataRange::QCPDataRange(int begin, int end) : + mBegin(begin), + mEnd(end) +{ +} + +/*! + Returns a data range that matches this data range, except that parts exceeding \a other are + excluded. + + This method is very similar to \ref intersection, with one distinction: If this range and the \a + other range share no intersection, the returned data range will be empty with begin and end set + to the respective boundary side of \a other, at which this range is residing. (\ref intersection + would just return a range with begin and end set to 0.) +*/ +QCPDataRange QCPDataRange::bounded(const QCPDataRange &other) const +{ + QCPDataRange result(intersection(other)); + if (result.isEmpty()) // no intersection, preserve respective bounding side of otherRange as both begin and end of return value + { + if (mEnd <= other.mBegin) + result = QCPDataRange(other.mBegin, other.mBegin); + else + result = QCPDataRange(other.mEnd, other.mEnd); + } + return result; +} + +/*! + Returns a data range that contains both this data range as well as \a other. +*/ +QCPDataRange QCPDataRange::expanded(const QCPDataRange &other) const +{ + return QCPDataRange(qMin(mBegin, other.mBegin), qMax(mEnd, other.mEnd)); +} + +/*! + Returns the data range which is contained in both this data range and \a other. + + This method is very similar to \ref bounded, with one distinction: If this range and the \a other + range share no intersection, the returned data range will be empty with begin and end set to 0. + (\ref bounded would return a range with begin and end set to one of the boundaries of \a other, + depending on which side this range is on.) + + \see QCPDataSelection::intersection +*/ +QCPDataRange QCPDataRange::intersection(const QCPDataRange &other) const +{ + QCPDataRange result(qMax(mBegin, other.mBegin), qMin(mEnd, other.mEnd)); + if (result.isValid()) + return result; + else + return QCPDataRange(); +} + +/*! + Returns whether this data range and \a other share common data points. + + \see intersection, contains +*/ +bool QCPDataRange::intersects(const QCPDataRange &other) const +{ + return !( (mBegin > other.mBegin && mBegin >= other.mEnd) || + (mEnd <= other.mBegin && mEnd < other.mEnd) ); +} + +/*! + Returns whether all data points described by this data range are also in \a other. + + \see intersects +*/ +bool QCPDataRange::contains(const QCPDataRange &other) const +{ + return mBegin <= other.mBegin && mEnd >= other.mEnd; +} + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataSelection +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataSelection + \brief Describes a data set by holding multiple QCPDataRange instances + + QCPDataSelection manages multiple instances of QCPDataRange in order to represent any (possibly + disjoint) set of data selection. + + The data selection can be modified with addition and subtraction operators which take + QCPDataSelection and QCPDataRange instances, as well as methods such as \ref addDataRange and + \ref clear. Read access is provided by \ref dataRange, \ref dataRanges, \ref dataRangeCount, etc. + + The method \ref simplify is used to join directly adjacent or even overlapping QCPDataRange + instances. QCPDataSelection automatically simplifies when using the addition/subtraction + operators. The only case when \ref simplify is left to the user, is when calling \ref + addDataRange, with the parameter \a simplify explicitly set to false. This is useful if many data + ranges will be added to the selection successively and the overhead for simplifying after each + iteration shall be avoided. In this case, you should make sure to call \ref simplify after + completing the operation. + + Use \ref enforceType to bring the data selection into a state complying with the constraints for + selections defined in \ref QCP::SelectionType. + + %QCustomPlot's \ref dataselection "data selection mechanism" is based on QCPDataSelection and + QCPDataRange. + + \section qcpdataselection-iterating Iterating over a data selection + + As an example, the following code snippet calculates the average value of a graph's data + \ref QCPAbstractPlottable::selection "selection": + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpdataselection-iterating-1 + +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataSelection::dataRangeCount() const + + Returns the number of ranges that make up the data selection. The ranges can be accessed by \ref + dataRange via their index. + + \see dataRange, dataPointCount +*/ + +/*! \fn QList QCPDataSelection::dataRanges() const + + Returns all data ranges that make up the data selection. If the data selection is simplified (the + usual state of the selection, see \ref simplify), the ranges are sorted by ascending data point + index. + + \see dataRange +*/ + +/*! \fn bool QCPDataSelection::isEmpty() const + + Returns true if there are no data ranges, and thus no data points, in this QCPDataSelection + instance. + + \see dataRangeCount +*/ + +/* end documentation of inline functions */ + +/*! + Creates an empty QCPDataSelection. +*/ +QCPDataSelection::QCPDataSelection() +{ +} + +/*! + Creates a QCPDataSelection containing the provided \a range. +*/ +QCPDataSelection::QCPDataSelection(const QCPDataRange &range) +{ + mDataRanges.append(range); +} + +/*! + Returns true if this selection is identical (contains the same data ranges with the same begin + and end indices) to \a other. + + Note that both data selections must be in simplified state (the usual state of the selection, see + \ref simplify) for this operator to return correct results. +*/ +bool QCPDataSelection::operator==(const QCPDataSelection &other) const +{ + if (mDataRanges.size() != other.mDataRanges.size()) + return false; + for (int i=0; i= other.end()) + break; // since data ranges are sorted after the simplify() call, no ranges which contain other will come after this + + if (thisEnd > other.begin()) // ranges which don't fulfill this are entirely before other and can be ignored + { + if (thisBegin >= other.begin()) // range leading segment is encompassed + { + if (thisEnd <= other.end()) // range fully encompassed, remove completely + { + mDataRanges.removeAt(i); + continue; + } else // only leading segment is encompassed, trim accordingly + mDataRanges[i].setBegin(other.end()); + } else // leading segment is not encompassed + { + if (thisEnd <= other.end()) // only trailing segment is encompassed, trim accordingly + { + mDataRanges[i].setEnd(other.begin()); + } else // other lies inside this range, so split range + { + mDataRanges[i].setEnd(other.begin()); + mDataRanges.insert(i+1, QCPDataRange(other.end(), thisEnd)); + break; // since data ranges are sorted (and don't overlap) after simplify() call, we're done here + } + } + } + ++i; + } + + return *this; +} + +/*! + Returns the total number of data points contained in all data ranges that make up this data + selection. +*/ +int QCPDataSelection::dataPointCount() const +{ + int result = 0; + for (int i=0; i= 0 && index < mDataRanges.size()) + { + return mDataRanges.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of range:" << index; + return QCPDataRange(); + } +} + +/*! + Returns a \ref QCPDataRange which spans the entire data selection, including possible + intermediate segments which are not part of the original data selection. +*/ +QCPDataRange QCPDataSelection::span() const +{ + if (isEmpty()) + return QCPDataRange(); + else + return QCPDataRange(mDataRanges.first().begin(), mDataRanges.last().end()); +} + +/*! + Adds the given \a dataRange to this data selection. This is equivalent to the += operator but + allows disabling immediate simplification by setting \a simplify to false. This can improve + performance if adding a very large amount of data ranges successively. In this case, make sure to + call \ref simplify manually, after the operation. +*/ +void QCPDataSelection::addDataRange(const QCPDataRange &dataRange, bool simplify) +{ + mDataRanges.append(dataRange); + if (simplify) + this->simplify(); +} + +/*! + Removes all data ranges. The data selection then contains no data points. + + \ref isEmpty +*/ +void QCPDataSelection::clear() +{ + mDataRanges.clear(); +} + +/*! + Sorts all data ranges by range begin index in ascending order, and then joins directly adjacent + or overlapping ranges. This can reduce the number of individual data ranges in the selection, and + prevents possible double-counting when iterating over the data points held by the data ranges. + + This method is automatically called when using the addition/subtraction operators. The only case + when \ref simplify is left to the user, is when calling \ref addDataRange, with the parameter \a + simplify explicitly set to false. +*/ +void QCPDataSelection::simplify() +{ + // remove any empty ranges: + for (int i=mDataRanges.size()-1; i>=0; --i) + { + if (mDataRanges.at(i).isEmpty()) + mDataRanges.removeAt(i); + } + if (mDataRanges.isEmpty()) + return; + + // sort ranges by starting value, ascending: + std::sort(mDataRanges.begin(), mDataRanges.end(), lessThanDataRangeBegin); + + // join overlapping/contiguous ranges: + int i = 1; + while (i < mDataRanges.size()) + { + if (mDataRanges.at(i-1).end() >= mDataRanges.at(i).begin()) // range i overlaps/joins with i-1, so expand range i-1 appropriately and remove range i from list + { + mDataRanges[i-1].setEnd(qMax(mDataRanges.at(i-1).end(), mDataRanges.at(i).end())); + mDataRanges.removeAt(i); + } else + ++i; + } +} + +/*! + Makes sure this data selection conforms to the specified \a type selection type. Before the type + is enforced, \ref simplify is called. + + Depending on \a type, enforcing means adding new data points that were previously not part of the + selection, or removing data points from the selection. If the current selection already conforms + to \a type, the data selection is not changed. + + \see QCP::SelectionType +*/ +void QCPDataSelection::enforceType(QCP::SelectionType type) +{ + simplify(); + switch (type) + { + case QCP::stNone: + { + mDataRanges.clear(); + break; + } + case QCP::stWhole: + { + // whole selection isn't defined by data range, so don't change anything (is handled in plottable methods) + break; + } + case QCP::stSingleData: + { + // reduce all data ranges to the single first data point: + if (!mDataRanges.isEmpty()) + { + if (mDataRanges.size() > 1) + mDataRanges = QList() << mDataRanges.first(); + if (mDataRanges.first().length() > 1) + mDataRanges.first().setEnd(mDataRanges.first().begin()+1); + } + break; + } + case QCP::stDataRange: + { + mDataRanges = QList() << span(); + break; + } + case QCP::stMultipleDataRanges: + { + // this is the selection type that allows all concievable combinations of ranges, so do nothing + break; + } + } +} + +/*! + Returns true if the data selection \a other is contained entirely in this data selection, i.e. + all data point indices that are in \a other are also in this data selection. + + \see QCPDataRange::contains +*/ +bool QCPDataSelection::contains(const QCPDataSelection &other) const +{ + if (other.isEmpty()) return false; + + int otherIndex = 0; + int thisIndex = 0; + while (thisIndex < mDataRanges.size() && otherIndex < other.mDataRanges.size()) + { + if (mDataRanges.at(thisIndex).contains(other.mDataRanges.at(otherIndex))) + ++otherIndex; + else + ++thisIndex; + } + return thisIndex < mDataRanges.size(); // if thisIndex ran all the way to the end to find a containing range for the current otherIndex, other is not contained in this +} + +/*! + Returns a data selection containing the points which are both in this data selection and in the + data range \a other. + + A common use case is to limit an unknown data selection to the valid range of a data container, + using \ref QCPDataContainer::dataRange as \a other. One can then safely iterate over the returned + data selection without exceeding the data container's bounds. +*/ +QCPDataSelection QCPDataSelection::intersection(const QCPDataRange &other) const +{ + QCPDataSelection result; + for (int i=0; iorientation() == Qt::Horizontal) + return QCPRange(axis->pixelToCoord(mRect.left()), axis->pixelToCoord(mRect.left()+mRect.width())); + else + return QCPRange(axis->pixelToCoord(mRect.top()+mRect.height()), axis->pixelToCoord(mRect.top())); + } else + { + qDebug() << Q_FUNC_INFO << "called with axis zero"; + return QCPRange(); + } +} + +/*! + Sets the pen that will be used to draw the selection rect outline. + + \see setBrush +*/ +void QCPSelectionRect::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the brush that will be used to fill the selection rect. By default the selection rect is not + filled, i.e. \a brush is Qt::NoBrush. + + \see setPen +*/ +void QCPSelectionRect::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + If there is currently a selection interaction going on (\ref isActive), the interaction is + canceled. The selection rect will emit the \ref canceled signal. +*/ +void QCPSelectionRect::cancel() +{ + if (mActive) + { + mActive = false; + emit canceled(mRect, 0); + } +} + +/*! \internal + + This method is called by QCustomPlot to indicate that a selection rect interaction was initiated. + The default implementation sets the selection rect to active, initializes the selection rect + geometry and emits the \ref started signal. +*/ +void QCPSelectionRect::startSelection(QMouseEvent *event) +{ + mActive = true; + mRect = QRect(event->pos(), event->pos()); + emit started(event); +} + +/*! \internal + + This method is called by QCustomPlot to indicate that an ongoing selection rect interaction needs + to update its geometry. The default implementation updates the rect and emits the \ref changed + signal. +*/ +void QCPSelectionRect::moveSelection(QMouseEvent *event) +{ + mRect.setBottomRight(event->pos()); + emit changed(mRect, event); + layer()->replot(); +} + +/*! \internal + + This method is called by QCustomPlot to indicate that an ongoing selection rect interaction has + finished by the user releasing the mouse button. The default implementation deactivates the + selection rect and emits the \ref accepted signal. +*/ +void QCPSelectionRect::endSelection(QMouseEvent *event) +{ + mRect.setBottomRight(event->pos()); + mActive = false; + emit accepted(mRect, event); +} + +/*! \internal + + This method is called by QCustomPlot when a key has been pressed by the user while the selection + rect interaction is active. The default implementation allows to \ref cancel the interaction by + hitting the escape key. +*/ +void QCPSelectionRect::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Escape && mActive) + { + mActive = false; + emit canceled(mRect, event); + } +} + +/* inherits documentation from base class */ +void QCPSelectionRect::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeOther); +} + +/*! \internal + + If the selection rect is active (\ref isActive), draws the selection rect defined by \a mRect. + + \seebaseclassmethod +*/ +void QCPSelectionRect::draw(QCPPainter *painter) +{ + if (mActive) + { + painter->setPen(mPen); + painter->setBrush(mBrush); + painter->drawRect(mRect); + } +} +/* end of 'src/selectionrect.cpp' */ + + +/* including file 'src/layout.cpp', size 74302 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPMarginGroup +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPMarginGroup + \brief A margin group allows synchronization of margin sides if working with multiple layout elements. + + QCPMarginGroup allows you to tie a margin side of two or more layout elements together, such that + they will all have the same size, based on the largest required margin in the group. + + \n + \image html QCPMarginGroup.png "Demonstration of QCPMarginGroup" + \n + + In certain situations it is desirable that margins at specific sides are synchronized across + layout elements. For example, if one QCPAxisRect is below another one in a grid layout, it will + provide a cleaner look to the user if the left and right margins of the two axis rects are of the + same size. The left axis of the top axis rect will then be at the same horizontal position as the + left axis of the lower axis rect, making them appear aligned. The same applies for the right + axes. This is what QCPMarginGroup makes possible. + + To add/remove a specific side of a layout element to/from a margin group, use the \ref + QCPLayoutElement::setMarginGroup method. To completely break apart the margin group, either call + \ref clear, or just delete the margin group. + + \section QCPMarginGroup-example Example + + First create a margin group: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-1 + Then set this group on the layout element sides: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpmargingroup-creation-2 + Here, we've used the first two axis rects of the plot and synchronized their left margins with + each other and their right margins with each other. +*/ + +/* start documentation of inline functions */ + +/*! \fn QList QCPMarginGroup::elements(QCP::MarginSide side) const + + Returns a list of all layout elements that have their margin \a side associated with this margin + group. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPMarginGroup instance in \a parentPlot. +*/ +QCPMarginGroup::QCPMarginGroup(QCustomPlot *parentPlot) : + QObject(parentPlot), + mParentPlot(parentPlot) +{ + mChildren.insert(QCP::msLeft, QList()); + mChildren.insert(QCP::msRight, QList()); + mChildren.insert(QCP::msTop, QList()); + mChildren.insert(QCP::msBottom, QList()); +} + +QCPMarginGroup::~QCPMarginGroup() +{ + clear(); +} + +/*! + Returns whether this margin group is empty. If this function returns true, no layout elements use + this margin group to synchronize margin sides. +*/ +bool QCPMarginGroup::isEmpty() const +{ + QHashIterator > it(mChildren); + while (it.hasNext()) + { + it.next(); + if (!it.value().isEmpty()) + return false; + } + return true; +} + +/*! + Clears this margin group. The synchronization of the margin sides that use this margin group is + lifted and they will use their individual margin sizes again. +*/ +void QCPMarginGroup::clear() +{ + // make all children remove themselves from this margin group: + QHashIterator > it(mChildren); + while (it.hasNext()) + { + it.next(); + const QList elements = it.value(); + for (int i=elements.size()-1; i>=0; --i) + elements.at(i)->setMarginGroup(it.key(), 0); // removes itself from mChildren via removeChild + } +} + +/*! \internal + + Returns the synchronized common margin for \a side. This is the margin value that will be used by + the layout element on the respective side, if it is part of this margin group. + + The common margin is calculated by requesting the automatic margin (\ref + QCPLayoutElement::calculateAutoMargin) of each element associated with \a side in this margin + group, and choosing the largest returned value. (QCPLayoutElement::minimumMargins is taken into + account, too.) +*/ +int QCPMarginGroup::commonMargin(QCP::MarginSide side) const +{ + // query all automatic margins of the layout elements in this margin group side and find maximum: + int result = 0; + const QList elements = mChildren.value(side); + for (int i=0; iautoMargins().testFlag(side)) + continue; + int m = qMax(elements.at(i)->calculateAutoMargin(side), QCP::getMarginValue(elements.at(i)->minimumMargins(), side)); + if (m > result) + result = m; + } + return result; +} + +/*! \internal + + Adds \a element to the internal list of child elements, for the margin \a side. + + This function does not modify the margin group property of \a element. +*/ +void QCPMarginGroup::addChild(QCP::MarginSide side, QCPLayoutElement *element) +{ + if (!mChildren[side].contains(element)) + mChildren[side].append(element); + else + qDebug() << Q_FUNC_INFO << "element is already child of this margin group side" << reinterpret_cast(element); +} + +/*! \internal + + Removes \a element from the internal list of child elements, for the margin \a side. + + This function does not modify the margin group property of \a element. +*/ +void QCPMarginGroup::removeChild(QCP::MarginSide side, QCPLayoutElement *element) +{ + if (!mChildren[side].removeOne(element)) + qDebug() << Q_FUNC_INFO << "element is not child of this margin group side" << reinterpret_cast(element); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutElement +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayoutElement + \brief The abstract base class for all objects that form \ref thelayoutsystem "the layout system". + + This is an abstract base class. As such, it can't be instantiated directly, rather use one of its subclasses. + + A Layout element is a rectangular object which can be placed in layouts. It has an outer rect + (QCPLayoutElement::outerRect) and an inner rect (\ref QCPLayoutElement::rect). The difference + between outer and inner rect is called its margin. The margin can either be set to automatic or + manual (\ref setAutoMargins) on a per-side basis. If a side is set to manual, that margin can be + set explicitly with \ref setMargins and will stay fixed at that value. If it's set to automatic, + the layout element subclass will control the value itself (via \ref calculateAutoMargin). + + Layout elements can be placed in layouts (base class QCPLayout) like QCPLayoutGrid. The top level + layout is reachable via \ref QCustomPlot::plotLayout, and is a \ref QCPLayoutGrid. Since \ref + QCPLayout itself derives from \ref QCPLayoutElement, layouts can be nested. + + Thus in QCustomPlot one can divide layout elements into two categories: The ones that are + invisible by themselves, because they don't draw anything. Their only purpose is to manage the + position and size of other layout elements. This category of layout elements usually use + QCPLayout as base class. Then there is the category of layout elements which actually draw + something. For example, QCPAxisRect, QCPLegend and QCPTextElement are of this category. This does + not necessarily mean that the latter category can't have child layout elements. QCPLegend for + instance, actually derives from QCPLayoutGrid and the individual legend items are child layout + elements in the grid layout. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayout *QCPLayoutElement::layout() const + + Returns the parent layout of this layout element. +*/ + +/*! \fn QRect QCPLayoutElement::rect() const + + Returns the inner rect of this layout element. The inner rect is the outer rect (\ref + setOuterRect) shrinked by the margins (\ref setMargins, \ref setAutoMargins). + + In some cases, the area between outer and inner rect is left blank. In other cases the margin + area is used to display peripheral graphics while the main content is in the inner rect. This is + where automatic margin calculation becomes interesting because it allows the layout element to + adapt the margins to the peripheral graphics it wants to draw. For example, \ref QCPAxisRect + draws the axis labels and tick labels in the margin area, thus needs to adjust the margins (if + \ref setAutoMargins is enabled) according to the space required by the labels of the axes. +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutElement and sets default values. +*/ +QCPLayoutElement::QCPLayoutElement(QCustomPlot *parentPlot) : + QCPLayerable(parentPlot), // parenthood is changed as soon as layout element gets inserted into a layout (except for top level layout) + mParentLayout(0), + mMinimumSize(), + mMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX), + mRect(0, 0, 0, 0), + mOuterRect(0, 0, 0, 0), + mMargins(0, 0, 0, 0), + mMinimumMargins(0, 0, 0, 0), + mAutoMargins(QCP::msAll) +{ +} + +QCPLayoutElement::~QCPLayoutElement() +{ + setMarginGroup(QCP::msAll, 0); // unregister at margin groups, if there are any + // unregister at layout: + if (qobject_cast(mParentLayout)) // the qobject_cast is just a safeguard in case the layout forgets to call clear() in its dtor and this dtor is called by QObject dtor + mParentLayout->take(this); +} + +/*! + Sets the outer rect of this layout element. If the layout element is inside a layout, the layout + sets the position and size of this layout element using this function. + + Calling this function externally has no effect, since the layout will overwrite any changes to + the outer rect upon the next replot. + + The layout element will adapt its inner \ref rect by applying the margins inward to the outer rect. + + \see rect +*/ +void QCPLayoutElement::setOuterRect(const QRect &rect) +{ + if (mOuterRect != rect) + { + mOuterRect = rect; + mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); + } +} + +/*! + Sets the margins of this layout element. If \ref setAutoMargins is disabled for some or all + sides, this function is used to manually set the margin on those sides. Sides that are still set + to be handled automatically are ignored and may have any value in \a margins. + + The margin is the distance between the outer rect (controlled by the parent layout via \ref + setOuterRect) and the inner \ref rect (which usually contains the main content of this layout + element). + + \see setAutoMargins +*/ +void QCPLayoutElement::setMargins(const QMargins &margins) +{ + if (mMargins != margins) + { + mMargins = margins; + mRect = mOuterRect.adjusted(mMargins.left(), mMargins.top(), -mMargins.right(), -mMargins.bottom()); + } +} + +/*! + If \ref setAutoMargins is enabled on some or all margins, this function is used to provide + minimum values for those margins. + + The minimum values are not enforced on margin sides that were set to be under manual control via + \ref setAutoMargins. + + \see setAutoMargins +*/ +void QCPLayoutElement::setMinimumMargins(const QMargins &margins) +{ + if (mMinimumMargins != margins) + { + mMinimumMargins = margins; + } +} + +/*! + Sets on which sides the margin shall be calculated automatically. If a side is calculated + automatically, a minimum margin value may be provided with \ref setMinimumMargins. If a side is + set to be controlled manually, the value may be specified with \ref setMargins. + + Margin sides that are under automatic control may participate in a \ref QCPMarginGroup (see \ref + setMarginGroup), to synchronize (align) it with other layout elements in the plot. + + \see setMinimumMargins, setMargins, QCP::MarginSide +*/ +void QCPLayoutElement::setAutoMargins(QCP::MarginSides sides) +{ + mAutoMargins = sides; +} + +/*! + Sets the minimum size for the inner \ref rect of this layout element. A parent layout tries to + respect the \a size here by changing row/column sizes in the layout accordingly. + + If the parent layout size is not sufficient to satisfy all minimum size constraints of its child + layout elements, the layout may set a size that is actually smaller than \a size. QCustomPlot + propagates the layout's size constraints to the outside by setting its own minimum QWidget size + accordingly, so violations of \a size should be exceptions. +*/ +void QCPLayoutElement::setMinimumSize(const QSize &size) +{ + if (mMinimumSize != size) + { + mMinimumSize = size; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! \overload + + Sets the minimum size for the inner \ref rect of this layout element. +*/ +void QCPLayoutElement::setMinimumSize(int width, int height) +{ + setMinimumSize(QSize(width, height)); +} + +/*! + Sets the maximum size for the inner \ref rect of this layout element. A parent layout tries to + respect the \a size here by changing row/column sizes in the layout accordingly. +*/ +void QCPLayoutElement::setMaximumSize(const QSize &size) +{ + if (mMaximumSize != size) + { + mMaximumSize = size; + if (mParentLayout) + mParentLayout->sizeConstraintsChanged(); + } +} + +/*! \overload + + Sets the maximum size for the inner \ref rect of this layout element. +*/ +void QCPLayoutElement::setMaximumSize(int width, int height) +{ + setMaximumSize(QSize(width, height)); +} + +/*! + Sets the margin \a group of the specified margin \a sides. + + Margin groups allow synchronizing specified margins across layout elements, see the documentation + of \ref QCPMarginGroup. + + To unset the margin group of \a sides, set \a group to 0. + + Note that margin groups only work for margin sides that are set to automatic (\ref + setAutoMargins). + + \see QCP::MarginSide +*/ +void QCPLayoutElement::setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group) +{ + QVector sideVector; + if (sides.testFlag(QCP::msLeft)) sideVector.append(QCP::msLeft); + if (sides.testFlag(QCP::msRight)) sideVector.append(QCP::msRight); + if (sides.testFlag(QCP::msTop)) sideVector.append(QCP::msTop); + if (sides.testFlag(QCP::msBottom)) sideVector.append(QCP::msBottom); + + for (int i=0; iremoveChild(side, this); + + if (!group) // if setting to 0, remove hash entry. Else set hash entry to new group and register there + { + mMarginGroups.remove(side); + } else // setting to a new group + { + mMarginGroups[side] = group; + group->addChild(side, this); + } + } + } +} + +/*! + Updates the layout element and sub-elements. This function is automatically called before every + replot by the parent layout element. It is called multiple times, once for every \ref + UpdatePhase. The phases are run through in the order of the enum values. For details about what + happens at the different phases, see the documentation of \ref UpdatePhase. + + Layout elements that have child elements should call the \ref update method of their child + elements, and pass the current \a phase unchanged. + + The default implementation executes the automatic margin mechanism in the \ref upMargins phase. + Subclasses should make sure to call the base class implementation. +*/ +void QCPLayoutElement::update(UpdatePhase phase) +{ + if (phase == upMargins) + { + if (mAutoMargins != QCP::msNone) + { + // set the margins of this layout element according to automatic margin calculation, either directly or via a margin group: + QMargins newMargins = mMargins; + QList allMarginSides = QList() << QCP::msLeft << QCP::msRight << QCP::msTop << QCP::msBottom; + foreach (QCP::MarginSide side, allMarginSides) + { + if (mAutoMargins.testFlag(side)) // this side's margin shall be calculated automatically + { + if (mMarginGroups.contains(side)) + QCP::setMarginValue(newMargins, side, mMarginGroups[side]->commonMargin(side)); // this side is part of a margin group, so get the margin value from that group + else + QCP::setMarginValue(newMargins, side, calculateAutoMargin(side)); // this side is not part of a group, so calculate the value directly + // apply minimum margin restrictions: + if (QCP::getMarginValue(newMargins, side) < QCP::getMarginValue(mMinimumMargins, side)) + QCP::setMarginValue(newMargins, side, QCP::getMarginValue(mMinimumMargins, side)); + } + } + setMargins(newMargins); + } + } +} + +/*! + Returns the minimum size this layout element (the inner \ref rect) may be compressed to. + + if a minimum size (\ref setMinimumSize) was not set manually, parent layouts consult this + function to determine the minimum allowed size of this layout element. (A manual minimum size is + considered set if it is non-zero.) +*/ +QSize QCPLayoutElement::minimumSizeHint() const +{ + return mMinimumSize; +} + +/*! + Returns the maximum size this layout element (the inner \ref rect) may be expanded to. + + if a maximum size (\ref setMaximumSize) was not set manually, parent layouts consult this + function to determine the maximum allowed size of this layout element. (A manual maximum size is + considered set if it is smaller than Qt's QWIDGETSIZE_MAX.) +*/ +QSize QCPLayoutElement::maximumSizeHint() const +{ + return mMaximumSize; +} + +/*! + Returns a list of all child elements in this layout element. If \a recursive is true, all + sub-child elements are included in the list, too. + + \warning There may be entries with value 0 in the returned list. (For example, QCPLayoutGrid may have + empty cells which yield 0 at the respective index.) +*/ +QList QCPLayoutElement::elements(bool recursive) const +{ + Q_UNUSED(recursive) + return QList(); +} + +/*! + Layout elements are sensitive to events inside their outer rect. If \a pos is within the outer + rect, this method returns a value corresponding to 0.99 times the parent plot's selection + tolerance. However, layout elements are not selectable by default. So if \a onlySelectable is + true, -1.0 is returned. + + See \ref QCPLayerable::selectTest for a general explanation of this virtual method. + + QCPLayoutElement subclasses may reimplement this method to provide more specific selection test + behaviour. +*/ +double QCPLayoutElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + + if (onlySelectable) + return -1; + + if (QRectF(mOuterRect).contains(pos)) + { + if (mParentPlot) + return mParentPlot->selectionTolerance()*0.99; + else + { + qDebug() << Q_FUNC_INFO << "parent plot not defined"; + return -1; + } + } else + return -1; +} + +/*! \internal + + propagates the parent plot initialization to all child elements, by calling \ref + QCPLayerable::initializeParentPlot on them. +*/ +void QCPLayoutElement::parentPlotInitialized(QCustomPlot *parentPlot) +{ + foreach (QCPLayoutElement* el, elements(false)) + { + if (!el->parentPlot()) + el->initializeParentPlot(parentPlot); + } +} + +/*! \internal + + Returns the margin size for this \a side. It is used if automatic margins is enabled for this \a + side (see \ref setAutoMargins). If a minimum margin was set with \ref setMinimumMargins, the + returned value will not be smaller than the specified minimum margin. + + The default implementation just returns the respective manual margin (\ref setMargins) or the + minimum margin, whichever is larger. +*/ +int QCPLayoutElement::calculateAutoMargin(QCP::MarginSide side) +{ + return qMax(QCP::getMarginValue(mMargins, side), QCP::getMarginValue(mMinimumMargins, side)); +} + +/*! \internal + + This virtual method is called when this layout element was moved to a different QCPLayout, or + when this layout element has changed its logical position (e.g. row and/or column) within the + same QCPLayout. Subclasses may use this to react accordingly. + + Since this method is called after the completion of the move, you can access the new parent + layout via \ref layout(). + + The default implementation does nothing. +*/ +void QCPLayoutElement::layoutChanged() +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayout +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLayout + \brief The abstract base class for layouts + + This is an abstract base class for layout elements whose main purpose is to define the position + and size of other child layout elements. In most cases, layouts don't draw anything themselves + (but there are exceptions to this, e.g. QCPLegend). + + QCPLayout derives from QCPLayoutElement, and thus can itself be nested in other layouts. + + QCPLayout introduces a common interface for accessing and manipulating the child elements. Those + functions are most notably \ref elementCount, \ref elementAt, \ref takeAt, \ref take, \ref + simplify, \ref removeAt, \ref remove and \ref clear. Individual subclasses may add more functions + to this interface which are more specialized to the form of the layout. For example, \ref + QCPLayoutGrid adds functions that take row and column indices to access cells of the layout grid + more conveniently. + + Since this is an abstract base class, you can't instantiate it directly. Rather use one of its + subclasses like QCPLayoutGrid or QCPLayoutInset. + + For a general introduction to the layout system, see the dedicated documentation page \ref + thelayoutsystem "The Layout System". +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual int QCPLayout::elementCount() const = 0 + + Returns the number of elements/cells in the layout. + + \see elements, elementAt +*/ + +/*! \fn virtual QCPLayoutElement* QCPLayout::elementAt(int index) const = 0 + + Returns the element in the cell with the given \a index. If \a index is invalid, returns 0. + + Note that even if \a index is valid, the respective cell may be empty in some layouts (e.g. + QCPLayoutGrid), so this function may return 0 in those cases. You may use this function to check + whether a cell is empty or not. + + \see elements, elementCount, takeAt +*/ + +/*! \fn virtual QCPLayoutElement* QCPLayout::takeAt(int index) = 0 + + Removes the element with the given \a index from the layout and returns it. + + If the \a index is invalid or the cell with that index is empty, returns 0. + + Note that some layouts don't remove the respective cell right away but leave an empty cell after + successful removal of the layout element. To collapse empty cells, use \ref simplify. + + \see elementAt, take +*/ + +/*! \fn virtual bool QCPLayout::take(QCPLayoutElement* element) = 0 + + Removes the specified \a element from the layout and returns true on success. + + If the \a element isn't in this layout, returns false. + + Note that some layouts don't remove the respective cell right away but leave an empty cell after + successful removal of the layout element. To collapse empty cells, use \ref simplify. + + \see takeAt +*/ + +/* end documentation of pure virtual functions */ + +/*! + Creates an instance of QCPLayout and sets default values. Note that since QCPLayout + is an abstract base class, it can't be instantiated directly. +*/ +QCPLayout::QCPLayout() +{ +} + +/*! + First calls the QCPLayoutElement::update base class implementation to update the margins on this + layout. + + Then calls \ref updateLayout which subclasses reimplement to reposition and resize their cells. + + Finally, \ref update is called on all child elements. +*/ +void QCPLayout::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + + // set child element rects according to layout: + if (phase == upLayout) + updateLayout(); + + // propagate update call to child elements: + const int elCount = elementCount(); + for (int i=0; iupdate(phase); + } +} + +/* inherits documentation from base class */ +QList QCPLayout::elements(bool recursive) const +{ + const int c = elementCount(); + QList result; +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + result.reserve(c); +#endif + for (int i=0; ielements(recursive); + } + } + return result; +} + +/*! + Simplifies the layout by collapsing empty cells. The exact behavior depends on subclasses, the + default implementation does nothing. + + Not all layouts need simplification. For example, QCPLayoutInset doesn't use explicit + simplification while QCPLayoutGrid does. +*/ +void QCPLayout::simplify() +{ +} + +/*! + Removes and deletes the element at the provided \a index. Returns true on success. If \a index is + invalid or points to an empty cell, returns false. + + This function internally uses \ref takeAt to remove the element from the layout and then deletes + the returned element. Note that some layouts don't remove the respective cell right away but leave an + empty cell after successful removal of the layout element. To collapse empty cells, use \ref + simplify. + + \see remove, takeAt +*/ +bool QCPLayout::removeAt(int index) +{ + if (QCPLayoutElement *el = takeAt(index)) + { + delete el; + return true; + } else + return false; +} + +/*! + Removes and deletes the provided \a element. Returns true on success. If \a element is not in the + layout, returns false. + + This function internally uses \ref takeAt to remove the element from the layout and then deletes + the element. Note that some layouts don't remove the respective cell right away but leave an + empty cell after successful removal of the layout element. To collapse empty cells, use \ref + simplify. + + \see removeAt, take +*/ +bool QCPLayout::remove(QCPLayoutElement *element) +{ + if (take(element)) + { + delete element; + return true; + } else + return false; +} + +/*! + Removes and deletes all layout elements in this layout. Finally calls \ref simplify to make sure + all empty cells are collapsed. + + \see remove, removeAt +*/ +void QCPLayout::clear() +{ + for (int i=elementCount()-1; i>=0; --i) + { + if (elementAt(i)) + removeAt(i); + } + simplify(); +} + +/*! + Subclasses call this method to report changed (minimum/maximum) size constraints. + + If the parent of this layout is again a QCPLayout, forwards the call to the parent's \ref + sizeConstraintsChanged. If the parent is a QWidget (i.e. is the \ref QCustomPlot::plotLayout of + QCustomPlot), calls QWidget::updateGeometry, so if the QCustomPlot widget is inside a Qt QLayout, + it may update itself and resize cells accordingly. +*/ +void QCPLayout::sizeConstraintsChanged() const +{ + if (QWidget *w = qobject_cast(parent())) + w->updateGeometry(); + else if (QCPLayout *l = qobject_cast(parent())) + l->sizeConstraintsChanged(); +} + +/*! \internal + + Subclasses reimplement this method to update the position and sizes of the child elements/cells + via calling their \ref QCPLayoutElement::setOuterRect. The default implementation does nothing. + + The geometry used as a reference is the inner \ref rect of this layout. Child elements should stay + within that rect. + + \ref getSectionSizes may help with the reimplementation of this function. + + \see update +*/ +void QCPLayout::updateLayout() +{ +} + + +/*! \internal + + Associates \a el with this layout. This is done by setting the \ref QCPLayoutElement::layout, the + \ref QCPLayerable::parentLayerable and the QObject parent to this layout. + + Further, if \a el didn't previously have a parent plot, calls \ref + QCPLayerable::initializeParentPlot on \a el to set the paret plot. + + This method is used by subclass specific methods that add elements to the layout. Note that this + method only changes properties in \a el. The removal from the old layout and the insertion into + the new layout must be done additionally. +*/ +void QCPLayout::adoptElement(QCPLayoutElement *el) +{ + if (el) + { + el->mParentLayout = this; + el->setParentLayerable(this); + el->setParent(this); + if (!el->parentPlot()) + el->initializeParentPlot(mParentPlot); + el->layoutChanged(); + } else + qDebug() << Q_FUNC_INFO << "Null element passed"; +} + +/*! \internal + + Disassociates \a el from this layout. This is done by setting the \ref QCPLayoutElement::layout + and the \ref QCPLayerable::parentLayerable to zero. The QObject parent is set to the parent + QCustomPlot. + + This method is used by subclass specific methods that remove elements from the layout (e.g. \ref + take or \ref takeAt). Note that this method only changes properties in \a el. The removal from + the old layout must be done additionally. +*/ +void QCPLayout::releaseElement(QCPLayoutElement *el) +{ + if (el) + { + el->mParentLayout = 0; + el->setParentLayerable(0); + el->setParent(mParentPlot); + // Note: Don't initializeParentPlot(0) here, because layout element will stay in same parent plot + } else + qDebug() << Q_FUNC_INFO << "Null element passed"; +} + +/*! \internal + + This is a helper function for the implementation of \ref updateLayout in subclasses. + + It calculates the sizes of one-dimensional sections with provided constraints on maximum section + sizes, minimum section sizes, relative stretch factors and the final total size of all sections. + + The QVector entries refer to the sections. Thus all QVectors must have the same size. + + \a maxSizes gives the maximum allowed size of each section. If there shall be no maximum size + imposed, set all vector values to Qt's QWIDGETSIZE_MAX. + + \a minSizes gives the minimum allowed size of each section. If there shall be no minimum size + imposed, set all vector values to zero. If the \a minSizes entries add up to a value greater than + \a totalSize, sections will be scaled smaller than the proposed minimum sizes. (In other words, + not exceeding the allowed total size is taken to be more important than not going below minimum + section sizes.) + + \a stretchFactors give the relative proportions of the sections to each other. If all sections + shall be scaled equally, set all values equal. If the first section shall be double the size of + each individual other section, set the first number of \a stretchFactors to double the value of + the other individual values (e.g. {2, 1, 1, 1}). + + \a totalSize is the value that the final section sizes will add up to. Due to rounding, the + actual sum may differ slightly. If you want the section sizes to sum up to exactly that value, + you could distribute the remaining difference on the sections. + + The return value is a QVector containing the section sizes. +*/ +QVector QCPLayout::getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const +{ + if (maxSizes.size() != minSizes.size() || minSizes.size() != stretchFactors.size()) + { + qDebug() << Q_FUNC_INFO << "Passed vector sizes aren't equal:" << maxSizes << minSizes << stretchFactors; + return QVector(); + } + if (stretchFactors.isEmpty()) + return QVector(); + int sectionCount = stretchFactors.size(); + QVector sectionSizes(sectionCount); + // if provided total size is forced smaller than total minimum size, ignore minimum sizes (squeeze sections): + int minSizeSum = 0; + for (int i=0; i minimumLockedSections; + QList unfinishedSections; + for (int i=0; i result(sectionCount); + for (int i=0; i= 0 && row < mElements.size()) + { + if (column >= 0 && column < mElements.first().size()) + { + if (QCPLayoutElement *result = mElements.at(row).at(column)) + return result; + else + qDebug() << Q_FUNC_INFO << "Requested cell is empty. Row:" << row << "Column:" << column; + } else + qDebug() << Q_FUNC_INFO << "Invalid column. Row:" << row << "Column:" << column; + } else + qDebug() << Q_FUNC_INFO << "Invalid row. Row:" << row << "Column:" << column; + return 0; +} + + +/*! \overload + + Adds the \a element to cell with \a row and \a column. If \a element is already in a layout, it + is first removed from there. If \a row or \a column don't exist yet, the layout is expanded + accordingly. + + Returns true if the element was added successfully, i.e. if the cell at \a row and \a column + didn't already have an element. + + Use the overload of this method without explicit row/column index to place the element according + to the configured fill order and wrapping settings. + + \see element, hasElement, take, remove +*/ +bool QCPLayoutGrid::addElement(int row, int column, QCPLayoutElement *element) +{ + if (!hasElement(row, column)) + { + if (element && element->layout()) // remove from old layout first + element->layout()->take(element); + expandTo(row+1, column+1); + mElements[row][column] = element; + if (element) + adoptElement(element); + return true; + } else + qDebug() << Q_FUNC_INFO << "There is already an element in the specified row/column:" << row << column; + return false; +} + +/*! \overload + + Adds the \a element to the next empty cell according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap). If \a element is already in a layout, it is first + removed from there. If necessary, the layout is expanded to hold the new element. + + Returns true if the element was added successfully. + + \see setFillOrder, setWrap, element, hasElement, take, remove +*/ +bool QCPLayoutGrid::addElement(QCPLayoutElement *element) +{ + int rowIndex = 0; + int colIndex = 0; + if (mFillOrder == foColumnsFirst) + { + while (hasElement(rowIndex, colIndex)) + { + ++colIndex; + if (colIndex >= mWrap && mWrap > 0) + { + colIndex = 0; + ++rowIndex; + } + } + } else + { + while (hasElement(rowIndex, colIndex)) + { + ++rowIndex; + if (rowIndex >= mWrap && mWrap > 0) + { + rowIndex = 0; + ++colIndex; + } + } + } + return addElement(rowIndex, colIndex, element); +} + +/*! + Returns whether the cell at \a row and \a column exists and contains a valid element, i.e. isn't + empty. + + \see element +*/ +bool QCPLayoutGrid::hasElement(int row, int column) +{ + if (row >= 0 && row < rowCount() && column >= 0 && column < columnCount()) + return mElements.at(row).at(column); + else + return false; +} + +/*! + Sets the stretch \a factor of \a column. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights (\ref QCPLayoutElement::setMinimumSize, \ref + QCPLayoutElement::setMaximumSize), regardless of the stretch factor. + + The default stretch factor of newly created rows/columns is 1. + + \see setColumnStretchFactors, setRowStretchFactor +*/ +void QCPLayoutGrid::setColumnStretchFactor(int column, double factor) +{ + if (column >= 0 && column < columnCount()) + { + if (factor > 0) + mColumnStretchFactors[column] = factor; + else + qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; + } else + qDebug() << Q_FUNC_INFO << "Invalid column:" << column; +} + +/*! + Sets the stretch \a factors of all columns. \a factors must have the size \ref columnCount. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights (\ref QCPLayoutElement::setMinimumSize, \ref + QCPLayoutElement::setMaximumSize), regardless of the stretch factor. + + The default stretch factor of newly created rows/columns is 1. + + \see setColumnStretchFactor, setRowStretchFactors +*/ +void QCPLayoutGrid::setColumnStretchFactors(const QList &factors) +{ + if (factors.size() == mColumnStretchFactors.size()) + { + mColumnStretchFactors = factors; + for (int i=0; i= 0 && row < rowCount()) + { + if (factor > 0) + mRowStretchFactors[row] = factor; + else + qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << factor; + } else + qDebug() << Q_FUNC_INFO << "Invalid row:" << row; +} + +/*! + Sets the stretch \a factors of all rows. \a factors must have the size \ref rowCount. + + Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond + their minimum and maximum widths/heights (\ref QCPLayoutElement::setMinimumSize, \ref + QCPLayoutElement::setMaximumSize), regardless of the stretch factor. + + The default stretch factor of newly created rows/columns is 1. + + \see setRowStretchFactor, setColumnStretchFactors +*/ +void QCPLayoutGrid::setRowStretchFactors(const QList &factors) +{ + if (factors.size() == mRowStretchFactors.size()) + { + mRowStretchFactors = factors; + for (int i=0; i tempElements; + if (rearrange) + { + tempElements.reserve(elCount); + for (int i=0; i()); + mRowStretchFactors.append(1); + } + // go through rows and expand columns as necessary: + int newColCount = qMax(columnCount(), newColumnCount); + for (int i=0; i rowCount()) + newIndex = rowCount(); + + mRowStretchFactors.insert(newIndex, 1); + QList newRow; + for (int col=0; col columnCount()) + newIndex = columnCount(); + + mColumnStretchFactors.insert(newIndex, 1); + for (int row=0; row= 0 && row < rowCount()) + { + if (column >= 0 && column < columnCount()) + { + switch (mFillOrder) + { + case foRowsFirst: return column*rowCount() + row; + case foColumnsFirst: return row*columnCount() + column; + } + } else + qDebug() << Q_FUNC_INFO << "row index out of bounds:" << row; + } else + qDebug() << Q_FUNC_INFO << "column index out of bounds:" << column; + return 0; +} + +/*! + Converts the linear index to row and column indices and writes the result to \a row and \a + column. + + The way the cells are indexed depends on \ref setFillOrder. If it is \ref foRowsFirst, the + indices increase left to right and then top to bottom. If it is \ref foColumnsFirst, the indices + increase top to bottom and then left to right. + + If there are no cells (i.e. column or row count is zero), sets \a row and \a column to -1. + + For the retrieved \a row and \a column to be valid, the passed \a index must be valid itself, + i.e. greater or equal to zero and smaller than the current \ref elementCount. + + \see rowColToIndex +*/ +void QCPLayoutGrid::indexToRowCol(int index, int &row, int &column) const +{ + row = -1; + column = -1; + if (columnCount() == 0 || rowCount() == 0) + return; + if (index < 0 || index >= elementCount()) + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return; + } + + switch (mFillOrder) + { + case foRowsFirst: + { + column = index / rowCount(); + row = index % rowCount(); + break; + } + case foColumnsFirst: + { + row = index / columnCount(); + column = index % columnCount(); + break; + } + } +} + +/* inherits documentation from base class */ +void QCPLayoutGrid::updateLayout() +{ + QVector minColWidths, minRowHeights, maxColWidths, maxRowHeights; + getMinimumRowColSizes(&minColWidths, &minRowHeights); + getMaximumRowColSizes(&maxColWidths, &maxRowHeights); + + int totalRowSpacing = (rowCount()-1) * mRowSpacing; + int totalColSpacing = (columnCount()-1) * mColumnSpacing; + QVector colWidths = getSectionSizes(maxColWidths, minColWidths, mColumnStretchFactors.toVector(), mRect.width()-totalColSpacing); + QVector rowHeights = getSectionSizes(maxRowHeights, minRowHeights, mRowStretchFactors.toVector(), mRect.height()-totalRowSpacing); + + // go through cells and set rects accordingly: + int yOffset = mRect.top(); + for (int row=0; row 0) + yOffset += rowHeights.at(row-1)+mRowSpacing; + int xOffset = mRect.left(); + for (int col=0; col 0) + xOffset += colWidths.at(col-1)+mColumnSpacing; + if (mElements.at(row).at(col)) + mElements.at(row).at(col)->setOuterRect(QRect(xOffset, yOffset, colWidths.at(col), rowHeights.at(row))); + } + } +} + +/*! + \seebaseclassmethod + + Note that the association of the linear \a index to the row/column based cells depends on the + current setting of \ref setFillOrder. + + \see rowColToIndex +*/ +QCPLayoutElement *QCPLayoutGrid::elementAt(int index) const +{ + if (index >= 0 && index < elementCount()) + { + int row, col; + indexToRowCol(index, row, col); + return mElements.at(row).at(col); + } else + return 0; +} + +/*! + \seebaseclassmethod + + Note that the association of the linear \a index to the row/column based cells depends on the + current setting of \ref setFillOrder. + + \see rowColToIndex +*/ +QCPLayoutElement *QCPLayoutGrid::takeAt(int index) +{ + if (QCPLayoutElement *el = elementAt(index)) + { + releaseElement(el); + int row, col; + indexToRowCol(index, row, col); + mElements[row][col] = 0; + return el; + } else + { + qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; + return 0; + } +} + +/* inherits documentation from base class */ +bool QCPLayoutGrid::take(QCPLayoutElement *element) +{ + if (element) + { + for (int i=0; i QCPLayoutGrid::elements(bool recursive) const +{ + QList result; + const int elCount = elementCount(); +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + result.reserve(elCount); +#endif + for (int i=0; ielements(recursive); + } + } + return result; +} + +/*! + Simplifies the layout by collapsing rows and columns which only contain empty cells. +*/ +void QCPLayoutGrid::simplify() +{ + // remove rows with only empty cells: + for (int row=rowCount()-1; row>=0; --row) + { + bool hasElements = false; + for (int col=0; col=0; --col) + { + bool hasElements = false; + for (int row=0; row minColWidths, minRowHeights; + getMinimumRowColSizes(&minColWidths, &minRowHeights); + QSize result(0, 0); + for (int i=0; i maxColWidths, maxRowHeights; + getMaximumRowColSizes(&maxColWidths, &maxRowHeights); + + QSize result(0, 0); + for (int i=0; i *minColWidths, QVector *minRowHeights) const +{ + *minColWidths = QVector(columnCount(), 0); + *minRowHeights = QVector(rowCount(), 0); + for (int row=0; rowminimumSizeHint(); + QSize min = mElements.at(row).at(col)->minimumSize(); + QSize final(min.width() > 0 ? min.width() : minHint.width(), min.height() > 0 ? min.height() : minHint.height()); + if (minColWidths->at(col) < final.width()) + (*minColWidths)[col] = final.width(); + if (minRowHeights->at(row) < final.height()) + (*minRowHeights)[row] = final.height(); + } + } + } +} + +/*! \internal + + Places the maximum column widths and row heights into \a maxColWidths and \a maxRowHeights + respectively. + + The maximum height of a row is the smallest maximum height of any element in that row. The + maximum width of a column is the smallest maximum width of any element in that column. + + This is a helper function for \ref updateLayout. + + \see getMinimumRowColSizes +*/ +void QCPLayoutGrid::getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const +{ + *maxColWidths = QVector(columnCount(), QWIDGETSIZE_MAX); + *maxRowHeights = QVector(rowCount(), QWIDGETSIZE_MAX); + for (int row=0; rowmaximumSizeHint(); + QSize max = mElements.at(row).at(col)->maximumSize(); + QSize final(max.width() < QWIDGETSIZE_MAX ? max.width() : maxHint.width(), max.height() < QWIDGETSIZE_MAX ? max.height() : maxHint.height()); + if (maxColWidths->at(col) > final.width()) + (*maxColWidths)[col] = final.width(); + if (maxRowHeights->at(row) > final.height()) + (*maxRowHeights)[row] = final.height(); + } + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLayoutInset +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPLayoutInset + \brief A layout that places child elements aligned to the border or arbitrarily positioned + + Elements are placed either aligned to the border or at arbitrary position in the area of the + layout. Which placement applies is controlled with the \ref InsetPlacement (\ref + setInsetPlacement). + + Elements are added via \ref addElement(QCPLayoutElement *element, Qt::Alignment alignment) or + addElement(QCPLayoutElement *element, const QRectF &rect). If the first method is used, the inset + placement will default to \ref ipBorderAligned and the element will be aligned according to the + \a alignment parameter. The second method defaults to \ref ipFree and allows placing elements at + arbitrary position and size, defined by \a rect. + + The alignment or rect can be set via \ref setInsetAlignment or \ref setInsetRect, respectively. + + This is the layout that every QCPAxisRect has as \ref QCPAxisRect::insetLayout. +*/ + +/* start documentation of inline functions */ + +/*! \fn virtual void QCPLayoutInset::simplify() + + The QCPInsetLayout does not need simplification since it can never have empty cells due to its + linear index structure. This method does nothing. +*/ + +/* end documentation of inline functions */ + +/*! + Creates an instance of QCPLayoutInset and sets default values. +*/ +QCPLayoutInset::QCPLayoutInset() +{ +} + +QCPLayoutInset::~QCPLayoutInset() +{ + // clear all child layout elements. This is important because only the specific layouts know how + // to handle removing elements (clear calls virtual removeAt method to do that). + clear(); +} + +/*! + Returns the placement type of the element with the specified \a index. +*/ +QCPLayoutInset::InsetPlacement QCPLayoutInset::insetPlacement(int index) const +{ + if (elementAt(index)) + return mInsetPlacement.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return ipFree; + } +} + +/*! + Returns the alignment of the element with the specified \a index. The alignment only has a + meaning, if the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned. +*/ +Qt::Alignment QCPLayoutInset::insetAlignment(int index) const +{ + if (elementAt(index)) + return mInsetAlignment.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return 0; + } +} + +/*! + Returns the rect of the element with the specified \a index. The rect only has a + meaning, if the inset placement (\ref setInsetPlacement) is \ref ipFree. +*/ +QRectF QCPLayoutInset::insetRect(int index) const +{ + if (elementAt(index)) + return mInsetRect.at(index); + else + { + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; + return QRectF(); + } +} + +/*! + Sets the inset placement type of the element with the specified \a index to \a placement. + + \see InsetPlacement +*/ +void QCPLayoutInset::setInsetPlacement(int index, QCPLayoutInset::InsetPlacement placement) +{ + if (elementAt(index)) + mInsetPlacement[index] = placement; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/*! + If the inset placement (\ref setInsetPlacement) is \ref ipBorderAligned, this function + is used to set the alignment of the element with the specified \a index to \a alignment. + + \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, + Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other + alignment flags will be ignored. +*/ +void QCPLayoutInset::setInsetAlignment(int index, Qt::Alignment alignment) +{ + if (elementAt(index)) + mInsetAlignment[index] = alignment; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/*! + If the inset placement (\ref setInsetPlacement) is \ref ipFree, this function is used to set the + position and size of the element with the specified \a index to \a rect. + + \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) + will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right + corner of the layout, with 35% width and height of the parent layout. + + Note that the minimum and maximum sizes of the embedded element (\ref + QCPLayoutElement::setMinimumSize, \ref QCPLayoutElement::setMaximumSize) are enforced. +*/ +void QCPLayoutInset::setInsetRect(int index, const QRectF &rect) +{ + if (elementAt(index)) + mInsetRect[index] = rect; + else + qDebug() << Q_FUNC_INFO << "Invalid element index:" << index; +} + +/* inherits documentation from base class */ +void QCPLayoutInset::updateLayout() +{ + for (int i=0; iminimumSizeHint(); + QSize maxSizeHint = mElements.at(i)->maximumSizeHint(); + finalMinSize.setWidth(mElements.at(i)->minimumSize().width() > 0 ? mElements.at(i)->minimumSize().width() : minSizeHint.width()); + finalMinSize.setHeight(mElements.at(i)->minimumSize().height() > 0 ? mElements.at(i)->minimumSize().height() : minSizeHint.height()); + finalMaxSize.setWidth(mElements.at(i)->maximumSize().width() < QWIDGETSIZE_MAX ? mElements.at(i)->maximumSize().width() : maxSizeHint.width()); + finalMaxSize.setHeight(mElements.at(i)->maximumSize().height() < QWIDGETSIZE_MAX ? mElements.at(i)->maximumSize().height() : maxSizeHint.height()); + if (mInsetPlacement.at(i) == ipFree) + { + insetRect = QRect(rect().x()+rect().width()*mInsetRect.at(i).x(), + rect().y()+rect().height()*mInsetRect.at(i).y(), + rect().width()*mInsetRect.at(i).width(), + rect().height()*mInsetRect.at(i).height()); + if (insetRect.size().width() < finalMinSize.width()) + insetRect.setWidth(finalMinSize.width()); + if (insetRect.size().height() < finalMinSize.height()) + insetRect.setHeight(finalMinSize.height()); + if (insetRect.size().width() > finalMaxSize.width()) + insetRect.setWidth(finalMaxSize.width()); + if (insetRect.size().height() > finalMaxSize.height()) + insetRect.setHeight(finalMaxSize.height()); + } else if (mInsetPlacement.at(i) == ipBorderAligned) + { + insetRect.setSize(finalMinSize); + Qt::Alignment al = mInsetAlignment.at(i); + if (al.testFlag(Qt::AlignLeft)) insetRect.moveLeft(rect().x()); + else if (al.testFlag(Qt::AlignRight)) insetRect.moveRight(rect().x()+rect().width()); + else insetRect.moveLeft(rect().x()+rect().width()*0.5-finalMinSize.width()*0.5); // default to Qt::AlignHCenter + if (al.testFlag(Qt::AlignTop)) insetRect.moveTop(rect().y()); + else if (al.testFlag(Qt::AlignBottom)) insetRect.moveBottom(rect().y()+rect().height()); + else insetRect.moveTop(rect().y()+rect().height()*0.5-finalMinSize.height()*0.5); // default to Qt::AlignVCenter + } + mElements.at(i)->setOuterRect(insetRect); + } +} + +/* inherits documentation from base class */ +int QCPLayoutInset::elementCount() const +{ + return mElements.size(); +} + +/* inherits documentation from base class */ +QCPLayoutElement *QCPLayoutInset::elementAt(int index) const +{ + if (index >= 0 && index < mElements.size()) + return mElements.at(index); + else + return 0; +} + +/* inherits documentation from base class */ +QCPLayoutElement *QCPLayoutInset::takeAt(int index) +{ + if (QCPLayoutElement *el = elementAt(index)) + { + releaseElement(el); + mElements.removeAt(index); + mInsetPlacement.removeAt(index); + mInsetAlignment.removeAt(index); + mInsetRect.removeAt(index); + return el; + } else + { + qDebug() << Q_FUNC_INFO << "Attempt to take invalid index:" << index; + return 0; + } +} + +/* inherits documentation from base class */ +bool QCPLayoutInset::take(QCPLayoutElement *element) +{ + if (element) + { + for (int i=0; irealVisibility() && mElements.at(i)->selectTest(pos, onlySelectable) >= 0) + return mParentPlot->selectionTolerance()*0.99; + } + return -1; +} + +/*! + Adds the specified \a element to the layout as an inset aligned at the border (\ref + setInsetAlignment is initialized with \ref ipBorderAligned). The alignment is set to \a + alignment. + + \a alignment is an or combination of the following alignment flags: Qt::AlignLeft, + Qt::AlignHCenter, Qt::AlighRight, Qt::AlignTop, Qt::AlignVCenter, Qt::AlignBottom. Any other + alignment flags will be ignored. + + \see addElement(QCPLayoutElement *element, const QRectF &rect) +*/ +void QCPLayoutInset::addElement(QCPLayoutElement *element, Qt::Alignment alignment) +{ + if (element) + { + if (element->layout()) // remove from old layout first + element->layout()->take(element); + mElements.append(element); + mInsetPlacement.append(ipBorderAligned); + mInsetAlignment.append(alignment); + mInsetRect.append(QRectF(0.6, 0.6, 0.4, 0.4)); + adoptElement(element); + } else + qDebug() << Q_FUNC_INFO << "Can't add null element"; +} + +/*! + Adds the specified \a element to the layout as an inset with free positioning/sizing (\ref + setInsetAlignment is initialized with \ref ipFree). The position and size is set to \a + rect. + + \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1) + will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right + corner of the layout, with 35% width and height of the parent layout. + + \see addElement(QCPLayoutElement *element, Qt::Alignment alignment) +*/ +void QCPLayoutInset::addElement(QCPLayoutElement *element, const QRectF &rect) +{ + if (element) + { + if (element->layout()) // remove from old layout first + element->layout()->take(element); + mElements.append(element); + mInsetPlacement.append(ipFree); + mInsetAlignment.append(Qt::AlignRight|Qt::AlignTop); + mInsetRect.append(rect); + adoptElement(element); + } else + qDebug() << Q_FUNC_INFO << "Can't add null element"; +} +/* end of 'src/layout.cpp' */ + + +/* including file 'src/lineending.cpp', size 11536 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLineEnding +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLineEnding + \brief Handles the different ending decorations for line-like items + + \image html QCPLineEnding.png "The various ending styles currently supported" + + For every ending a line-like item has, an instance of this class exists. For example, QCPItemLine + has two endings which can be set with QCPItemLine::setHead and QCPItemLine::setTail. + + The styles themselves are defined via the enum QCPLineEnding::EndingStyle. Most decorations can + be modified regarding width and length, see \ref setWidth and \ref setLength. The direction of + the ending decoration (e.g. direction an arrow is pointing) is controlled by the line-like item. + For example, when both endings of a QCPItemLine are set to be arrows, they will point to opposite + directions, e.g. "outward". This can be changed by \ref setInverted, which would make the + respective arrow point inward. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify a + QCPLineEnding::EndingStyle where actually a QCPLineEnding is expected, e.g. + \snippet documentation/doc-code-snippets/mainwindow.cpp qcplineending-sethead +*/ + +/*! + Creates a QCPLineEnding instance with default values (style \ref esNone). +*/ +QCPLineEnding::QCPLineEnding() : + mStyle(esNone), + mWidth(8), + mLength(10), + mInverted(false) +{ +} + +/*! + Creates a QCPLineEnding instance with the specified values. +*/ +QCPLineEnding::QCPLineEnding(QCPLineEnding::EndingStyle style, double width, double length, bool inverted) : + mStyle(style), + mWidth(width), + mLength(length), + mInverted(inverted) +{ +} + +/*! + Sets the style of the ending decoration. +*/ +void QCPLineEnding::setStyle(QCPLineEnding::EndingStyle style) +{ + mStyle = style; +} + +/*! + Sets the width of the ending decoration, if the style supports it. On arrows, for example, the + width defines the size perpendicular to the arrow's pointing direction. + + \see setLength +*/ +void QCPLineEnding::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets the length of the ending decoration, if the style supports it. On arrows, for example, the + length defines the size in pointing direction. + + \see setWidth +*/ +void QCPLineEnding::setLength(double length) +{ + mLength = length; +} + +/*! + Sets whether the ending decoration shall be inverted. For example, an arrow decoration will point + inward when \a inverted is set to true. + + Note that also the \a width direction is inverted. For symmetrical ending styles like arrows or + discs, this doesn't make a difference. However, asymmetric styles like \ref esHalfBar are + affected by it, which can be used to control to which side the half bar points to. +*/ +void QCPLineEnding::setInverted(bool inverted) +{ + mInverted = inverted; +} + +/*! \internal + + Returns the maximum pixel radius the ending decoration might cover, starting from the position + the decoration is drawn at (typically a line ending/\ref QCPItemPosition of an item). + + This is relevant for clipping. Only omit painting of the decoration when the position where the + decoration is supposed to be drawn is farther away from the clipping rect than the returned + distance. +*/ +double QCPLineEnding::boundingDistance() const +{ + switch (mStyle) + { + case esNone: + return 0; + + case esFlatArrow: + case esSpikeArrow: + case esLineArrow: + case esSkewedBar: + return qSqrt(mWidth*mWidth+mLength*mLength); // items that have width and length + + case esDisc: + case esSquare: + case esDiamond: + case esBar: + case esHalfBar: + return mWidth*1.42; // items that only have a width -> width*sqrt(2) + + } + return 0; +} + +/*! + Starting from the origin of this line ending (which is style specific), returns the length + covered by the line ending symbol, in backward direction. + + For example, the \ref esSpikeArrow has a shorter real length than a \ref esFlatArrow, even if + both have the same \ref setLength value, because the spike arrow has an inward curved back, which + reduces the length along its center axis (the drawing origin for arrows is at the tip). + + This function is used for precise, style specific placement of line endings, for example in + QCPAxes. +*/ +double QCPLineEnding::realLength() const +{ + switch (mStyle) + { + case esNone: + case esLineArrow: + case esSkewedBar: + case esBar: + case esHalfBar: + return 0; + + case esFlatArrow: + return mLength; + + case esDisc: + case esSquare: + case esDiamond: + return mWidth*0.5; + + case esSpikeArrow: + return mLength*0.8; + } + return 0; +} + +/*! \internal + + Draws the line ending with the specified \a painter at the position \a pos. The direction of the + line ending is controlled with \a dir. +*/ +void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const +{ + if (mStyle == esNone) + return; + + QCPVector2D lengthVec = dir.normalized() * mLength*(mInverted ? -1 : 1); + if (lengthVec.isNull()) + lengthVec = QCPVector2D(1, 0); + QCPVector2D widthVec = dir.normalized().perpendicular() * mWidth*0.5*(mInverted ? -1 : 1); + + QPen penBackup = painter->pen(); + QBrush brushBackup = painter->brush(); + QPen miterPen = penBackup; + miterPen.setJoinStyle(Qt::MiterJoin); // to make arrow heads spikey + QBrush brush(painter->pen().color(), Qt::SolidPattern); + switch (mStyle) + { + case esNone: break; + case esFlatArrow: + { + QPointF points[3] = {pos.toPointF(), + (pos-lengthVec+widthVec).toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 3); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esSpikeArrow: + { + QPointF points[4] = {pos.toPointF(), + (pos-lengthVec+widthVec).toPointF(), + (pos-lengthVec*0.8).toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esLineArrow: + { + QPointF points[3] = {(pos-lengthVec+widthVec).toPointF(), + pos.toPointF(), + (pos-lengthVec-widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->drawPolyline(points, 3); + painter->setPen(penBackup); + break; + } + case esDisc: + { + painter->setBrush(brush); + painter->drawEllipse(pos.toPointF(), mWidth*0.5, mWidth*0.5); + painter->setBrush(brushBackup); + break; + } + case esSquare: + { + QCPVector2D widthVecPerp = widthVec.perpendicular(); + QPointF points[4] = {(pos-widthVecPerp+widthVec).toPointF(), + (pos-widthVecPerp-widthVec).toPointF(), + (pos+widthVecPerp-widthVec).toPointF(), + (pos+widthVecPerp+widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esDiamond: + { + QCPVector2D widthVecPerp = widthVec.perpendicular(); + QPointF points[4] = {(pos-widthVecPerp).toPointF(), + (pos-widthVec).toPointF(), + (pos+widthVecPerp).toPointF(), + (pos+widthVec).toPointF() + }; + painter->setPen(miterPen); + painter->setBrush(brush); + painter->drawConvexPolygon(points, 4); + painter->setBrush(brushBackup); + painter->setPen(penBackup); + break; + } + case esBar: + { + painter->drawLine((pos+widthVec).toPointF(), (pos-widthVec).toPointF()); + break; + } + case esHalfBar: + { + painter->drawLine((pos+widthVec).toPointF(), pos.toPointF()); + break; + } + case esSkewedBar: + { + if (qFuzzyIsNull(painter->pen().widthF()) && !painter->modes().testFlag(QCPPainter::pmNonCosmetic)) + { + // if drawing with cosmetic pen (perfectly thin stroke, happens only in vector exports), draw bar exactly on tip of line + painter->drawLine((pos+widthVec+lengthVec*0.2*(mInverted?-1:1)).toPointF(), + (pos-widthVec-lengthVec*0.2*(mInverted?-1:1)).toPointF()); + } else + { + // if drawing with thick (non-cosmetic) pen, shift bar a little in line direction to prevent line from sticking through bar slightly + painter->drawLine((pos+widthVec+lengthVec*0.2*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF(), + (pos-widthVec-lengthVec*0.2*(mInverted?-1:1)+dir.normalized()*qMax(1.0f, (float)painter->pen().widthF())*0.5f).toPointF()); + } + break; + } + } +} + +/*! \internal + \overload + + Draws the line ending. The direction is controlled with the \a angle parameter in radians. +*/ +void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const +{ + draw(painter, pos, QCPVector2D(qCos(angle), qSin(angle))); +} +/* end of 'src/lineending.cpp' */ + + +/* including file 'src/axis/axisticker.cpp', size 18664 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTicker +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTicker + \brief The base class tick generator used by QCPAxis to create tick positions and tick labels + + Each QCPAxis has an internal QCPAxisTicker (or a subclass) in order to generate tick positions + and tick labels for the current axis range. The ticker of an axis can be set via \ref + QCPAxis::setTicker. Since that method takes a QSharedPointer, multiple + axes can share the same ticker instance. + + This base class generates normal tick coordinates and numeric labels for linear axes. It picks a + reasonable tick step (the separation between ticks) which results in readable tick labels. The + number of ticks that should be approximately generated can be set via \ref setTickCount. + Depending on the current tick step strategy (\ref setTickStepStrategy), the algorithm either + sacrifices readability to better match the specified tick count (\ref + QCPAxisTicker::tssMeetTickCount) or relaxes the tick count in favor of better tick steps (\ref + QCPAxisTicker::tssReadability), which is the default. + + The following more specialized axis ticker subclasses are available, see details in the + respective class documentation: + +
+ + + + + + + +
QCPAxisTickerFixed\image html axisticker-fixed.png
QCPAxisTickerLog\image html axisticker-log.png
QCPAxisTickerPi\image html axisticker-pi.png
QCPAxisTickerText\image html axisticker-text.png
QCPAxisTickerDateTime\image html axisticker-datetime.png
QCPAxisTickerTime\image html axisticker-time.png + \image html axisticker-time2.png
+
+ + \section axisticker-subclassing Creating own axis tickers + + Creating own axis tickers can be achieved very easily by sublassing QCPAxisTicker and + reimplementing some or all of the available virtual methods. + + In the simplest case you might wish to just generate different tick steps than the other tickers, + so you only reimplement the method \ref getTickStep. If you additionally want control over the + string that will be shown as tick label, reimplement \ref getTickLabel. + + If you wish to have complete control, you can generate the tick vectors and tick label vectors + yourself by reimplementing \ref createTickVector and \ref createLabelVector. The default + implementations use the previously mentioned virtual methods \ref getTickStep and \ref + getTickLabel, but your reimplementations don't necessarily need to do so. For example in the case + of unequal tick steps, the method \ref getTickStep loses its usefulness and can be ignored. + + The sub tick count between major ticks can be controlled with \ref getSubTickCount. Full sub tick + placement control is obtained by reimplementing \ref createSubTickVector. + + See the documentation of all these virtual methods in QCPAxisTicker for detailed information + about the parameters and expected return values. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTicker::QCPAxisTicker() : + mTickStepStrategy(tssReadability), + mTickCount(5), + mTickOrigin(0) +{ +} + +QCPAxisTicker::~QCPAxisTicker() +{ + +} + +/*! + Sets which strategy the axis ticker follows when choosing the size of the tick step. For the + available strategies, see \ref TickStepStrategy. +*/ +void QCPAxisTicker::setTickStepStrategy(QCPAxisTicker::TickStepStrategy strategy) +{ + mTickStepStrategy = strategy; +} + +/*! + Sets how many ticks this ticker shall aim to generate across the axis range. Note that \a count + is not guaranteed to be matched exactly, as generating readable tick intervals may conflict with + the requested number of ticks. + + Whether the readability has priority over meeting the requested \a count can be specified with + \ref setTickStepStrategy. +*/ +void QCPAxisTicker::setTickCount(int count) +{ + if (count > 0) + mTickCount = count; + else + qDebug() << Q_FUNC_INFO << "tick count must be greater than zero:" << count; +} + +/*! + Sets the mathematical coordinate (or "offset") of the zeroth tick. This tick coordinate is just a + concept and doesn't need to be inside the currently visible axis range. + + By default \a origin is zero, which for example yields ticks {-5, 0, 5, 10, 15,...} when the tick + step is five. If \a origin is now set to 1 instead, the correspondingly generated ticks would be + {-4, 1, 6, 11, 16,...}. +*/ +void QCPAxisTicker::setTickOrigin(double origin) +{ + mTickOrigin = origin; +} + +/*! + This is the method called by QCPAxis in order to actually generate tick coordinates (\a ticks), + tick label strings (\a tickLabels) and sub tick coordinates (\a subTicks). + + The ticks are generated for the specified \a range. The generated labels typically follow the + specified \a locale, \a formatChar and number \a precision, however this might be different (or + even irrelevant) for certain QCPAxisTicker subclasses. + + The output parameter \a ticks is filled with the generated tick positions in axis coordinates. + The output parameters \a subTicks and \a tickLabels are optional (set them to 0 if not needed) + and are respectively filled with sub tick coordinates, and tick label strings belonging to \a + ticks by index. +*/ +void QCPAxisTicker::generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels) +{ + // generate (major) ticks: + double tickStep = getTickStep(range); + ticks = createTickVector(tickStep, range); + trimTicks(range, ticks, true); // trim ticks to visible range plus one outer tick on each side (incase a subclass createTickVector creates more) + + // generate sub ticks between major ticks: + if (subTicks) + { + if (ticks.size() > 0) + { + *subTicks = createSubTickVector(getSubTickCount(tickStep), ticks); + trimTicks(range, *subTicks, false); + } else + *subTicks = QVector(); + } + + // finally trim also outliers (no further clipping happens in axis drawing): + trimTicks(range, ticks, false); + // generate labels for visible ticks if requested: + if (tickLabels) + *tickLabels = createLabelVector(ticks, locale, formatChar, precision); +} + +/*! \internal + + Takes the entire currently visible axis range and returns a sensible tick step in + order to provide readable tick labels as well as a reasonable number of tick counts (see \ref + setTickCount, \ref setTickStepStrategy). + + If a QCPAxisTicker subclass only wants a different tick step behaviour than the default + implementation, it should reimplement this method. See \ref cleanMantissa for a possible helper + function. +*/ +double QCPAxisTicker::getTickStep(const QCPRange &range) +{ + double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + return cleanMantissa(exactStep); +} + +/*! \internal + + Takes the \a tickStep, i.e. the distance between two consecutive ticks, and returns + an appropriate number of sub ticks for that specific tick step. + + Note that a returned sub tick count of e.g. 4 will split each tick interval into 5 sections. +*/ +int QCPAxisTicker::getSubTickCount(double tickStep) +{ + int result = 1; // default to 1, if no proper value can be found + + // separate integer and fractional part of mantissa: + double epsilon = 0.01; + double intPartf; + int intPart; + double fracPart = modf(getMantissa(tickStep), &intPartf); + intPart = intPartf; + + // handle cases with (almost) integer mantissa: + if (fracPart < epsilon || 1.0-fracPart < epsilon) + { + if (1.0-fracPart < epsilon) + ++intPart; + switch (intPart) + { + case 1: result = 4; break; // 1.0 -> 0.2 substep + case 2: result = 3; break; // 2.0 -> 0.5 substep + case 3: result = 2; break; // 3.0 -> 1.0 substep + case 4: result = 3; break; // 4.0 -> 1.0 substep + case 5: result = 4; break; // 5.0 -> 1.0 substep + case 6: result = 2; break; // 6.0 -> 2.0 substep + case 7: result = 6; break; // 7.0 -> 1.0 substep + case 8: result = 3; break; // 8.0 -> 2.0 substep + case 9: result = 2; break; // 9.0 -> 3.0 substep + } + } else + { + // handle cases with significantly fractional mantissa: + if (qAbs(fracPart-0.5) < epsilon) // *.5 mantissa + { + switch (intPart) + { + case 1: result = 2; break; // 1.5 -> 0.5 substep + case 2: result = 4; break; // 2.5 -> 0.5 substep + case 3: result = 4; break; // 3.5 -> 0.7 substep + case 4: result = 2; break; // 4.5 -> 1.5 substep + case 5: result = 4; break; // 5.5 -> 1.1 substep (won't occur with default getTickStep from here on) + case 6: result = 4; break; // 6.5 -> 1.3 substep + case 7: result = 2; break; // 7.5 -> 2.5 substep + case 8: result = 4; break; // 8.5 -> 1.7 substep + case 9: result = 4; break; // 9.5 -> 1.9 substep + } + } + // if mantissa fraction isn't 0.0 or 0.5, don't bother finding good sub tick marks, leave default + } + + return result; +} + +/*! \internal + + This method returns the tick label string as it should be printed under the \a tick coordinate. + If a textual number is returned, it should respect the provided \a locale, \a formatChar and \a + precision. + + If the returned value contains exponentials of the form "2e5" and beautifully typeset powers is + enabled in the QCPAxis number format (\ref QCPAxis::setNumberFormat), the exponential part will + be formatted accordingly using multiplication symbol and superscript during rendering of the + label automatically. +*/ +QString QCPAxisTicker::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + return locale.toString(tick, formatChar.toLatin1(), precision); +} + +/*! \internal + + Returns a vector containing all coordinates of sub ticks that should be drawn. It generates \a + subTickCount sub ticks between each tick pair given in \a ticks. + + If a QCPAxisTicker subclass needs maximal control over the generated sub ticks, it should + reimplement this method. Depending on the purpose of the subclass it doesn't necessarily need to + base its result on \a subTickCount or \a ticks. +*/ +QVector QCPAxisTicker::createSubTickVector(int subTickCount, const QVector &ticks) +{ + QVector result; + if (subTickCount <= 0 || ticks.size() < 2) + return result; + + result.reserve((ticks.size()-1)*subTickCount); + for (int i=1; i QCPAxisTicker::createTickVector(double tickStep, const QCPRange &range) +{ + QVector result; + // Generate tick positions according to tickStep: + qint64 firstStep = floor((range.lower-mTickOrigin)/tickStep); // do not use qFloor here, or we'll lose 64 bit precision + qint64 lastStep = ceil((range.upper-mTickOrigin)/tickStep); // do not use qCeil here, or we'll lose 64 bit precision + int tickcount = lastStep-firstStep+1; + if (tickcount < 0) tickcount = 0; + result.resize(tickcount); + for (int i=0; i QCPAxisTicker::createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision) +{ + QVector result; + result.reserve(ticks.size()); + for (int i=0; i &ticks, bool keepOneOutlier) const +{ + bool lowFound = false; + bool highFound = false; + int lowIndex = 0; + int highIndex = -1; + + for (int i=0; i < ticks.size(); ++i) + { + if (ticks.at(i) >= range.lower) + { + lowFound = true; + lowIndex = i; + break; + } + } + for (int i=ticks.size()-1; i >= 0; --i) + { + if (ticks.at(i) <= range.upper) + { + highFound = true; + highIndex = i; + break; + } + } + + if (highFound && lowFound) + { + int trimFront = qMax(0, lowIndex-(keepOneOutlier ? 1 : 0)); + int trimBack = qMax(0, ticks.size()-(keepOneOutlier ? 2 : 1)-highIndex); + if (trimFront > 0 || trimBack > 0) + ticks = ticks.mid(trimFront, ticks.size()-trimFront-trimBack); + } else // all ticks are either all below or all above the range + ticks.clear(); +} + +/*! \internal + + Returns the coordinate contained in \a candidates which is closest to the provided \a target. + + This method assumes \a candidates is not empty and sorted in ascending order. +*/ +double QCPAxisTicker::pickClosest(double target, const QVector &candidates) const +{ + if (candidates.size() == 1) + return candidates.first(); + QVector::const_iterator it = std::lower_bound(candidates.constBegin(), candidates.constEnd(), target); + if (it == candidates.constEnd()) + return *(it-1); + else if (it == candidates.constBegin()) + return *it; + else + return target-*(it-1) < *it-target ? *(it-1) : *it; +} + +/*! \internal + + Returns the decimal mantissa of \a input. Optionally, if \a magnitude is not set to zero, it also + returns the magnitude of \a input as a power of 10. + + For example, an input of 142.6 will return a mantissa of 1.426 and a magnitude of 100. +*/ +double QCPAxisTicker::getMantissa(double input, double *magnitude) const +{ + const double mag = qPow(10.0, qFloor(qLn(input)/qLn(10.0))); + if (magnitude) *magnitude = mag; + return input/mag; +} + +/*! \internal + + Returns a number that is close to \a input but has a clean, easier human readable mantissa. How + strongly the mantissa is altered, and thus how strong the result deviates from the original \a + input, depends on the current tick step strategy (see \ref setTickStepStrategy). +*/ +double QCPAxisTicker::cleanMantissa(double input) const +{ + double magnitude; + const double mantissa = getMantissa(input, &magnitude); + switch (mTickStepStrategy) + { + case tssReadability: + { + return pickClosest(mantissa, QVector() << 1.0 << 2.0 << 2.5 << 5.0 << 10.0)*magnitude; + } + case tssMeetTickCount: + { + // this gives effectively a mantissa of 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 8.0, 10.0 + if (mantissa <= 5.0) + return (int)(mantissa*2)/2.0*magnitude; // round digit after decimal point to 0.5 + else + return (int)(mantissa/2.0)*2.0*magnitude; // round to first digit in multiples of 2 + } + } + return input; +} +/* end of 'src/axis/axisticker.cpp' */ + + +/* including file 'src/axis/axistickerdatetime.cpp', size 14443 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerDateTime +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerDateTime + \brief Specialized axis ticker for calendar dates and times as axis ticks + + \image html axisticker-datetime.png + + This QCPAxisTicker subclass generates ticks that correspond to real calendar dates and times. The + plot axis coordinate is interpreted as Unix Time, so seconds since Epoch (January 1, 1970, 00:00 + UTC). This is also used for example by QDateTime in the toTime_t()/setTime_t() methods + with a precision of one second. Since Qt 4.7, millisecond accuracy can be obtained from QDateTime + by using QDateTime::fromMSecsSinceEpoch()/1000.0. The static methods \ref dateTimeToKey + and \ref keyToDateTime conveniently perform this conversion achieving a precision of one + millisecond on all Qt versions. + + The format of the date/time display in the tick labels is controlled with \ref setDateTimeFormat. + If a different time spec (time zone) shall be used, see \ref setDateTimeSpec. + + This ticker produces unequal tick spacing in order to provide intuitive date and time-of-day + ticks. For example, if the axis range spans a few years such that there is one tick per year, + ticks will be positioned on 1. January of every year. This is intuitive but, due to leap years, + will result in slightly unequal tick intervals (visually unnoticeable). The same can be seen in + the image above: even though the number of days varies month by month, this ticker generates + ticks on the same day of each month. + + If you would like to change the date/time that is used as a (mathematical) starting date for the + ticks, use the \ref setTickOrigin(const QDateTime &origin) method overload, which takes a + QDateTime. If you pass 15. July, 9:45 to this method, the yearly ticks will end up on 15. July at + 9:45 of every year. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerdatetime-creation + + \note If you rather wish to display relative times in terms of days, hours, minutes, seconds and + milliseconds, and are not interested in the intricacies of real calendar dates with months and + (leap) years, have a look at QCPAxisTickerTime instead. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerDateTime::QCPAxisTickerDateTime() : + mDateTimeFormat(QLatin1String("hh:mm:ss\ndd.MM.yy")), + mDateTimeSpec(Qt::LocalTime), + mDateStrategy(dsNone) +{ + setTickCount(4); +} + +/*! + Sets the format in which dates and times are displayed as tick labels. For details about the \a + format string, see the documentation of QDateTime::toString(). + + Newlines can be inserted with "\n". + + \see setDateTimeSpec +*/ +void QCPAxisTickerDateTime::setDateTimeFormat(const QString &format) +{ + mDateTimeFormat = format; +} + +/*! + Sets the time spec that is used for creating the tick labels from corresponding dates/times. + + The default value of QDateTime objects (and also QCPAxisTickerDateTime) is + Qt::LocalTime. However, if the date time values passed to QCustomPlot (e.g. in the form + of axis ranges or keys of a plottable) are given in the UTC spec, set \a spec to Qt::UTC + to get the correct axis labels. + + \see setDateTimeFormat +*/ +void QCPAxisTickerDateTime::setDateTimeSpec(Qt::TimeSpec spec) +{ + mDateTimeSpec = spec; +} + +/*! + Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) in seconds since Epoch (1. Jan 1970, + 00:00 UTC). For the date time ticker it might be more intuitive to use the overload which + directly takes a QDateTime, see \ref setTickOrigin(const QDateTime &origin). + + This is useful to define the month/day/time recurring at greater tick interval steps. For + example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick + per year, the ticks will end up on 15. July at 9:45 of every year. +*/ +void QCPAxisTickerDateTime::setTickOrigin(double origin) +{ + QCPAxisTicker::setTickOrigin(origin); +} + +/*! + Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) as a QDateTime \a origin. + + This is useful to define the month/day/time recurring at greater tick interval steps. For + example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick + per year, the ticks will end up on 15. July at 9:45 of every year. +*/ +void QCPAxisTickerDateTime::setTickOrigin(const QDateTime &origin) +{ + setTickOrigin(dateTimeToKey(origin)); +} + +/*! \internal + + Returns a sensible tick step with intervals appropriate for a date-time-display, such as weekly, + monthly, bi-monthly, etc. + + Note that this tick step isn't used exactly when generating the tick vector in \ref + createTickVector, but only as a guiding value requiring some correction for each individual tick + interval. Otherwise this would lead to unintuitive date displays, e.g. jumping between first day + in the month to the last day in the previous month from tick to tick, due to the non-uniform + length of months. The same problem arises with leap years. + + \seebaseclassmethod +*/ +double QCPAxisTickerDateTime::getTickStep(const QCPRange &range) +{ + double result = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + + mDateStrategy = dsNone; + if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds + { + result = cleanMantissa(result); + } else if (result < 86400*30.4375*12) // below a year + { + result = pickClosest(result, QVector() + << 1 << 2.5 << 5 << 10 << 15 << 30 << 60 << 2.5*60 << 5*60 << 10*60 << 15*60 << 30*60 << 60*60 // second, minute, hour range + << 3600*2 << 3600*3 << 3600*6 << 3600*12 << 3600*24 // hour to day range + << 86400*2 << 86400*5 << 86400*7 << 86400*14 << 86400*30.4375 << 86400*30.4375*2 << 86400*30.4375*3 << 86400*30.4375*6 << 86400*30.4375*12); // day, week, month range (avg. days per month includes leap years) + if (result > 86400*30.4375-1) // month tick intervals or larger + mDateStrategy = dsUniformDayInMonth; + else if (result > 3600*24-1) // day tick intervals or larger + mDateStrategy = dsUniformTimeInDay; + } else // more than a year, go back to normal clean mantissa algorithm but in units of years + { + const double secondsPerYear = 86400*30.4375*12; // average including leap years + result = cleanMantissa(result/secondsPerYear)*secondsPerYear; + mDateStrategy = dsUniformDayInMonth; + } + return result; +} + +/*! \internal + + Returns a sensible sub tick count with intervals appropriate for a date-time-display, such as weekly, + monthly, bi-monthly, etc. + + \seebaseclassmethod +*/ +int QCPAxisTickerDateTime::getSubTickCount(double tickStep) +{ + int result = QCPAxisTicker::getSubTickCount(tickStep); + switch (qRound(tickStep)) // hand chosen subticks for specific minute/hour/day/week/month range (as specified in getTickStep) + { + case 5*60: result = 4; break; + case 10*60: result = 1; break; + case 15*60: result = 2; break; + case 30*60: result = 1; break; + case 60*60: result = 3; break; + case 3600*2: result = 3; break; + case 3600*3: result = 2; break; + case 3600*6: result = 1; break; + case 3600*12: result = 3; break; + case 3600*24: result = 3; break; + case 86400*2: result = 1; break; + case 86400*5: result = 4; break; + case 86400*7: result = 6; break; + case 86400*14: result = 1; break; + case (int)(86400*30.4375+0.5): result = 3; break; + case (int)(86400*30.4375*2+0.5): result = 1; break; + case (int)(86400*30.4375*3+0.5): result = 2; break; + case (int)(86400*30.4375*6+0.5): result = 5; break; + case (int)(86400*30.4375*12+0.5): result = 3; break; + } + return result; +} + +/*! \internal + + Generates a date/time tick label for tick coordinate \a tick, based on the currently set format + (\ref setDateTimeFormat) and time spec (\ref setDateTimeSpec). + + \seebaseclassmethod +*/ +QString QCPAxisTickerDateTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + Q_UNUSED(precision) + Q_UNUSED(formatChar) + return locale.toString(keyToDateTime(tick).toTimeSpec(mDateTimeSpec), mDateTimeFormat); +} + +/*! \internal + + Uses the passed \a tickStep as a guiding value and applies corrections in order to obtain + non-uniform tick intervals but intuitive tick labels, e.g. falling on the same day of each month. + + \seebaseclassmethod +*/ +QVector QCPAxisTickerDateTime::createTickVector(double tickStep, const QCPRange &range) +{ + QVector result = QCPAxisTicker::createTickVector(tickStep, range); + if (!result.isEmpty()) + { + if (mDateStrategy == dsUniformTimeInDay) + { + QDateTime uniformDateTime = keyToDateTime(mTickOrigin); // the time of this datetime will be set for all other ticks, if possible + QDateTime tickDateTime; + for (int i=0; i 15) // with leap years involved, date month may jump backwards or forwards, and needs to be corrected before setting day + tickDateTime = tickDateTime.addMonths(-1); + tickDateTime.setDate(QDate(tickDateTime.date().year(), tickDateTime.date().month(), thisUniformDay)); + result[i] = dateTimeToKey(tickDateTime); + } + } + } + return result; +} + +/*! + A convenience method which turns \a key (in seconds since Epoch 1. Jan 1970, 00:00 UTC) into a + QDateTime object. This can be used to turn axis coordinates to actual QDateTimes. + + The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it + works around the lack of a QDateTime::fromMSecsSinceEpoch in Qt 4.6) + + \see dateTimeToKey +*/ +QDateTime QCPAxisTickerDateTime::keyToDateTime(double key) +{ +# if QT_VERSION < QT_VERSION_CHECK(4, 7, 0) + return QDateTime::fromTime_t(key).addMSecs((key-(qint64)key)*1000); +# else + return QDateTime::fromMSecsSinceEpoch(key*1000.0); +# endif +} + +/*! \overload + + A convenience method which turns a QDateTime object into a double value that corresponds to + seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by + QCPAxisTickerDateTime. + + The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it + works around the lack of a QDateTime::toMSecsSinceEpoch in Qt 4.6) + + \see keyToDateTime +*/ +double QCPAxisTickerDateTime::dateTimeToKey(const QDateTime dateTime) +{ +# if QT_VERSION < QT_VERSION_CHECK(4, 7, 0) + return dateTime.toTime_t()+dateTime.time().msec()/1000.0; +# else + return dateTime.toMSecsSinceEpoch()/1000.0; +# endif +} + +/*! \overload + + A convenience method which turns a QDate object into a double value that corresponds to + seconds since Epoch (1. Jan 1970, 00:00 UTC). This is the format used as axis coordinates by + QCPAxisTickerDateTime. + + \see keyToDateTime +*/ +double QCPAxisTickerDateTime::dateTimeToKey(const QDate date) +{ +# if QT_VERSION < QT_VERSION_CHECK(4, 7, 0) + return QDateTime(date).toTime_t(); +# else + return QDateTime(date).toMSecsSinceEpoch()/1000.0; +# endif +} +/* end of 'src/axis/axistickerdatetime.cpp' */ + + +/* including file 'src/axis/axistickertime.cpp', size 11747 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerTime +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerTime + \brief Specialized axis ticker for time spans in units of milliseconds to days + + \image html axisticker-time.png + + This QCPAxisTicker subclass generates ticks that corresponds to time intervals. + + The format of the time display in the tick labels is controlled with \ref setTimeFormat and \ref + setFieldWidth. The time coordinate is in the unit of seconds with respect to the time coordinate + zero. Unlike with QCPAxisTickerDateTime, the ticks don't correspond to a specific calendar date + and time. + + The time can be displayed in milliseconds, seconds, minutes, hours and days. Depending on the + largest available unit in the format specified with \ref setTimeFormat, any time spans above will + be carried in that largest unit. So for example if the format string is "%m:%s" and a tick at + coordinate value 7815 (being 2 hours, 10 minutes and 15 seconds) is created, the resulting tick + label will show "130:15" (130 minutes, 15 seconds). If the format string is "%h:%m:%s", the hour + unit will be used and the label will thus be "02:10:15". Negative times with respect to the axis + zero will carry a leading minus sign. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation + + Here is an example of a time axis providing time information in days, hours and minutes. Due to + the axis range spanning a few days and the wanted tick count (\ref setTickCount), the ticker + decided to use tick steps of 12 hours: + + \image html axisticker-time2.png + + The format string for this example is + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertime-creation-2 + + \note If you rather wish to display calendar dates and times, have a look at QCPAxisTickerDateTime + instead. +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerTime::QCPAxisTickerTime() : + mTimeFormat(QLatin1String("%h:%m:%s")), + mSmallestUnit(tuSeconds), + mBiggestUnit(tuHours) +{ + setTickCount(4); + mFieldWidth[tuMilliseconds] = 3; + mFieldWidth[tuSeconds] = 2; + mFieldWidth[tuMinutes] = 2; + mFieldWidth[tuHours] = 2; + mFieldWidth[tuDays] = 1; + + mFormatPattern[tuMilliseconds] = QLatin1String("%z"); + mFormatPattern[tuSeconds] = QLatin1String("%s"); + mFormatPattern[tuMinutes] = QLatin1String("%m"); + mFormatPattern[tuHours] = QLatin1String("%h"); + mFormatPattern[tuDays] = QLatin1String("%d"); +} + +/*! + Sets the format that will be used to display time in the tick labels. + + The available patterns are: + - %%z for milliseconds + - %%s for seconds + - %%m for minutes + - %%h for hours + - %%d for days + + The field width (zero padding) can be controlled for each unit with \ref setFieldWidth. + + The largest unit that appears in \a format will carry all the remaining time of a certain tick + coordinate, even if it overflows the natural limit of the unit. For example, if %%m is the + largest unit it might become larger than 59 in order to consume larger time values. If on the + other hand %%h is available, the minutes will wrap around to zero after 59 and the time will + carry to the hour digit. +*/ +void QCPAxisTickerTime::setTimeFormat(const QString &format) +{ + mTimeFormat = format; + + // determine smallest and biggest unit in format, to optimize unit replacement and allow biggest + // unit to consume remaining time of a tick value and grow beyond its modulo (e.g. min > 59) + mSmallestUnit = tuMilliseconds; + mBiggestUnit = tuMilliseconds; + bool hasSmallest = false; + for (int i = tuMilliseconds; i <= tuDays; ++i) + { + TimeUnit unit = static_cast(i); + if (mTimeFormat.contains(mFormatPattern.value(unit))) + { + if (!hasSmallest) + { + mSmallestUnit = unit; + hasSmallest = true; + } + mBiggestUnit = unit; + } + } +} + +/*! + Sets the field widh of the specified \a unit to be \a width digits, when displayed in the tick + label. If the number for the specific unit is shorter than \a width, it will be padded with an + according number of zeros to the left in order to reach the field width. + + \see setTimeFormat +*/ +void QCPAxisTickerTime::setFieldWidth(QCPAxisTickerTime::TimeUnit unit, int width) +{ + mFieldWidth[unit] = qMax(width, 1); +} + +/*! \internal + + Returns the tick step appropriate for time displays, depending on the provided \a range and the + smallest available time unit in the current format (\ref setTimeFormat). For example if the unit + of seconds isn't available in the format, this method will not generate steps (like 2.5 minutes) + that require sub-minute precision to be displayed correctly. + + \seebaseclassmethod +*/ +double QCPAxisTickerTime::getTickStep(const QCPRange &range) +{ + double result = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + + if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds + { + if (mSmallestUnit == tuMilliseconds) + result = qMax(cleanMantissa(result), 0.001); // smallest tick step is 1 millisecond + else // have no milliseconds available in format, so stick with 1 second tickstep + result = 1.0; + } else if (result < 3600*24) // below a day + { + // the filling of availableSteps seems a bit contorted but it fills in a sorted fashion and thus saves a post-fill sorting run + QVector availableSteps; + // seconds range: + if (mSmallestUnit <= tuSeconds) + availableSteps << 1; + if (mSmallestUnit == tuMilliseconds) + availableSteps << 2.5; // only allow half second steps if milliseconds are there to display it + else if (mSmallestUnit == tuSeconds) + availableSteps << 2; + if (mSmallestUnit <= tuSeconds) + availableSteps << 5 << 10 << 15 << 30; + // minutes range: + if (mSmallestUnit <= tuMinutes) + availableSteps << 1*60; + if (mSmallestUnit <= tuSeconds) + availableSteps << 2.5*60; // only allow half minute steps if seconds are there to display it + else if (mSmallestUnit == tuMinutes) + availableSteps << 2*60; + if (mSmallestUnit <= tuMinutes) + availableSteps << 5*60 << 10*60 << 15*60 << 30*60; + // hours range: + if (mSmallestUnit <= tuHours) + availableSteps << 1*3600 << 2*3600 << 3*3600 << 6*3600 << 12*3600 << 24*3600; + // pick available step that is most appropriate to approximate ideal step: + result = pickClosest(result, availableSteps); + } else // more than a day, go back to normal clean mantissa algorithm but in units of days + { + const double secondsPerDay = 3600*24; + result = cleanMantissa(result/secondsPerDay)*secondsPerDay; + } + return result; +} + +/*! \internal + + Returns the sub tick count appropriate for the provided \a tickStep and time displays. + + \seebaseclassmethod +*/ +int QCPAxisTickerTime::getSubTickCount(double tickStep) +{ + int result = QCPAxisTicker::getSubTickCount(tickStep); + switch (qRound(tickStep)) // hand chosen subticks for specific minute/hour/day range (as specified in getTickStep) + { + case 5*60: result = 4; break; + case 10*60: result = 1; break; + case 15*60: result = 2; break; + case 30*60: result = 1; break; + case 60*60: result = 3; break; + case 3600*2: result = 3; break; + case 3600*3: result = 2; break; + case 3600*6: result = 1; break; + case 3600*12: result = 3; break; + case 3600*24: result = 3; break; + } + return result; +} + +/*! \internal + + Returns the tick label corresponding to the provided \a tick and the configured format and field + widths (\ref setTimeFormat, \ref setFieldWidth). + + \seebaseclassmethod +*/ +QString QCPAxisTickerTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + Q_UNUSED(precision) + Q_UNUSED(formatChar) + Q_UNUSED(locale) + bool negative = tick < 0; + if (negative) tick *= -1; + double values[tuDays+1]; // contains the msec/sec/min/... value with its respective modulo (e.g. minute 0..59) + double restValues[tuDays+1]; // contains the msec/sec/min/... value as if it's the largest available unit and thus consumes the remaining time + + restValues[tuMilliseconds] = tick*1000; + values[tuMilliseconds] = modf(restValues[tuMilliseconds]/1000, &restValues[tuSeconds])*1000; + values[tuSeconds] = modf(restValues[tuSeconds]/60, &restValues[tuMinutes])*60; + values[tuMinutes] = modf(restValues[tuMinutes]/60, &restValues[tuHours])*60; + values[tuHours] = modf(restValues[tuHours]/24, &restValues[tuDays])*24; + // no need to set values[tuDays] because days are always a rest value (there is no higher unit so it consumes all remaining time) + + QString result = mTimeFormat; + for (int i = mSmallestUnit; i <= mBiggestUnit; ++i) + { + TimeUnit iUnit = static_cast(i); + replaceUnit(result, iUnit, qRound(iUnit == mBiggestUnit ? restValues[iUnit] : values[iUnit])); + } + if (negative) + result.prepend(QLatin1Char('-')); + return result; +} + +/*! \internal + + Replaces all occurrences of the format pattern belonging to \a unit in \a text with the specified + \a value, using the field width as specified with \ref setFieldWidth for the \a unit. +*/ +void QCPAxisTickerTime::replaceUnit(QString &text, QCPAxisTickerTime::TimeUnit unit, int value) const +{ + QString valueStr = QString::number(value); + while (valueStr.size() < mFieldWidth.value(unit)) + valueStr.prepend(QLatin1Char('0')); + + text.replace(mFormatPattern.value(unit), valueStr); +} +/* end of 'src/axis/axistickertime.cpp' */ + + +/* including file 'src/axis/axistickerfixed.cpp', size 5583 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerFixed +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerFixed + \brief Specialized axis ticker with a fixed tick step + + \image html axisticker-fixed.png + + This QCPAxisTicker subclass generates ticks with a fixed tick step set with \ref setTickStep. It + is also possible to allow integer multiples and integer powers of the specified tick step with + \ref setScaleStrategy. + + A typical application of this ticker is to make an axis only display integers, by setting the + tick step of the ticker to 1.0 and the scale strategy to \ref ssMultiples. + + Another case is when a certain number has a special meaning and axis ticks should only appear at + multiples of that value. In this case you might also want to consider \ref QCPAxisTickerPi + because despite the name it is not limited to only pi symbols/values. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerfixed-creation +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerFixed::QCPAxisTickerFixed() : + mTickStep(1.0), + mScaleStrategy(ssNone) +{ +} + +/*! + Sets the fixed tick interval to \a step. + + The axis ticker will only use this tick step when generating axis ticks. This might cause a very + high tick density and overlapping labels if the axis range is zoomed out. Using \ref + setScaleStrategy it is possible to relax the fixed step and also allow multiples or powers of \a + step. This will enable the ticker to reduce the number of ticks to a reasonable amount (see \ref + setTickCount). +*/ +void QCPAxisTickerFixed::setTickStep(double step) +{ + if (step > 0) + mTickStep = step; + else + qDebug() << Q_FUNC_INFO << "tick step must be greater than zero:" << step; +} + +/*! + Sets whether the specified tick step (\ref setTickStep) is absolutely fixed or whether + modifications may be applied to it before calculating the finally used tick step, such as + permitting multiples or powers. See \ref ScaleStrategy for details. + + The default strategy is \ref ssNone, which means the tick step is absolutely fixed. +*/ +void QCPAxisTickerFixed::setScaleStrategy(QCPAxisTickerFixed::ScaleStrategy strategy) +{ + mScaleStrategy = strategy; +} + +/*! \internal + + Determines the actually used tick step from the specified tick step and scale strategy (\ref + setTickStep, \ref setScaleStrategy). + + This method either returns the specified tick step exactly, or, if the scale strategy is not \ref + ssNone, a modification of it to allow varying the number of ticks in the current axis range. + + \seebaseclassmethod +*/ +double QCPAxisTickerFixed::getTickStep(const QCPRange &range) +{ + switch (mScaleStrategy) + { + case ssNone: + { + return mTickStep; + } + case ssMultiples: + { + double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + if (exactStep < mTickStep) + return mTickStep; + else + return (qint64)(cleanMantissa(exactStep/mTickStep)+0.5)*mTickStep; + } + case ssPowers: + { + double exactStep = range.size()/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + return qPow(mTickStep, (int)(qLn(exactStep)/qLn(mTickStep)+0.5)); + } + } + return mTickStep; +} +/* end of 'src/axis/axistickerfixed.cpp' */ + + +/* including file 'src/axis/axistickertext.cpp', size 8653 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerText +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerText + \brief Specialized axis ticker which allows arbitrary labels at specified coordinates + + \image html axisticker-text.png + + This QCPAxisTicker subclass generates ticks which can be directly specified by the user as + coordinates and associated strings. They can be passed as a whole with \ref setTicks or one at a + time with \ref addTick. Alternatively you can directly access the internal storage via \ref ticks + and modify the tick/label data there. + + This is useful for cases where the axis represents categories rather than numerical values. + + If you are updating the ticks of this ticker regularly and in a dynamic fasion (e.g. dependent on + the axis range), it is a sign that you should probably create an own ticker by subclassing + QCPAxisTicker, instead of using this one. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickertext-creation +*/ + +/* start of documentation of inline functions */ + +/*! \fn QMap &QCPAxisTickerText::ticks() + + Returns a non-const reference to the internal map which stores the tick coordinates and their + labels. + + You can access the map directly in order to add, remove or manipulate ticks, as an alternative to + using the methods provided by QCPAxisTickerText, such as \ref setTicks and \ref addTick. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerText::QCPAxisTickerText() : + mSubTickCount(0) +{ +} + +/*! \overload + + Sets the ticks that shall appear on the axis. The map key of \a ticks corresponds to the axis + coordinate, and the map value is the string that will appear as tick label. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTicks, addTick, clear +*/ +void QCPAxisTickerText::setTicks(const QMap &ticks) +{ + mTicks = ticks; +} + +/*! \overload + + Sets the ticks that shall appear on the axis. The entries of \a positions correspond to the axis + coordinates, and the entries of \a labels are the respective strings that will appear as tick + labels. + + \see addTicks, addTick, clear +*/ +void QCPAxisTickerText::setTicks(const QVector &positions, const QVector labels) +{ + clear(); + addTicks(positions, labels); +} + +/*! + Sets the number of sub ticks that shall appear between ticks. For QCPAxisTickerText, there is no + automatic sub tick count calculation. So if sub ticks are needed, they must be configured with this + method. +*/ +void QCPAxisTickerText::setSubTickCount(int subTicks) +{ + if (subTicks >= 0) + mSubTickCount = subTicks; + else + qDebug() << Q_FUNC_INFO << "sub tick count can't be negative:" << subTicks; +} + +/*! + Clears all ticks. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see setTicks, addTicks, addTick +*/ +void QCPAxisTickerText::clear() +{ + mTicks.clear(); +} + +/*! + Adds a single tick to the axis at the given axis coordinate \a position, with the provided tick \a + label. + + \see addTicks, setTicks, clear +*/ +void QCPAxisTickerText::addTick(double position, QString label) +{ + mTicks.insert(position, label); +} + +/*! \overload + + Adds the provided \a ticks to the ones already existing. The map key of \a ticks corresponds to + the axis coordinate, and the map value is the string that will appear as tick label. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTick, setTicks, clear +*/ +void QCPAxisTickerText::addTicks(const QMap &ticks) +{ + mTicks.unite(ticks); +} + +/*! \overload + + Adds the provided ticks to the ones already existing. The entries of \a positions correspond to + the axis coordinates, and the entries of \a labels are the respective strings that will appear as + tick labels. + + An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks + getter. + + \see addTick, setTicks, clear +*/ +void QCPAxisTickerText::addTicks(const QVector &positions, const QVector &labels) +{ + if (positions.size() != labels.size()) + qDebug() << Q_FUNC_INFO << "passed unequal length vectors for positions and labels:" << positions.size() << labels.size(); + int n = qMin(positions.size(), labels.size()); + for (int i=0; i QCPAxisTickerText::createTickVector(double tickStep, const QCPRange &range) +{ + Q_UNUSED(tickStep) + QVector result; + if (mTicks.isEmpty()) + return result; + + QMap::const_iterator start = mTicks.lowerBound(range.lower); + QMap::const_iterator end = mTicks.upperBound(range.upper); + // this method should try to give one tick outside of range so proper subticks can be generated: + if (start != mTicks.constBegin()) --start; + if (end != mTicks.constEnd()) ++end; + for (QMap::const_iterator it = start; it != end; ++it) + result.append(it.key()); + + return result; +} +/* end of 'src/axis/axistickertext.cpp' */ + + +/* including file 'src/axis/axistickerpi.cpp', size 11170 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerPi +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerPi + \brief Specialized axis ticker to display ticks in units of an arbitrary constant, for example pi + + \image html axisticker-pi.png + + This QCPAxisTicker subclass generates ticks that are expressed with respect to a given symbolic + constant with a numerical value specified with \ref setPiValue and an appearance in the tick + labels specified with \ref setPiSymbol. + + Ticks may be generated at fractions of the symbolic constant. How these fractions appear in the + tick label can be configured with \ref setFractionStyle. + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerpi-creation +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerPi::QCPAxisTickerPi() : + mPiSymbol(QLatin1String(" ")+QChar(0x03C0)), + mPiValue(M_PI), + mPeriodicity(0), + mFractionStyle(fsUnicodeFractions), + mPiTickStep(0) +{ + setTickCount(4); +} + +/*! + Sets how the symbol part (which is always a suffix to the number) shall appear in the axis tick + label. + + If a space shall appear between the number and the symbol, make sure the space is contained in \a + symbol. +*/ +void QCPAxisTickerPi::setPiSymbol(QString symbol) +{ + mPiSymbol = symbol; +} + +/*! + Sets the numerical value that the symbolic constant has. + + This will be used to place the appropriate fractions of the symbol at the respective axis + coordinates. +*/ +void QCPAxisTickerPi::setPiValue(double pi) +{ + mPiValue = pi; +} + +/*! + Sets whether the axis labels shall appear periodicly and if so, at which multiplicity of the + symbolic constant. + + To disable periodicity, set \a multiplesOfPi to zero. + + For example, an axis that identifies 0 with 2pi would set \a multiplesOfPi to two. +*/ +void QCPAxisTickerPi::setPeriodicity(int multiplesOfPi) +{ + mPeriodicity = qAbs(multiplesOfPi); +} + +/*! + Sets how the numerical/fractional part preceding the symbolic constant is displayed in tick + labels. See \ref FractionStyle for the various options. +*/ +void QCPAxisTickerPi::setFractionStyle(QCPAxisTickerPi::FractionStyle style) +{ + mFractionStyle = style; +} + +/*! \internal + + Returns the tick step, using the constant's value (\ref setPiValue) as base unit. In consequence + the numerical/fractional part preceding the symbolic constant is made to have a readable + mantissa. + + \seebaseclassmethod +*/ +double QCPAxisTickerPi::getTickStep(const QCPRange &range) +{ + mPiTickStep = range.size()/mPiValue/(double)(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers + mPiTickStep = cleanMantissa(mPiTickStep); + return mPiTickStep*mPiValue; +} + +/*! \internal + + Returns the sub tick count, using the constant's value (\ref setPiValue) as base unit. In + consequence the sub ticks divide the numerical/fractional part preceding the symbolic constant + reasonably, and not the total tick coordinate. + + \seebaseclassmethod +*/ +int QCPAxisTickerPi::getSubTickCount(double tickStep) +{ + return QCPAxisTicker::getSubTickCount(tickStep/mPiValue); +} + +/*! \internal + + Returns the tick label as a fractional/numerical part and a symbolic string as suffix. The + formatting of the fraction is done according to the specified \ref setFractionStyle. The appended + symbol is specified with \ref setPiSymbol. + + \seebaseclassmethod +*/ +QString QCPAxisTickerPi::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) +{ + double tickInPis = tick/mPiValue; + if (mPeriodicity > 0) + tickInPis = fmod(tickInPis, mPeriodicity); + + if (mFractionStyle != fsFloatingPoint && mPiTickStep > 0.09 && mPiTickStep < 50) + { + // simply construct fraction from decimal like 1.234 -> 1234/1000 and then simplify fraction, smaller digits are irrelevant due to mPiTickStep conditional above + int denominator = 1000; + int numerator = qRound(tickInPis*denominator); + simplifyFraction(numerator, denominator); + if (qAbs(numerator) == 1 && denominator == 1) + return (numerator < 0 ? QLatin1String("-") : QLatin1String("")) + mPiSymbol.trimmed(); + else if (numerator == 0) + return QLatin1String("0"); + else + return fractionToString(numerator, denominator) + mPiSymbol; + } else + { + if (qFuzzyIsNull(tickInPis)) + return QLatin1String("0"); + else if (qFuzzyCompare(qAbs(tickInPis), 1.0)) + return (tickInPis < 0 ? QLatin1String("-") : QLatin1String("")) + mPiSymbol.trimmed(); + else + return QCPAxisTicker::getTickLabel(tickInPis, locale, formatChar, precision) + mPiSymbol; + } +} + +/*! \internal + + Takes the fraction given by \a numerator and \a denominator and modifies the values to make sure + the fraction is in irreducible form, i.e. numerator and denominator don't share any common + factors which could be cancelled. +*/ +void QCPAxisTickerPi::simplifyFraction(int &numerator, int &denominator) const +{ + if (numerator == 0 || denominator == 0) + return; + + int num = numerator; + int denom = denominator; + while (denom != 0) // euclidean gcd algorithm + { + int oldDenom = denom; + denom = num % denom; + num = oldDenom; + } + // num is now gcd of numerator and denominator + numerator /= num; + denominator /= num; +} + +/*! \internal + + Takes the fraction given by \a numerator and \a denominator and returns a string representation. + The result depends on the configured fraction style (\ref setFractionStyle). + + This method is used to format the numerical/fractional part when generating tick labels. It + simplifies the passed fraction to an irreducible form using \ref simplifyFraction and factors out + any integer parts of the fraction (e.g. "10/4" becomes "2 1/2"). +*/ +QString QCPAxisTickerPi::fractionToString(int numerator, int denominator) const +{ + if (denominator == 0) + { + qDebug() << Q_FUNC_INFO << "called with zero denominator"; + return QString(); + } + if (mFractionStyle == fsFloatingPoint) // should never be the case when calling this function + { + qDebug() << Q_FUNC_INFO << "shouldn't be called with fraction style fsDecimal"; + return QString::number(numerator/(double)denominator); // failsafe + } + int sign = numerator*denominator < 0 ? -1 : 1; + numerator = qAbs(numerator); + denominator = qAbs(denominator); + + if (denominator == 1) + { + return QString::number(sign*numerator); + } else + { + int integerPart = numerator/denominator; + int remainder = numerator%denominator; + if (remainder == 0) + { + return QString::number(sign*integerPart); + } else + { + if (mFractionStyle == fsAsciiFractions) + { + return QString(QLatin1String("%1%2%3/%4")) + .arg(sign == -1 ? QLatin1String("-") : QLatin1String("")) + .arg(integerPart > 0 ? QString::number(integerPart)+QLatin1String(" ") : QLatin1String("")) + .arg(remainder) + .arg(denominator); + } else if (mFractionStyle == fsUnicodeFractions) + { + return QString(QLatin1String("%1%2%3")) + .arg(sign == -1 ? QLatin1String("-") : QLatin1String("")) + .arg(integerPart > 0 ? QString::number(integerPart) : QLatin1String("")) + .arg(unicodeFraction(remainder, denominator)); + } + } + } + return QString(); +} + +/*! \internal + + Returns the unicode string representation of the fraction given by \a numerator and \a + denominator. This is the representation used in \ref fractionToString when the fraction style + (\ref setFractionStyle) is \ref fsUnicodeFractions. + + This method doesn't use the single-character common fractions but builds each fraction from a + superscript unicode number, the unicode fraction character, and a subscript unicode number. +*/ +QString QCPAxisTickerPi::unicodeFraction(int numerator, int denominator) const +{ + return unicodeSuperscript(numerator)+QChar(0x2044)+unicodeSubscript(denominator); +} + +/*! \internal + + Returns the unicode string representing \a number as superscript. This is used to build + unicode fractions in \ref unicodeFraction. +*/ +QString QCPAxisTickerPi::unicodeSuperscript(int number) const +{ + if (number == 0) + return QString(QChar(0x2070)); + + QString result; + while (number > 0) + { + const int digit = number%10; + switch (digit) + { + case 1: { result.prepend(QChar(0x00B9)); break; } + case 2: { result.prepend(QChar(0x00B2)); break; } + case 3: { result.prepend(QChar(0x00B3)); break; } + default: { result.prepend(QChar(0x2070+digit)); break; } + } + number /= 10; + } + return result; +} + +/*! \internal + + Returns the unicode string representing \a number as subscript. This is used to build unicode + fractions in \ref unicodeFraction. +*/ +QString QCPAxisTickerPi::unicodeSubscript(int number) const +{ + if (number == 0) + return QString(QChar(0x2080)); + + QString result; + while (number > 0) + { + result.prepend(QChar(0x2080+number%10)); + number /= 10; + } + return result; +} +/* end of 'src/axis/axistickerpi.cpp' */ + + +/* including file 'src/axis/axistickerlog.cpp', size 7106 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisTickerLog +//////////////////////////////////////////////////////////////////////////////////////////////////// +/*! \class QCPAxisTickerLog + \brief Specialized axis ticker suited for logarithmic axes + + \image html axisticker-log.png + + This QCPAxisTicker subclass generates ticks with unequal tick intervals suited for logarithmic + axis scales. The ticks are placed at powers of the specified log base (\ref setLogBase). + + Especially in the case of a log base equal to 10 (the default), it might be desirable to have + tick labels in the form of powers of ten without mantissa display. To achieve this, set the + number precision (\ref QCPAxis::setNumberPrecision) to zero and the number format (\ref + QCPAxis::setNumberFormat) to scientific (exponential) display with beautifully typeset decimal + powers, so a format string of "eb". This will result in the following axis tick labels: + + \image html axisticker-log-powers.png + + The ticker can be created and assigned to an axis like this: + \snippet documentation/doc-image-generator/mainwindow.cpp axistickerlog-creation +*/ + +/*! + Constructs the ticker and sets reasonable default values. Axis tickers are commonly created + managed by a QSharedPointer, which then can be passed to QCPAxis::setTicker. +*/ +QCPAxisTickerLog::QCPAxisTickerLog() : + mLogBase(10.0), + mSubTickCount(8), // generates 10 intervals + mLogBaseLnInv(1.0/qLn(mLogBase)) +{ +} + +/*! + Sets the logarithm base used for tick coordinate generation. The ticks will be placed at integer + powers of \a base. +*/ +void QCPAxisTickerLog::setLogBase(double base) +{ + if (base > 0) + { + mLogBase = base; + mLogBaseLnInv = 1.0/qLn(mLogBase); + } else + qDebug() << Q_FUNC_INFO << "log base has to be greater than zero:" << base; +} + +/*! + Sets the number of sub ticks in a tick interval. Within each interval, the sub ticks are spaced + linearly to provide a better visual guide, so the sub tick density increases toward the higher + tick. + + Note that \a subTicks is the number of sub ticks (not sub intervals) in one tick interval. So in + the case of logarithm base 10 an intuitive sub tick spacing would be achieved with eight sub + ticks (the default). This means e.g. between the ticks 10 and 100 there will be eight ticks, + namely at 20, 30, 40, 50, 60, 70, 80 and 90. +*/ +void QCPAxisTickerLog::setSubTickCount(int subTicks) +{ + if (subTicks >= 0) + mSubTickCount = subTicks; + else + qDebug() << Q_FUNC_INFO << "sub tick count can't be negative:" << subTicks; +} + +/*! \internal + + Since logarithmic tick steps are necessarily different for each tick interval, this method does + nothing in the case of QCPAxisTickerLog + + \seebaseclassmethod +*/ +double QCPAxisTickerLog::getTickStep(const QCPRange &range) +{ + // Logarithmic axis ticker has unequal tick spacing, so doesn't need this method + Q_UNUSED(range) + return 1.0; +} + +/*! \internal + + Returns the sub tick count specified in \ref setSubTickCount. For QCPAxisTickerLog, there is no + automatic sub tick count calculation necessary. + + \seebaseclassmethod +*/ +int QCPAxisTickerLog::getSubTickCount(double tickStep) +{ + Q_UNUSED(tickStep) + return mSubTickCount; +} + +/*! \internal + + Creates ticks with a spacing given by the logarithm base and an increasing integer power in the + provided \a range. The step in which the power increases tick by tick is chosen in order to keep + the total number of ticks as close as possible to the tick count (\ref setTickCount). The + parameter \a tickStep is ignored for QCPAxisTickerLog + + \seebaseclassmethod +*/ +QVector QCPAxisTickerLog::createTickVector(double tickStep, const QCPRange &range) +{ + Q_UNUSED(tickStep) + QVector result; + if (range.lower > 0 && range.upper > 0) // positive range + { + double exactPowerStep = qLn(range.upper/range.lower)*mLogBaseLnInv/(double)(mTickCount+1e-10); + double newLogBase = qPow(mLogBase, qMax((int)cleanMantissa(exactPowerStep), 1)); + double currentTick = qPow(newLogBase, qFloor(qLn(range.lower)/qLn(newLogBase))); + result.append(currentTick); + while (currentTick < range.upper && currentTick > 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case + { + currentTick *= newLogBase; + result.append(currentTick); + } + } else if (range.lower < 0 && range.upper < 0) // negative range + { + double exactPowerStep = qLn(range.lower/range.upper)*mLogBaseLnInv/(double)(mTickCount+1e-10); + double newLogBase = qPow(mLogBase, qMax((int)cleanMantissa(exactPowerStep), 1)); + double currentTick = -qPow(newLogBase, qCeil(qLn(-range.lower)/qLn(newLogBase))); + result.append(currentTick); + while (currentTick < range.upper && currentTick < 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case + { + currentTick /= newLogBase; + result.append(currentTick); + } + } else // invalid range for logarithmic scale, because lower and upper have different sign + { + qDebug() << Q_FUNC_INFO << "Invalid range for logarithmic plot: " << range.lower << ".." << range.upper; + } + + return result; +} +/* end of 'src/axis/axistickerlog.cpp' */ + + +/* including file 'src/axis/axis.cpp', size 94458 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGrid +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGrid + \brief Responsible for drawing the grid of a QCPAxis. + + This class is tightly bound to QCPAxis. Every axis owns a grid instance and uses it to draw the + grid lines, sub grid lines and zero-line. You can interact with the grid of an axis via \ref + QCPAxis::grid. Normally, you don't need to create an instance of QCPGrid yourself. + + The axis and grid drawing was split into two classes to allow them to be placed on different + layers (both QCPAxis and QCPGrid inherit from QCPLayerable). Thus it is possible to have the grid + in the background and the axes in the foreground, and any plottables/items in between. This + described situation is the default setup, see the QCPLayer documentation. +*/ + +/*! + Creates a QCPGrid instance and sets default values. + + You shouldn't instantiate grids on their own, since every QCPAxis brings its own QCPGrid. +*/ +QCPGrid::QCPGrid(QCPAxis *parentAxis) : + QCPLayerable(parentAxis->parentPlot(), QString(), parentAxis), + mParentAxis(parentAxis) +{ + // warning: this is called in QCPAxis constructor, so parentAxis members should not be accessed/called + setParent(parentAxis); + setPen(QPen(QColor(200,200,200), 0, Qt::DotLine)); + setSubGridPen(QPen(QColor(220,220,220), 0, Qt::DotLine)); + setZeroLinePen(QPen(QColor(200,200,200), 0, Qt::SolidLine)); + setSubGridVisible(false); + setAntialiased(false); + setAntialiasedSubGrid(false); + setAntialiasedZeroLine(false); +} + +/*! + Sets whether grid lines at sub tick marks are drawn. + + \see setSubGridPen +*/ +void QCPGrid::setSubGridVisible(bool visible) +{ + mSubGridVisible = visible; +} + +/*! + Sets whether sub grid lines are drawn antialiased. +*/ +void QCPGrid::setAntialiasedSubGrid(bool enabled) +{ + mAntialiasedSubGrid = enabled; +} + +/*! + Sets whether zero lines are drawn antialiased. +*/ +void QCPGrid::setAntialiasedZeroLine(bool enabled) +{ + mAntialiasedZeroLine = enabled; +} + +/*! + Sets the pen with which (major) grid lines are drawn. +*/ +void QCPGrid::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen with which sub grid lines are drawn. +*/ +void QCPGrid::setSubGridPen(const QPen &pen) +{ + mSubGridPen = pen; +} + +/*! + Sets the pen with which zero lines are drawn. + + Zero lines are lines at value coordinate 0 which may be drawn with a different pen than other grid + lines. To disable zero lines and just draw normal grid lines at zero, set \a pen to Qt::NoPen. +*/ +void QCPGrid::setZeroLinePen(const QPen &pen) +{ + mZeroLinePen = pen; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing the major grid lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPGrid::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeGrid); +} + +/*! \internal + + Draws grid lines and sub grid lines at the positions of (sub) ticks of the parent axis, spanning + over the complete axis rect. Also draws the zero line, if appropriate (\ref setZeroLinePen). +*/ +void QCPGrid::draw(QCPPainter *painter) +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + if (mParentAxis->subTicks() && mSubGridVisible) + drawSubGridLines(painter); + drawGridLines(painter); +} + +/*! \internal + + Draws the main grid lines and possibly a zero line with the specified painter. + + This is a helper function called by \ref draw. +*/ +void QCPGrid::drawGridLines(QCPPainter *painter) const +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + const int tickCount = mParentAxis->mTickVector.size(); + double t; // helper variable, result of coordinate-to-pixel transforms + if (mParentAxis->orientation() == Qt::Horizontal) + { + // draw zeroline: + int zeroLineIndex = -1; + if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(mZeroLinePen); + double epsilon = mParentAxis->range().size()*1E-6; // for comparing double to zero + for (int i=0; imTickVector.at(i)) < epsilon) + { + zeroLineIndex = i; + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + break; + } + } + } + // draw grid lines: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + for (int i=0; icoordToPixel(mParentAxis->mTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + } + } else + { + // draw zeroline: + int zeroLineIndex = -1; + if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0) + { + applyAntialiasingHint(painter, mAntialiasedZeroLine, QCP::aeZeroLine); + painter->setPen(mZeroLinePen); + double epsilon = mParentAxis->mRange.size()*1E-6; // for comparing double to zero + for (int i=0; imTickVector.at(i)) < epsilon) + { + zeroLineIndex = i; + t = mParentAxis->coordToPixel(mParentAxis->mTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + break; + } + } + } + // draw grid lines: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + for (int i=0; icoordToPixel(mParentAxis->mTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + } + } +} + +/*! \internal + + Draws the sub grid lines with the specified painter. + + This is a helper function called by \ref draw. +*/ +void QCPGrid::drawSubGridLines(QCPPainter *painter) const +{ + if (!mParentAxis) { qDebug() << Q_FUNC_INFO << "invalid parent axis"; return; } + + applyAntialiasingHint(painter, mAntialiasedSubGrid, QCP::aeSubGrid); + double t; // helper variable, result of coordinate-to-pixel transforms + painter->setPen(mSubGridPen); + if (mParentAxis->orientation() == Qt::Horizontal) + { + for (int i=0; imSubTickVector.size(); ++i) + { + t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // x + painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top())); + } + } else + { + for (int i=0; imSubTickVector.size(); ++i) + { + t = mParentAxis->coordToPixel(mParentAxis->mSubTickVector.at(i)); // y + painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t)); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxis +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxis + \brief Manages a single axis inside a QCustomPlot. + + Usually doesn't need to be instantiated externally. Access %QCustomPlot's default four axes via + QCustomPlot::xAxis (bottom), QCustomPlot::yAxis (left), QCustomPlot::xAxis2 (top) and + QCustomPlot::yAxis2 (right). + + Axes are always part of an axis rect, see QCPAxisRect. + \image html AxisNamesOverview.png +
Naming convention of axis parts
+ \n + + \image html AxisRectSpacingOverview.png +
Overview of the spacings and paddings that define the geometry of an axis. The dashed gray line + on the left represents the QCustomPlot widget border.
+ + Each axis holds an instance of QCPAxisTicker which is used to generate the tick coordinates and + tick labels. You can access the currently installed \ref ticker or set a new one (possibly one of + the specialized subclasses, or your own subclass) via \ref setTicker. For details, see the + documentation of QCPAxisTicker. +*/ + +/* start of documentation of inline functions */ + +/*! \fn Qt::Orientation QCPAxis::orientation() const + + Returns the orientation of this axis. The axis orientation (horizontal or vertical) is deduced + from the axis type (left, top, right or bottom). + + \see orientation(AxisType type), pixelOrientation +*/ + +/*! \fn QCPGrid *QCPAxis::grid() const + + Returns the \ref QCPGrid instance belonging to this axis. Access it to set details about the way the + grid is displayed. +*/ + +/*! \fn static Qt::Orientation QCPAxis::orientation(AxisType type) + + Returns the orientation of the specified axis type + + \see orientation(), pixelOrientation +*/ + +/*! \fn int QCPAxis::pixelOrientation() const + + Returns which direction points towards higher coordinate values/keys, in pixel space. + + This method returns either 1 or -1. If it returns 1, then going in the positive direction along + the orientation of the axis in pixels corresponds to going from lower to higher axis coordinates. + On the other hand, if this method returns -1, going to smaller pixel values corresponds to going + from lower to higher axis coordinates. + + For example, this is useful to easily shift axis coordinates by a certain amount given in pixels, + without having to care about reversed or vertically aligned axes: + + \code + double newKey = keyAxis->pixelToCoord(keyAxis->coordToPixel(oldKey)+10*keyAxis->pixelOrientation()); + \endcode + + \a newKey will then contain a key that is ten pixels towards higher keys, starting from \a oldKey. +*/ + +/*! \fn QSharedPointer QCPAxis::ticker() const + + Returns a modifiable shared pointer to the currently installed axis ticker. The axis ticker is + responsible for generating the tick positions and tick labels of this axis. You can access the + \ref QCPAxisTicker with this method and modify basic properties such as the approximate tick count + (\ref QCPAxisTicker::setTickCount). + + You can gain more control over the axis ticks by setting a different \ref QCPAxisTicker subclass, see + the documentation there. A new axis ticker can be set with \ref setTicker. + + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis + ticker simply by passing the same shared pointer to multiple axes. + + \see setTicker +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange) + + This signal is emitted when the range of this axis has changed. You can connect it to the \ref + setRange slot of another axis to communicate the new range to the other axis, in order for it to + be synchronized. + + You may also manipulate/correct the range with \ref setRange in a slot connected to this signal. + This is useful if for example a maximum range span shall not be exceeded, or if the lower/upper + range shouldn't go beyond certain values (see \ref QCPRange::bounded). For example, the following + slot would limit the x axis to ranges between 0 and 10: + \code + customPlot->xAxis->setRange(newRange.bounded(0, 10)) + \endcode +*/ + +/*! \fn void QCPAxis::rangeChanged(const QCPRange &newRange, const QCPRange &oldRange) + \overload + + Additionally to the new range, this signal also provides the previous range held by the axis as + \a oldRange. +*/ + +/*! \fn void QCPAxis::scaleTypeChanged(QCPAxis::ScaleType scaleType); + + This signal is emitted when the scale type changes, by calls to \ref setScaleType +*/ + +/*! \fn void QCPAxis::selectionChanged(QCPAxis::SelectableParts selection) + + This signal is emitted when the selection state of this axis has changed, either by user interaction + or by a direct call to \ref setSelectedParts. +*/ + +/*! \fn void QCPAxis::selectableChanged(const QCPAxis::SelectableParts &parts); + + This signal is emitted when the selectability changes, by calls to \ref setSelectableParts +*/ + +/* end of documentation of signals */ + +/*! + Constructs an Axis instance of Type \a type for the axis rect \a parent. + + Usually it isn't necessary to instantiate axes directly, because you can let QCustomPlot create + them for you with \ref QCPAxisRect::addAxis. If you want to use own QCPAxis-subclasses however, + create them manually and then inject them also via \ref QCPAxisRect::addAxis. +*/ +QCPAxis::QCPAxis(QCPAxisRect *parent, AxisType type) : + QCPLayerable(parent->parentPlot(), QString(), parent), + // axis base: + mAxisType(type), + mAxisRect(parent), + mPadding(5), + mOrientation(orientation(type)), + mSelectableParts(spAxis | spTickLabels | spAxisLabel), + mSelectedParts(spNone), + mBasePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedBasePen(QPen(Qt::blue, 2)), + // axis label: + mLabel(), + mLabelFont(mParentPlot->font()), + mSelectedLabelFont(QFont(mLabelFont.family(), mLabelFont.pointSize(), QFont::Bold)), + mLabelColor(Qt::black), + mSelectedLabelColor(Qt::blue), + // tick labels: + mTickLabels(true), + mTickLabelFont(mParentPlot->font()), + mSelectedTickLabelFont(QFont(mTickLabelFont.family(), mTickLabelFont.pointSize(), QFont::Bold)), + mTickLabelColor(Qt::black), + mSelectedTickLabelColor(Qt::blue), + mNumberPrecision(6), + mNumberFormatChar('g'), + mNumberBeautifulPowers(true), + // ticks and subticks: + mTicks(true), + mSubTicks(true), + mTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedTickPen(QPen(Qt::blue, 2)), + mSubTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + mSelectedSubTickPen(QPen(Qt::blue, 2)), + // scale and range: + mRange(0, 5), + mRangeReversed(false), + mScaleType(stLinear), + // internal members: + mGrid(new QCPGrid(this)), + mAxisPainter(new QCPAxisPainterPrivate(parent->parentPlot())), + mTicker(new QCPAxisTicker), + mCachedMarginValid(false), + mCachedMargin(0) +{ + setParent(parent); + mGrid->setVisible(false); + setAntialiased(false); + setLayer(mParentPlot->currentLayer()); // it's actually on that layer already, but we want it in front of the grid, so we place it on there again + + if (type == atTop) + { + setTickLabelPadding(3); + setLabelPadding(6); + } else if (type == atRight) + { + setTickLabelPadding(7); + setLabelPadding(12); + } else if (type == atBottom) + { + setTickLabelPadding(3); + setLabelPadding(3); + } else if (type == atLeft) + { + setTickLabelPadding(5); + setLabelPadding(10); + } +} + +QCPAxis::~QCPAxis() +{ + delete mAxisPainter; + delete mGrid; // delete grid here instead of via parent ~QObject for better defined deletion order +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLabelPadding() const +{ + return mAxisPainter->tickLabelPadding; +} + +/* No documentation as it is a property getter */ +double QCPAxis::tickLabelRotation() const +{ + return mAxisPainter->tickLabelRotation; +} + +/* No documentation as it is a property getter */ +QCPAxis::LabelSide QCPAxis::tickLabelSide() const +{ + return mAxisPainter->tickLabelSide; +} + +/* No documentation as it is a property getter */ +QString QCPAxis::numberFormat() const +{ + QString result; + result.append(mNumberFormatChar); + if (mNumberBeautifulPowers) + { + result.append(QLatin1Char('b')); + if (mAxisPainter->numberMultiplyCross) + result.append(QLatin1Char('c')); + } + return result; +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLengthIn() const +{ + return mAxisPainter->tickLengthIn; +} + +/* No documentation as it is a property getter */ +int QCPAxis::tickLengthOut() const +{ + return mAxisPainter->tickLengthOut; +} + +/* No documentation as it is a property getter */ +int QCPAxis::subTickLengthIn() const +{ + return mAxisPainter->subTickLengthIn; +} + +/* No documentation as it is a property getter */ +int QCPAxis::subTickLengthOut() const +{ + return mAxisPainter->subTickLengthOut; +} + +/* No documentation as it is a property getter */ +int QCPAxis::labelPadding() const +{ + return mAxisPainter->labelPadding; +} + +/* No documentation as it is a property getter */ +int QCPAxis::offset() const +{ + return mAxisPainter->offset; +} + +/* No documentation as it is a property getter */ +QCPLineEnding QCPAxis::lowerEnding() const +{ + return mAxisPainter->lowerEnding; +} + +/* No documentation as it is a property getter */ +QCPLineEnding QCPAxis::upperEnding() const +{ + return mAxisPainter->upperEnding; +} + +/*! + Sets whether the axis uses a linear scale or a logarithmic scale. + + Note that this method controls the coordinate transformation. You will likely also want to use a + logarithmic tick spacing and labeling, which can be achieved by setting an instance of \ref + QCPAxisTickerLog via \ref setTicker. See the documentation of \ref QCPAxisTickerLog about the + details of logarithmic axis tick creation. + + \ref setNumberPrecision +*/ +void QCPAxis::setScaleType(QCPAxis::ScaleType type) +{ + if (mScaleType != type) + { + mScaleType = type; + if (mScaleType == stLogarithmic) + setRange(mRange.sanitizedForLogScale()); + mCachedMarginValid = false; + emit scaleTypeChanged(mScaleType); + } +} + +/*! + Sets the range of the axis. + + This slot may be connected with the \ref rangeChanged signal of another axis so this axis + is always synchronized with the other axis range, when it changes. + + To invert the direction of an axis, use \ref setRangeReversed. +*/ +void QCPAxis::setRange(const QCPRange &range) +{ + if (range.lower == mRange.lower && range.upper == mRange.upper) + return; + + if (!QCPRange::validRange(range)) return; + QCPRange oldRange = mRange; + if (mScaleType == stLogarithmic) + { + mRange = range.sanitizedForLogScale(); + } else + { + mRange = range.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains iSelectAxes.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelectedParts + directly. + + \see SelectablePart, setSelectedParts +*/ +void QCPAxis::setSelectableParts(const SelectableParts &selectable) +{ + if (mSelectableParts != selectable) + { + mSelectableParts = selectable; + emit selectableChanged(mSelectableParts); + } +} + +/*! + Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font. + + The entire selection mechanism for axes is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you + wish to change the selection state manually. + + This function can change the selection state of a part, independent of the \ref setSelectableParts setting. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see SelectablePart, setSelectableParts, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, + setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor +*/ +void QCPAxis::setSelectedParts(const SelectableParts &selected) +{ + if (mSelectedParts != selected) + { + mSelectedParts = selected; + emit selectionChanged(mSelectedParts); + } +} + +/*! + \overload + + Sets the lower and upper bound of the axis range. + + To invert the direction of an axis, use \ref setRangeReversed. + + There is also a slot to set a range, see \ref setRange(const QCPRange &range). +*/ +void QCPAxis::setRange(double lower, double upper) +{ + if (lower == mRange.lower && upper == mRange.upper) + return; + + if (!QCPRange::validRange(lower, upper)) return; + QCPRange oldRange = mRange; + mRange.lower = lower; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + \overload + + Sets the range of the axis. + + The \a position coordinate indicates together with the \a alignment parameter, where the new + range will be positioned. \a size defines the size of the new axis range. \a alignment may be + Qt::AlignLeft, Qt::AlignRight or Qt::AlignCenter. This will cause the left border, right border, + or center of the range to be aligned with \a position. Any other values of \a alignment will + default to Qt::AlignCenter. +*/ +void QCPAxis::setRange(double position, double size, Qt::AlignmentFlag alignment) +{ + if (alignment == Qt::AlignLeft) + setRange(position, position+size); + else if (alignment == Qt::AlignRight) + setRange(position-size, position); + else // alignment == Qt::AlignCenter + setRange(position-size/2.0, position+size/2.0); +} + +/*! + Sets the lower bound of the axis range. The upper bound is not changed. + \see setRange +*/ +void QCPAxis::setRangeLower(double lower) +{ + if (mRange.lower == lower) + return; + + QCPRange oldRange = mRange; + mRange.lower = lower; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets the upper bound of the axis range. The lower bound is not changed. + \see setRange +*/ +void QCPAxis::setRangeUpper(double upper) +{ + if (mRange.upper == upper) + return; + + QCPRange oldRange = mRange; + mRange.upper = upper; + if (mScaleType == stLogarithmic) + { + mRange = mRange.sanitizedForLogScale(); + } else + { + mRange = mRange.sanitizedForLinScale(); + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Sets whether the axis range (direction) is displayed reversed. Normally, the values on horizontal + axes increase left to right, on vertical axes bottom to top. When \a reversed is set to true, the + direction of increasing values is inverted. + + Note that the range and data interface stays the same for reversed axes, e.g. the \a lower part + of the \ref setRange interface will still reference the mathematically smaller number than the \a + upper part. +*/ +void QCPAxis::setRangeReversed(bool reversed) +{ + mRangeReversed = reversed; +} + +/*! + The axis ticker is responsible for generating the tick positions and tick labels. See the + documentation of QCPAxisTicker for details on how to work with axis tickers. + + You can change the tick positioning/labeling behaviour of this axis by setting a different + QCPAxisTicker subclass using this method. If you only wish to modify the currently installed axis + ticker, access it via \ref ticker. + + Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis + ticker simply by passing the same shared pointer to multiple axes. + + \see ticker +*/ +void QCPAxis::setTicker(QSharedPointer ticker) +{ + if (ticker) + mTicker = ticker; + else + qDebug() << Q_FUNC_INFO << "can not set 0 as axis ticker"; + // no need to invalidate margin cache here because produced tick labels are checked for changes in setupTickVector +} + +/*! + Sets whether tick marks are displayed. + + Note that setting \a show to false does not imply that tick labels are invisible, too. To achieve + that, see \ref setTickLabels. + + \see setSubTicks +*/ +void QCPAxis::setTicks(bool show) +{ + if (mTicks != show) + { + mTicks = show; + mCachedMarginValid = false; + } +} + +/*! + Sets whether tick labels are displayed. Tick labels are the numbers drawn next to tick marks. +*/ +void QCPAxis::setTickLabels(bool show) +{ + if (mTickLabels != show) + { + mTickLabels = show; + mCachedMarginValid = false; + if (!mTickLabels) + mTickVectorLabels.clear(); + } +} + +/*! + Sets the distance between the axis base line (including any outward ticks) and the tick labels. + \see setLabelPadding, setPadding +*/ +void QCPAxis::setTickLabelPadding(int padding) +{ + if (mAxisPainter->tickLabelPadding != padding) + { + mAxisPainter->tickLabelPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the font of the tick labels. + + \see setTickLabels, setTickLabelColor +*/ +void QCPAxis::setTickLabelFont(const QFont &font) +{ + if (font != mTickLabelFont) + { + mTickLabelFont = font; + mCachedMarginValid = false; + } +} + +/*! + Sets the color of the tick labels. + + \see setTickLabels, setTickLabelFont +*/ +void QCPAxis::setTickLabelColor(const QColor &color) +{ + mTickLabelColor = color; +} + +/*! + Sets the rotation of the tick labels. If \a degrees is zero, the labels are drawn normally. Else, + the tick labels are drawn rotated by \a degrees clockwise. The specified angle is bound to values + from -90 to 90 degrees. + + If \a degrees is exactly -90, 0 or 90, the tick labels are centered on the tick coordinate. For + other angles, the label is drawn with an offset such that it seems to point toward or away from + the tick mark. +*/ +void QCPAxis::setTickLabelRotation(double degrees) +{ + if (!qFuzzyIsNull(degrees-mAxisPainter->tickLabelRotation)) + { + mAxisPainter->tickLabelRotation = qBound(-90.0, degrees, 90.0); + mCachedMarginValid = false; + } +} + +/*! + Sets whether the tick labels (numbers) shall appear inside or outside the axis rect. + + The usual and default setting is \ref lsOutside. Very compact plots sometimes require tick labels + to be inside the axis rect, to save space. If \a side is set to \ref lsInside, the tick labels + appear on the inside are additionally clipped to the axis rect. +*/ +void QCPAxis::setTickLabelSide(LabelSide side) +{ + mAxisPainter->tickLabelSide = side; + mCachedMarginValid = false; +} + +/*! + Sets the number format for the numbers in tick labels. This \a formatCode is an extended version + of the format code used e.g. by QString::number() and QLocale::toString(). For reference about + that, see the "Argument Formats" section in the detailed description of the QString class. + + \a formatCode is a string of one, two or three characters. The first character is identical to + the normal format code used by Qt. In short, this means: 'e'/'E' scientific format, 'f' fixed + format, 'g'/'G' scientific or fixed, whichever is shorter. + + The second and third characters are optional and specific to QCustomPlot:\n + If the first char was 'e' or 'g', numbers are/might be displayed in the scientific format, e.g. + "5.5e9", which is ugly in a plot. So when the second char of \a formatCode is set to 'b' (for + "beautiful"), those exponential numbers are formatted in a more natural way, i.e. "5.5 + [multiplication sign] 10 [superscript] 9". By default, the multiplication sign is a centered dot. + If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can + be set to 'c'. The inserted multiplication signs are the UTF-8 characters 215 (0xD7) for the + cross and 183 (0xB7) for the dot. + + Examples for \a formatCode: + \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large, + normal scientific format is used + \li \c gb If number is small, fixed format is used, if number is large, scientific format is used with + beautifully typeset decimal powers and a dot as multiplication sign + \li \c ebc All numbers are in scientific format with beautifully typeset decimal power and a cross as + multiplication sign + \li \c fb illegal format code, since fixed format doesn't support (or need) beautifully typeset decimal + powers. Format code will be reduced to 'f'. + \li \c hello illegal format code, since first char is not 'e', 'E', 'f', 'g' or 'G'. Current format + code will not be changed. +*/ +void QCPAxis::setNumberFormat(const QString &formatCode) +{ + if (formatCode.isEmpty()) + { + qDebug() << Q_FUNC_INFO << "Passed formatCode is empty"; + return; + } + mCachedMarginValid = false; + + // interpret first char as number format char: + QString allowedFormatChars(QLatin1String("eEfgG")); + if (allowedFormatChars.contains(formatCode.at(0))) + { + mNumberFormatChar = QLatin1Char(formatCode.at(0).toLatin1()); + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (first char not in 'eEfgG'):" << formatCode; + return; + } + if (formatCode.length() < 2) + { + mNumberBeautifulPowers = false; + mAxisPainter->numberMultiplyCross = false; + return; + } + + // interpret second char as indicator for beautiful decimal powers: + if (formatCode.at(1) == QLatin1Char('b') && (mNumberFormatChar == QLatin1Char('e') || mNumberFormatChar == QLatin1Char('g'))) + { + mNumberBeautifulPowers = true; + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode; + return; + } + if (formatCode.length() < 3) + { + mAxisPainter->numberMultiplyCross = false; + return; + } + + // interpret third char as indicator for dot or cross multiplication symbol: + if (formatCode.at(2) == QLatin1Char('c')) + { + mAxisPainter->numberMultiplyCross = true; + } else if (formatCode.at(2) == QLatin1Char('d')) + { + mAxisPainter->numberMultiplyCross = false; + } else + { + qDebug() << Q_FUNC_INFO << "Invalid number format code (third char neither 'c' nor 'd'):" << formatCode; + return; + } +} + +/*! + Sets the precision of the tick label numbers. See QLocale::toString(double i, char f, int prec) + for details. The effect of precisions are most notably for number Formats starting with 'e', see + \ref setNumberFormat +*/ +void QCPAxis::setNumberPrecision(int precision) +{ + if (mNumberPrecision != precision) + { + mNumberPrecision = precision; + mCachedMarginValid = false; + } +} + +/*! + Sets the length of the ticks in pixels. \a inside is the length the ticks will reach inside the + plot and \a outside is the length they will reach outside the plot. If \a outside is greater than + zero, the tick labels and axis label will increase their distance to the axis accordingly, so + they won't collide with the ticks. + + \see setSubTickLength, setTickLengthIn, setTickLengthOut +*/ +void QCPAxis::setTickLength(int inside, int outside) +{ + setTickLengthIn(inside); + setTickLengthOut(outside); +} + +/*! + Sets the length of the inward ticks in pixels. \a inside is the length the ticks will reach + inside the plot. + + \see setTickLengthOut, setTickLength, setSubTickLength +*/ +void QCPAxis::setTickLengthIn(int inside) +{ + if (mAxisPainter->tickLengthIn != inside) + { + mAxisPainter->tickLengthIn = inside; + } +} + +/*! + Sets the length of the outward ticks in pixels. \a outside is the length the ticks will reach + outside the plot. If \a outside is greater than zero, the tick labels and axis label will + increase their distance to the axis accordingly, so they won't collide with the ticks. + + \see setTickLengthIn, setTickLength, setSubTickLength +*/ +void QCPAxis::setTickLengthOut(int outside) +{ + if (mAxisPainter->tickLengthOut != outside) + { + mAxisPainter->tickLengthOut = outside; + mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets whether sub tick marks are displayed. + + Sub ticks are only potentially visible if (major) ticks are also visible (see \ref setTicks) + + \see setTicks +*/ +void QCPAxis::setSubTicks(bool show) +{ + if (mSubTicks != show) + { + mSubTicks = show; + mCachedMarginValid = false; + } +} + +/*! + Sets the length of the subticks in pixels. \a inside is the length the subticks will reach inside + the plot and \a outside is the length they will reach outside the plot. If \a outside is greater + than zero, the tick labels and axis label will increase their distance to the axis accordingly, + so they won't collide with the ticks. + + \see setTickLength, setSubTickLengthIn, setSubTickLengthOut +*/ +void QCPAxis::setSubTickLength(int inside, int outside) +{ + setSubTickLengthIn(inside); + setSubTickLengthOut(outside); +} + +/*! + Sets the length of the inward subticks in pixels. \a inside is the length the subticks will reach inside + the plot. + + \see setSubTickLengthOut, setSubTickLength, setTickLength +*/ +void QCPAxis::setSubTickLengthIn(int inside) +{ + if (mAxisPainter->subTickLengthIn != inside) + { + mAxisPainter->subTickLengthIn = inside; + } +} + +/*! + Sets the length of the outward subticks in pixels. \a outside is the length the subticks will reach + outside the plot. If \a outside is greater than zero, the tick labels will increase their + distance to the axis accordingly, so they won't collide with the ticks. + + \see setSubTickLengthIn, setSubTickLength, setTickLength +*/ +void QCPAxis::setSubTickLengthOut(int outside) +{ + if (mAxisPainter->subTickLengthOut != outside) + { + mAxisPainter->subTickLengthOut = outside; + mCachedMarginValid = false; // only outside tick length can change margin + } +} + +/*! + Sets the pen, the axis base line is drawn with. + + \see setTickPen, setSubTickPen +*/ +void QCPAxis::setBasePen(const QPen &pen) +{ + mBasePen = pen; +} + +/*! + Sets the pen, tick marks will be drawn with. + + \see setTickLength, setBasePen +*/ +void QCPAxis::setTickPen(const QPen &pen) +{ + mTickPen = pen; +} + +/*! + Sets the pen, subtick marks will be drawn with. + + \see setSubTickCount, setSubTickLength, setBasePen +*/ +void QCPAxis::setSubTickPen(const QPen &pen) +{ + mSubTickPen = pen; +} + +/*! + Sets the font of the axis label. + + \see setLabelColor +*/ +void QCPAxis::setLabelFont(const QFont &font) +{ + if (mLabelFont != font) + { + mLabelFont = font; + mCachedMarginValid = false; + } +} + +/*! + Sets the color of the axis label. + + \see setLabelFont +*/ +void QCPAxis::setLabelColor(const QColor &color) +{ + mLabelColor = color; +} + +/*! + Sets the text of the axis label that will be shown below/above or next to the axis, depending on + its orientation. To disable axis labels, pass an empty string as \a str. +*/ +void QCPAxis::setLabel(const QString &str) +{ + if (mLabel != str) + { + mLabel = str; + mCachedMarginValid = false; + } +} + +/*! + Sets the distance between the tick labels and the axis label. + + \see setTickLabelPadding, setPadding +*/ +void QCPAxis::setLabelPadding(int padding) +{ + if (mAxisPainter->labelPadding != padding) + { + mAxisPainter->labelPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the padding of the axis. + + When \ref QCPAxisRect::setAutoMargins is enabled, the padding is the additional outer most space, + that is left blank. + + The axis padding has no meaning if \ref QCPAxisRect::setAutoMargins is disabled. + + \see setLabelPadding, setTickLabelPadding +*/ +void QCPAxis::setPadding(int padding) +{ + if (mPadding != padding) + { + mPadding = padding; + mCachedMarginValid = false; + } +} + +/*! + Sets the offset the axis has to its axis rect side. + + If an axis rect side has multiple axes and automatic margin calculation is enabled for that side, + only the offset of the inner most axis has meaning (even if it is set to be invisible). The + offset of the other, outer axes is controlled automatically, to place them at appropriate + positions. +*/ +void QCPAxis::setOffset(int offset) +{ + mAxisPainter->offset = offset; +} + +/*! + Sets the font that is used for tick labels when they are selected. + + \see setTickLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickLabelFont(const QFont &font) +{ + if (font != mSelectedTickLabelFont) + { + mSelectedTickLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts + } +} + +/*! + Sets the font that is used for the axis label when it is selected. + + \see setLabelFont, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedLabelFont(const QFont &font) +{ + mSelectedLabelFont = font; + // don't set mCachedMarginValid to false here because margin calculation is always done with non-selected fonts +} + +/*! + Sets the color that is used for tick labels when they are selected. + + \see setTickLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickLabelColor(const QColor &color) +{ + if (color != mSelectedTickLabelColor) + { + mSelectedTickLabelColor = color; + } +} + +/*! + Sets the color that is used for the axis label when it is selected. + + \see setLabelColor, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedLabelColor(const QColor &color) +{ + mSelectedLabelColor = color; +} + +/*! + Sets the pen that is used to draw the axis base line when selected. + + \see setBasePen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedBasePen(const QPen &pen) +{ + mSelectedBasePen = pen; +} + +/*! + Sets the pen that is used to draw the (major) ticks when selected. + + \see setTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedTickPen(const QPen &pen) +{ + mSelectedTickPen = pen; +} + +/*! + Sets the pen that is used to draw the subticks when selected. + + \see setSubTickPen, setSelectableParts, setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAxis::setSelectedSubTickPen(const QPen &pen) +{ + mSelectedSubTickPen = pen; +} + +/*! + Sets the style for the lower axis ending. See the documentation of QCPLineEnding for available + styles. + + For horizontal axes, this method refers to the left ending, for vertical axes the bottom ending. + Note that this meaning does not change when the axis range is reversed with \ref + setRangeReversed. + + \see setUpperEnding +*/ +void QCPAxis::setLowerEnding(const QCPLineEnding &ending) +{ + mAxisPainter->lowerEnding = ending; +} + +/*! + Sets the style for the upper axis ending. See the documentation of QCPLineEnding for available + styles. + + For horizontal axes, this method refers to the right ending, for vertical axes the top ending. + Note that this meaning does not change when the axis range is reversed with \ref + setRangeReversed. + + \see setLowerEnding +*/ +void QCPAxis::setUpperEnding(const QCPLineEnding &ending) +{ + mAxisPainter->upperEnding = ending; +} + +/*! + If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper + bounds of the range. The range is simply moved by \a diff. + + If the scale type is \ref stLogarithmic, the range bounds are multiplied by \a diff. This + corresponds to an apparent "linear" move in logarithmic scaling by a distance of log(diff). +*/ +void QCPAxis::moveRange(double diff) +{ + QCPRange oldRange = mRange; + if (mScaleType == stLinear) + { + mRange.lower += diff; + mRange.upper += diff; + } else // mScaleType == stLogarithmic + { + mRange.lower *= diff; + mRange.upper *= diff; + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Scales the range of this axis by \a factor around the center of the current axis range. For + example, if \a factor is 2.0, then the axis range will double its size, and the point at the axis + range center won't have changed its position in the QCustomPlot widget (i.e. coordinates around + the center will have moved symmetrically closer). + + If you wish to scale around a different coordinate than the current axis range center, use the + overload \ref scaleRange(double factor, double center). +*/ +void QCPAxis::scaleRange(double factor) +{ + scaleRange(factor, range().center()); +} + +/*! \overload + + Scales the range of this axis by \a factor around the coordinate \a center. For example, if \a + factor is 2.0, \a center is 1.0, then the axis range will double its size, and the point at + coordinate 1.0 won't have changed its position in the QCustomPlot widget (i.e. coordinates + around 1.0 will have moved symmetrically closer to 1.0). + + \see scaleRange(double factor) +*/ +void QCPAxis::scaleRange(double factor, double center) +{ + QCPRange oldRange = mRange; + if (mScaleType == stLinear) + { + QCPRange newRange; + newRange.lower = (mRange.lower-center)*factor + center; + newRange.upper = (mRange.upper-center)*factor + center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLinScale(); + } else // mScaleType == stLogarithmic + { + if ((mRange.upper < 0 && center < 0) || (mRange.upper > 0 && center > 0)) // make sure center has same sign as range + { + QCPRange newRange; + newRange.lower = qPow(mRange.lower/center, factor)*center; + newRange.upper = qPow(mRange.upper/center, factor)*center; + if (QCPRange::validRange(newRange)) + mRange = newRange.sanitizedForLogScale(); + } else + qDebug() << Q_FUNC_INFO << "Center of scaling operation doesn't lie in same logarithmic sign domain as range:" << center; + } + emit rangeChanged(mRange); + emit rangeChanged(mRange, oldRange); +} + +/*! + Scales the range of this axis to have a certain scale \a ratio to \a otherAxis. The scaling will + be done around the center of the current axis range. + + For example, if \a ratio is 1, this axis is the \a yAxis and \a otherAxis is \a xAxis, graphs + plotted with those axes will appear in a 1:1 aspect ratio, independent of the aspect ratio the + axis rect has. + + This is an operation that changes the range of this axis once, it doesn't fix the scale ratio + indefinitely. Note that calling this function in the constructor of the QCustomPlot's parent + won't have the desired effect, since the widget dimensions aren't defined yet, and a resizeEvent + will follow. +*/ +void QCPAxis::setScaleRatio(const QCPAxis *otherAxis, double ratio) +{ + int otherPixelSize, ownPixelSize; + + if (otherAxis->orientation() == Qt::Horizontal) + otherPixelSize = otherAxis->axisRect()->width(); + else + otherPixelSize = otherAxis->axisRect()->height(); + + if (orientation() == Qt::Horizontal) + ownPixelSize = axisRect()->width(); + else + ownPixelSize = axisRect()->height(); + + double newRangeSize = ratio*otherAxis->range().size()*ownPixelSize/(double)otherPixelSize; + setRange(range().center(), newRangeSize, Qt::AlignCenter); +} + +/*! + Changes the axis range such that all plottables associated with this axis are fully visible in + that dimension. + + \see QCPAbstractPlottable::rescaleAxes, QCustomPlot::rescaleAxes +*/ +void QCPAxis::rescale(bool onlyVisiblePlottables) +{ + QList p = plottables(); + QCPRange newRange; + bool haveRange = false; + for (int i=0; irealVisibility() && onlyVisiblePlottables) + continue; + QCPRange plottableRange; + bool currentFoundRange; + QCP::SignDomain signDomain = QCP::sdBoth; + if (mScaleType == stLogarithmic) + signDomain = (mRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); + if (p.at(i)->keyAxis() == this) + plottableRange = p.at(i)->getKeyRange(currentFoundRange, signDomain); + else + plottableRange = p.at(i)->getValueRange(currentFoundRange, signDomain); + if (currentFoundRange) + { + if (!haveRange) + newRange = plottableRange; + else + newRange.expand(plottableRange); + haveRange = true; + } + } + if (haveRange) + { + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (mScaleType == stLinear) + { + newRange.lower = center-mRange.size()/2.0; + newRange.upper = center+mRange.size()/2.0; + } else // mScaleType == stLogarithmic + { + newRange.lower = center/qSqrt(mRange.upper/mRange.lower); + newRange.upper = center*qSqrt(mRange.upper/mRange.lower); + } + } + setRange(newRange); + } +} + +/*! + Transforms \a value, in pixel coordinates of the QCustomPlot widget, to axis coordinates. +*/ +double QCPAxis::pixelToCoord(double value) const +{ + if (orientation() == Qt::Horizontal) + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (value-mAxisRect->left())/(double)mAxisRect->width()*mRange.size()+mRange.lower; + else + return -(value-mAxisRect->left())/(double)mAxisRect->width()*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return qPow(mRange.upper/mRange.lower, (value-mAxisRect->left())/(double)mAxisRect->width())*mRange.lower; + else + return qPow(mRange.upper/mRange.lower, (mAxisRect->left()-value)/(double)mAxisRect->width())*mRange.upper; + } + } else // orientation() == Qt::Vertical + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (mAxisRect->bottom()-value)/(double)mAxisRect->height()*mRange.size()+mRange.lower; + else + return -(mAxisRect->bottom()-value)/(double)mAxisRect->height()*mRange.size()+mRange.upper; + } else // mScaleType == stLogarithmic + { + if (!mRangeReversed) + return qPow(mRange.upper/mRange.lower, (mAxisRect->bottom()-value)/(double)mAxisRect->height())*mRange.lower; + else + return qPow(mRange.upper/mRange.lower, (value-mAxisRect->bottom())/(double)mAxisRect->height())*mRange.upper; + } + } +} + +/*! + Transforms \a value, in coordinates of the axis, to pixel coordinates of the QCustomPlot widget. +*/ +double QCPAxis::coordToPixel(double value) const +{ + if (orientation() == Qt::Horizontal) + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return (value-mRange.lower)/mRange.size()*mAxisRect->width()+mAxisRect->left(); + else + return (mRange.upper-value)/mRange.size()*mAxisRect->width()+mAxisRect->left(); + } else // mScaleType == stLogarithmic + { + if (value >= 0 && mRange.upper < 0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->right()+200 : mAxisRect->left()-200; + else if (value <= 0 && mRange.upper > 0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->left()-200 : mAxisRect->right()+200; + else + { + if (!mRangeReversed) + return qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); + else + return qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left(); + } + } + } else // orientation() == Qt::Vertical + { + if (mScaleType == stLinear) + { + if (!mRangeReversed) + return mAxisRect->bottom()-(value-mRange.lower)/mRange.size()*mAxisRect->height(); + else + return mAxisRect->bottom()-(mRange.upper-value)/mRange.size()*mAxisRect->height(); + } else // mScaleType == stLogarithmic + { + if (value >= 0 && mRange.upper < 0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->top()-200 : mAxisRect->bottom()+200; + else if (value <= 0 && mRange.upper > 0) // invalid value for logarithmic scale, just draw it outside visible range + return !mRangeReversed ? mAxisRect->bottom()+200 : mAxisRect->top()-200; + else + { + if (!mRangeReversed) + return mAxisRect->bottom()-qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->height(); + else + return mAxisRect->bottom()-qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->height(); + } + } + } +} + +/*! + Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function + is independent of the user-selectable parts defined with \ref setSelectableParts. Further, this + function does not change the current selection state of the axis. + + If the axis is not visible (\ref setVisible), this function always returns \ref spNone. + + \see setSelectedParts, setSelectableParts, QCustomPlot::setInteractions +*/ +QCPAxis::SelectablePart QCPAxis::getPartAt(const QPointF &pos) const +{ + if (!mVisible) + return spNone; + + if (mAxisPainter->axisSelectionBox().contains(pos.toPoint())) + return spAxis; + else if (mAxisPainter->tickLabelsSelectionBox().contains(pos.toPoint())) + return spTickLabels; + else if (mAxisPainter->labelSelectionBox().contains(pos.toPoint())) + return spAxisLabel; + else + return spNone; +} + +/* inherits documentation from base class */ +double QCPAxis::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mParentPlot) return -1; + SelectablePart part = getPartAt(pos); + if ((onlySelectable && !mSelectableParts.testFlag(part)) || part == spNone) + return -1; + + if (details) + details->setValue(part); + return mParentPlot->selectionTolerance()*0.99; +} + +/*! + Returns a list of all the plottables that have this axis as key or value axis. + + If you are only interested in plottables of type QCPGraph, see \ref graphs. + + \see graphs, items +*/ +QList QCPAxis::plottables() const +{ + QList result; + if (!mParentPlot) return result; + + for (int i=0; imPlottables.size(); ++i) + { + if (mParentPlot->mPlottables.at(i)->keyAxis() == this ||mParentPlot->mPlottables.at(i)->valueAxis() == this) + result.append(mParentPlot->mPlottables.at(i)); + } + return result; +} + +/*! + Returns a list of all the graphs that have this axis as key or value axis. + + \see plottables, items +*/ +QList QCPAxis::graphs() const +{ + QList result; + if (!mParentPlot) return result; + + for (int i=0; imGraphs.size(); ++i) + { + if (mParentPlot->mGraphs.at(i)->keyAxis() == this || mParentPlot->mGraphs.at(i)->valueAxis() == this) + result.append(mParentPlot->mGraphs.at(i)); + } + return result; +} + +/*! + Returns a list of all the items that are associated with this axis. An item is considered + associated with an axis if at least one of its positions uses the axis as key or value axis. + + \see plottables, graphs +*/ +QList QCPAxis::items() const +{ + QList result; + if (!mParentPlot) return result; + + for (int itemId=0; itemIdmItems.size(); ++itemId) + { + QList positions = mParentPlot->mItems.at(itemId)->positions(); + for (int posId=0; posIdkeyAxis() == this || positions.at(posId)->valueAxis() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + break; + } + } + } + return result; +} + +/*! + Transforms a margin side to the logically corresponding axis type. (QCP::msLeft to + QCPAxis::atLeft, QCP::msRight to QCPAxis::atRight, etc.) +*/ +QCPAxis::AxisType QCPAxis::marginSideToAxisType(QCP::MarginSide side) +{ + switch (side) + { + case QCP::msLeft: return atLeft; + case QCP::msRight: return atRight; + case QCP::msTop: return atTop; + case QCP::msBottom: return atBottom; + default: break; + } + qDebug() << Q_FUNC_INFO << "Invalid margin side passed:" << (int)side; + return atLeft; +} + +/*! + Returns the axis type that describes the opposite axis of an axis with the specified \a type. +*/ +QCPAxis::AxisType QCPAxis::opposite(QCPAxis::AxisType type) +{ + switch (type) + { + case atLeft: return atRight; break; + case atRight: return atLeft; break; + case atBottom: return atTop; break; + case atTop: return atBottom; break; + default: qDebug() << Q_FUNC_INFO << "invalid axis type"; return atLeft; break; + } +} + +/* inherits documentation from base class */ +void QCPAxis::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + SelectablePart part = details.value(); + if (mSelectableParts.testFlag(part)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(additive ? mSelectedParts^part : part); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAxis::deselectEvent(bool *selectionStateChanged) +{ + SelectableParts selBefore = mSelectedParts; + setSelectedParts(mSelectedParts & ~mSelectableParts); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing axis lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased +*/ +void QCPAxis::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeAxes); +} + +/*! \internal + + Draws the axis with the specified \a painter, using the internal QCPAxisPainterPrivate instance. + + \seebaseclassmethod +*/ +void QCPAxis::draw(QCPPainter *painter) +{ + QVector subTickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickLabels; // the final vector passed to QCPAxisPainter + tickPositions.reserve(mTickVector.size()); + tickLabels.reserve(mTickVector.size()); + subTickPositions.reserve(mSubTickVector.size()); + + if (mTicks) + { + for (int i=0; itype = mAxisType; + mAxisPainter->basePen = getBasePen(); + mAxisPainter->labelFont = getLabelFont(); + mAxisPainter->labelColor = getLabelColor(); + mAxisPainter->label = mLabel; + mAxisPainter->substituteExponent = mNumberBeautifulPowers; + mAxisPainter->tickPen = getTickPen(); + mAxisPainter->subTickPen = getSubTickPen(); + mAxisPainter->tickLabelFont = getTickLabelFont(); + mAxisPainter->tickLabelColor = getTickLabelColor(); + mAxisPainter->axisRect = mAxisRect->rect(); + mAxisPainter->viewportRect = mParentPlot->viewport(); + mAxisPainter->abbreviateDecimalPowers = mScaleType == stLogarithmic; + mAxisPainter->reversedEndings = mRangeReversed; + mAxisPainter->tickPositions = tickPositions; + mAxisPainter->tickLabels = tickLabels; + mAxisPainter->subTickPositions = subTickPositions; + mAxisPainter->draw(painter); +} + +/*! \internal + + Prepares the internal tick vector, sub tick vector and tick label vector. This is done by calling + QCPAxisTicker::generate on the currently installed ticker. + + If a change in the label text/count is detected, the cached axis margin is invalidated to make + sure the next margin calculation recalculates the label sizes and returns an up-to-date value. +*/ +void QCPAxis::setupTickVectors() +{ + if (!mParentPlot) return; + if ((!mTicks && !mTickLabels && !mGrid->visible()) || mRange.size() <= 0) return; + + QVector oldLabels = mTickVectorLabels; + mTicker->generate(mRange, mParentPlot->locale(), mNumberFormatChar, mNumberPrecision, mTickVector, mSubTicks ? &mSubTickVector : 0, mTickLabels ? &mTickVectorLabels : 0); + mCachedMarginValid &= mTickVectorLabels == oldLabels; // if labels have changed, margin might have changed, too +} + +/*! \internal + + Returns the pen that is used to draw the axis base line. Depending on the selection state, this + is either mSelectedBasePen or mBasePen. +*/ +QPen QCPAxis::getBasePen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedBasePen : mBasePen; +} + +/*! \internal + + Returns the pen that is used to draw the (major) ticks. Depending on the selection state, this + is either mSelectedTickPen or mTickPen. +*/ +QPen QCPAxis::getTickPen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedTickPen : mTickPen; +} + +/*! \internal + + Returns the pen that is used to draw the subticks. Depending on the selection state, this + is either mSelectedSubTickPen or mSubTickPen. +*/ +QPen QCPAxis::getSubTickPen() const +{ + return mSelectedParts.testFlag(spAxis) ? mSelectedSubTickPen : mSubTickPen; +} + +/*! \internal + + Returns the font that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelFont or mTickLabelFont. +*/ +QFont QCPAxis::getTickLabelFont() const +{ + return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelFont : mTickLabelFont; +} + +/*! \internal + + Returns the font that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelFont or mLabelFont. +*/ +QFont QCPAxis::getLabelFont() const +{ + return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelFont : mLabelFont; +} + +/*! \internal + + Returns the color that is used to draw the tick labels. Depending on the selection state, this + is either mSelectedTickLabelColor or mTickLabelColor. +*/ +QColor QCPAxis::getTickLabelColor() const +{ + return mSelectedParts.testFlag(spTickLabels) ? mSelectedTickLabelColor : mTickLabelColor; +} + +/*! \internal + + Returns the color that is used to draw the axis label. Depending on the selection state, this + is either mSelectedLabelColor or mLabelColor. +*/ +QColor QCPAxis::getLabelColor() const +{ + return mSelectedParts.testFlag(spAxisLabel) ? mSelectedLabelColor : mLabelColor; +} + +/*! \internal + + Returns the appropriate outward margin for this axis. It is needed if \ref + QCPAxisRect::setAutoMargins is set to true on the parent axis rect. An axis with axis type \ref + atLeft will return an appropriate left margin, \ref atBottom will return an appropriate bottom + margin and so forth. For the calculation, this function goes through similar steps as \ref draw, + so changing one function likely requires the modification of the other one as well. + + The margin consists of the outward tick length, tick label padding, tick label size, label + padding, label size, and padding. + + The margin is cached internally, so repeated calls while leaving the axis range, fonts, etc. + unchanged are very fast. +*/ +int QCPAxis::calculateMargin() +{ + if (!mVisible) // if not visible, directly return 0, don't cache 0 because we can't react to setVisible in QCPAxis + return 0; + + if (mCachedMarginValid) + return mCachedMargin; + + // run through similar steps as QCPAxis::draw, and calculate margin needed to fit axis and its labels + int margin = 0; + + QVector tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter + QVector tickLabels; // the final vector passed to QCPAxisPainter + tickPositions.reserve(mTickVector.size()); + tickLabels.reserve(mTickVector.size()); + + if (mTicks) + { + for (int i=0; itype = mAxisType; + mAxisPainter->labelFont = getLabelFont(); + mAxisPainter->label = mLabel; + mAxisPainter->tickLabelFont = mTickLabelFont; + mAxisPainter->axisRect = mAxisRect->rect(); + mAxisPainter->viewportRect = mParentPlot->viewport(); + mAxisPainter->tickPositions = tickPositions; + mAxisPainter->tickLabels = tickLabels; + margin += mAxisPainter->size(); + margin += mPadding; + + mCachedMargin = margin; + mCachedMarginValid = true; + return margin; +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAxis::selectionCategory() const +{ + return QCP::iSelectAxes; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisPainterPrivate +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxisPainterPrivate + + \internal + \brief (Private) + + This is a private class and not part of the public QCustomPlot interface. + + It is used by QCPAxis to do the low-level drawing of axis backbone, tick marks, tick labels and + axis label. It also buffers the labels to reduce replot times. The parameters are configured by + directly accessing the public member variables. +*/ + +/*! + Constructs a QCPAxisPainterPrivate instance. Make sure to not create a new instance on every + redraw, to utilize the caching mechanisms. +*/ +QCPAxisPainterPrivate::QCPAxisPainterPrivate(QCustomPlot *parentPlot) : + type(QCPAxis::atLeft), + basePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + lowerEnding(QCPLineEnding::esNone), + upperEnding(QCPLineEnding::esNone), + labelPadding(0), + tickLabelPadding(0), + tickLabelRotation(0), + tickLabelSide(QCPAxis::lsOutside), + substituteExponent(true), + numberMultiplyCross(false), + tickLengthIn(5), + tickLengthOut(0), + subTickLengthIn(2), + subTickLengthOut(0), + tickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + subTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)), + offset(0), + abbreviateDecimalPowers(false), + reversedEndings(false), + mParentPlot(parentPlot), + mLabelCache(16) // cache at most 16 (tick) labels +{ +} + +QCPAxisPainterPrivate::~QCPAxisPainterPrivate() +{ +} + +/*! \internal + + Draws the axis with the specified \a painter. + + The selection boxes (mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox) are set + here, too. +*/ +void QCPAxisPainterPrivate::draw(QCPPainter *painter) +{ + QByteArray newHash = generateLabelParameterHash(); + if (newHash != mLabelParameterHash) + { + mLabelCache.clear(); + mLabelParameterHash = newHash; + } + + QPoint origin; + switch (type) + { + case QCPAxis::atLeft: origin = axisRect.bottomLeft() +QPoint(-offset, 0); break; + case QCPAxis::atRight: origin = axisRect.bottomRight()+QPoint(+offset, 0); break; + case QCPAxis::atTop: origin = axisRect.topLeft() +QPoint(0, -offset); break; + case QCPAxis::atBottom: origin = axisRect.bottomLeft() +QPoint(0, +offset); break; + } + + double xCor = 0, yCor = 0; // paint system correction, for pixel exact matches (affects baselines and ticks of top/right axes) + switch (type) + { + case QCPAxis::atTop: yCor = -1; break; + case QCPAxis::atRight: xCor = 1; break; + default: break; + } + int margin = 0; + // draw baseline: + QLineF baseLine; + painter->setPen(basePen); + if (QCPAxis::orientation(type) == Qt::Horizontal) + baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(axisRect.width()+xCor, yCor)); + else + baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(xCor, -axisRect.height()+yCor)); + if (reversedEndings) + baseLine = QLineF(baseLine.p2(), baseLine.p1()); // won't make a difference for line itself, but for line endings later + painter->drawLine(baseLine); + + // draw ticks: + if (!tickPositions.isEmpty()) + { + painter->setPen(tickPen); + int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; // direction of ticks ("inward" is right for left axis and left for right axis) + if (QCPAxis::orientation(type) == Qt::Horizontal) + { + for (int i=0; idrawLine(QLineF(tickPositions.at(i)+xCor, origin.y()-tickLengthOut*tickDir+yCor, tickPositions.at(i)+xCor, origin.y()+tickLengthIn*tickDir+yCor)); + } else + { + for (int i=0; idrawLine(QLineF(origin.x()-tickLengthOut*tickDir+xCor, tickPositions.at(i)+yCor, origin.x()+tickLengthIn*tickDir+xCor, tickPositions.at(i)+yCor)); + } + } + + // draw subticks: + if (!subTickPositions.isEmpty()) + { + painter->setPen(subTickPen); + // direction of ticks ("inward" is right for left axis and left for right axis) + int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; + if (QCPAxis::orientation(type) == Qt::Horizontal) + { + for (int i=0; idrawLine(QLineF(subTickPositions.at(i)+xCor, origin.y()-subTickLengthOut*tickDir+yCor, subTickPositions.at(i)+xCor, origin.y()+subTickLengthIn*tickDir+yCor)); + } else + { + for (int i=0; idrawLine(QLineF(origin.x()-subTickLengthOut*tickDir+xCor, subTickPositions.at(i)+yCor, origin.x()+subTickLengthIn*tickDir+xCor, subTickPositions.at(i)+yCor)); + } + } + margin += qMax(0, qMax(tickLengthOut, subTickLengthOut)); + + // draw axis base endings: + bool antialiasingBackup = painter->antialiasing(); + painter->setAntialiasing(true); // always want endings to be antialiased, even if base and ticks themselves aren't + painter->setBrush(QBrush(basePen.color())); + QCPVector2D baseLineVector(baseLine.dx(), baseLine.dy()); + if (lowerEnding.style() != QCPLineEnding::esNone) + lowerEnding.draw(painter, QCPVector2D(baseLine.p1())-baseLineVector.normalized()*lowerEnding.realLength()*(lowerEnding.inverted()?-1:1), -baseLineVector); + if (upperEnding.style() != QCPLineEnding::esNone) + upperEnding.draw(painter, QCPVector2D(baseLine.p2())+baseLineVector.normalized()*upperEnding.realLength()*(upperEnding.inverted()?-1:1), baseLineVector); + painter->setAntialiasing(antialiasingBackup); + + // tick labels: + QRect oldClipRect; + if (tickLabelSide == QCPAxis::lsInside) // if using inside labels, clip them to the axis rect + { + oldClipRect = painter->clipRegion().boundingRect(); + painter->setClipRect(axisRect); + } + QSize tickLabelsSize(0, 0); // size of largest tick label, for offset calculation of axis label + if (!tickLabels.isEmpty()) + { + if (tickLabelSide == QCPAxis::lsOutside) + margin += tickLabelPadding; + painter->setFont(tickLabelFont); + painter->setPen(QPen(tickLabelColor)); + const int maxLabelIndex = qMin(tickPositions.size(), tickLabels.size()); + int distanceToAxis = margin; + if (tickLabelSide == QCPAxis::lsInside) + distanceToAxis = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); + for (int i=0; isetClipRect(oldClipRect); + + // axis label: + QRect labelBounds; + if (!label.isEmpty()) + { + margin += labelPadding; + painter->setFont(labelFont); + painter->setPen(QPen(labelColor)); + labelBounds = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip, label); + if (type == QCPAxis::atLeft) + { + QTransform oldTransform = painter->transform(); + painter->translate((origin.x()-margin-labelBounds.height()), origin.y()); + painter->rotate(-90); + painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + painter->setTransform(oldTransform); + } + else if (type == QCPAxis::atRight) + { + QTransform oldTransform = painter->transform(); + painter->translate((origin.x()+margin+labelBounds.height()), origin.y()-axisRect.height()); + painter->rotate(90); + painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + painter->setTransform(oldTransform); + } + else if (type == QCPAxis::atTop) + painter->drawText(origin.x(), origin.y()-margin-labelBounds.height(), axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + else if (type == QCPAxis::atBottom) + painter->drawText(origin.x(), origin.y()+margin, axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label); + } + + // set selection boxes: + int selectionTolerance = 0; + if (mParentPlot) + selectionTolerance = mParentPlot->selectionTolerance(); + else + qDebug() << Q_FUNC_INFO << "mParentPlot is null"; + int selAxisOutSize = qMax(qMax(tickLengthOut, subTickLengthOut), selectionTolerance); + int selAxisInSize = selectionTolerance; + int selTickLabelSize; + int selTickLabelOffset; + if (tickLabelSide == QCPAxis::lsOutside) + { + selTickLabelSize = (QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); + selTickLabelOffset = qMax(tickLengthOut, subTickLengthOut)+tickLabelPadding; + } else + { + selTickLabelSize = -(QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width()); + selTickLabelOffset = -(qMax(tickLengthIn, subTickLengthIn)+tickLabelPadding); + } + int selLabelSize = labelBounds.height(); + int selLabelOffset = qMax(tickLengthOut, subTickLengthOut)+(!tickLabels.isEmpty() && tickLabelSide == QCPAxis::lsOutside ? tickLabelPadding+selTickLabelSize : 0)+labelPadding; + if (type == QCPAxis::atLeft) + { + mAxisSelectionBox.setCoords(origin.x()-selAxisOutSize, axisRect.top(), origin.x()+selAxisInSize, axisRect.bottom()); + mTickLabelsSelectionBox.setCoords(origin.x()-selTickLabelOffset-selTickLabelSize, axisRect.top(), origin.x()-selTickLabelOffset, axisRect.bottom()); + mLabelSelectionBox.setCoords(origin.x()-selLabelOffset-selLabelSize, axisRect.top(), origin.x()-selLabelOffset, axisRect.bottom()); + } else if (type == QCPAxis::atRight) + { + mAxisSelectionBox.setCoords(origin.x()-selAxisInSize, axisRect.top(), origin.x()+selAxisOutSize, axisRect.bottom()); + mTickLabelsSelectionBox.setCoords(origin.x()+selTickLabelOffset+selTickLabelSize, axisRect.top(), origin.x()+selTickLabelOffset, axisRect.bottom()); + mLabelSelectionBox.setCoords(origin.x()+selLabelOffset+selLabelSize, axisRect.top(), origin.x()+selLabelOffset, axisRect.bottom()); + } else if (type == QCPAxis::atTop) + { + mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisOutSize, axisRect.right(), origin.y()+selAxisInSize); + mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()-selTickLabelOffset-selTickLabelSize, axisRect.right(), origin.y()-selTickLabelOffset); + mLabelSelectionBox.setCoords(axisRect.left(), origin.y()-selLabelOffset-selLabelSize, axisRect.right(), origin.y()-selLabelOffset); + } else if (type == QCPAxis::atBottom) + { + mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisInSize, axisRect.right(), origin.y()+selAxisOutSize); + mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()+selTickLabelOffset+selTickLabelSize, axisRect.right(), origin.y()+selTickLabelOffset); + mLabelSelectionBox.setCoords(axisRect.left(), origin.y()+selLabelOffset+selLabelSize, axisRect.right(), origin.y()+selLabelOffset); + } + mAxisSelectionBox = mAxisSelectionBox.normalized(); + mTickLabelsSelectionBox = mTickLabelsSelectionBox.normalized(); + mLabelSelectionBox = mLabelSelectionBox.normalized(); + // draw hitboxes for debug purposes: + //painter->setBrush(Qt::NoBrush); + //painter->drawRects(QVector() << mAxisSelectionBox << mTickLabelsSelectionBox << mLabelSelectionBox); +} + +/*! \internal + + Returns the size ("margin" in QCPAxisRect context, so measured perpendicular to the axis backbone + direction) needed to fit the axis. +*/ +int QCPAxisPainterPrivate::size() const +{ + int result = 0; + + // get length of tick marks pointing outwards: + if (!tickPositions.isEmpty()) + result += qMax(0, qMax(tickLengthOut, subTickLengthOut)); + + // calculate size of tick labels: + if (tickLabelSide == QCPAxis::lsOutside) + { + QSize tickLabelsSize(0, 0); + if (!tickLabels.isEmpty()) + { + for (int i=0; ibufferDevicePixelRatio())); + result.append(QByteArray::number(tickLabelRotation)); + result.append(QByteArray::number((int)tickLabelSide)); + result.append(QByteArray::number((int)substituteExponent)); + result.append(QByteArray::number((int)numberMultiplyCross)); + result.append(tickLabelColor.name().toLatin1()+QByteArray::number(tickLabelColor.alpha(), 16)); + result.append(tickLabelFont.toString().toLatin1()); + return result; +} + +/*! \internal + + Draws a single tick label with the provided \a painter, utilizing the internal label cache to + significantly speed up drawing of labels that were drawn in previous calls. The tick label is + always bound to an axis, the distance to the axis is controllable via \a distanceToAxis in + pixels. The pixel position in the axis direction is passed in the \a position parameter. Hence + for the bottom axis, \a position would indicate the horizontal pixel position (not coordinate), + at which the label should be drawn. + + In order to later draw the axis label in a place that doesn't overlap with the tick labels, the + largest tick label size is needed. This is acquired by passing a \a tickLabelsSize to the \ref + drawTickLabel calls during the process of drawing all tick labels of one axis. In every call, \a + tickLabelsSize is expanded, if the drawn label exceeds the value \a tickLabelsSize currently + holds. + + The label is drawn with the font and pen that are currently set on the \a painter. To draw + superscripted powers, the font is temporarily made smaller by a fixed factor (see \ref + getTickLabelData). +*/ +void QCPAxisPainterPrivate::placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize) +{ + // warning: if you change anything here, also adapt getMaxTickLabelSize() accordingly! + if (text.isEmpty()) return; + QSize finalSize; + QPointF labelAnchor; + switch (type) + { + case QCPAxis::atLeft: labelAnchor = QPointF(axisRect.left()-distanceToAxis-offset, position); break; + case QCPAxis::atRight: labelAnchor = QPointF(axisRect.right()+distanceToAxis+offset, position); break; + case QCPAxis::atTop: labelAnchor = QPointF(position, axisRect.top()-distanceToAxis-offset); break; + case QCPAxis::atBottom: labelAnchor = QPointF(position, axisRect.bottom()+distanceToAxis+offset); break; + } + if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && !painter->modes().testFlag(QCPPainter::pmNoCaching)) // label caching enabled + { + CachedLabel *cachedLabel = mLabelCache.take(text); // attempt to get label from cache + if (!cachedLabel) // no cached label existed, create it + { + cachedLabel = new CachedLabel; + TickLabelData labelData = getTickLabelData(painter->font(), text); + cachedLabel->offset = getTickLabelDrawOffset(labelData)+labelData.rotatedTotalBounds.topLeft(); + if (!qFuzzyCompare(1.0, mParentPlot->bufferDevicePixelRatio())) + { + cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()*mParentPlot->bufferDevicePixelRatio()); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatio()); +#endif + } else + cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()); + cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()); + cachedLabel->pixmap.fill(Qt::transparent); + QCPPainter cachePainter(&cachedLabel->pixmap); + cachePainter.setPen(painter->pen()); + drawTickLabel(&cachePainter, -labelData.rotatedTotalBounds.topLeft().x(), -labelData.rotatedTotalBounds.topLeft().y(), labelData); + } + // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): + bool labelClippedByBorder = false; + if (tickLabelSide == QCPAxis::lsOutside) + { + if (QCPAxis::orientation(type) == Qt::Horizontal) + labelClippedByBorder = labelAnchor.x()+cachedLabel->offset.x()+cachedLabel->pixmap.width()/mParentPlot->bufferDevicePixelRatio() > viewportRect.right() || labelAnchor.x()+cachedLabel->offset.x() < viewportRect.left(); + else + labelClippedByBorder = labelAnchor.y()+cachedLabel->offset.y()+cachedLabel->pixmap.height()/mParentPlot->bufferDevicePixelRatio() > viewportRect.bottom() || labelAnchor.y()+cachedLabel->offset.y() < viewportRect.top(); + } + if (!labelClippedByBorder) + { + painter->drawPixmap(labelAnchor+cachedLabel->offset, cachedLabel->pixmap); + finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); + } + mLabelCache.insert(text, cachedLabel); // return label to cache or insert for the first time if newly created + } else // label caching disabled, draw text directly on surface: + { + TickLabelData labelData = getTickLabelData(painter->font(), text); + QPointF finalPosition = labelAnchor + getTickLabelDrawOffset(labelData); + // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels): + bool labelClippedByBorder = false; + if (tickLabelSide == QCPAxis::lsOutside) + { + if (QCPAxis::orientation(type) == Qt::Horizontal) + labelClippedByBorder = finalPosition.x()+(labelData.rotatedTotalBounds.width()+labelData.rotatedTotalBounds.left()) > viewportRect.right() || finalPosition.x()+labelData.rotatedTotalBounds.left() < viewportRect.left(); + else + labelClippedByBorder = finalPosition.y()+(labelData.rotatedTotalBounds.height()+labelData.rotatedTotalBounds.top()) > viewportRect.bottom() || finalPosition.y()+labelData.rotatedTotalBounds.top() < viewportRect.top(); + } + if (!labelClippedByBorder) + { + drawTickLabel(painter, finalPosition.x(), finalPosition.y(), labelData); + finalSize = labelData.rotatedTotalBounds.size(); + } + } + + // expand passed tickLabelsSize if current tick label is larger: + if (finalSize.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(finalSize.width()); + if (finalSize.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(finalSize.height()); +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Draws the tick label specified in \a labelData with \a painter at the pixel positions \a x and \a + y. This function is used by \ref placeTickLabel to create new tick labels for the cache, or to + directly draw the labels on the QCustomPlot surface when label caching is disabled, i.e. when + QCP::phCacheLabels plotting hint is not set. +*/ +void QCPAxisPainterPrivate::drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const +{ + // backup painter settings that we're about to change: + QTransform oldTransform = painter->transform(); + QFont oldFont = painter->font(); + + // transform painter to position/rotation: + painter->translate(x, y); + if (!qFuzzyIsNull(tickLabelRotation)) + painter->rotate(tickLabelRotation); + + // draw text: + if (!labelData.expPart.isEmpty()) // indicator that beautiful powers must be used + { + painter->setFont(labelData.baseFont); + painter->drawText(0, 0, 0, 0, Qt::TextDontClip, labelData.basePart); + if (!labelData.suffixPart.isEmpty()) + painter->drawText(labelData.baseBounds.width()+1+labelData.expBounds.width(), 0, 0, 0, Qt::TextDontClip, labelData.suffixPart); + painter->setFont(labelData.expFont); + painter->drawText(labelData.baseBounds.width()+1, 0, labelData.expBounds.width(), labelData.expBounds.height(), Qt::TextDontClip, labelData.expPart); + } else + { + painter->setFont(labelData.baseFont); + painter->drawText(0, 0, labelData.totalBounds.width(), labelData.totalBounds.height(), Qt::TextDontClip | Qt::AlignHCenter, labelData.basePart); + } + + // reset painter settings to what it was before: + painter->setTransform(oldTransform); + painter->setFont(oldFont); +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Transforms the passed \a text and \a font to a tickLabelData structure that can then be further + processed by \ref getTickLabelDrawOffset and \ref drawTickLabel. It splits the text into base and + exponent if necessary (member substituteExponent) and calculates appropriate bounding boxes. +*/ +QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(const QFont &font, const QString &text) const +{ + TickLabelData result; + + // determine whether beautiful decimal powers should be used + bool useBeautifulPowers = false; + int ePos = -1; // first index of exponent part, text before that will be basePart, text until eLast will be expPart + int eLast = -1; // last index of exponent part, rest of text after this will be suffixPart + if (substituteExponent) + { + ePos = text.indexOf(QLatin1Char('e')); + if (ePos > 0 && text.at(ePos-1).isDigit()) + { + eLast = ePos; + while (eLast+1 < text.size() && (text.at(eLast+1) == QLatin1Char('+') || text.at(eLast+1) == QLatin1Char('-') || text.at(eLast+1).isDigit())) + ++eLast; + if (eLast > ePos) // only if also to right of 'e' is a digit/+/- interpret it as beautifiable power + useBeautifulPowers = true; + } + } + + // calculate text bounding rects and do string preparation for beautiful decimal powers: + result.baseFont = font; + if (result.baseFont.pointSizeF() > 0) // might return -1 if specified with setPixelSize, in that case we can't do correction in next line + result.baseFont.setPointSizeF(result.baseFont.pointSizeF()+0.05); // QFontMetrics.boundingRect has a bug for exact point sizes that make the results oscillate due to internal rounding + if (useBeautifulPowers) + { + // split text into parts of number/symbol that will be drawn normally and part that will be drawn as exponent: + result.basePart = text.left(ePos); + result.suffixPart = text.mid(eLast+1); // also drawn normally but after exponent + // in log scaling, we want to turn "1*10^n" into "10^n", else add multiplication sign and decimal base: + if (abbreviateDecimalPowers && result.basePart == QLatin1String("1")) + result.basePart = QLatin1String("10"); + else + result.basePart += (numberMultiplyCross ? QString(QChar(215)) : QString(QChar(183))) + QLatin1String("10"); + result.expPart = text.mid(ePos+1, eLast-ePos); + // clip "+" and leading zeros off expPart: + while (result.expPart.length() > 2 && result.expPart.at(1) == QLatin1Char('0')) // length > 2 so we leave one zero when numberFormatChar is 'e' + result.expPart.remove(1, 1); + if (!result.expPart.isEmpty() && result.expPart.at(0) == QLatin1Char('+')) + result.expPart.remove(0, 1); + // prepare smaller font for exponent: + result.expFont = font; + if (result.expFont.pointSize() > 0) + result.expFont.setPointSize(result.expFont.pointSize()*0.75); + else + result.expFont.setPixelSize(result.expFont.pixelSize()*0.75); + // calculate bounding rects of base part(s), exponent part and total one: + result.baseBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.basePart); + result.expBounds = QFontMetrics(result.expFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.expPart); + if (!result.suffixPart.isEmpty()) + result.suffixBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.suffixPart); + result.totalBounds = result.baseBounds.adjusted(0, 0, result.expBounds.width()+result.suffixBounds.width()+2, 0); // +2 consists of the 1 pixel spacing between base and exponent (see drawTickLabel) and an extra pixel to include AA + } else // useBeautifulPowers == false + { + result.basePart = text; + result.totalBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, result.basePart); + } + result.totalBounds.moveTopLeft(QPoint(0, 0)); // want bounding box aligned top left at origin, independent of how it was created, to make further processing simpler + + // calculate possibly different bounding rect after rotation: + result.rotatedTotalBounds = result.totalBounds; + if (!qFuzzyIsNull(tickLabelRotation)) + { + QTransform transform; + transform.rotate(tickLabelRotation); + result.rotatedTotalBounds = transform.mapRect(result.rotatedTotalBounds); + } + + return result; +} + +/*! \internal + + This is a \ref placeTickLabel helper function. + + Calculates the offset at which the top left corner of the specified tick label shall be drawn. + The offset is relative to a point right next to the tick the label belongs to. + + This function is thus responsible for e.g. centering tick labels under ticks and positioning them + appropriately when they are rotated. +*/ +QPointF QCPAxisPainterPrivate::getTickLabelDrawOffset(const TickLabelData &labelData) const +{ + /* + calculate label offset from base point at tick (non-trivial, for best visual appearance): short + explanation for bottom axis: The anchor, i.e. the point in the label that is placed + horizontally under the corresponding tick is always on the label side that is closer to the + axis (e.g. the left side of the text when we're rotating clockwise). On that side, the height + is halved and the resulting point is defined the anchor. This way, a 90 degree rotated text + will be centered under the tick (i.e. displaced horizontally by half its height). At the same + time, a 45 degree rotated text will "point toward" its tick, as is typical for rotated tick + labels. + */ + bool doRotation = !qFuzzyIsNull(tickLabelRotation); + bool flip = qFuzzyCompare(qAbs(tickLabelRotation), 90.0); // perfect +/-90 degree flip. Indicates vertical label centering on vertical axes. + double radians = tickLabelRotation/180.0*M_PI; + int x=0, y=0; + if ((type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsInside)) // Anchor at right side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = -qCos(radians)*labelData.totalBounds.width(); + y = flip ? -labelData.totalBounds.width()/2.0 : -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height()/2.0; + } else + { + x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height(); + y = flip ? +labelData.totalBounds.width()/2.0 : +qSin(-radians)*labelData.totalBounds.width()-qCos(-radians)*labelData.totalBounds.height()/2.0; + } + } else + { + x = -labelData.totalBounds.width(); + y = -labelData.totalBounds.height()/2.0; + } + } else if ((type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsInside)) // Anchor at left side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = +qSin(radians)*labelData.totalBounds.height(); + y = flip ? -labelData.totalBounds.width()/2.0 : -qCos(radians)*labelData.totalBounds.height()/2.0; + } else + { + x = 0; + y = flip ? +labelData.totalBounds.width()/2.0 : -qCos(-radians)*labelData.totalBounds.height()/2.0; + } + } else + { + x = 0; + y = -labelData.totalBounds.height()/2.0; + } + } else if ((type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsInside)) // Anchor at bottom side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = -qCos(radians)*labelData.totalBounds.width()+qSin(radians)*labelData.totalBounds.height()/2.0; + y = -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height(); + } else + { + x = -qSin(-radians)*labelData.totalBounds.height()/2.0; + y = -qCos(-radians)*labelData.totalBounds.height(); + } + } else + { + x = -labelData.totalBounds.width()/2.0; + y = -labelData.totalBounds.height(); + } + } else if ((type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsInside)) // Anchor at top side of tick label + { + if (doRotation) + { + if (tickLabelRotation > 0) + { + x = +qSin(radians)*labelData.totalBounds.height()/2.0; + y = 0; + } else + { + x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height()/2.0; + y = +qSin(-radians)*labelData.totalBounds.width(); + } + } else + { + x = -labelData.totalBounds.width()/2.0; + y = 0; + } + } + + return QPointF(x, y); +} + +/*! \internal + + Simulates the steps done by \ref placeTickLabel by calculating bounding boxes of the text label + to be drawn, depending on number format etc. Since only the largest tick label is wanted for the + margin calculation, the passed \a tickLabelsSize is only expanded, if it's currently set to a + smaller width/height. +*/ +void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const +{ + // note: this function must return the same tick label sizes as the placeTickLabel function. + QSize finalSize; + if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && mLabelCache.contains(text)) // label caching enabled and have cached label + { + const CachedLabel *cachedLabel = mLabelCache.object(text); + finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); + } else // label caching disabled or no label with this text cached: + { + TickLabelData labelData = getTickLabelData(font, text); + finalSize = labelData.rotatedTotalBounds.size(); + } + + // expand passed tickLabelsSize if current tick label is larger: + if (finalSize.width() > tickLabelsSize->width()) + tickLabelsSize->setWidth(finalSize.width()); + if (finalSize.height() > tickLabelsSize->height()) + tickLabelsSize->setHeight(finalSize.height()); +} +/* end of 'src/axis/axis.cpp' */ + + +/* including file 'src/scatterstyle.cpp', size 17420 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPScatterStyle +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPScatterStyle + \brief Represents the visual appearance of scatter points + + This class holds information about shape, color and size of scatter points. In plottables like + QCPGraph it is used to store how scatter points shall be drawn. For example, \ref + QCPGraph::setScatterStyle takes a QCPScatterStyle instance. + + A scatter style consists of a shape (\ref setShape), a line color (\ref setPen) and possibly a + fill (\ref setBrush), if the shape provides a fillable area. Further, the size of the shape can + be controlled with \ref setSize. + + \section QCPScatterStyle-defining Specifying a scatter style + + You can set all these configurations either by calling the respective functions on an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-1 + + Or you can use one of the various constructors that take different parameter combinations, making + it easy to specify a scatter style in a single call, like so: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-creation-2 + + \section QCPScatterStyle-undefinedpen Leaving the color/pen up to the plottable + + There are two constructors which leave the pen undefined: \ref QCPScatterStyle() and \ref + QCPScatterStyle(ScatterShape shape, double size). If those constructors are used, a call to \ref + isPenDefined will return false. It leads to scatter points that inherit the pen from the + plottable that uses the scatter style. Thus, if such a scatter style is passed to QCPGraph, the line + color of the graph (\ref QCPGraph::setPen) will be used by the scatter points. This makes + it very convenient to set up typical scatter settings: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpscatterstyle-shortcreation + + Notice that it wasn't even necessary to explicitly call a QCPScatterStyle constructor. This works + because QCPScatterStyle provides a constructor that can transform a \ref ScatterShape directly + into a QCPScatterStyle instance (that's the \ref QCPScatterStyle(ScatterShape shape, double size) + constructor with a default for \a size). In those cases, C++ allows directly supplying a \ref + ScatterShape, where actually a QCPScatterStyle is expected. + + \section QCPScatterStyle-custompath-and-pixmap Custom shapes and pixmaps + + QCPScatterStyle supports drawing custom shapes and arbitrary pixmaps as scatter points. + + For custom shapes, you can provide a QPainterPath with the desired shape to the \ref + setCustomPath function or call the constructor that takes a painter path. The scatter shape will + automatically be set to \ref ssCustom. + + For pixmaps, you call \ref setPixmap with the desired QPixmap. Alternatively you can use the + constructor that takes a QPixmap. The scatter shape will automatically be set to \ref ssPixmap. + Note that \ref setSize does not influence the appearance of the pixmap. +*/ + +/* start documentation of inline functions */ + +/*! \fn bool QCPScatterStyle::isNone() const + + Returns whether the scatter shape is \ref ssNone. + + \see setShape +*/ + +/*! \fn bool QCPScatterStyle::isPenDefined() const + + Returns whether a pen has been defined for this scatter style. + + The pen is undefined if a constructor is called that does not carry \a pen as parameter. Those + are \ref QCPScatterStyle() and \ref QCPScatterStyle(ScatterShape shape, double size). If the pen + is undefined, the pen of the respective plottable will be used for drawing scatters. + + If a pen was defined for this scatter style instance, and you now wish to undefine the pen, call + \ref undefinePen. + + \see setPen +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPScatterStyle instance with size set to 6. No shape, pen or brush is defined. + + Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited + from the plottable that uses this scatter style. +*/ +QCPScatterStyle::QCPScatterStyle() : + mSize(6), + mShape(ssNone), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape and size to \a size. No pen or + brush is defined. + + Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited + from the plottable that uses this scatter style. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, double size) : + mSize(size), + mShape(shape), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, + and size to \a size. No brush is defined, i.e. the scatter point will not be filled. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, double size) : + mSize(size), + mShape(shape), + mPen(QPen(color)), + mBrush(Qt::NoBrush), + mPenDefined(true) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color, + the brush color to \a fill (with a solid pattern), and size to \a size. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) : + mSize(size), + mShape(shape), + mPen(QPen(color)), + mBrush(QBrush(fill)), + mPenDefined(true) +{ +} + +/*! + Creates a new QCPScatterStyle instance with shape set to \a shape, the pen set to \a pen, the + brush to \a brush, and size to \a size. + + \warning In some cases it might be tempting to directly use a pen style like Qt::NoPen as \a pen + and a color like Qt::blue as \a brush. Notice however, that the corresponding call\n + QCPScatterStyle(QCPScatterShape::ssCircle, Qt::NoPen, Qt::blue, 5)\n + doesn't necessarily lead C++ to use this constructor in some cases, but might mistake + Qt::NoPen for a QColor and use the + \ref QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) + constructor instead (which will lead to an unexpected look of the scatter points). To prevent + this, be more explicit with the parameter types. For example, use QBrush(Qt::blue) + instead of just Qt::blue, to clearly point out to the compiler that this constructor is + wanted. +*/ +QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size) : + mSize(size), + mShape(shape), + mPen(pen), + mBrush(brush), + mPenDefined(pen.style() != Qt::NoPen) +{ +} + +/*! + Creates a new QCPScatterStyle instance which will show the specified \a pixmap. The scatter shape + is set to \ref ssPixmap. +*/ +QCPScatterStyle::QCPScatterStyle(const QPixmap &pixmap) : + mSize(5), + mShape(ssPixmap), + mPen(Qt::NoPen), + mBrush(Qt::NoBrush), + mPixmap(pixmap), + mPenDefined(false) +{ +} + +/*! + Creates a new QCPScatterStyle instance with a custom shape that is defined via \a customPath. The + scatter shape is set to \ref ssCustom. + + The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly + different meaning than for built-in scatter points: The custom path will be drawn scaled by a + factor of \a size/6.0. Since the default \a size is 6, the custom path will appear at a its + natural size by default. To double the size of the path for example, set \a size to 12. +*/ +QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush, double size) : + mSize(size), + mShape(ssCustom), + mPen(pen), + mBrush(brush), + mCustomPath(customPath), + mPenDefined(pen.style() != Qt::NoPen) +{ +} + +/*! + Copies the specified \a properties from the \a other scatter style to this scatter style. +*/ +void QCPScatterStyle::setFromOther(const QCPScatterStyle &other, ScatterProperties properties) +{ + if (properties.testFlag(spPen)) + { + setPen(other.pen()); + if (!other.isPenDefined()) + undefinePen(); + } + if (properties.testFlag(spBrush)) + setBrush(other.brush()); + if (properties.testFlag(spSize)) + setSize(other.size()); + if (properties.testFlag(spShape)) + { + setShape(other.shape()); + if (other.shape() == ssPixmap) + setPixmap(other.pixmap()); + else if (other.shape() == ssCustom) + setCustomPath(other.customPath()); + } +} + +/*! + Sets the size (pixel diameter) of the drawn scatter points to \a size. + + \see setShape +*/ +void QCPScatterStyle::setSize(double size) +{ + mSize = size; +} + +/*! + Sets the shape to \a shape. + + Note that the calls \ref setPixmap and \ref setCustomPath automatically set the shape to \ref + ssPixmap and \ref ssCustom, respectively. + + \see setSize +*/ +void QCPScatterStyle::setShape(QCPScatterStyle::ScatterShape shape) +{ + mShape = shape; +} + +/*! + Sets the pen that will be used to draw scatter points to \a pen. + + If the pen was previously undefined (see \ref isPenDefined), the pen is considered defined after + a call to this function, even if \a pen is Qt::NoPen. If you have defined a pen + previously by calling this function and now wish to undefine the pen, call \ref undefinePen. + + \see setBrush +*/ +void QCPScatterStyle::setPen(const QPen &pen) +{ + mPenDefined = true; + mPen = pen; +} + +/*! + Sets the brush that will be used to fill scatter points to \a brush. Note that not all scatter + shapes have fillable areas. For example, \ref ssPlus does not while \ref ssCircle does. + + \see setPen +*/ +void QCPScatterStyle::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the pixmap that will be drawn as scatter point to \a pixmap. + + Note that \ref setSize does not influence the appearance of the pixmap. + + The scatter shape is automatically set to \ref ssPixmap. +*/ +void QCPScatterStyle::setPixmap(const QPixmap &pixmap) +{ + setShape(ssPixmap); + mPixmap = pixmap; +} + +/*! + Sets the custom shape that will be drawn as scatter point to \a customPath. + + The scatter shape is automatically set to \ref ssCustom. +*/ +void QCPScatterStyle::setCustomPath(const QPainterPath &customPath) +{ + setShape(ssCustom); + mCustomPath = customPath; +} + +/*! + Sets this scatter style to have an undefined pen (see \ref isPenDefined for what an undefined pen + implies). + + A call to \ref setPen will define a pen. +*/ +void QCPScatterStyle::undefinePen() +{ + mPenDefined = false; +} + +/*! + Applies the pen and the brush of this scatter style to \a painter. If this scatter style has an + undefined pen (\ref isPenDefined), sets the pen of \a painter to \a defaultPen instead. + + This function is used by plottables (or any class that wants to draw scatters) just before a + number of scatters with this style shall be drawn with the \a painter. + + \see drawShape +*/ +void QCPScatterStyle::applyTo(QCPPainter *painter, const QPen &defaultPen) const +{ + painter->setPen(mPenDefined ? mPen : defaultPen); + painter->setBrush(mBrush); +} + +/*! + Draws the scatter shape with \a painter at position \a pos. + + This function does not modify the pen or the brush on the painter, as \ref applyTo is meant to be + called before scatter points are drawn with \ref drawShape. + + \see applyTo +*/ +void QCPScatterStyle::drawShape(QCPPainter *painter, const QPointF &pos) const +{ + drawShape(painter, pos.x(), pos.y()); +} + +/*! \overload + Draws the scatter shape with \a painter at position \a x and \a y. +*/ +void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const +{ + double w = mSize/2.0; + switch (mShape) + { + case ssNone: break; + case ssDot: + { + painter->drawLine(QPointF(x, y), QPointF(x+0.0001, y)); + break; + } + case ssCross: + { + painter->drawLine(QLineF(x-w, y-w, x+w, y+w)); + painter->drawLine(QLineF(x-w, y+w, x+w, y-w)); + break; + } + case ssPlus: + { + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + break; + } + case ssCircle: + { + painter->drawEllipse(QPointF(x , y), w, w); + break; + } + case ssDisc: + { + QBrush b = painter->brush(); + painter->setBrush(painter->pen().color()); + painter->drawEllipse(QPointF(x , y), w, w); + painter->setBrush(b); + break; + } + case ssSquare: + { + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + break; + } + case ssDiamond: + { + painter->drawLine(QLineF(x-w, y, x, y-w)); + painter->drawLine(QLineF( x, y-w, x+w, y)); + painter->drawLine(QLineF(x+w, y, x, y+w)); + painter->drawLine(QLineF( x, y+w, x-w, y)); + break; + } + case ssStar: + { + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.707, y+w*0.707)); + painter->drawLine(QLineF(x-w*0.707, y+w*0.707, x+w*0.707, y-w*0.707)); + break; + } + case ssTriangle: + { + painter->drawLine(QLineF(x-w, y+0.755*w, x+w, y+0.755*w)); + painter->drawLine(QLineF(x+w, y+0.755*w, x, y-0.977*w)); + painter->drawLine(QLineF( x, y-0.977*w, x-w, y+0.755*w)); + break; + } + case ssTriangleInverted: + { + painter->drawLine(QLineF(x-w, y-0.755*w, x+w, y-0.755*w)); + painter->drawLine(QLineF(x+w, y-0.755*w, x, y+0.977*w)); + painter->drawLine(QLineF( x, y+0.977*w, x-w, y-0.755*w)); + break; + } + case ssCrossSquare: + { + painter->drawLine(QLineF(x-w, y-w, x+w*0.95, y+w*0.95)); + painter->drawLine(QLineF(x-w, y+w*0.95, x+w*0.95, y-w)); + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + break; + } + case ssPlusSquare: + { + painter->drawLine(QLineF(x-w, y, x+w*0.95, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + painter->drawRect(QRectF(x-w, y-w, mSize, mSize)); + break; + } + case ssCrossCircle: + { + painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.670, y+w*0.670)); + painter->drawLine(QLineF(x-w*0.707, y+w*0.670, x+w*0.670, y-w*0.707)); + painter->drawEllipse(QPointF(x, y), w, w); + break; + } + case ssPlusCircle: + { + painter->drawLine(QLineF(x-w, y, x+w, y)); + painter->drawLine(QLineF( x, y+w, x, y-w)); + painter->drawEllipse(QPointF(x, y), w, w); + break; + } + case ssPeace: + { + painter->drawLine(QLineF(x, y-w, x, y+w)); + painter->drawLine(QLineF(x, y, x-w*0.707, y+w*0.707)); + painter->drawLine(QLineF(x, y, x+w*0.707, y+w*0.707)); + painter->drawEllipse(QPointF(x, y), w, w); + break; + } + case ssPixmap: + { + const double widthHalf = mPixmap.width()*0.5; + const double heightHalf = mPixmap.height()*0.5; +#if QT_VERSION < QT_VERSION_CHECK(4, 8, 0) + const QRectF clipRect = painter->clipRegion().boundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf); +#else + const QRectF clipRect = painter->clipBoundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf); +#endif + if (clipRect.contains(x, y)) + painter->drawPixmap(x-widthHalf, y-heightHalf, mPixmap); + break; + } + case ssCustom: + { + QTransform oldTransform = painter->transform(); + painter->translate(x, y); + painter->scale(mSize/6.0, mSize/6.0); + painter->drawPath(mCustomPath); + painter->setTransform(oldTransform); + break; + } + } +} +/* end of 'src/scatterstyle.cpp' */ + +//amalgamation: add datacontainer.cpp + +/* including file 'src/plottable.cpp', size 38861 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPSelectionDecorator +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPSelectionDecorator + \brief Controls how a plottable's data selection is drawn + + Each \ref QCPAbstractPlottable instance has one \ref QCPSelectionDecorator (accessible via \ref + QCPAbstractPlottable::selectionDecorator) and uses it when drawing selected segments of its data. + + The selection decorator controls both pen (\ref setPen) and brush (\ref setBrush), as well as the + scatter style (\ref setScatterStyle) if the plottable draws scatters. Since a \ref + QCPScatterStyle is itself composed of different properties such as color shape and size, the + decorator allows specifying exactly which of those properties shall be used for the selected data + point, via \ref setUsedScatterProperties. + + A \ref QCPSelectionDecorator subclass instance can be passed to a plottable via \ref + QCPAbstractPlottable::setSelectionDecorator, allowing greater customizability of the appearance + of selected segments. + + Use \ref copyFrom to easily transfer the settings of one decorator to another one. This is + especially useful since plottables take ownership of the passed selection decorator, and thus the + same decorator instance can not be passed to multiple plottables. + + Selection decorators can also themselves perform drawing operations by reimplementing \ref + drawDecoration, which is called by the plottable's draw method. The base class \ref + QCPSelectionDecorator does not make use of this however. For example, \ref + QCPSelectionDecoratorBracket draws brackets around selected data segments. +*/ + +/*! + Creates a new QCPSelectionDecorator instance with default values +*/ +QCPSelectionDecorator::QCPSelectionDecorator() : + mPen(QColor(80, 80, 255), 2.5), + mBrush(Qt::NoBrush), + mScatterStyle(QCPScatterStyle::ssNone, QPen(Qt::blue, 2), Qt::NoBrush, 6.0), + mUsedScatterProperties(QCPScatterStyle::spPen), + mPlottable(0) +{ +} + +QCPSelectionDecorator::~QCPSelectionDecorator() +{ +} + +/*! + Sets the pen that will be used by the parent plottable to draw selected data segments. +*/ +void QCPSelectionDecorator::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the brush that will be used by the parent plottable to draw selected data segments. +*/ +void QCPSelectionDecorator::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the scatter style that will be used by the parent plottable to draw scatters in selected + data segments. + + \a usedProperties specifies which parts of the passed \a scatterStyle will be used by the + plottable. The used properties can also be changed via \ref setUsedScatterProperties. +*/ +void QCPSelectionDecorator::setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties) +{ + mScatterStyle = scatterStyle; + setUsedScatterProperties(usedProperties); +} + +/*! + Use this method to define which properties of the scatter style (set via \ref setScatterStyle) + will be used for selected data segments. All properties of the scatter style that are not + specified in \a properties will remain as specified in the plottable's original scatter style. +*/ +void QCPSelectionDecorator::setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties) +{ + mUsedScatterProperties = properties; +} + +/*! + Sets the pen of \a painter to the pen of this selection decorator. + + \see applyBrush, getFinalScatterStyle +*/ +void QCPSelectionDecorator::applyPen(QCPPainter *painter) const +{ + painter->setPen(mPen); +} + +/*! + Sets the brush of \a painter to the brush of this selection decorator. + + \see applyPen, getFinalScatterStyle +*/ +void QCPSelectionDecorator::applyBrush(QCPPainter *painter) const +{ + painter->setBrush(mBrush); +} + +/*! + Returns the scatter style that the parent plottable shall use for selected scatter points. The + plottable's original (unselected) scatter style must be passed as \a unselectedStyle. Depending + on the setting of \ref setUsedScatterProperties, the returned scatter style is a mixture of this + selecion decorator's scatter style (\ref setScatterStyle), and \a unselectedStyle. + + \see applyPen, applyBrush, setScatterStyle +*/ +QCPScatterStyle QCPSelectionDecorator::getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const +{ + QCPScatterStyle result(unselectedStyle); + result.setFromOther(mScatterStyle, mUsedScatterProperties); + + // if style shall inherit pen from plottable (has no own pen defined), give it the selected + // plottable pen explicitly, so it doesn't use the unselected plottable pen when used in the + // plottable: + if (!result.isPenDefined()) + result.setPen(mPen); + + return result; +} + +/*! + Copies all properties (e.g. color, fill, scatter style) of the \a other selection decorator to + this selection decorator. +*/ +void QCPSelectionDecorator::copyFrom(const QCPSelectionDecorator *other) +{ + setPen(other->pen()); + setBrush(other->brush()); + setScatterStyle(other->scatterStyle(), other->usedScatterProperties()); +} + +/*! + This method is called by all plottables' draw methods to allow custom selection decorations to be + drawn. Use the passed \a painter to perform the drawing operations. \a selection carries the data + selection for which the decoration shall be drawn. + + The default base class implementation of \ref QCPSelectionDecorator has no special decoration, so + this method does nothing. +*/ +void QCPSelectionDecorator::drawDecoration(QCPPainter *painter, QCPDataSelection selection) +{ + Q_UNUSED(painter) + Q_UNUSED(selection) +} + +/*! \internal + + This method is called as soon as a selection decorator is associated with a plottable, by a call + to \ref QCPAbstractPlottable::setSelectionDecorator. This way the selection decorator can obtain a pointer to the plottable that uses it (e.g. to access + data points via the \ref QCPAbstractPlottable::interface1D interface). + + If the selection decorator was already added to a different plottable before, this method aborts + the registration and returns false. +*/ +bool QCPSelectionDecorator::registerWithPlottable(QCPAbstractPlottable *plottable) +{ + if (!mPlottable) + { + mPlottable = plottable; + return true; + } else + { + qDebug() << Q_FUNC_INFO << "This selection decorator is already registered with plottable:" << reinterpret_cast(mPlottable); + return false; + } +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPlottable +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPlottable + \brief The abstract base class for all data representing objects in a plot. + + It defines a very basic interface like name, pen, brush, visibility etc. Since this class is + abstract, it can't be instantiated. Use one of the subclasses or create a subclass yourself to + create new ways of displaying data (see "Creating own plottables" below). Plottables that display + one-dimensional data (i.e. data points have a single key dimension and one or multiple values at + each key) are based off of the template subclass \ref QCPAbstractPlottable1D, see details + there. + + All further specifics are in the subclasses, for example: + \li A normal graph with possibly a line and/or scatter points \ref QCPGraph + (typically created with \ref QCustomPlot::addGraph) + \li A parametric curve: \ref QCPCurve + \li A bar chart: \ref QCPBars + \li A statistical box plot: \ref QCPStatisticalBox + \li A color encoded two-dimensional map: \ref QCPColorMap + \li An OHLC/Candlestick chart: \ref QCPFinancial + + \section plottables-subclassing Creating own plottables + + Subclassing directly from QCPAbstractPlottable is only recommended if you wish to display + two-dimensional data like \ref QCPColorMap, i.e. two logical key dimensions and one (or more) + data dimensions. If you want to display data with only one logical key dimension, you should + rather derive from \ref QCPAbstractPlottable1D. + + If subclassing QCPAbstractPlottable directly, these are the pure virtual functions you must + implement: + \li \ref selectTest + \li \ref draw + \li \ref drawLegendIcon + \li \ref getKeyRange + \li \ref getValueRange + + See the documentation of those functions for what they need to do. + + For drawing your plot, you can use the \ref coordsToPixels functions to translate a point in plot + coordinates to pixel coordinates. This function is quite convenient, because it takes the + orientation of the key and value axes into account for you (x and y are swapped when the key axis + is vertical and the value axis horizontal). If you are worried about performance (i.e. you need + to translate many points in a loop like QCPGraph), you can directly use \ref + QCPAxis::coordToPixel. However, you must then take care about the orientation of the axis + yourself. + + Here are some important members you inherit from QCPAbstractPlottable: + + + + + + + + + + + + + + + + + + + + + + + + + + +
QCustomPlot *\b mParentPlotA pointer to the parent QCustomPlot instance. The parent plot is inferred from the axes that are passed in the constructor.
QString \b mNameThe name of the plottable.
QPen \b mPenThe generic pen of the plottable. You should use this pen for the most prominent data representing lines in the plottable + (e.g QCPGraph uses this pen for its graph lines and scatters)
QBrush \b mBrushThe generic brush of the plottable. You should use this brush for the most prominent fillable structures in the plottable + (e.g. QCPGraph uses this brush to control filling under the graph)
QPointer<\ref QCPAxis> \b mKeyAxis, \b mValueAxisThe key and value axes this plottable is attached to. Call their QCPAxis::coordToPixel functions to translate coordinates + to pixels in either the key or value dimension. Make sure to check whether the pointer is null before using it. If one of + the axes is null, don't draw the plottable.
\ref QCPSelectionDecorator \b mSelectionDecoratorThe currently set selection decorator which specifies how selected data of the plottable shall be drawn and decorated. + When drawing your data, you must consult this decorator for the appropriate pen/brush before drawing unselected/selected data segments. + Finally, you should call its \ref QCPSelectionDecorator::drawDecoration method at the end of your \ref draw implementation.
\ref QCP::SelectionType \b mSelectableIn which composition, if at all, this plottable's data may be selected. Enforcing this setting on the data selection is done + by QCPAbstractPlottable automatically.
\ref QCPDataSelection \b mSelectionHolds the current selection state of the plottable's data, i.e. the selected data ranges (\ref QCPDataRange).
+*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPSelectionDecorator *QCPAbstractPlottable::selectionDecorator() const + + Provides access to the selection decorator of this plottable. The selection decorator controls + how selected data ranges are drawn (e.g. their pen color and fill), see \ref + QCPSelectionDecorator for details. + + If you wish to use an own \ref QCPSelectionDecorator subclass, pass an instance of it to \ref + setSelectionDecorator. +*/ + +/*! \fn bool QCPAbstractPlottable::selected() const + + Returns true if there are any data points of the plottable currently selected. Use \ref selection + to retrieve the current \ref QCPDataSelection. +*/ + +/*! \fn QCPDataSelection QCPAbstractPlottable::selection() const + + Returns a \ref QCPDataSelection encompassing all the data points that are currently selected on + this plottable. + + \see selected, setSelection, setSelectable +*/ + +/*! \fn virtual QCPPlottableInterface1D *QCPAbstractPlottable::interface1D() + + If this plottable is a one-dimensional plottable, i.e. it implements the \ref + QCPPlottableInterface1D, returns the \a this pointer with that type. Otherwise (e.g. in the case + of a \ref QCPColorMap) returns zero. + + You can use this method to gain read access to data coordinates while holding a pointer to the + abstract base class only. +*/ + +/* end of documentation of inline functions */ +/* start of documentation of pure virtual functions */ + +/*! \fn void QCPAbstractPlottable::drawLegendIcon(QCPPainter *painter, const QRect &rect) const = 0 + \internal + + called by QCPLegend::draw (via QCPPlottableLegendItem::draw) to create a graphical representation + of this plottable inside \a rect, next to the plottable name. + + The passed \a painter has its cliprect set to \a rect, so painting outside of \a rect won't + appear outside the legend icon border. +*/ + +/*! \fn QCPRange QCPAbstractPlottable::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const = 0 + + Returns the coordinate range that all data in this plottable span in the key axis dimension. For + logarithmic plots, one can set \a inSignDomain to either \ref QCP::sdNegative or \ref + QCP::sdPositive in order to restrict the returned range to that sign domain. E.g. when only + negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and all positive points + will be ignored for range calculation. For no restriction, just set \a inSignDomain to \ref + QCP::sdBoth (default). \a foundRange is an output parameter that indicates whether a range could + be found or not. If this is false, you shouldn't use the returned range (e.g. no points in data). + + Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by + this function may have size zero (e.g. when there is only one data point). In this case \a + foundRange would return true, but the returned range is not a valid range in terms of \ref + QCPRange::validRange. + + \see rescaleAxes, getValueRange +*/ + +/*! \fn QCPRange QCPAbstractPlottable::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const = 0 + + Returns the coordinate range that the data points in the specified key range (\a inKeyRange) span + in the value axis dimension. For logarithmic plots, one can set \a inSignDomain to either \ref + QCP::sdNegative or \ref QCP::sdPositive in order to restrict the returned range to that sign + domain. E.g. when only negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and + all positive points will be ignored for range calculation. For no restriction, just set \a + inSignDomain to \ref QCP::sdBoth (default). \a foundRange is an output parameter that indicates + whether a range could be found or not. If this is false, you shouldn't use the returned range + (e.g. no points in data). + + If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), + all data points are considered, without any restriction on the keys. + + Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by + this function may have size zero (e.g. when there is only one data point). In this case \a + foundRange would return true, but the returned range is not a valid range in terms of \ref + QCPRange::validRange. + + \see rescaleAxes, getKeyRange +*/ + +/* end of documentation of pure virtual functions */ +/* start of documentation of signals */ + +/*! \fn void QCPAbstractPlottable::selectionChanged(bool selected) + + This signal is emitted when the selection state of this plottable has changed, either by user + interaction or by a direct call to \ref setSelection. The parameter \a selected indicates whether + there are any points selected or not. + + \see selectionChanged(const QCPDataSelection &selection) +*/ + +/*! \fn void QCPAbstractPlottable::selectionChanged(const QCPDataSelection &selection) + + This signal is emitted when the selection state of this plottable has changed, either by user + interaction or by a direct call to \ref setSelection. The parameter \a selection holds the + currently selected data ranges. + + \see selectionChanged(bool selected) +*/ + +/*! \fn void QCPAbstractPlottable::selectableChanged(QCP::SelectionType selectable); + + This signal is emitted when the selectability of this plottable has changed. + + \see setSelectable +*/ + +/* end of documentation of signals */ + +/*! + Constructs an abstract plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as + its value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance + and have perpendicular orientations. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + Since QCPAbstractPlottable is an abstract class that defines the basic interface to plottables, + it can't be directly instantiated. + + You probably want one of the subclasses like \ref QCPGraph or \ref QCPCurve instead. +*/ +QCPAbstractPlottable::QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPLayerable(keyAxis->parentPlot(), QString(), keyAxis->axisRect()), + mName(), + mAntialiasedFill(true), + mAntialiasedScatters(true), + mPen(Qt::black), + mBrush(Qt::NoBrush), + mKeyAxis(keyAxis), + mValueAxis(valueAxis), + mSelectable(QCP::stWhole), + mSelectionDecorator(0) +{ + if (keyAxis->parentPlot() != valueAxis->parentPlot()) + qDebug() << Q_FUNC_INFO << "Parent plot of keyAxis is not the same as that of valueAxis."; + if (keyAxis->orientation() == valueAxis->orientation()) + qDebug() << Q_FUNC_INFO << "keyAxis and valueAxis must be orthogonal to each other."; + + mParentPlot->registerPlottable(this); + setSelectionDecorator(new QCPSelectionDecorator); +} + +QCPAbstractPlottable::~QCPAbstractPlottable() +{ + if (mSelectionDecorator) + { + delete mSelectionDecorator; + mSelectionDecorator = 0; + } +} + +/*! + The name is the textual representation of this plottable as it is displayed in the legend + (\ref QCPLegend). It may contain any UTF-8 characters, including newlines. +*/ +void QCPAbstractPlottable::setName(const QString &name) +{ + mName = name; +} + +/*! + Sets whether fills of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedFill(bool enabled) +{ + mAntialiasedFill = enabled; +} + +/*! + Sets whether the scatter symbols of this plottable are drawn antialiased or not. + + Note that this setting may be overridden by \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPAbstractPlottable::setAntialiasedScatters(bool enabled) +{ + mAntialiasedScatters = enabled; +} + +/*! + The pen is used to draw basic lines that make up the plottable representation in the + plot. + + For example, the \ref QCPGraph subclass draws its graph lines with this pen. + + \see setBrush +*/ +void QCPAbstractPlottable::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + The brush is used to draw basic fills of the plottable representation in the + plot. The Fill can be a color, gradient or texture, see the usage of QBrush. + + For example, the \ref QCPGraph subclass draws the fill under the graph with this brush, when + it's not set to Qt::NoBrush. + + \see setPen +*/ +void QCPAbstractPlottable::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + The key axis of a plottable can be set to any axis of a QCustomPlot, as long as it is orthogonal + to the plottable's value axis. This function performs no checks to make sure this is the case. + The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and the + y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setValueAxis +*/ +void QCPAbstractPlottable::setKeyAxis(QCPAxis *axis) +{ + mKeyAxis = axis; +} + +/*! + The value axis of a plottable can be set to any axis of a QCustomPlot, as long as it is + orthogonal to the plottable's key axis. This function performs no checks to make sure this is the + case. The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and + the y-axis (QCustomPlot::yAxis) as value axis. + + Normally, the key and value axes are set in the constructor of the plottable (or \ref + QCustomPlot::addGraph when working with QCPGraphs through the dedicated graph interface). + + \see setKeyAxis +*/ +void QCPAbstractPlottable::setValueAxis(QCPAxis *axis) +{ + mValueAxis = axis; +} + + +/*! + Sets which data ranges of this plottable are selected. Selected data ranges are drawn differently + (e.g. color) in the plot. This can be controlled via the selection decorator (see \ref + selectionDecorator). + + The entire selection mechanism for plottables is handled automatically when \ref + QCustomPlot::setInteractions contains iSelectPlottables. You only need to call this function when + you wish to change the selection state programmatically. + + Using \ref setSelectable you can further specify for each plottable whether and to which + granularity it is selectable. If \a selection is not compatible with the current \ref + QCP::SelectionType set via \ref setSelectable, the resulting selection will be adjusted + accordingly (see \ref QCPDataSelection::enforceType). + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see setSelectable, selectTest +*/ +void QCPAbstractPlottable::setSelection(QCPDataSelection selection) +{ + selection.enforceType(mSelectable); + if (mSelection != selection) + { + mSelection = selection; + emit selectionChanged(selected()); + emit selectionChanged(mSelection); + } +} + +/*! + Use this method to set an own QCPSelectionDecorator (subclass) instance. This allows you to + customize the visual representation of selected data ranges further than by using the default + QCPSelectionDecorator. + + The plottable takes ownership of the \a decorator. + + The currently set decorator can be accessed via \ref selectionDecorator. +*/ +void QCPAbstractPlottable::setSelectionDecorator(QCPSelectionDecorator *decorator) +{ + if (decorator) + { + if (decorator->registerWithPlottable(this)) + { + if (mSelectionDecorator) // delete old decorator if necessary + delete mSelectionDecorator; + mSelectionDecorator = decorator; + } + } else if (mSelectionDecorator) // just clear decorator + { + delete mSelectionDecorator; + mSelectionDecorator = 0; + } +} + +/*! + Sets whether and to which granularity this plottable can be selected. + + A selection can happen by clicking on the QCustomPlot surface (When \ref + QCustomPlot::setInteractions contains \ref QCP::iSelectPlottables), by dragging a selection rect + (When \ref QCustomPlot::setSelectionRectMode is \ref QCP::srmSelect), or programmatically by + calling \ref setSelection. + + \see setSelection, QCP::SelectionType +*/ +void QCPAbstractPlottable::setSelectable(QCP::SelectionType selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + QCPDataSelection oldSelection = mSelection; + mSelection.enforceType(mSelectable); + emit selectableChanged(mSelectable); + if (mSelection != oldSelection) + { + emit selectionChanged(selected()); + emit selectionChanged(mSelection); + } + } +} + + +/*! + Convenience function for transforming a key/value pair to pixels on the QCustomPlot surface, + taking the orientations of the axes associated with this plottable into account (e.g. whether key + represents x or y). + + \a key and \a value are transformed to the coodinates in pixels and are written to \a x and \a y. + + \see pixelsToCoords, QCPAxis::coordToPixel +*/ +void QCPAbstractPlottable::coordsToPixels(double key, double value, double &x, double &y) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + x = keyAxis->coordToPixel(key); + y = valueAxis->coordToPixel(value); + } else + { + y = keyAxis->coordToPixel(key); + x = valueAxis->coordToPixel(value); + } +} + +/*! \overload + + Transforms the given \a key and \a value to pixel coordinates and returns them in a QPointF. +*/ +const QPointF QCPAbstractPlottable::coordsToPixels(double key, double value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + if (keyAxis->orientation() == Qt::Horizontal) + return QPointF(keyAxis->coordToPixel(key), valueAxis->coordToPixel(value)); + else + return QPointF(valueAxis->coordToPixel(value), keyAxis->coordToPixel(key)); +} + +/*! + Convenience function for transforming a x/y pixel pair on the QCustomPlot surface to plot coordinates, + taking the orientations of the axes associated with this plottable into account (e.g. whether key + represents x or y). + + \a x and \a y are transformed to the plot coodinates and are written to \a key and \a value. + + \see coordsToPixels, QCPAxis::coordToPixel +*/ +void QCPAbstractPlottable::pixelsToCoords(double x, double y, double &key, double &value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + key = keyAxis->pixelToCoord(x); + value = valueAxis->pixelToCoord(y); + } else + { + key = keyAxis->pixelToCoord(y); + value = valueAxis->pixelToCoord(x); + } +} + +/*! \overload + + Returns the pixel input \a pixelPos as plot coordinates \a key and \a value. +*/ +void QCPAbstractPlottable::pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const +{ + pixelsToCoords(pixelPos.x(), pixelPos.y(), key, value); +} + +/*! + Rescales the key and value axes associated with this plottable to contain all displayed data, so + the whole plottable is visible. If the scaling of an axis is logarithmic, rescaleAxes will make + sure not to rescale to an illegal range i.e. a range containing different signs and/or zero. + Instead it will stay in the current sign domain and ignore all parts of the plottable that lie + outside of that domain. + + \a onlyEnlarge makes sure the ranges are only expanded, never reduced. So it's possible to show + multiple plottables in their entirety by multiple calls to rescaleAxes where the first call has + \a onlyEnlarge set to false (the default), and all subsequent set to true. + + \see rescaleKeyAxis, rescaleValueAxis, QCustomPlot::rescaleAxes, QCPAxis::rescale +*/ +void QCPAbstractPlottable::rescaleAxes(bool onlyEnlarge) const +{ + rescaleKeyAxis(onlyEnlarge); + rescaleValueAxis(onlyEnlarge); +} + +/*! + Rescales the key axis of the plottable so the whole plottable is visible. + + See \ref rescaleAxes for detailed behaviour. +*/ +void QCPAbstractPlottable::rescaleKeyAxis(bool onlyEnlarge) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + if (!keyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } + + QCP::SignDomain signDomain = QCP::sdBoth; + if (keyAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (keyAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); + + bool foundRange; + QCPRange newRange = getKeyRange(foundRange, signDomain); + if (foundRange) + { + if (onlyEnlarge) + newRange.expand(keyAxis->range()); + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (keyAxis->scaleType() == QCPAxis::stLinear) + { + newRange.lower = center-keyAxis->range().size()/2.0; + newRange.upper = center+keyAxis->range().size()/2.0; + } else // scaleType() == stLogarithmic + { + newRange.lower = center/qSqrt(keyAxis->range().upper/keyAxis->range().lower); + newRange.upper = center*qSqrt(keyAxis->range().upper/keyAxis->range().lower); + } + } + keyAxis->setRange(newRange); + } +} + +/*! + Rescales the value axis of the plottable so the whole plottable is visible. If \a inKeyRange is + set to true, only the data points which are in the currently visible key axis range are + considered. + + Returns true if the axis was actually scaled. This might not be the case if this plottable has an + invalid range, e.g. because it has no data points. + + See \ref rescaleAxes for detailed behaviour. +*/ +void QCPAbstractPlottable::rescaleValueAxis(bool onlyEnlarge, bool inKeyRange) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCP::SignDomain signDomain = QCP::sdBoth; + if (valueAxis->scaleType() == QCPAxis::stLogarithmic) + signDomain = (valueAxis->range().upper < 0 ? QCP::sdNegative : QCP::sdPositive); + + bool foundRange; + QCPRange newRange = getValueRange(foundRange, signDomain, inKeyRange ? keyAxis->range() : QCPRange()); + if (foundRange) + { + if (onlyEnlarge) + newRange.expand(valueAxis->range()); + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (valueAxis->scaleType() == QCPAxis::stLinear) + { + newRange.lower = center-valueAxis->range().size()/2.0; + newRange.upper = center+valueAxis->range().size()/2.0; + } else // scaleType() == stLogarithmic + { + newRange.lower = center/qSqrt(valueAxis->range().upper/valueAxis->range().lower); + newRange.upper = center*qSqrt(valueAxis->range().upper/valueAxis->range().lower); + } + } + valueAxis->setRange(newRange); + } +} + +/*! \overload + + Adds this plottable to the specified \a legend. + + Creates a QCPPlottableLegendItem which is inserted into the legend. Returns true on success, i.e. + when the legend exists and a legend item associated with this plottable isn't already in the + legend. + + If the plottable needs a more specialized representation in the legend, you can create a + corresponding subclass of \ref QCPPlottableLegendItem and add it to the legend manually instead + of calling this method. + + \see removeFromLegend, QCPLegend::addItem +*/ +bool QCPAbstractPlottable::addToLegend(QCPLegend *legend) +{ + if (!legend) + { + qDebug() << Q_FUNC_INFO << "passed legend is null"; + return false; + } + if (legend->parentPlot() != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "passed legend isn't in the same QCustomPlot as this plottable"; + return false; + } + + if (!legend->hasItemWithPlottable(this)) + { + legend->addItem(new QCPPlottableLegendItem(legend, this)); + return true; + } else + return false; +} + +/*! \overload + + Adds this plottable to the legend of the parent QCustomPlot (\ref QCustomPlot::legend). + + \see removeFromLegend +*/ +bool QCPAbstractPlottable::addToLegend() +{ + if (!mParentPlot || !mParentPlot->legend) + return false; + else + return addToLegend(mParentPlot->legend); +} + +/*! \overload + + Removes the plottable from the specifed \a legend. This means the \ref QCPPlottableLegendItem + that is associated with this plottable is removed. + + Returns true on success, i.e. if the legend exists and a legend item associated with this + plottable was found and removed. + + \see addToLegend, QCPLegend::removeItem +*/ +bool QCPAbstractPlottable::removeFromLegend(QCPLegend *legend) const +{ + if (!legend) + { + qDebug() << Q_FUNC_INFO << "passed legend is null"; + return false; + } + + if (QCPPlottableLegendItem *lip = legend->itemWithPlottable(this)) + return legend->removeItem(lip); + else + return false; +} + +/*! \overload + + Removes the plottable from the legend of the parent QCustomPlot. + + \see addToLegend +*/ +bool QCPAbstractPlottable::removeFromLegend() const +{ + if (!mParentPlot || !mParentPlot->legend) + return false; + else + return removeFromLegend(mParentPlot->legend); +} + +/* inherits documentation from base class */ +QRect QCPAbstractPlottable::clipRect() const +{ + if (mKeyAxis && mValueAxis) + return mKeyAxis.data()->axisRect()->rect() & mValueAxis.data()->axisRect()->rect(); + else + return QRect(); +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractPlottable::selectionCategory() const +{ + return QCP::iSelectPlottables; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased, applyFillAntialiasingHint, applyScattersAntialiasingHint +*/ +void QCPAbstractPlottable::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aePlottables); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable fills. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyDefaultAntialiasingHint, applyScattersAntialiasingHint +*/ +void QCPAbstractPlottable::applyFillAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedFill, QCP::aeFills); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing plottable scatter points. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased, applyFillAntialiasingHint, applyDefaultAntialiasingHint +*/ +void QCPAbstractPlottable::applyScattersAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiasedScatters, QCP::aeScatters); +} + +/* inherits documentation from base class */ +void QCPAbstractPlottable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + + if (mSelectable != QCP::stNone) + { + QCPDataSelection newSelection = details.value(); + QCPDataSelection selectionBefore = mSelection; + if (additive) + { + if (mSelectable == QCP::stWhole) // in whole selection mode, we toggle to no selection even if currently unselected point was hit + { + if (selected()) + setSelection(QCPDataSelection()); + else + setSelection(newSelection); + } else // in all other selection modes we toggle selections of homogeneously selected/unselected segments + { + if (mSelection.contains(newSelection)) // if entire newSelection is already selected, toggle selection + setSelection(mSelection-newSelection); + else + setSelection(mSelection+newSelection); + } + } else + setSelection(newSelection); + if (selectionStateChanged) + *selectionStateChanged = mSelection != selectionBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractPlottable::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable != QCP::stNone) + { + QCPDataSelection selectionBefore = mSelection; + setSelection(QCPDataSelection()); + if (selectionStateChanged) + *selectionStateChanged = mSelection != selectionBefore; + } +} +/* end of 'src/plottable.cpp' */ + + +/* including file 'src/item.cpp', size 49269 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemAnchor +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemAnchor + \brief An anchor of an item to which positions can be attached to. + + An item (QCPAbstractItem) may have one or more anchors. Unlike QCPItemPosition, an anchor doesn't + control anything on its item, but provides a way to tie other items via their positions to the + anchor. + + For example, a QCPItemRect is defined by its positions \a topLeft and \a bottomRight. + Additionally it has various anchors like \a top, \a topRight or \a bottomLeft etc. So you can + attach the \a start (which is a QCPItemPosition) of a QCPItemLine to one of the anchors by + calling QCPItemPosition::setParentAnchor on \a start, passing the wanted anchor of the + QCPItemRect. This way the start of the line will now always follow the respective anchor location + on the rect item. + + Note that QCPItemPosition derives from QCPItemAnchor, so every position can also serve as an + anchor to other positions. + + To learn how to provide anchors in your own item subclasses, see the subclassing section of the + QCPAbstractItem documentation. +*/ + +/* start documentation of inline functions */ + +/*! \fn virtual QCPItemPosition *QCPItemAnchor::toQCPItemPosition() + + Returns 0 if this instance is merely a QCPItemAnchor, and a valid pointer of type QCPItemPosition* if + it actually is a QCPItemPosition (which is a subclass of QCPItemAnchor). + + This safe downcast functionality could also be achieved with a dynamic_cast. However, QCustomPlot avoids + dynamic_cast to work with projects that don't have RTTI support enabled (e.g. -fno-rtti flag with + gcc compiler). +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPItemAnchor. You shouldn't create QCPItemAnchor instances directly, even if + you want to make a new item subclass. Use \ref QCPAbstractItem::createAnchor instead, as + explained in the subclassing section of the QCPAbstractItem documentation. +*/ +QCPItemAnchor::QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId) : + mName(name), + mParentPlot(parentPlot), + mParentItem(parentItem), + mAnchorId(anchorId) +{ +} + +QCPItemAnchor::~QCPItemAnchor() +{ + // unregister as parent at children: + foreach (QCPItemPosition *child, mChildrenX.toList()) + { + if (child->parentAnchorX() == this) + child->setParentAnchorX(0); // this acts back on this anchor and child removes itself from mChildrenX + } + foreach (QCPItemPosition *child, mChildrenY.toList()) + { + if (child->parentAnchorY() == this) + child->setParentAnchorY(0); // this acts back on this anchor and child removes itself from mChildrenY + } +} + +/*! + Returns the final absolute pixel position of the QCPItemAnchor on the QCustomPlot surface. + + The pixel information is internally retrieved via QCPAbstractItem::anchorPixelPosition of the + parent item, QCPItemAnchor is just an intermediary. +*/ +QPointF QCPItemAnchor::pixelPosition() const +{ + if (mParentItem) + { + if (mAnchorId > -1) + { + return mParentItem->anchorPixelPosition(mAnchorId); + } else + { + qDebug() << Q_FUNC_INFO << "no valid anchor id set:" << mAnchorId; + return QPointF(); + } + } else + { + qDebug() << Q_FUNC_INFO << "no parent item set"; + return QPointF(); + } +} + +/*! \internal + + Adds \a pos to the childX list of this anchor, which keeps track of which children use this + anchor as parent anchor for the respective coordinate. This is necessary to notify the children + prior to destruction of the anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::addChildX(QCPItemPosition *pos) +{ + if (!mChildrenX.contains(pos)) + mChildrenX.insert(pos); + else + qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); +} + +/*! \internal + + Removes \a pos from the childX list of this anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::removeChildX(QCPItemPosition *pos) +{ + if (!mChildrenX.remove(pos)) + qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); +} + +/*! \internal + + Adds \a pos to the childY list of this anchor, which keeps track of which children use this + anchor as parent anchor for the respective coordinate. This is necessary to notify the children + prior to destruction of the anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::addChildY(QCPItemPosition *pos) +{ + if (!mChildrenY.contains(pos)) + mChildrenY.insert(pos); + else + qDebug() << Q_FUNC_INFO << "provided pos is child already" << reinterpret_cast(pos); +} + +/*! \internal + + Removes \a pos from the childY list of this anchor. + + Note that this function does not change the parent setting in \a pos. +*/ +void QCPItemAnchor::removeChildY(QCPItemPosition *pos) +{ + if (!mChildrenY.remove(pos)) + qDebug() << Q_FUNC_INFO << "provided pos isn't child" << reinterpret_cast(pos); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemPosition +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemPosition + \brief Manages the position of an item. + + Every item has at least one public QCPItemPosition member pointer which provides ways to position the + item on the QCustomPlot surface. Some items have multiple positions, for example QCPItemRect has two: + \a topLeft and \a bottomRight. + + QCPItemPosition has a type (\ref PositionType) that can be set with \ref setType. This type + defines how coordinates passed to \ref setCoords are to be interpreted, e.g. as absolute pixel + coordinates, as plot coordinates of certain axes, etc. For more advanced plots it is also + possible to assign different types per X/Y coordinate of the position (see \ref setTypeX, \ref + setTypeY). This way an item could be positioned at a fixed pixel distance from the top in the Y + direction, while following a plot coordinate in the X direction. + + A QCPItemPosition may have a parent QCPItemAnchor, see \ref setParentAnchor. This way you can tie + multiple items together. If the QCPItemPosition has a parent, its coordinates (\ref setCoords) + are considered to be absolute pixels in the reference frame of the parent anchor, where (0, 0) + means directly ontop of the parent anchor. For example, You could attach the \a start position of + a QCPItemLine to the \a bottom anchor of a QCPItemText to make the starting point of the line + always be centered under the text label, no matter where the text is moved to. For more advanced + plots, it is possible to assign different parent anchors per X/Y coordinate of the position, see + \ref setParentAnchorX, \ref setParentAnchorY. This way an item could follow another item in the X + direction but stay at a fixed position in the Y direction. Or even follow item A in X, and item B + in Y. + + Note that every QCPItemPosition inherits from QCPItemAnchor and thus can itself be used as parent + anchor for other positions. + + To set the apparent pixel position on the QCustomPlot surface directly, use \ref setPixelPosition. This + works no matter what type this QCPItemPosition is or what parent-child situation it is in, as \ref + setPixelPosition transforms the coordinates appropriately, to make the position appear at the specified + pixel values. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPItemPosition::PositionType *QCPItemPosition::type() const + + Returns the current position type. + + If different types were set for X and Y (\ref setTypeX, \ref setTypeY), this method returns the + type of the X coordinate. In that case rather use \a typeX() and \a typeY(). + + \see setType +*/ + +/*! \fn QCPItemAnchor *QCPItemPosition::parentAnchor() const + + Returns the current parent anchor. + + If different parent anchors were set for X and Y (\ref setParentAnchorX, \ref setParentAnchorY), + this method returns the parent anchor of the Y coordinate. In that case rather use \a + parentAnchorX() and \a parentAnchorY(). + + \see setParentAnchor +*/ + +/* end documentation of inline functions */ + +/*! + Creates a new QCPItemPosition. You shouldn't create QCPItemPosition instances directly, even if + you want to make a new item subclass. Use \ref QCPAbstractItem::createPosition instead, as + explained in the subclassing section of the QCPAbstractItem documentation. +*/ +QCPItemPosition::QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name) : + QCPItemAnchor(parentPlot, parentItem, name), + mPositionTypeX(ptAbsolute), + mPositionTypeY(ptAbsolute), + mKey(0), + mValue(0), + mParentAnchorX(0), + mParentAnchorY(0) +{ +} + +QCPItemPosition::~QCPItemPosition() +{ + // unregister as parent at children: + // Note: this is done in ~QCPItemAnchor again, but it's important QCPItemPosition does it itself, because only then + // the setParentAnchor(0) call the correct QCPItemPosition::pixelPosition function instead of QCPItemAnchor::pixelPosition + foreach (QCPItemPosition *child, mChildrenX.toList()) + { + if (child->parentAnchorX() == this) + child->setParentAnchorX(0); // this acts back on this anchor and child removes itself from mChildrenX + } + foreach (QCPItemPosition *child, mChildrenY.toList()) + { + if (child->parentAnchorY() == this) + child->setParentAnchorY(0); // this acts back on this anchor and child removes itself from mChildrenY + } + // unregister as child in parent: + if (mParentAnchorX) + mParentAnchorX->removeChildX(this); + if (mParentAnchorY) + mParentAnchorY->removeChildY(this); +} + +/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ +QCPAxisRect *QCPItemPosition::axisRect() const +{ + return mAxisRect.data(); +} + +/*! + Sets the type of the position. The type defines how the coordinates passed to \ref setCoords + should be handled and how the QCPItemPosition should behave in the plot. + + The possible values for \a type can be separated in two main categories: + + \li The position is regarded as a point in plot coordinates. This corresponds to \ref ptPlotCoords + and requires two axes that define the plot coordinate system. They can be specified with \ref setAxes. + By default, the QCustomPlot's x- and yAxis are used. + + \li The position is fixed on the QCustomPlot surface, i.e. independent of axis ranges. This + corresponds to all other types, i.e. \ref ptAbsolute, \ref ptViewportRatio and \ref + ptAxisRectRatio. They differ only in the way the absolute position is described, see the + documentation of \ref PositionType for details. For \ref ptAxisRectRatio, note that you can specify + the axis rect with \ref setAxisRect. By default this is set to the main axis rect. + + Note that the position type \ref ptPlotCoords is only available (and sensible) when the position + has no parent anchor (\ref setParentAnchor). + + If the type is changed, the apparent pixel position on the plot is preserved. This means + the coordinates as retrieved with coords() and set with \ref setCoords may change in the process. + + This method sets the type for both X and Y directions. It is also possible to set different types + for X and Y, see \ref setTypeX, \ref setTypeY. +*/ +void QCPItemPosition::setType(QCPItemPosition::PositionType type) +{ + setTypeX(type); + setTypeY(type); +} + +/*! + This method sets the position type of the X coordinate to \a type. + + For a detailed description of what a position type is, see the documentation of \ref setType. + + \see setType, setTypeY +*/ +void QCPItemPosition::setTypeX(QCPItemPosition::PositionType type) +{ + if (mPositionTypeX != type) + { + // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect + // were deleted), don't try to recover the pixelPosition() because it would output a qDebug warning. + bool retainPixelPosition = true; + if ((mPositionTypeX == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) + retainPixelPosition = false; + if ((mPositionTypeX == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) + retainPixelPosition = false; + + QPointF pixel; + if (retainPixelPosition) + pixel = pixelPosition(); + + mPositionTypeX = type; + + if (retainPixelPosition) + setPixelPosition(pixel); + } +} + +/*! + This method sets the position type of the Y coordinate to \a type. + + For a detailed description of what a position type is, see the documentation of \ref setType. + + \see setType, setTypeX +*/ +void QCPItemPosition::setTypeY(QCPItemPosition::PositionType type) +{ + if (mPositionTypeY != type) + { + // if switching from or to coordinate type that isn't valid (e.g. because axes or axis rect + // were deleted), don't try to recover the pixelPosition() because it would output a qDebug warning. + bool retainPixelPosition = true; + if ((mPositionTypeY == ptPlotCoords || type == ptPlotCoords) && (!mKeyAxis || !mValueAxis)) + retainPixelPosition = false; + if ((mPositionTypeY == ptAxisRectRatio || type == ptAxisRectRatio) && (!mAxisRect)) + retainPixelPosition = false; + + QPointF pixel; + if (retainPixelPosition) + pixel = pixelPosition(); + + mPositionTypeY = type; + + if (retainPixelPosition) + setPixelPosition(pixel); + } +} + +/*! + Sets the parent of this QCPItemPosition to \a parentAnchor. This means the position will now + follow any position changes of the anchor. The local coordinate system of positions with a parent + anchor always is absolute pixels, with (0, 0) being exactly on top of the parent anchor. (Hence + the type shouldn't be set to \ref ptPlotCoords for positions with parent anchors.) + + if \a keepPixelPosition is true, the current pixel position of the QCPItemPosition is preserved + during reparenting. If it's set to false, the coordinates are set to (0, 0), i.e. the position + will be exactly on top of the parent anchor. + + To remove this QCPItemPosition from any parent anchor, set \a parentAnchor to 0. + + If the QCPItemPosition previously had no parent and the type is \ref ptPlotCoords, the type is + set to \ref ptAbsolute, to keep the position in a valid state. + + This method sets the parent anchor for both X and Y directions. It is also possible to set + different parents for X and Y, see \ref setParentAnchorX, \ref setParentAnchorY. +*/ +bool QCPItemPosition::setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + bool successX = setParentAnchorX(parentAnchor, keepPixelPosition); + bool successY = setParentAnchorY(parentAnchor, keepPixelPosition); + return successX && successY; +} + +/*! + This method sets the parent anchor of the X coordinate to \a parentAnchor. + + For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. + + \see setParentAnchor, setParentAnchorY +*/ +bool QCPItemPosition::setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + // make sure self is not assigned as parent: + if (parentAnchor == this) + { + qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); + return false; + } + // make sure no recursive parent-child-relationships are created: + QCPItemAnchor *currentParent = parentAnchor; + while (currentParent) + { + if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) + { + // is a QCPItemPosition, might have further parent, so keep iterating + if (currentParentPos == this) + { + qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); + return false; + } + currentParent = currentParentPos->parentAnchorX(); + } else + { + // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the + // same, to prevent a position being child of an anchor which itself depends on the position, + // because they're both on the same item: + if (currentParent->mParentItem == mParentItem) + { + qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); + return false; + } + break; + } + } + + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: + if (!mParentAnchorX && mPositionTypeX == ptPlotCoords) + setTypeX(ptAbsolute); + + // save pixel position: + QPointF pixelP; + if (keepPixelPosition) + pixelP = pixelPosition(); + // unregister at current parent anchor: + if (mParentAnchorX) + mParentAnchorX->removeChildX(this); + // register at new parent anchor: + if (parentAnchor) + parentAnchor->addChildX(this); + mParentAnchorX = parentAnchor; + // restore pixel position under new parent: + if (keepPixelPosition) + setPixelPosition(pixelP); + else + setCoords(0, coords().y()); + return true; +} + +/*! + This method sets the parent anchor of the Y coordinate to \a parentAnchor. + + For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor. + + \see setParentAnchor, setParentAnchorX +*/ +bool QCPItemPosition::setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition) +{ + // make sure self is not assigned as parent: + if (parentAnchor == this) + { + qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast(parentAnchor); + return false; + } + // make sure no recursive parent-child-relationships are created: + QCPItemAnchor *currentParent = parentAnchor; + while (currentParent) + { + if (QCPItemPosition *currentParentPos = currentParent->toQCPItemPosition()) + { + // is a QCPItemPosition, might have further parent, so keep iterating + if (currentParentPos == this) + { + qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast(parentAnchor); + return false; + } + currentParent = currentParentPos->parentAnchorY(); + } else + { + // is a QCPItemAnchor, can't have further parent. Now make sure the parent items aren't the + // same, to prevent a position being child of an anchor which itself depends on the position, + // because they're both on the same item: + if (currentParent->mParentItem == mParentItem) + { + qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast(parentAnchor); + return false; + } + break; + } + } + + // if previously no parent set and PosType is still ptPlotCoords, set to ptAbsolute: + if (!mParentAnchorY && mPositionTypeY == ptPlotCoords) + setTypeY(ptAbsolute); + + // save pixel position: + QPointF pixelP; + if (keepPixelPosition) + pixelP = pixelPosition(); + // unregister at current parent anchor: + if (mParentAnchorY) + mParentAnchorY->removeChildY(this); + // register at new parent anchor: + if (parentAnchor) + parentAnchor->addChildY(this); + mParentAnchorY = parentAnchor; + // restore pixel position under new parent: + if (keepPixelPosition) + setPixelPosition(pixelP); + else + setCoords(coords().x(), 0); + return true; +} + +/*! + Sets the coordinates of this QCPItemPosition. What the coordinates mean, is defined by the type + (\ref setType, \ref setTypeX, \ref setTypeY). + + For example, if the type is \ref ptAbsolute, \a key and \a value mean the x and y pixel position + on the QCustomPlot surface. In that case the origin (0, 0) is in the top left corner of the + QCustomPlot viewport. If the type is \ref ptPlotCoords, \a key and \a value mean a point in the + plot coordinate system defined by the axes set by \ref setAxes. By default those are the + QCustomPlot's xAxis and yAxis. See the documentation of \ref setType for other available + coordinate types and their meaning. + + If different types were configured for X and Y (\ref setTypeX, \ref setTypeY), \a key and \a + value must also be provided in the different coordinate systems. Here, the X type refers to \a + key, and the Y type refers to \a value. + + \see setPixelPosition +*/ +void QCPItemPosition::setCoords(double key, double value) +{ + mKey = key; + mValue = value; +} + +/*! \overload + + Sets the coordinates as a QPointF \a pos where pos.x has the meaning of \a key and pos.y the + meaning of \a value of the \ref setCoords(double key, double value) method. +*/ +void QCPItemPosition::setCoords(const QPointF &pos) +{ + setCoords(pos.x(), pos.y()); +} + +/*! + Returns the final absolute pixel position of the QCPItemPosition on the QCustomPlot surface. It + includes all effects of type (\ref setType) and possible parent anchors (\ref setParentAnchor). + + \see setPixelPosition +*/ +QPointF QCPItemPosition::pixelPosition() const +{ + QPointF result; + + // determine X: + switch (mPositionTypeX) + { + case ptAbsolute: + { + result.rx() = mKey; + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + break; + } + case ptViewportRatio: + { + result.rx() = mKey*mParentPlot->viewport().width(); + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + else + result.rx() += mParentPlot->viewport().left(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + result.rx() = mKey*mAxisRect.data()->width(); + if (mParentAnchorX) + result.rx() += mParentAnchorX->pixelPosition().x(); + else + result.rx() += mAxisRect.data()->left(); + } else + qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) + result.rx() = mKeyAxis.data()->coordToPixel(mKey); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) + result.rx() = mValueAxis.data()->coordToPixel(mValue); + else + qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; + break; + } + } + + // determine Y: + switch (mPositionTypeY) + { + case ptAbsolute: + { + result.ry() = mValue; + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + break; + } + case ptViewportRatio: + { + result.ry() = mValue*mParentPlot->viewport().height(); + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + else + result.ry() += mParentPlot->viewport().top(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + result.ry() = mValue*mAxisRect.data()->height(); + if (mParentAnchorY) + result.ry() += mParentAnchorY->pixelPosition().y(); + else + result.ry() += mAxisRect.data()->top(); + } else + qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) + result.ry() = mKeyAxis.data()->coordToPixel(mKey); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) + result.ry() = mValueAxis.data()->coordToPixel(mValue); + else + qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; + break; + } + } + + return result; +} + +/*! + When \ref setType is \ref ptPlotCoords, this function may be used to specify the axes the + coordinates set with \ref setCoords relate to. By default they are set to the initial xAxis and + yAxis of the QCustomPlot. +*/ +void QCPItemPosition::setAxes(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + mKeyAxis = keyAxis; + mValueAxis = valueAxis; +} + +/*! + When \ref setType is \ref ptAxisRectRatio, this function may be used to specify the axis rect the + coordinates set with \ref setCoords relate to. By default this is set to the main axis rect of + the QCustomPlot. +*/ +void QCPItemPosition::setAxisRect(QCPAxisRect *axisRect) +{ + mAxisRect = axisRect; +} + +/*! + Sets the apparent pixel position. This works no matter what type (\ref setType) this + QCPItemPosition is or what parent-child situation it is in, as coordinates are transformed + appropriately, to make the position finally appear at the specified pixel values. + + Only if the type is \ref ptAbsolute and no parent anchor is set, this function's effect is + identical to that of \ref setCoords. + + \see pixelPosition, setCoords +*/ +void QCPItemPosition::setPixelPosition(const QPointF &pixelPosition) +{ + double x = pixelPosition.x(); + double y = pixelPosition.y(); + + switch (mPositionTypeX) + { + case ptAbsolute: + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + break; + } + case ptViewportRatio: + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + else + x -= mParentPlot->viewport().left(); + x /= (double)mParentPlot->viewport().width(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + if (mParentAnchorX) + x -= mParentAnchorX->pixelPosition().x(); + else + x -= mAxisRect.data()->left(); + x /= (double)mAxisRect.data()->width(); + } else + qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Horizontal) + x = mKeyAxis.data()->pixelToCoord(x); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Horizontal) + y = mValueAxis.data()->pixelToCoord(x); + else + qDebug() << Q_FUNC_INFO << "Item position type x is ptPlotCoords, but no axes were defined"; + break; + } + } + + switch (mPositionTypeY) + { + case ptAbsolute: + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + break; + } + case ptViewportRatio: + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + else + y -= mParentPlot->viewport().top(); + y /= (double)mParentPlot->viewport().height(); + break; + } + case ptAxisRectRatio: + { + if (mAxisRect) + { + if (mParentAnchorY) + y -= mParentAnchorY->pixelPosition().y(); + else + y -= mAxisRect.data()->top(); + y /= (double)mAxisRect.data()->height(); + } else + qDebug() << Q_FUNC_INFO << "Item position type y is ptAxisRectRatio, but no axis rect was defined"; + break; + } + case ptPlotCoords: + { + if (mKeyAxis && mKeyAxis.data()->orientation() == Qt::Vertical) + x = mKeyAxis.data()->pixelToCoord(y); + else if (mValueAxis && mValueAxis.data()->orientation() == Qt::Vertical) + y = mValueAxis.data()->pixelToCoord(y); + else + qDebug() << Q_FUNC_INFO << "Item position type y is ptPlotCoords, but no axes were defined"; + break; + } + } + + setCoords(x, y); +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractItem + \brief The abstract base class for all items in a plot. + + In QCustomPlot, items are supplemental graphical elements that are neither plottables + (QCPAbstractPlottable) nor axes (QCPAxis). While plottables are always tied to two axes and thus + plot coordinates, items can also be placed in absolute coordinates independent of any axes. Each + specific item has at least one QCPItemPosition member which controls the positioning. Some items + are defined by more than one coordinate and thus have two or more QCPItemPosition members (For + example, QCPItemRect has \a topLeft and \a bottomRight). + + This abstract base class defines a very basic interface like visibility and clipping. Since this + class is abstract, it can't be instantiated. Use one of the subclasses or create a subclass + yourself to create new items. + + The built-in items are: + + + + + + + + + + +
QCPItemLineA line defined by a start and an end point. May have different ending styles on each side (e.g. arrows).
QCPItemStraightLineA straight line defined by a start and a direction point. Unlike QCPItemLine, the straight line is infinitely long and has no endings.
QCPItemCurveA curve defined by start, end and two intermediate control points. May have different ending styles on each side (e.g. arrows).
QCPItemRectA rectangle
QCPItemEllipseAn ellipse
QCPItemPixmapAn arbitrary pixmap
QCPItemTextA text label
QCPItemBracketA bracket which may be used to reference/highlight certain parts in the plot.
QCPItemTracerAn item that can be attached to a QCPGraph and sticks to its data points, given a key coordinate.
+ + \section items-clipping Clipping + + Items are by default clipped to the main axis rect (they are only visible inside the axis rect). + To make an item visible outside that axis rect, disable clipping via \ref setClipToAxisRect + "setClipToAxisRect(false)". + + On the other hand if you want the item to be clipped to a different axis rect, specify it via + \ref setClipAxisRect. This clipAxisRect property of an item is only used for clipping behaviour, and + in principle is independent of the coordinate axes the item might be tied to via its position + members (\ref QCPItemPosition::setAxes). However, it is common that the axis rect for clipping + also contains the axes used for the item positions. + + \section items-using Using items + + First you instantiate the item you want to use and add it to the plot: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-1 + by default, the positions of the item are bound to the x- and y-Axis of the plot. So we can just + set the plot coordinates where the line should start/end: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-2 + If we don't want the line to be positioned in plot coordinates but a different coordinate system, + e.g. absolute pixel positions on the QCustomPlot surface, we need to change the position type like this: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-3 + Then we can set the coordinates, this time in pixels: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-4 + and make the line visible on the entire QCustomPlot, by disabling clipping to the axis rect: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpitemline-creation-5 + + For more advanced plots, it is even possible to set different types and parent anchors per X/Y + coordinate of an item position, using for example \ref QCPItemPosition::setTypeX or \ref + QCPItemPosition::setParentAnchorX. For details, see the documentation of \ref QCPItemPosition. + + \section items-subclassing Creating own items + + To create an own item, you implement a subclass of QCPAbstractItem. These are the pure + virtual functions, you must implement: + \li \ref selectTest + \li \ref draw + + See the documentation of those functions for what they need to do. + + \subsection items-positioning Allowing the item to be positioned + + As mentioned, item positions are represented by QCPItemPosition members. Let's assume the new item shall + have only one point as its position (as opposed to two like a rect or multiple like a polygon). You then add + a public member of type QCPItemPosition like so: + + \code QCPItemPosition * const myPosition;\endcode + + the const makes sure the pointer itself can't be modified from the user of your new item (the QCPItemPosition + instance it points to, can be modified, of course). + The initialization of this pointer is made easy with the \ref createPosition function. Just assign + the return value of this function to each QCPItemPosition in the constructor of your item. \ref createPosition + takes a string which is the name of the position, typically this is identical to the variable name. + For example, the constructor of QCPItemExample could look like this: + + \code + QCPItemExample::QCPItemExample(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + myPosition(createPosition("myPosition")) + { + // other constructor code + } + \endcode + + \subsection items-drawing The draw function + + To give your item a visual representation, reimplement the \ref draw function and use the passed + QCPPainter to draw the item. You can retrieve the item position in pixel coordinates from the + position member(s) via \ref QCPItemPosition::pixelPosition. + + To optimize performance you should calculate a bounding rect first (don't forget to take the pen + width into account), check whether it intersects the \ref clipRect, and only draw the item at all + if this is the case. + + \subsection items-selection The selectTest function + + Your implementation of the \ref selectTest function may use the helpers \ref + QCPVector2D::distanceSquaredToLine and \ref rectDistance. With these, the implementation of the + selection test becomes significantly simpler for most items. See the documentation of \ref + selectTest for what the function parameters mean and what the function should return. + + \subsection anchors Providing anchors + + Providing anchors (QCPItemAnchor) starts off like adding a position. First you create a public + member, e.g. + + \code QCPItemAnchor * const bottom;\endcode + + and create it in the constructor with the \ref createAnchor function, assigning it a name and an + anchor id (an integer enumerating all anchors on the item, you may create an own enum for this). + Since anchors can be placed anywhere, relative to the item's position(s), your item needs to + provide the position of every anchor with the reimplementation of the \ref anchorPixelPosition(int + anchorId) function. + + In essence the QCPItemAnchor is merely an intermediary that itself asks your item for the pixel + position when anything attached to the anchor needs to know the coordinates. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QList QCPAbstractItem::positions() const + + Returns all positions of the item in a list. + + \see anchors, position +*/ + +/*! \fn QList QCPAbstractItem::anchors() const + + Returns all anchors of the item in a list. Note that since a position (QCPItemPosition) is always + also an anchor, the list will also contain the positions of this item. + + \see positions, anchor +*/ + +/* end of documentation of inline functions */ +/* start documentation of pure virtual functions */ + +/*! \fn void QCPAbstractItem::draw(QCPPainter *painter) = 0 + \internal + + Draws this item with the provided \a painter. + + The cliprect of the provided painter is set to the rect returned by \ref clipRect before this + function is called. The clipRect depends on the clipping settings defined by \ref + setClipToAxisRect and \ref setClipAxisRect. +*/ + +/* end documentation of pure virtual functions */ +/* start documentation of signals */ + +/*! \fn void QCPAbstractItem::selectionChanged(bool selected) + This signal is emitted when the selection state of this item has changed, either by user interaction + or by a direct call to \ref setSelected. +*/ + +/* end documentation of signals */ + +/*! + Base class constructor which initializes base class members. +*/ +QCPAbstractItem::QCPAbstractItem(QCustomPlot *parentPlot) : + QCPLayerable(parentPlot), + mClipToAxisRect(false), + mSelectable(true), + mSelected(false) +{ + parentPlot->registerItem(this); + + QList rects = parentPlot->axisRects(); + if (rects.size() > 0) + { + setClipToAxisRect(true); + setClipAxisRect(rects.first()); + } +} + +QCPAbstractItem::~QCPAbstractItem() +{ + // don't delete mPositions because every position is also an anchor and thus in mAnchors + qDeleteAll(mAnchors); +} + +/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */ +QCPAxisRect *QCPAbstractItem::clipAxisRect() const +{ + return mClipAxisRect.data(); +} + +/*! + Sets whether the item shall be clipped to an axis rect or whether it shall be visible on the + entire QCustomPlot. The axis rect can be set with \ref setClipAxisRect. + + \see setClipAxisRect +*/ +void QCPAbstractItem::setClipToAxisRect(bool clip) +{ + mClipToAxisRect = clip; + if (mClipToAxisRect) + setParentLayerable(mClipAxisRect.data()); +} + +/*! + Sets the clip axis rect. It defines the rect that will be used to clip the item when \ref + setClipToAxisRect is set to true. + + \see setClipToAxisRect +*/ +void QCPAbstractItem::setClipAxisRect(QCPAxisRect *rect) +{ + mClipAxisRect = rect; + if (mClipToAxisRect) + setParentLayerable(mClipAxisRect.data()); +} + +/*! + Sets whether the user can (de-)select this item by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains QCustomPlot::iSelectItems.) + + However, even when \a selectable was set to false, it is possible to set the selection manually, + by calling \ref setSelected. + + \see QCustomPlot::setInteractions, setSelected +*/ +void QCPAbstractItem::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets whether this item is selected or not. When selected, it might use a different visual + appearance (e.g. pen and brush), this depends on the specific item though. + + The entire selection mechanism for items is handled automatically when \ref + QCustomPlot::setInteractions contains QCustomPlot::iSelectItems. You only need to call this + function when you wish to change the selection state manually. + + This function can change the selection state even when \ref setSelectable was set to false. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + \see setSelectable, selectTest +*/ +void QCPAbstractItem::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/*! + Returns the QCPItemPosition with the specified \a name. If this item doesn't have a position by + that name, returns 0. + + This function provides an alternative way to access item positions. Normally, you access + positions direcly by their member pointers (which typically have the same variable name as \a + name). + + \see positions, anchor +*/ +QCPItemPosition *QCPAbstractItem::position(const QString &name) const +{ + for (int i=0; iname() == name) + return mPositions.at(i); + } + qDebug() << Q_FUNC_INFO << "position with name not found:" << name; + return 0; +} + +/*! + Returns the QCPItemAnchor with the specified \a name. If this item doesn't have an anchor by + that name, returns 0. + + This function provides an alternative way to access item anchors. Normally, you access + anchors direcly by their member pointers (which typically have the same variable name as \a + name). + + \see anchors, position +*/ +QCPItemAnchor *QCPAbstractItem::anchor(const QString &name) const +{ + for (int i=0; iname() == name) + return mAnchors.at(i); + } + qDebug() << Q_FUNC_INFO << "anchor with name not found:" << name; + return 0; +} + +/*! + Returns whether this item has an anchor with the specified \a name. + + Note that you can check for positions with this function, too. This is because every position is + also an anchor (QCPItemPosition inherits from QCPItemAnchor). + + \see anchor, position +*/ +bool QCPAbstractItem::hasAnchor(const QString &name) const +{ + for (int i=0; iname() == name) + return true; + } + return false; +} + +/*! \internal + + Returns the rect the visual representation of this item is clipped to. This depends on the + current setting of \ref setClipToAxisRect as well as the axis rect set with \ref setClipAxisRect. + + If the item is not clipped to an axis rect, QCustomPlot's viewport rect is returned. + + \see draw +*/ +QRect QCPAbstractItem::clipRect() const +{ + if (mClipToAxisRect && mClipAxisRect) + return mClipAxisRect.data()->rect(); + else + return mParentPlot->viewport(); +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing item lines. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \see setAntialiased +*/ +void QCPAbstractItem::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeItems); +} + +/*! \internal + + A convenience function which returns the selectTest value for a specified \a rect and a specified + click position \a pos. \a filledRect defines whether a click inside the rect should also be + considered a hit or whether only the rect border is sensitive to hits. + + This function may be used to help with the implementation of the \ref selectTest function for + specific items. + + For example, if your item consists of four rects, call this function four times, once for each + rect, in your \ref selectTest reimplementation. Finally, return the minimum (non -1) of all four + returned values. +*/ +double QCPAbstractItem::rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const +{ + double result = -1; + + // distance to border: + QList lines; + lines << QLineF(rect.topLeft(), rect.topRight()) << QLineF(rect.bottomLeft(), rect.bottomRight()) + << QLineF(rect.topLeft(), rect.bottomLeft()) << QLineF(rect.topRight(), rect.bottomRight()); + double minDistSqr = std::numeric_limits::max(); + for (int i=0; i mParentPlot->selectionTolerance()*0.99) + { + if (rect.contains(pos)) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; +} + +/*! \internal + + Returns the pixel position of the anchor with Id \a anchorId. This function must be reimplemented in + item subclasses if they want to provide anchors (QCPItemAnchor). + + For example, if the item has two anchors with id 0 and 1, this function takes one of these anchor + ids and returns the respective pixel points of the specified anchor. + + \see createAnchor +*/ +QPointF QCPAbstractItem::anchorPixelPosition(int anchorId) const +{ + qDebug() << Q_FUNC_INFO << "called on item which shouldn't have any anchors (this method not reimplemented). anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Creates a QCPItemPosition, registers it with this item and returns a pointer to it. The specified + \a name must be a unique string that is usually identical to the variable name of the position + member (This is needed to provide the name-based \ref position access to positions). + + Don't delete positions created by this function manually, as the item will take care of it. + + Use this function in the constructor (initialization list) of the specific item subclass to + create each position member. Don't create QCPItemPositions with \b new yourself, because they + won't be registered with the item properly. + + \see createAnchor +*/ +QCPItemPosition *QCPAbstractItem::createPosition(const QString &name) +{ + if (hasAnchor(name)) + qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; + QCPItemPosition *newPosition = new QCPItemPosition(mParentPlot, this, name); + mPositions.append(newPosition); + mAnchors.append(newPosition); // every position is also an anchor + newPosition->setAxes(mParentPlot->xAxis, mParentPlot->yAxis); + newPosition->setType(QCPItemPosition::ptPlotCoords); + if (mParentPlot->axisRect()) + newPosition->setAxisRect(mParentPlot->axisRect()); + newPosition->setCoords(0, 0); + return newPosition; +} + +/*! \internal + + Creates a QCPItemAnchor, registers it with this item and returns a pointer to it. The specified + \a name must be a unique string that is usually identical to the variable name of the anchor + member (This is needed to provide the name based \ref anchor access to anchors). + + The \a anchorId must be a number identifying the created anchor. It is recommended to create an + enum (e.g. "AnchorIndex") for this on each item that uses anchors. This id is used by the anchor + to identify itself when it calls QCPAbstractItem::anchorPixelPosition. That function then returns + the correct pixel coordinates for the passed anchor id. + + Don't delete anchors created by this function manually, as the item will take care of it. + + Use this function in the constructor (initialization list) of the specific item subclass to + create each anchor member. Don't create QCPItemAnchors with \b new yourself, because then they + won't be registered with the item properly. + + \see createPosition +*/ +QCPItemAnchor *QCPAbstractItem::createAnchor(const QString &name, int anchorId) +{ + if (hasAnchor(name)) + qDebug() << Q_FUNC_INFO << "anchor/position with name exists already:" << name; + QCPItemAnchor *newAnchor = new QCPItemAnchor(mParentPlot, this, name, anchorId); + mAnchors.append(newAnchor); + return newAnchor; +} + +/* inherits documentation from base class */ +void QCPAbstractItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractItem::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractItem::selectionCategory() const +{ + return QCP::iSelectItems; +} +/* end of 'src/item.cpp' */ + + +/* including file 'src/core.cpp', size 124243 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCustomPlot +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCustomPlot + + \brief The central class of the library. This is the QWidget which displays the plot and + interacts with the user. + + For tutorials on how to use QCustomPlot, see the website\n + http://www.qcustomplot.com/ +*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPSelectionRect *QCustomPlot::selectionRect() const + + Allows access to the currently used QCPSelectionRect instance (or subclass thereof), that is used + to handle and draw selection rect interactions (see \ref setSelectionRectMode). + + \see setSelectionRect +*/ + +/*! \fn QCPLayoutGrid *QCustomPlot::plotLayout() const + + Returns the top level layout of this QCustomPlot instance. It is a \ref QCPLayoutGrid, initially containing just + one cell with the main QCPAxisRect inside. +*/ + +/* end of documentation of inline functions */ +/* start of documentation of signals */ + +/*! \fn void QCustomPlot::mouseDoubleClick(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse double click event. +*/ + +/*! \fn void QCustomPlot::mousePress(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse press event. + + It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref + QCPAxisRect::setRangeDragAxes. +*/ + +/*! \fn void QCustomPlot::mouseMove(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse move event. + + It is emitted before QCustomPlot handles any other mechanism like range dragging. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref + QCPAxisRect::setRangeDragAxes. + + \warning It is discouraged to change the drag-axes with \ref QCPAxisRect::setRangeDragAxes here, + because the dragging starting point was saved the moment the mouse was pressed. Thus it only has + a meaning for the range drag axes that were set at that moment. If you want to change the drag + axes, consider doing this in the \ref mousePress signal instead. +*/ + +/*! \fn void QCustomPlot::mouseRelease(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse release event. + + It is emitted before QCustomPlot handles any other mechanisms like object selection. So a + slot connected to this signal can still influence the behaviour e.g. with \ref setInteractions or + \ref QCPAbstractPlottable::setSelectable. +*/ + +/*! \fn void QCustomPlot::mouseWheel(QMouseEvent *event) + + This signal is emitted when the QCustomPlot receives a mouse wheel event. + + It is emitted before QCustomPlot handles any other mechanisms like range zooming. So a slot + connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeZoom, \ref + QCPAxisRect::setRangeZoomAxes or \ref QCPAxisRect::setRangeZoomFactor. +*/ + +/*! \fn void QCustomPlot::plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) + + This signal is emitted when a plottable is clicked. + + \a event is the mouse event that caused the click and \a plottable is the plottable that received + the click. The parameter \a dataIndex indicates the data point that was closest to the click + position. + + \see plottableDoubleClick +*/ + +/*! \fn void QCustomPlot::plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event) + + This signal is emitted when a plottable is double clicked. + + \a event is the mouse event that caused the click and \a plottable is the plottable that received + the click. The parameter \a dataIndex indicates the data point that was closest to the click + position. + + \see plottableClick +*/ + +/*! \fn void QCustomPlot::itemClick(QCPAbstractItem *item, QMouseEvent *event) + + This signal is emitted when an item is clicked. + + \a event is the mouse event that caused the click and \a item is the item that received the + click. + + \see itemDoubleClick +*/ + +/*! \fn void QCustomPlot::itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event) + + This signal is emitted when an item is double clicked. + + \a event is the mouse event that caused the click and \a item is the item that received the + click. + + \see itemClick +*/ + +/*! \fn void QCustomPlot::axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) + + This signal is emitted when an axis is clicked. + + \a event is the mouse event that caused the click, \a axis is the axis that received the click and + \a part indicates the part of the axis that was clicked. + + \see axisDoubleClick +*/ + +/*! \fn void QCustomPlot::axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) + + This signal is emitted when an axis is double clicked. + + \a event is the mouse event that caused the click, \a axis is the axis that received the click and + \a part indicates the part of the axis that was clicked. + + \see axisClick +*/ + +/*! \fn void QCustomPlot::legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) + + This signal is emitted when a legend (item) is clicked. + + \a event is the mouse event that caused the click, \a legend is the legend that received the + click and \a item is the legend item that received the click. If only the legend and no item is + clicked, \a item is 0. This happens for a click inside the legend padding or the space between + two items. + + \see legendDoubleClick +*/ + +/*! \fn void QCustomPlot::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event) + + This signal is emitted when a legend (item) is double clicked. + + \a event is the mouse event that caused the click, \a legend is the legend that received the + click and \a item is the legend item that received the click. If only the legend and no item is + clicked, \a item is 0. This happens for a click inside the legend padding or the space between + two items. + + \see legendClick +*/ + +/*! \fn void QCustomPlot::selectionChangedByUser() + + This signal is emitted after the user has changed the selection in the QCustomPlot, e.g. by + clicking. It is not emitted when the selection state of an object has changed programmatically by + a direct call to setSelected()/setSelection() on an object or by calling \ref + deselectAll. + + In addition to this signal, selectable objects also provide individual signals, for example \ref + QCPAxis::selectionChanged or \ref QCPAbstractPlottable::selectionChanged. Note that those signals + are emitted even if the selection state is changed programmatically. + + See the documentation of \ref setInteractions for details about the selection mechanism. + + \see selectedPlottables, selectedGraphs, selectedItems, selectedAxes, selectedLegends +*/ + +/*! \fn void QCustomPlot::beforeReplot() + + This signal is emitted immediately before a replot takes place (caused by a call to the slot \ref + replot). + + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them + replot synchronously, it won't cause an infinite recursion. + + \see replot, afterReplot +*/ + +/*! \fn void QCustomPlot::afterReplot() + + This signal is emitted immediately after a replot has taken place (caused by a call to the slot \ref + replot). + + It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them + replot synchronously, it won't cause an infinite recursion. + + \see replot, beforeReplot +*/ + +/* end of documentation of signals */ +/* start of documentation of public members */ + +/*! \var QCPAxis *QCustomPlot::xAxis + + A pointer to the primary x Axis (bottom) of the main axis rect of the plot. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::yAxis + + A pointer to the primary y Axis (left) of the main axis rect of the plot. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::xAxis2 + + A pointer to the secondary x Axis (top) of the main axis rect of the plot. Secondary axes are + invisible by default. Use QCPAxis::setVisible to change this (or use \ref + QCPAxisRect::setupFullAxesBox). + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPAxis *QCustomPlot::yAxis2 + + A pointer to the secondary y Axis (right) of the main axis rect of the plot. Secondary axes are + invisible by default. Use QCPAxis::setVisible to change this (or use \ref + QCPAxisRect::setupFullAxesBox). + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple axis rects or multiple axes to one side, use the \ref + QCPAxisRect::axis interface to access the new axes. If one of the four default axes or the + default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointers become 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/*! \var QCPLegend *QCustomPlot::legend + + A pointer to the default legend of the main axis rect. The legend is invisible by default. Use + QCPLegend::setVisible to change this. + + QCustomPlot offers convenient pointers to the axes (\ref xAxis, \ref yAxis, \ref xAxis2, \ref + yAxis2) and the \ref legend. They make it very easy working with plots that only have a single + axis rect and at most one axis at each axis rect side. If you use \link thelayoutsystem the + layout system\endlink to add multiple legends to the plot, use the layout system interface to + access the new legend. For example, legends can be placed inside an axis rect's \ref + QCPAxisRect::insetLayout "inset layout", and must then also be accessed via the inset layout. If + the default legend is removed due to manipulation of the layout system (e.g. by removing the main + axis rect), the corresponding pointer becomes 0. + + If an axis convenience pointer is currently zero and a new axis rect or a corresponding axis is + added in the place of the main axis rect, QCustomPlot resets the convenience pointers to the + according new axes. Similarly the \ref legend convenience pointer will be reset if a legend is + added after the main legend was removed before. +*/ + +/* end of documentation of public members */ + +/*! + Constructs a QCustomPlot and sets reasonable default values. +*/ +QCustomPlot::QCustomPlot(QWidget *parent) : + QWidget(parent), + xAxis(0), + yAxis(0), + xAxis2(0), + yAxis2(0), + legend(0), + mBufferDevicePixelRatio(1.0), // will be adapted to primary screen below + mPlotLayout(0), + mAutoAddPlottableToLegend(true), + mAntialiasedElements(QCP::aeNone), + mNotAntialiasedElements(QCP::aeNone), + mInteractions(0), + mSelectionTolerance(8), + mNoAntialiasingOnDrag(false), + mBackgroundBrush(Qt::white, Qt::SolidPattern), + mBackgroundScaled(true), + mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), + mCurrentLayer(0), + mPlottingHints(QCP::phCacheLabels|QCP::phImmediateRefresh), + mMultiSelectModifier(Qt::ControlModifier), + mSelectionRectMode(QCP::srmNone), + mSelectionRect(0), + mOpenGl(false), + mMouseHasMoved(false), + mMouseEventLayerable(0), + mReplotting(false), + mReplotQueued(false), + mOpenGlMultisamples(16), + mOpenGlAntialiasedElementsBackup(QCP::aeNone), + mOpenGlCacheLabelsBackup(true) +{ + setAttribute(Qt::WA_NoMousePropagation); + setAttribute(Qt::WA_OpaquePaintEvent); + setFocusPolicy(Qt::ClickFocus); + setMouseTracking(true); + QLocale currentLocale = locale(); + currentLocale.setNumberOptions(QLocale::OmitGroupSeparator); + setLocale(currentLocale); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + setBufferDevicePixelRatio(QWidget::devicePixelRatio()); +#endif + + mOpenGlAntialiasedElementsBackup = mAntialiasedElements; + mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); + // create initial layers: + mLayers.append(new QCPLayer(this, QLatin1String("background"))); + mLayers.append(new QCPLayer(this, QLatin1String("grid"))); + mLayers.append(new QCPLayer(this, QLatin1String("main"))); + mLayers.append(new QCPLayer(this, QLatin1String("axes"))); + mLayers.append(new QCPLayer(this, QLatin1String("legend"))); + mLayers.append(new QCPLayer(this, QLatin1String("overlay"))); + updateLayerIndices(); + setCurrentLayer(QLatin1String("main")); + layer(QLatin1String("overlay"))->setMode(QCPLayer::lmBuffered); + + // create initial layout, axis rect and legend: + mPlotLayout = new QCPLayoutGrid; + mPlotLayout->initializeParentPlot(this); + mPlotLayout->setParent(this); // important because if parent is QWidget, QCPLayout::sizeConstraintsChanged will call QWidget::updateGeometry + mPlotLayout->setLayer(QLatin1String("main")); + QCPAxisRect *defaultAxisRect = new QCPAxisRect(this, true); + mPlotLayout->addElement(0, 0, defaultAxisRect); + xAxis = defaultAxisRect->axis(QCPAxis::atBottom); + yAxis = defaultAxisRect->axis(QCPAxis::atLeft); + xAxis2 = defaultAxisRect->axis(QCPAxis::atTop); + yAxis2 = defaultAxisRect->axis(QCPAxis::atRight); + legend = new QCPLegend; + legend->setVisible(false); + defaultAxisRect->insetLayout()->addElement(legend, Qt::AlignRight|Qt::AlignTop); + defaultAxisRect->insetLayout()->setMargins(QMargins(12, 12, 12, 12)); + + defaultAxisRect->setLayer(QLatin1String("background")); + xAxis->setLayer(QLatin1String("axes")); + yAxis->setLayer(QLatin1String("axes")); + xAxis2->setLayer(QLatin1String("axes")); + yAxis2->setLayer(QLatin1String("axes")); + xAxis->grid()->setLayer(QLatin1String("grid")); + yAxis->grid()->setLayer(QLatin1String("grid")); + xAxis2->grid()->setLayer(QLatin1String("grid")); + yAxis2->grid()->setLayer(QLatin1String("grid")); + legend->setLayer(QLatin1String("legend")); + + // create selection rect instance: + mSelectionRect = new QCPSelectionRect(this); + mSelectionRect->setLayer(QLatin1String("overlay")); + + setViewport(rect()); // needs to be called after mPlotLayout has been created + + replot(rpQueuedReplot); +} + +QCustomPlot::~QCustomPlot() +{ + clearPlottables(); + clearItems(); + + if (mPlotLayout) + { + delete mPlotLayout; + mPlotLayout = 0; + } + + mCurrentLayer = 0; + qDeleteAll(mLayers); // don't use removeLayer, because it would prevent the last layer to be removed + mLayers.clear(); +} + +/*! + Sets which elements are forcibly drawn antialiased as an \a or combination of QCP::AntialiasedElement. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a antialiasedElements contains \ref QCP::aePlottables, all plottables will be + drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set + to. + + if an element in \a antialiasedElements is already set in \ref setNotAntialiasedElements, it is + removed from there. + + \see setNotAntialiasedElements +*/ +void QCustomPlot::setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements) +{ + mAntialiasedElements = antialiasedElements; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mNotAntialiasedElements |= ~mAntialiasedElements; +} + +/*! + Sets whether the specified \a antialiasedElement is forcibly drawn antialiased. + + See \ref setAntialiasedElements for details. + + \see setNotAntialiasedElement +*/ +void QCustomPlot::setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled) +{ + if (!enabled && mAntialiasedElements.testFlag(antialiasedElement)) + mAntialiasedElements &= ~antialiasedElement; + else if (enabled && !mAntialiasedElements.testFlag(antialiasedElement)) + mAntialiasedElements |= antialiasedElement; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mNotAntialiasedElements |= ~mAntialiasedElements; +} + +/*! + Sets which elements are forcibly drawn not antialiased as an \a or combination of + QCP::AntialiasedElement. + + This overrides the antialiasing settings for whole element groups, normally controlled with the + \a setAntialiasing function on the individual elements. If an element is neither specified in + \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on + each individual element instance is used. + + For example, if \a notAntialiasedElements contains \ref QCP::aePlottables, no plottables will be + drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set + to. + + if an element in \a notAntialiasedElements is already set in \ref setAntialiasedElements, it is + removed from there. + + \see setAntialiasedElements +*/ +void QCustomPlot::setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements) +{ + mNotAntialiasedElements = notAntialiasedElements; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mAntialiasedElements |= ~mNotAntialiasedElements; +} + +/*! + Sets whether the specified \a notAntialiasedElement is forcibly drawn not antialiased. + + See \ref setNotAntialiasedElements for details. + + \see setAntialiasedElement +*/ +void QCustomPlot::setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled) +{ + if (!enabled && mNotAntialiasedElements.testFlag(notAntialiasedElement)) + mNotAntialiasedElements &= ~notAntialiasedElement; + else if (enabled && !mNotAntialiasedElements.testFlag(notAntialiasedElement)) + mNotAntialiasedElements |= notAntialiasedElement; + + // make sure elements aren't in mNotAntialiasedElements and mAntialiasedElements simultaneously: + if ((mNotAntialiasedElements & mAntialiasedElements) != 0) + mAntialiasedElements |= ~mNotAntialiasedElements; +} + +/*! + If set to true, adding a plottable (e.g. a graph) to the QCustomPlot automatically also adds the + plottable to the legend (QCustomPlot::legend). + + \see addGraph, QCPLegend::addItem +*/ +void QCustomPlot::setAutoAddPlottableToLegend(bool on) +{ + mAutoAddPlottableToLegend = on; +} + +/*! + Sets the possible interactions of this QCustomPlot as an or-combination of \ref QCP::Interaction + enums. There are the following types of interactions: + + Axis range manipulation is controlled via \ref QCP::iRangeDrag and \ref QCP::iRangeZoom. When the + respective interaction is enabled, the user may drag axes ranges and zoom with the mouse wheel. + For details how to control which axes the user may drag/zoom and in what orientations, see \ref + QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeDragAxes, + \ref QCPAxisRect::setRangeZoomAxes. + + Plottable data selection is controlled by \ref QCP::iSelectPlottables. If \ref + QCP::iSelectPlottables is set, the user may select plottables (graphs, curves, bars,...) and + their data by clicking on them or in their vicinity (\ref setSelectionTolerance). Whether the + user can actually select a plottable and its data can further be restricted with the \ref + QCPAbstractPlottable::setSelectable method on the specific plottable. For details, see the + special page about the \ref dataselection "data selection mechanism". To retrieve a list of all + currently selected plottables, call \ref selectedPlottables. If you're only interested in + QCPGraphs, you may use the convenience function \ref selectedGraphs. + + Item selection is controlled by \ref QCP::iSelectItems. If \ref QCP::iSelectItems is set, the user + may select items (QCPItemLine, QCPItemText,...) by clicking on them or in their vicinity. To find + out whether a specific item is selected, call QCPAbstractItem::selected(). To retrieve a list of + all currently selected items, call \ref selectedItems. + + Axis selection is controlled with \ref QCP::iSelectAxes. If \ref QCP::iSelectAxes is set, the user + may select parts of the axes by clicking on them. What parts exactly (e.g. Axis base line, tick + labels, axis label) are selectable can be controlled via \ref QCPAxis::setSelectableParts for + each axis. To retrieve a list of all axes that currently contain selected parts, call \ref + selectedAxes. Which parts of an axis are selected, can be retrieved with QCPAxis::selectedParts(). + + Legend selection is controlled with \ref QCP::iSelectLegend. If this is set, the user may + select the legend itself or individual items by clicking on them. What parts exactly are + selectable can be controlled via \ref QCPLegend::setSelectableParts. To find out whether the + legend or any of its child items are selected, check the value of QCPLegend::selectedParts. To + find out which child items are selected, call \ref QCPLegend::selectedItems. + + All other selectable elements The selection of all other selectable objects (e.g. + QCPTextElement, or your own layerable subclasses) is controlled with \ref QCP::iSelectOther. If set, the + user may select those objects by clicking on them. To find out which are currently selected, you + need to check their selected state explicitly. + + If the selection state has changed by user interaction, the \ref selectionChangedByUser signal is + emitted. Each selectable object additionally emits an individual selectionChanged signal whenever + their selection state has changed, i.e. not only by user interaction. + + To allow multiple objects to be selected by holding the selection modifier (\ref + setMultiSelectModifier), set the flag \ref QCP::iMultiSelect. + + \note In addition to the selection mechanism presented here, QCustomPlot always emits + corresponding signals, when an object is clicked or double clicked. see \ref plottableClick and + \ref plottableDoubleClick for example. + + \see setInteraction, setSelectionTolerance +*/ +void QCustomPlot::setInteractions(const QCP::Interactions &interactions) +{ + mInteractions = interactions; +} + +/*! + Sets the single \a interaction of this QCustomPlot to \a enabled. + + For details about the interaction system, see \ref setInteractions. + + \see setInteractions +*/ +void QCustomPlot::setInteraction(const QCP::Interaction &interaction, bool enabled) +{ + if (!enabled && mInteractions.testFlag(interaction)) + mInteractions &= ~interaction; + else if (enabled && !mInteractions.testFlag(interaction)) + mInteractions |= interaction; +} + +/*! + Sets the tolerance that is used to decide whether a click selects an object (e.g. a plottable) or + not. + + If the user clicks in the vicinity of the line of e.g. a QCPGraph, it's only regarded as a + potential selection when the minimum distance between the click position and the graph line is + smaller than \a pixels. Objects that are defined by an area (e.g. QCPBars) only react to clicks + directly inside the area and ignore this selection tolerance. In other words, it only has meaning + for parts of objects that are too thin to exactly hit with a click and thus need such a + tolerance. + + \see setInteractions, QCPLayerable::selectTest +*/ +void QCustomPlot::setSelectionTolerance(int pixels) +{ + mSelectionTolerance = pixels; +} + +/*! + Sets whether antialiasing is disabled for this QCustomPlot while the user is dragging axes + ranges. If many objects, especially plottables, are drawn antialiased, this greatly improves + performance during dragging. Thus it creates a more responsive user experience. As soon as the + user stops dragging, the last replot is done with normal antialiasing, to restore high image + quality. + + \see setAntialiasedElements, setNotAntialiasedElements +*/ +void QCustomPlot::setNoAntialiasingOnDrag(bool enabled) +{ + mNoAntialiasingOnDrag = enabled; +} + +/*! + Sets the plotting hints for this QCustomPlot instance as an \a or combination of QCP::PlottingHint. + + \see setPlottingHint +*/ +void QCustomPlot::setPlottingHints(const QCP::PlottingHints &hints) +{ + mPlottingHints = hints; +} + +/*! + Sets the specified plotting \a hint to \a enabled. + + \see setPlottingHints +*/ +void QCustomPlot::setPlottingHint(QCP::PlottingHint hint, bool enabled) +{ + QCP::PlottingHints newHints = mPlottingHints; + if (!enabled) + newHints &= ~hint; + else + newHints |= hint; + + if (newHints != mPlottingHints) + setPlottingHints(newHints); +} + +/*! + Sets the keyboard modifier that will be recognized as multi-select-modifier. + + If \ref QCP::iMultiSelect is specified in \ref setInteractions, the user may select multiple + objects (or data points) by clicking on them one after the other while holding down \a modifier. + + By default the multi-select-modifier is set to Qt::ControlModifier. + + \see setInteractions +*/ +void QCustomPlot::setMultiSelectModifier(Qt::KeyboardModifier modifier) +{ + mMultiSelectModifier = modifier; +} + +/*! + Sets how QCustomPlot processes mouse click-and-drag interactions by the user. + + If \a mode is \ref QCP::srmNone, the mouse drag is forwarded to the underlying objects. For + example, QCPAxisRect may process a mouse drag by dragging axis ranges, see \ref + QCPAxisRect::setRangeDrag. If \a mode is not \ref QCP::srmNone, the current selection rect (\ref + selectionRect) becomes activated and allows e.g. rect zooming and data point selection. + + If you wish to provide your user both with axis range dragging and data selection/range zooming, + use this method to switch between the modes just before the interaction is processed, e.g. in + reaction to the \ref mousePress or \ref mouseMove signals. For example you could check whether + the user is holding a certain keyboard modifier, and then decide which \a mode shall be set. + + If a selection rect interaction is currently active, and \a mode is set to \ref QCP::srmNone, the + interaction is canceled (\ref QCPSelectionRect::cancel). Switching between any of the other modes + will keep the selection rect active. Upon completion of the interaction, the behaviour is as + defined by the currently set \a mode, not the mode that was set when the interaction started. + + \see setInteractions, setSelectionRect, QCPSelectionRect +*/ +void QCustomPlot::setSelectionRectMode(QCP::SelectionRectMode mode) +{ + if (mSelectionRect) + { + if (mode == QCP::srmNone) + mSelectionRect->cancel(); // when switching to none, we immediately want to abort a potentially active selection rect + + // disconnect old connections: + if (mSelectionRectMode == QCP::srmSelect) + disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mSelectionRectMode == QCP::srmZoom) + disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + + // establish new ones: + if (mode == QCP::srmSelect) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mode == QCP::srmZoom) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + } + + mSelectionRectMode = mode; +} + +/*! + Sets the \ref QCPSelectionRect instance that QCustomPlot will use if \a mode is not \ref + QCP::srmNone and the user performs a click-and-drag interaction. QCustomPlot takes ownership of + the passed \a selectionRect. It can be accessed later via \ref selectionRect. + + This method is useful if you wish to replace the default QCPSelectionRect instance with an + instance of a QCPSelectionRect subclass, to introduce custom behaviour of the selection rect. + + \see setSelectionRectMode +*/ +void QCustomPlot::setSelectionRect(QCPSelectionRect *selectionRect) +{ + if (mSelectionRect) + delete mSelectionRect; + + mSelectionRect = selectionRect; + + if (mSelectionRect) + { + // establish connections with new selection rect: + if (mSelectionRectMode == QCP::srmSelect) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*))); + else if (mSelectionRectMode == QCP::srmZoom) + connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*))); + } +} + +/*! + This method allows to enable OpenGL plot rendering, for increased plotting performance of + graphically demanding plots (thick lines, translucent fills, etc.). + + If \a enabled is set to true, QCustomPlot will try to initialize OpenGL and, if successful, + continue plotting with hardware acceleration. The parameter \a multisampling controls how many + samples will be used per pixel, it essentially controls the antialiasing quality. If \a + multisampling is set too high for the current graphics hardware, the maximum allowed value will + be used. + + You can test whether switching to OpenGL rendering was successful by checking whether the + according getter \a QCustomPlot::openGl() returns true. If the OpenGL initialization fails, + rendering continues with the regular software rasterizer, and an according qDebug output is + generated. + + If switching to OpenGL was successful, this method disables label caching (\ref setPlottingHint + "setPlottingHint(QCP::phCacheLabels, false)") and turns on QCustomPlot's antialiasing override + for all elements (\ref setAntialiasedElements "setAntialiasedElements(QCP::aeAll)"), leading to a + higher quality output. The antialiasing override allows for pixel-grid aligned drawing in the + OpenGL paint device. As stated before, in OpenGL rendering the actual antialiasing of the plot is + controlled with \a multisampling. If \a enabled is set to false, the antialiasing/label caching + settings are restored to what they were before OpenGL was enabled, if they weren't altered in the + meantime. + + \note OpenGL support is only enabled if QCustomPlot is compiled with the macro \c QCUSTOMPLOT_USE_OPENGL + defined. This define must be set before including the QCustomPlot header both during compilation + of the QCustomPlot library as well as when compiling your application. It is best to just include + the line DEFINES += QCUSTOMPLOT_USE_OPENGL in the respective qmake project files. + \note If you are using a Qt version before 5.0, you must also add the module "opengl" to your \c + QT variable in the qmake project files. For Qt versions 5.0 and higher, QCustomPlot switches to a + newer OpenGL interface which is already in the "gui" module. +*/ +void QCustomPlot::setOpenGl(bool enabled, int multisampling) +{ + mOpenGlMultisamples = qMax(0, multisampling); +#ifdef QCUSTOMPLOT_USE_OPENGL + mOpenGl = enabled; + if (mOpenGl) + { + if (setupOpenGl()) + { + // backup antialiasing override and labelcaching setting so we can restore upon disabling OpenGL + mOpenGlAntialiasedElementsBackup = mAntialiasedElements; + mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); + // set antialiasing override to antialias all (aligns gl pixel grid properly), and disable label caching (would use software rasterizer for pixmap caches): + setAntialiasedElements(QCP::aeAll); + setPlottingHint(QCP::phCacheLabels, false); + } else + { + qDebug() << Q_FUNC_INFO << "Failed to enable OpenGL, continuing plotting without hardware acceleration."; + mOpenGl = false; + } + } else + { + // restore antialiasing override and labelcaching to what it was before enabling OpenGL, if nobody changed it in the meantime: + if (mAntialiasedElements == QCP::aeAll) + setAntialiasedElements(mOpenGlAntialiasedElementsBackup); + if (!mPlottingHints.testFlag(QCP::phCacheLabels)) + setPlottingHint(QCP::phCacheLabels, mOpenGlCacheLabelsBackup); + freeOpenGl(); + } + // recreate all paint buffers: + mPaintBuffers.clear(); + setupPaintBuffers(); +#else + Q_UNUSED(enabled) + qDebug() << Q_FUNC_INFO << "QCustomPlot can't use OpenGL because QCUSTOMPLOT_USE_OPENGL was not defined during compilation (add 'DEFINES += QCUSTOMPLOT_USE_OPENGL' to your qmake .pro file)"; +#endif +} + +/*! + Sets the viewport of this QCustomPlot. Usually users of QCustomPlot don't need to change the + viewport manually. + + The viewport is the area in which the plot is drawn. All mechanisms, e.g. margin caluclation take + the viewport to be the outer border of the plot. The viewport normally is the rect() of the + QCustomPlot widget, i.e. a rect with top left (0, 0) and size of the QCustomPlot widget. + + Don't confuse the viewport with the axis rect (QCustomPlot::axisRect). An axis rect is typically + an area enclosed by four axes, where the graphs/plottables are drawn in. The viewport is larger + and contains also the axes themselves, their tick numbers, their labels, or even additional axis + rects, color scales and other layout elements. + + This function is used to allow arbitrary size exports with \ref toPixmap, \ref savePng, \ref + savePdf, etc. by temporarily changing the viewport size. +*/ +void QCustomPlot::setViewport(const QRect &rect) +{ + mViewport = rect; + if (mPlotLayout) + mPlotLayout->setOuterRect(mViewport); +} + +/*! + Sets the device pixel ratio used by the paint buffers of this QCustomPlot instance. + + Normally, this doesn't need to be set manually, because it is initialized with the regular \a + QWidget::devicePixelRatio which is configured by Qt to fit the display device (e.g. 1 for normal + displays, 2 for High-DPI displays). + + Device pixel ratios are supported by Qt only for Qt versions since 5.4. If this method is called + when QCustomPlot is being used with older Qt versions, outputs an according qDebug message and + leaves the internal buffer device pixel ratio at 1.0. +*/ +void QCustomPlot::setBufferDevicePixelRatio(double ratio) +{ + if (!qFuzzyCompare(ratio, mBufferDevicePixelRatio)) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mBufferDevicePixelRatio = ratio; + for (int i=0; isetDevicePixelRatio(mBufferDevicePixelRatio); + // Note: axis label cache has devicePixelRatio as part of cache hash, so no need to manually clear cache here +#else + qDebug() << Q_FUNC_INFO << "Device pixel ratios not supported for Qt versions before 5.4"; + mBufferDevicePixelRatio = 1.0; +#endif + } +} + +/*! + Sets \a pm as the viewport background pixmap (see \ref setViewport). The pixmap is always drawn + below all other objects in the plot. + + For cases where the provided pixmap doesn't have the same size as the viewport, scaling can be + enabled with \ref setBackgroundScaled and the scaling mode (whether and how the aspect ratio is + preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, + consider using the overloaded version of this function. + + If a background brush was set with \ref setBackground(const QBrush &brush), the viewport will + first be filled with that brush, before drawing the background pixmap. This can be useful for + background pixmaps with translucent areas. + + \see setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QPixmap &pm) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); +} + +/*! + Sets the background brush of the viewport (see \ref setViewport). + + Before drawing everything else, the background is filled with \a brush. If a background pixmap + was set with \ref setBackground(const QPixmap &pm), this brush will be used to fill the viewport + before the background pixmap is drawn. This can be useful for background pixmaps with translucent + areas. + + Set \a brush to Qt::NoBrush or Qt::Transparent to leave background transparent. This can be + useful for exporting to image formats which support transparency, e.g. \ref savePng. + + \see setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QBrush &brush) +{ + mBackgroundBrush = brush; +} + +/*! \overload + + Allows setting the background pixmap of the viewport, whether it shall be scaled and how it + shall be scaled in one call. + + \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); + mBackgroundScaled = scaled; + mBackgroundScaledMode = mode; +} + +/*! + Sets whether the viewport background pixmap shall be scaled to fit the viewport. If \a scaled is + set to true, control whether and how the aspect ratio of the original pixmap is preserved with + \ref setBackgroundScaledMode. + + Note that the scaled version of the original pixmap is buffered, so there is no performance + penalty on replots. (Except when the viewport dimensions are changed continuously.) + + \see setBackground, setBackgroundScaledMode +*/ +void QCustomPlot::setBackgroundScaled(bool scaled) +{ + mBackgroundScaled = scaled; +} + +/*! + If scaling of the viewport background pixmap is enabled (\ref setBackgroundScaled), use this + function to define whether and how the aspect ratio of the original pixmap is preserved. + + \see setBackground, setBackgroundScaled +*/ +void QCustomPlot::setBackgroundScaledMode(Qt::AspectRatioMode mode) +{ + mBackgroundScaledMode = mode; +} + +/*! + Returns the plottable with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last added + plottable, see QCustomPlot::plottable() + + \see plottableCount +*/ +QCPAbstractPlottable *QCustomPlot::plottable(int index) +{ + if (index >= 0 && index < mPlottables.size()) + { + return mPlottables.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last plottable that was added to the plot. If there are no plottables in the plot, + returns 0. + + \see plottableCount +*/ +QCPAbstractPlottable *QCustomPlot::plottable() +{ + if (!mPlottables.isEmpty()) + { + return mPlottables.last(); + } else + return 0; +} + +/*! + Removes the specified plottable from the plot and deletes it. If necessary, the corresponding + legend item is also removed from the default legend (QCustomPlot::legend). + + Returns true on success. + + \see clearPlottables +*/ +bool QCustomPlot::removePlottable(QCPAbstractPlottable *plottable) +{ + if (!mPlottables.contains(plottable)) + { + qDebug() << Q_FUNC_INFO << "plottable not in list:" << reinterpret_cast(plottable); + return false; + } + + // remove plottable from legend: + plottable->removeFromLegend(); + // special handling for QCPGraphs to maintain the simple graph interface: + if (QCPGraph *graph = qobject_cast(plottable)) + mGraphs.removeOne(graph); + // remove plottable: + delete plottable; + mPlottables.removeOne(plottable); + return true; +} + +/*! \overload + + Removes and deletes the plottable by its \a index. +*/ +bool QCustomPlot::removePlottable(int index) +{ + if (index >= 0 && index < mPlottables.size()) + return removePlottable(mPlottables[index]); + else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return false; + } +} + +/*! + Removes all plottables from the plot and deletes them. Corresponding legend items are also + removed from the default legend (QCustomPlot::legend). + + Returns the number of plottables removed. + + \see removePlottable +*/ +int QCustomPlot::clearPlottables() +{ + int c = mPlottables.size(); + for (int i=c-1; i >= 0; --i) + removePlottable(mPlottables[i]); + return c; +} + +/*! + Returns the number of currently existing plottables in the plot + + \see plottable +*/ +int QCustomPlot::plottableCount() const +{ + return mPlottables.size(); +} + +/*! + Returns a list of the selected plottables. If no plottables are currently selected, the list is empty. + + There is a convenience function if you're only interested in selected graphs, see \ref selectedGraphs. + + \see setInteractions, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection +*/ +QList QCustomPlot::selectedPlottables() const +{ + QList result; + foreach (QCPAbstractPlottable *plottable, mPlottables) + { + if (plottable->selected()) + result.append(plottable); + } + return result; +} + +/*! + Returns the plottable at the pixel position \a pos. Plottables that only consist of single lines + (like graphs) have a tolerance band around them, see \ref setSelectionTolerance. If multiple + plottables come into consideration, the one closest to \a pos is returned. + + If \a onlySelectable is true, only plottables that are selectable + (QCPAbstractPlottable::setSelectable) are considered. + + If there is no plottable at \a pos, the return value is 0. + + \see itemAt, layoutElementAt +*/ +QCPAbstractPlottable *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable) const +{ + QCPAbstractPlottable *resultPlottable = 0; + double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value + + foreach (QCPAbstractPlottable *plottable, mPlottables) + { + if (onlySelectable && !plottable->selectable()) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPabstractPlottable::selectable + continue; + if ((plottable->keyAxis()->axisRect()->rect() & plottable->valueAxis()->axisRect()->rect()).contains(pos.toPoint())) // only consider clicks inside the rect that is spanned by the plottable's key/value axes + { + double currentDistance = plottable->selectTest(pos, false); + if (currentDistance >= 0 && currentDistance < resultDistance) + { + resultPlottable = plottable; + resultDistance = currentDistance; + } + } + } + + return resultPlottable; +} + +/*! + Returns whether this QCustomPlot instance contains the \a plottable. +*/ +bool QCustomPlot::hasPlottable(QCPAbstractPlottable *plottable) const +{ + return mPlottables.contains(plottable); +} + +/*! + Returns the graph with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last created + graph, see QCustomPlot::graph() + + \see graphCount, addGraph +*/ +QCPGraph *QCustomPlot::graph(int index) const +{ + if (index >= 0 && index < mGraphs.size()) + { + return mGraphs.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last graph, that was created with \ref addGraph. If there are no graphs in the plot, + returns 0. + + \see graphCount, addGraph +*/ +QCPGraph *QCustomPlot::graph() const +{ + if (!mGraphs.isEmpty()) + { + return mGraphs.last(); + } else + return 0; +} + +/*! + Creates a new graph inside the plot. If \a keyAxis and \a valueAxis are left unspecified (0), the + bottom (xAxis) is used as key and the left (yAxis) is used as value axis. If specified, \a + keyAxis and \a valueAxis must reside in this QCustomPlot. + + \a keyAxis will be used as key axis (typically "x") and \a valueAxis as value axis (typically + "y") for the graph. + + Returns a pointer to the newly created graph, or 0 if adding the graph failed. + + \see graph, graphCount, removeGraph, clearGraphs +*/ +QCPGraph *QCustomPlot::addGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) +{ + if (!keyAxis) keyAxis = xAxis; + if (!valueAxis) valueAxis = yAxis; + if (!keyAxis || !valueAxis) + { + qDebug() << Q_FUNC_INFO << "can't use default QCustomPlot xAxis or yAxis, because at least one is invalid (has been deleted)"; + return 0; + } + if (keyAxis->parentPlot() != this || valueAxis->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "passed keyAxis or valueAxis doesn't have this QCustomPlot as parent"; + return 0; + } + + QCPGraph *newGraph = new QCPGraph(keyAxis, valueAxis); + newGraph->setName(QLatin1String("Graph ")+QString::number(mGraphs.size())); + return newGraph; +} + +/*! + Removes the specified \a graph from the plot and deletes it. If necessary, the corresponding + legend item is also removed from the default legend (QCustomPlot::legend). If any other graphs in + the plot have a channel fill set towards the removed graph, the channel fill property of those + graphs is reset to zero (no channel fill). + + Returns true on success. + + \see clearGraphs +*/ +bool QCustomPlot::removeGraph(QCPGraph *graph) +{ + return removePlottable(graph); +} + +/*! \overload + + Removes and deletes the graph by its \a index. +*/ +bool QCustomPlot::removeGraph(int index) +{ + if (index >= 0 && index < mGraphs.size()) + return removeGraph(mGraphs[index]); + else + return false; +} + +/*! + Removes all graphs from the plot and deletes them. Corresponding legend items are also removed + from the default legend (QCustomPlot::legend). + + Returns the number of graphs removed. + + \see removeGraph +*/ +int QCustomPlot::clearGraphs() +{ + int c = mGraphs.size(); + for (int i=c-1; i >= 0; --i) + removeGraph(mGraphs[i]); + return c; +} + +/*! + Returns the number of currently existing graphs in the plot + + \see graph, addGraph +*/ +int QCustomPlot::graphCount() const +{ + return mGraphs.size(); +} + +/*! + Returns a list of the selected graphs. If no graphs are currently selected, the list is empty. + + If you are not only interested in selected graphs but other plottables like QCPCurve, QCPBars, + etc., use \ref selectedPlottables. + + \see setInteractions, selectedPlottables, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection +*/ +QList QCustomPlot::selectedGraphs() const +{ + QList result; + foreach (QCPGraph *graph, mGraphs) + { + if (graph->selected()) + result.append(graph); + } + return result; +} + +/*! + Returns the item with \a index. If the index is invalid, returns 0. + + There is an overloaded version of this function with no parameter which returns the last added + item, see QCustomPlot::item() + + \see itemCount +*/ +QCPAbstractItem *QCustomPlot::item(int index) const +{ + if (index >= 0 && index < mItems.size()) + { + return mItems.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! \overload + + Returns the last item that was added to this plot. If there are no items in the plot, + returns 0. + + \see itemCount +*/ +QCPAbstractItem *QCustomPlot::item() const +{ + if (!mItems.isEmpty()) + { + return mItems.last(); + } else + return 0; +} + +/*! + Removes the specified item from the plot and deletes it. + + Returns true on success. + + \see clearItems +*/ +bool QCustomPlot::removeItem(QCPAbstractItem *item) +{ + if (mItems.contains(item)) + { + delete item; + mItems.removeOne(item); + return true; + } else + { + qDebug() << Q_FUNC_INFO << "item not in list:" << reinterpret_cast(item); + return false; + } +} + +/*! \overload + + Removes and deletes the item by its \a index. +*/ +bool QCustomPlot::removeItem(int index) +{ + if (index >= 0 && index < mItems.size()) + return removeItem(mItems[index]); + else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return false; + } +} + +/*! + Removes all items from the plot and deletes them. + + Returns the number of items removed. + + \see removeItem +*/ +int QCustomPlot::clearItems() +{ + int c = mItems.size(); + for (int i=c-1; i >= 0; --i) + removeItem(mItems[i]); + return c; +} + +/*! + Returns the number of currently existing items in the plot + + \see item +*/ +int QCustomPlot::itemCount() const +{ + return mItems.size(); +} + +/*! + Returns a list of the selected items. If no items are currently selected, the list is empty. + + \see setInteractions, QCPAbstractItem::setSelectable, QCPAbstractItem::setSelected +*/ +QList QCustomPlot::selectedItems() const +{ + QList result; + foreach (QCPAbstractItem *item, mItems) + { + if (item->selected()) + result.append(item); + } + return result; +} + +/*! + Returns the item at the pixel position \a pos. Items that only consist of single lines (e.g. \ref + QCPItemLine or \ref QCPItemCurve) have a tolerance band around them, see \ref + setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is + returned. + + If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are + considered. + + If there is no item at \a pos, the return value is 0. + + \see plottableAt, layoutElementAt +*/ +QCPAbstractItem *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const +{ + QCPAbstractItem *resultItem = 0; + double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value + + foreach (QCPAbstractItem *item, mItems) + { + if (onlySelectable && !item->selectable()) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPAbstractItem::selectable + continue; + if (!item->clipToAxisRect() || item->clipRect().contains(pos.toPoint())) // only consider clicks inside axis cliprect of the item if actually clipped to it + { + double currentDistance = item->selectTest(pos, false); + if (currentDistance >= 0 && currentDistance < resultDistance) + { + resultItem = item; + resultDistance = currentDistance; + } + } + } + + return resultItem; +} + +/*! + Returns whether this QCustomPlot contains the \a item. + + \see item +*/ +bool QCustomPlot::hasItem(QCPAbstractItem *item) const +{ + return mItems.contains(item); +} + +/*! + Returns the layer with the specified \a name. If there is no layer with the specified name, 0 is + returned. + + Layer names are case-sensitive. + + \see addLayer, moveLayer, removeLayer +*/ +QCPLayer *QCustomPlot::layer(const QString &name) const +{ + foreach (QCPLayer *layer, mLayers) + { + if (layer->name() == name) + return layer; + } + return 0; +} + +/*! \overload + + Returns the layer by \a index. If the index is invalid, 0 is returned. + + \see addLayer, moveLayer, removeLayer +*/ +QCPLayer *QCustomPlot::layer(int index) const +{ + if (index >= 0 && index < mLayers.size()) + { + return mLayers.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! + Returns the layer that is set as current layer (see \ref setCurrentLayer). +*/ +QCPLayer *QCustomPlot::currentLayer() const +{ + return mCurrentLayer; +} + +/*! + Sets the layer with the specified \a name to be the current layer. All layerables (\ref + QCPLayerable), e.g. plottables and items, are created on the current layer. + + Returns true on success, i.e. if there is a layer with the specified \a name in the QCustomPlot. + + Layer names are case-sensitive. + + \see addLayer, moveLayer, removeLayer, QCPLayerable::setLayer +*/ +bool QCustomPlot::setCurrentLayer(const QString &name) +{ + if (QCPLayer *newCurrentLayer = layer(name)) + { + return setCurrentLayer(newCurrentLayer); + } else + { + qDebug() << Q_FUNC_INFO << "layer with name doesn't exist:" << name; + return false; + } +} + +/*! \overload + + Sets the provided \a layer to be the current layer. + + Returns true on success, i.e. when \a layer is a valid layer in the QCustomPlot. + + \see addLayer, moveLayer, removeLayer +*/ +bool QCustomPlot::setCurrentLayer(QCPLayer *layer) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + + mCurrentLayer = layer; + return true; +} + +/*! + Returns the number of currently existing layers in the plot + + \see layer, addLayer +*/ +int QCustomPlot::layerCount() const +{ + return mLayers.size(); +} + +/*! + Adds a new layer to this QCustomPlot instance. The new layer will have the name \a name, which + must be unique. Depending on \a insertMode, it is positioned either below or above \a otherLayer. + + Returns true on success, i.e. if there is no other layer named \a name and \a otherLayer is a + valid layer inside this QCustomPlot. + + If \a otherLayer is 0, the highest layer in the QCustomPlot will be used. + + For an explanation of what layers are in QCustomPlot, see the documentation of \ref QCPLayer. + + \see layer, moveLayer, removeLayer +*/ +bool QCustomPlot::addLayer(const QString &name, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) +{ + if (!otherLayer) + otherLayer = mLayers.last(); + if (!mLayers.contains(otherLayer)) + { + qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); + return false; + } + if (layer(name)) + { + qDebug() << Q_FUNC_INFO << "A layer exists already with the name" << name; + return false; + } + + QCPLayer *newLayer = new QCPLayer(this, name); + mLayers.insert(otherLayer->index() + (insertMode==limAbove ? 1:0), newLayer); + updateLayerIndices(); + setupPaintBuffers(); // associates new layer with the appropriate paint buffer + return true; +} + +/*! + Removes the specified \a layer and returns true on success. + + All layerables (e.g. plottables and items) on the removed layer will be moved to the layer below + \a layer. If \a layer is the bottom layer, the layerables are moved to the layer above. In both + cases, the total rendering order of all layerables in the QCustomPlot is preserved. + + If \a layer is the current layer (\ref setCurrentLayer), the layer below (or above, if bottom + layer) becomes the new current layer. + + It is not possible to remove the last layer of the plot. + + \see layer, addLayer, moveLayer +*/ +bool QCustomPlot::removeLayer(QCPLayer *layer) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + if (mLayers.size() < 2) + { + qDebug() << Q_FUNC_INFO << "can't remove last layer"; + return false; + } + + // append all children of this layer to layer below (if this is lowest layer, prepend to layer above) + int removedIndex = layer->index(); + bool isFirstLayer = removedIndex==0; + QCPLayer *targetLayer = isFirstLayer ? mLayers.at(removedIndex+1) : mLayers.at(removedIndex-1); + QList children = layer->children(); + if (isFirstLayer) // prepend in reverse order (so order relative to each other stays the same) + { + for (int i=children.size()-1; i>=0; --i) + children.at(i)->moveToLayer(targetLayer, true); + } else // append normally + { + for (int i=0; imoveToLayer(targetLayer, false); + } + // if removed layer is current layer, change current layer to layer below/above: + if (layer == mCurrentLayer) + setCurrentLayer(targetLayer); + // invalidate the paint buffer that was responsible for this layer: + if (!layer->mPaintBuffer.isNull()) + layer->mPaintBuffer.data()->setInvalidated(); + // remove layer: + delete layer; + mLayers.removeOne(layer); + updateLayerIndices(); + return true; +} + +/*! + Moves the specified \a layer either above or below \a otherLayer. Whether it's placed above or + below is controlled with \a insertMode. + + Returns true on success, i.e. when both \a layer and \a otherLayer are valid layers in the + QCustomPlot. + + \see layer, addLayer, moveLayer +*/ +bool QCustomPlot::moveLayer(QCPLayer *layer, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode) +{ + if (!mLayers.contains(layer)) + { + qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast(layer); + return false; + } + if (!mLayers.contains(otherLayer)) + { + qDebug() << Q_FUNC_INFO << "otherLayer not a layer of this QCustomPlot:" << reinterpret_cast(otherLayer); + return false; + } + + if (layer->index() > otherLayer->index()) + mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 1:0)); + else if (layer->index() < otherLayer->index()) + mLayers.move(layer->index(), otherLayer->index() + (insertMode==limAbove ? 0:-1)); + + // invalidate the paint buffers that are responsible for the layers: + if (!layer->mPaintBuffer.isNull()) + layer->mPaintBuffer.data()->setInvalidated(); + if (!otherLayer->mPaintBuffer.isNull()) + otherLayer->mPaintBuffer.data()->setInvalidated(); + + updateLayerIndices(); + return true; +} + +/*! + Returns the number of axis rects in the plot. + + All axis rects can be accessed via QCustomPlot::axisRect(). + + Initially, only one axis rect exists in the plot. + + \see axisRect, axisRects +*/ +int QCustomPlot::axisRectCount() const +{ + return axisRects().size(); +} + +/*! + Returns the axis rect with \a index. + + Initially, only one axis rect (with index 0) exists in the plot. If multiple axis rects were + added, all of them may be accessed with this function in a linear fashion (even when they are + nested in a layout hierarchy or inside other axis rects via QCPAxisRect::insetLayout). + + \see axisRectCount, axisRects +*/ +QCPAxisRect *QCustomPlot::axisRect(int index) const +{ + const QList rectList = axisRects(); + if (index >= 0 && index < rectList.size()) + { + return rectList.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "invalid axis rect index" << index; + return 0; + } +} + +/*! + Returns all axis rects in the plot. + + \see axisRectCount, axisRect +*/ +QList QCustomPlot::axisRects() const +{ + QList result; + QStack elementStack; + if (mPlotLayout) + elementStack.push(mPlotLayout); + + while (!elementStack.isEmpty()) + { + foreach (QCPLayoutElement *element, elementStack.pop()->elements(false)) + { + if (element) + { + elementStack.push(element); + if (QCPAxisRect *ar = qobject_cast(element)) + result.append(ar); + } + } + } + + return result; +} + +/*! + Returns the layout element at pixel position \a pos. If there is no element at that position, + returns 0. + + Only visible elements are used. If \ref QCPLayoutElement::setVisible on the element itself or on + any of its parent elements is set to false, it will not be considered. + + \see itemAt, plottableAt +*/ +QCPLayoutElement *QCustomPlot::layoutElementAt(const QPointF &pos) const +{ + QCPLayoutElement *currentElement = mPlotLayout; + bool searchSubElements = true; + while (searchSubElements && currentElement) + { + searchSubElements = false; + foreach (QCPLayoutElement *subElement, currentElement->elements(false)) + { + if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) + { + currentElement = subElement; + searchSubElements = true; + break; + } + } + } + return currentElement; +} + +/*! + Returns the layout element of type \ref QCPAxisRect at pixel position \a pos. This method ignores + other layout elements even if they are visually in front of the axis rect (e.g. a \ref + QCPLegend). If there is no axis rect at that position, returns 0. + + Only visible axis rects are used. If \ref QCPLayoutElement::setVisible on the axis rect itself or + on any of its parent elements is set to false, it will not be considered. + + \see layoutElementAt +*/ +QCPAxisRect *QCustomPlot::axisRectAt(const QPointF &pos) const +{ + QCPAxisRect *result = 0; + QCPLayoutElement *currentElement = mPlotLayout; + bool searchSubElements = true; + while (searchSubElements && currentElement) + { + searchSubElements = false; + foreach (QCPLayoutElement *subElement, currentElement->elements(false)) + { + if (subElement && subElement->realVisibility() && subElement->selectTest(pos, false) >= 0) + { + currentElement = subElement; + searchSubElements = true; + if (QCPAxisRect *ar = qobject_cast(currentElement)) + result = ar; + break; + } + } + } + return result; +} + +/*! + Returns the axes that currently have selected parts, i.e. whose selection state is not \ref + QCPAxis::spNone. + + \see selectedPlottables, selectedLegends, setInteractions, QCPAxis::setSelectedParts, + QCPAxis::setSelectableParts +*/ +QList QCustomPlot::selectedAxes() const +{ + QList result, allAxes; + foreach (QCPAxisRect *rect, axisRects()) + allAxes << rect->axes(); + + foreach (QCPAxis *axis, allAxes) + { + if (axis->selectedParts() != QCPAxis::spNone) + result.append(axis); + } + + return result; +} + +/*! + Returns the legends that currently have selected parts, i.e. whose selection state is not \ref + QCPLegend::spNone. + + \see selectedPlottables, selectedAxes, setInteractions, QCPLegend::setSelectedParts, + QCPLegend::setSelectableParts, QCPLegend::selectedItems +*/ +QList QCustomPlot::selectedLegends() const +{ + QList result; + + QStack elementStack; + if (mPlotLayout) + elementStack.push(mPlotLayout); + + while (!elementStack.isEmpty()) + { + foreach (QCPLayoutElement *subElement, elementStack.pop()->elements(false)) + { + if (subElement) + { + elementStack.push(subElement); + if (QCPLegend *leg = qobject_cast(subElement)) + { + if (leg->selectedParts() != QCPLegend::spNone) + result.append(leg); + } + } + } + } + + return result; +} + +/*! + Deselects all layerables (plottables, items, axes, legends,...) of the QCustomPlot. + + Since calling this function is not a user interaction, this does not emit the \ref + selectionChangedByUser signal. The individual selectionChanged signals are emitted though, if the + objects were previously selected. + + \see setInteractions, selectedPlottables, selectedItems, selectedAxes, selectedLegends +*/ +void QCustomPlot::deselectAll() +{ + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + layerable->deselectEvent(0); + } +} + +/*! + Causes a complete replot into the internal paint buffer(s). Finally, the widget surface is + refreshed with the new buffer contents. This is the method that must be called to make changes to + the plot, e.g. on the axis ranges or data points of graphs, visible. + + The parameter \a refreshPriority can be used to fine-tune the timing of the replot. For example + if your application calls \ref replot very quickly in succession (e.g. multiple independent + functions change some aspects of the plot and each wants to make sure the change gets replotted), + it is advisable to set \a refreshPriority to \ref QCustomPlot::rpQueuedReplot. This way, the + actual replotting is deferred to the next event loop iteration. Multiple successive calls of \ref + replot with this priority will only cause a single replot, avoiding redundant replots and + improving performance. + + Under a few circumstances, QCustomPlot causes a replot by itself. Those are resize events of the + QCustomPlot widget and user interactions (object selection and range dragging/zooming). + + Before the replot happens, the signal \ref beforeReplot is emitted. After the replot, \ref + afterReplot is emitted. It is safe to mutually connect the replot slot with any of those two + signals on two QCustomPlots to make them replot synchronously, it won't cause an infinite + recursion. + + If a layer is in mode \ref QCPLayer::lmBuffered (\ref QCPLayer::setMode), it is also possible to + replot only that specific layer via \ref QCPLayer::replot. See the documentation there for + details. +*/ +void QCustomPlot::replot(QCustomPlot::RefreshPriority refreshPriority) +{ + if (refreshPriority == QCustomPlot::rpQueuedReplot) + { + if (!mReplotQueued) + { + mReplotQueued = true; + QTimer::singleShot(0, this, SLOT(replot())); + } + return; + } + + if (mReplotting) // incase signals loop back to replot slot + return; + mReplotting = true; + mReplotQueued = false; + emit beforeReplot(); + + updateLayout(); + // draw all layered objects (grid, axes, plottables, items, legend,...) into their buffers: + setupPaintBuffers(); + foreach (QCPLayer *layer, mLayers) + layer->drawToPaintBuffer(); + for (int i=0; isetInvalidated(false); + + if ((refreshPriority == rpRefreshHint && mPlottingHints.testFlag(QCP::phImmediateRefresh)) || refreshPriority==rpImmediateRefresh) + repaint(); + else + update(); + + emit afterReplot(); + mReplotting = false; +} + +/*! + Rescales the axes such that all plottables (like graphs) in the plot are fully visible. + + if \a onlyVisiblePlottables is set to true, only the plottables that have their visibility set to true + (QCPLayerable::setVisible), will be used to rescale the axes. + + \see QCPAbstractPlottable::rescaleAxes, QCPAxis::rescale +*/ +void QCustomPlot::rescaleAxes(bool onlyVisiblePlottables) +{ + QList allAxes; + foreach (QCPAxisRect *rect, axisRects()) + allAxes << rect->axes(); + + foreach (QCPAxis *axis, allAxes) + axis->rescale(onlyVisiblePlottables); +} + +/*! + Saves a PDF with the vectorized plot to the file \a fileName. The axis ratio as well as the scale + of texts and lines will be derived from the specified \a width and \a height. This means, the + output will look like the normal on-screen output of a QCustomPlot widget with the corresponding + pixel width and height. If either \a width or \a height is zero, the exported image will have the + same dimensions as the QCustomPlot widget currently has. + + Setting \a exportPen to \ref QCP::epNoCosmetic allows to disable the use of cosmetic pens when + drawing to the PDF file. Cosmetic pens are pens with numerical width 0, which are always drawn as + a one pixel wide line, no matter what zoom factor is set in the PDF-Viewer. For more information + about cosmetic pens, see the QPainter and QPen documentation. + + The objects of the plot will appear in the current selection state. If you don't want any + selected objects to be painted in their selected look, deselect everything with \ref deselectAll + before calling this function. + + Returns true on success. + + \warning + \li If you plan on editing the exported PDF file with a vector graphics editor like Inkscape, it + is advised to set \a exportPen to \ref QCP::epNoCosmetic to avoid losing those cosmetic lines + (which might be quite many, because cosmetic pens are the default for e.g. axes and tick marks). + \li If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \a pdfCreator and \a pdfTitle may be used to set the according metadata fields in the resulting + PDF file. + + \note On Android systems, this method does nothing and issues an according qDebug warning + message. This is also the case if for other reasons the define flag \c QT_NO_PRINTER is set. + + \see savePng, saveBmp, saveJpg, saveRastered +*/ +bool QCustomPlot::savePdf(const QString &fileName, int width, int height, QCP::ExportPen exportPen, const QString &pdfCreator, const QString &pdfTitle) +{ + bool success = false; +#ifdef QT_NO_PRINTER + Q_UNUSED(fileName) + Q_UNUSED(exportPen) + Q_UNUSED(width) + Q_UNUSED(height) + Q_UNUSED(pdfCreator) + Q_UNUSED(pdfTitle) + qDebug() << Q_FUNC_INFO << "Qt was built without printer support (QT_NO_PRINTER). PDF not created."; +#else + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + + QPrinter printer(QPrinter::ScreenResolution); + printer.setOutputFileName(fileName); + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setColorMode(QPrinter::Color); + printer.printEngine()->setProperty(QPrintEngine::PPK_Creator, pdfCreator); + printer.printEngine()->setProperty(QPrintEngine::PPK_DocumentName, pdfTitle); + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) + printer.setFullPage(true); + printer.setPaperSize(viewport().size(), QPrinter::DevicePixel); +#else + QPageLayout pageLayout; + pageLayout.setMode(QPageLayout::FullPageMode); + pageLayout.setOrientation(QPageLayout::Portrait); + pageLayout.setMargins(QMarginsF(0, 0, 0, 0)); + pageLayout.setPageSize(QPageSize(viewport().size(), QPageSize::Point, QString(), QPageSize::ExactMatch)); + printer.setPageLayout(pageLayout); +#endif + QCPPainter printpainter; + if (printpainter.begin(&printer)) + { + printpainter.setMode(QCPPainter::pmVectorized); + printpainter.setMode(QCPPainter::pmNoCaching); + printpainter.setMode(QCPPainter::pmNonCosmetic, exportPen==QCP::epNoCosmetic); + printpainter.setWindow(mViewport); + if (mBackgroundBrush.style() != Qt::NoBrush && + mBackgroundBrush.color() != Qt::white && + mBackgroundBrush.color() != Qt::transparent && + mBackgroundBrush.color().alpha() > 0) // draw pdf background color if not white/transparent + printpainter.fillRect(viewport(), mBackgroundBrush); + draw(&printpainter); + printpainter.end(); + success = true; + } + setViewport(oldViewport); +#endif // QT_NO_PRINTER + return success; +} + +/*! + Saves a PNG image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + image compression can be controlled with the \a quality parameter which must be between 0 and 100 + or -1 to use the default setting. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the PNG format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + If you want the PNG to have a transparent background, call \ref setBackground(const QBrush &brush) + with no brush (Qt::NoBrush) or a transparent color (Qt::transparent), before saving. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, saveBmp, saveJpg, saveRastered +*/ +bool QCustomPlot::savePng(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "PNG", quality, resolution, resolutionUnit); +} + +/*! + Saves a JPEG image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + image compression can be controlled with the \a quality parameter which must be between 0 and 100 + or -1 to use the default setting. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the JPEG format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, savePng, saveBmp, saveRastered +*/ +bool QCustomPlot::saveJpg(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "JPG", quality, resolution, resolutionUnit); +} + +/*! + Saves a BMP image file to \a fileName on disc. The output plot will have the dimensions \a width + and \a height in pixels, multiplied by \a scale. If either \a width or \a height is zero, the + current width and height of the QCustomPlot widget is used instead. Line widths and texts etc. + are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale + parameter. + + For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an + image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths, + texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full + 200*200 pixel resolution. + + If you use a high scaling factor, it is recommended to enable antialiasing for all elements by + temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows + QCustomPlot to place objects with sub-pixel accuracy. + + The \a resolution will be written to the image file header and has no direct consequence for the + quality or the pixel size. However, if opening the image with a tool which respects the metadata, + it will be able to scale the image to match either a given size in real units of length (inch, + centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is + given, by setting \a resolutionUnit. The \a resolution is converted to the format's expected + resolution unit internally. + + Returns true on success. If this function fails, most likely the BMP format isn't supported by + the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The objects of the plot will appear in the current selection state. If you don't want any selected + objects to be painted in their selected look, deselect everything with \ref deselectAll before calling + this function. + + \warning If calling this function inside the constructor of the parent of the QCustomPlot widget + (i.e. the MainWindow constructor, if QCustomPlot is inside the MainWindow), always provide + explicit non-zero widths and heights. If you leave \a width or \a height as 0 (default), this + function uses the current width and height of the QCustomPlot widget. However, in Qt, these + aren't defined yet inside the constructor, so you would get an image that has strange + widths/heights. + + \see savePdf, savePng, saveJpg, saveRastered +*/ +bool QCustomPlot::saveBmp(const QString &fileName, int width, int height, double scale, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + return saveRastered(fileName, width, height, scale, "BMP", -1, resolution, resolutionUnit); +} + +/*! \internal + + Returns a minimum size hint that corresponds to the minimum size of the top level layout + (\ref plotLayout). To prevent QCustomPlot from being collapsed to size/width zero, set a minimum + size (setMinimumSize) either on the whole QCustomPlot or on any layout elements inside the plot. + This is especially important, when placed in a QLayout where other components try to take in as + much space as possible (e.g. QMdiArea). +*/ +QSize QCustomPlot::minimumSizeHint() const +{ + return mPlotLayout->minimumSizeHint(); +} + +/*! \internal + + Returns a size hint that is the same as \ref minimumSizeHint. + +*/ +QSize QCustomPlot::sizeHint() const +{ + return mPlotLayout->minimumSizeHint(); +} + +/*! \internal + + Event handler for when the QCustomPlot widget needs repainting. This does not cause a \ref replot, but + draws the internal buffer on the widget surface. +*/ +void QCustomPlot::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + QCPPainter painter(this); + if (painter.isActive()) + { + painter.setRenderHint(QPainter::HighQualityAntialiasing); // to make Antialiasing look good if using the OpenGL graphicssystem + if (mBackgroundBrush.style() != Qt::NoBrush) + painter.fillRect(mViewport, mBackgroundBrush); + drawBackground(&painter); + for (int bufferIndex = 0; bufferIndex < mPaintBuffers.size(); ++bufferIndex) + mPaintBuffers.at(bufferIndex)->draw(&painter); + } +} + +/*! \internal + + Event handler for a resize of the QCustomPlot widget. The viewport (which becomes the outer rect + of mPlotLayout) is resized appropriately. Finally a \ref replot is performed. +*/ +void QCustomPlot::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event) + // resize and repaint the buffer: + setViewport(rect()); + replot(rpQueuedRefresh); // queued refresh is important here, to prevent painting issues in some contexts (e.g. MDI subwindow) +} + +/*! \internal + + Event handler for when a double click occurs. Emits the \ref mouseDoubleClick signal, then + determines the layerable under the cursor and forwards the event to it. Finally, emits the + specialized signals when certain objecs are clicked (e.g. \ref plottableDoubleClick, \ref + axisDoubleClick, etc.). + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCustomPlot::mouseDoubleClickEvent(QMouseEvent *event) +{ + emit mouseDoubleClick(event); + mMouseHasMoved = false; + mMousePressPos = event->pos(); + + // determine layerable under the cursor (this event is called instead of the second press event in a double-click): + QList details; + QList candidates = layerableListAt(mMousePressPos, false, &details); + for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list + candidates.at(i)->mouseDoubleClickEvent(event, details.at(i)); + if (event->isAccepted()) + { + mMouseEventLayerable = candidates.at(i); + mMouseEventLayerableDetails = details.at(i); + break; + } + } + + // emit specialized object double click signals: + if (!candidates.isEmpty()) + { + if (QCPAbstractPlottable *ap = qobject_cast(candidates.first())) + { + int dataIndex = 0; + if (!details.first().value().isEmpty()) + dataIndex = details.first().value().dataRange().begin(); + emit plottableDoubleClick(ap, dataIndex, event); + } else if (QCPAxis *ax = qobject_cast(candidates.first())) + emit axisDoubleClick(ax, details.first().value(), event); + else if (QCPAbstractItem *ai = qobject_cast(candidates.first())) + emit itemDoubleClick(ai, event); + else if (QCPLegend *lg = qobject_cast(candidates.first())) + emit legendDoubleClick(lg, 0, event); + else if (QCPAbstractLegendItem *li = qobject_cast(candidates.first())) + emit legendDoubleClick(li->parentLegend(), li, event); + } + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for when a mouse button is pressed. Emits the mousePress signal. + + If the current \ref setSelectionRectMode is not \ref QCP::srmNone, passes the event to the + selection rect. Otherwise determines the layerable under the cursor and forwards the event to it. + + \see mouseMoveEvent, mouseReleaseEvent +*/ +void QCustomPlot::mousePressEvent(QMouseEvent *event) +{ + emit mousePress(event); + // save some state to tell in releaseEvent whether it was a click: + mMouseHasMoved = false; + mMousePressPos = event->pos(); + + if (mSelectionRect && mSelectionRectMode != QCP::srmNone) + { + if (mSelectionRectMode != QCP::srmZoom || qobject_cast(axisRectAt(mMousePressPos))) // in zoom mode only activate selection rect if on an axis rect + mSelectionRect->startSelection(event); + } else + { + // no selection rect interaction, so forward event to layerable under the cursor: + QList details; + QList candidates = layerableListAt(mMousePressPos, false, &details); + for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list + candidates.at(i)->mousePressEvent(event, details.at(i)); + if (event->isAccepted()) + { + mMouseEventLayerable = candidates.at(i); + mMouseEventLayerableDetails = details.at(i); + break; + } + } + } + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for when the cursor is moved. Emits the \ref mouseMove signal. + + If the selection rect (\ref setSelectionRect) is currently active, the event is forwarded to it + in order to update the rect geometry. + + Otherwise, if a layout element has mouse capture focus (a mousePressEvent happened on top of the + layout element before), the mouseMoveEvent is forwarded to that element. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCustomPlot::mouseMoveEvent(QMouseEvent *event) +{ + emit mouseMove(event); + + if (!mMouseHasMoved && (mMousePressPos-event->pos()).manhattanLength() > 3) + mMouseHasMoved = true; // moved too far from mouse press position, don't handle as click on mouse release + + if (mSelectionRect && mSelectionRect->isActive()) + mSelectionRect->moveSelection(event); + else if (mMouseEventLayerable) // call event of affected layerable: + mMouseEventLayerable->mouseMoveEvent(event, mMousePressPos); + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for when a mouse button is released. Emits the \ref mouseRelease signal. + + If the mouse was moved less than a certain threshold in any direction since the \ref + mousePressEvent, it is considered a click which causes the selection mechanism (if activated via + \ref setInteractions) to possibly change selection states accordingly. Further, specialized mouse + click signals are emitted (e.g. \ref plottableClick, \ref axisClick, etc.) + + If a layerable is the mouse capturer (a \ref mousePressEvent happened on top of the layerable + before), the \ref mouseReleaseEvent is forwarded to that element. + + \see mousePressEvent, mouseMoveEvent +*/ +void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) +{ + emit mouseRelease(event); + + if (!mMouseHasMoved) // mouse hasn't moved (much) between press and release, so handle as click + { + if (mSelectionRect && mSelectionRect->isActive()) // a simple click shouldn't successfully finish a selection rect, so cancel it here + mSelectionRect->cancel(); + if (event->button() == Qt::LeftButton) + processPointSelection(event); + + // emit specialized click signals of QCustomPlot instance: + if (QCPAbstractPlottable *ap = qobject_cast(mMouseEventLayerable)) + { + int dataIndex = 0; + if (!mMouseEventLayerableDetails.value().isEmpty()) + dataIndex = mMouseEventLayerableDetails.value().dataRange().begin(); + emit plottableClick(ap, dataIndex, event); + } else if (QCPAxis *ax = qobject_cast(mMouseEventLayerable)) + emit axisClick(ax, mMouseEventLayerableDetails.value(), event); + else if (QCPAbstractItem *ai = qobject_cast(mMouseEventLayerable)) + emit itemClick(ai, event); + else if (QCPLegend *lg = qobject_cast(mMouseEventLayerable)) + emit legendClick(lg, 0, event); + else if (QCPAbstractLegendItem *li = qobject_cast(mMouseEventLayerable)) + emit legendClick(li->parentLegend(), li, event); + } + + if (mSelectionRect && mSelectionRect->isActive()) // Note: if a click was detected above, the selection rect is canceled there + { + // finish selection rect, the appropriate action will be taken via signal-slot connection: + mSelectionRect->endSelection(event); + } else + { + // call event of affected layerable: + if (mMouseEventLayerable) + { + mMouseEventLayerable->mouseReleaseEvent(event, mMousePressPos); + mMouseEventLayerable = 0; + } + } + + if (noAntialiasingOnDrag()) + replot(rpQueuedReplot); + + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + Event handler for mouse wheel events. First, the \ref mouseWheel signal is emitted. Then + determines the affected layerable and forwards the event to it. +*/ +void QCustomPlot::wheelEvent(QWheelEvent *event) +{ + emit mouseWheel(event); + // forward event to layerable under cursor: + QList candidates = layerableListAt(event->pos(), false); + for (int i=0; iaccept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list + candidates.at(i)->wheelEvent(event); + if (event->isAccepted()) + break; + } + event->accept(); // in case QCPLayerable reimplementation manipulates event accepted state. In QWidget event system, QCustomPlot wants to accept the event. +} + +/*! \internal + + This function draws the entire plot, including background pixmap, with the specified \a painter. + It does not make use of the paint buffers like \ref replot, so this is the function typically + used by saving/exporting methods such as \ref savePdf or \ref toPainter. + + Note that it does not fill the background with the background brush (as the user may specify with + \ref setBackground(const QBrush &brush)), this is up to the respective functions calling this + method. +*/ +void QCustomPlot::draw(QCPPainter *painter) +{ + updateLayout(); + + // draw viewport background pixmap: + drawBackground(painter); + + // draw all layered objects (grid, axes, plottables, items, legend,...): + foreach (QCPLayer *layer, mLayers) + layer->draw(painter); + + /* Debug code to draw all layout element rects + foreach (QCPLayoutElement* el, findChildren()) + { + painter->setBrush(Qt::NoBrush); + painter->setPen(QPen(QColor(0, 0, 0, 100), 0, Qt::DashLine)); + painter->drawRect(el->rect()); + painter->setPen(QPen(QColor(255, 0, 0, 100), 0, Qt::DashLine)); + painter->drawRect(el->outerRect()); + } + */ +} + +/*! \internal + + Performs the layout update steps defined by \ref QCPLayoutElement::UpdatePhase, by calling \ref + QCPLayoutElement::update on the main plot layout. + + Here, the layout elements calculate their positions and margins, and prepare for the following + draw call. +*/ +void QCustomPlot::updateLayout() +{ + // run through layout phases: + mPlotLayout->update(QCPLayoutElement::upPreparation); + mPlotLayout->update(QCPLayoutElement::upMargins); + mPlotLayout->update(QCPLayoutElement::upLayout); +} + +/*! \internal + + Draws the viewport background pixmap of the plot. + + If a pixmap was provided via \ref setBackground, this function buffers the scaled version + depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside + the viewport with the provided \a painter. The scaled version is buffered in + mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when + the axis rect has changed in a way that requires a rescale of the background pixmap (this is + dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was + set. + + Note that this function does not draw a fill with the background brush + (\ref setBackground(const QBrush &brush)) beneath the pixmap. + + \see setBackground, setBackgroundScaled, setBackgroundScaledMode +*/ +void QCustomPlot::drawBackground(QCPPainter *painter) +{ + // Note: background color is handled in individual replot/save functions + + // draw background pixmap (on top of fill, if brush specified): + if (!mBackgroundPixmap.isNull()) + { + if (mBackgroundScaled) + { + // check whether mScaledBackground needs to be updated: + QSize scaledSize(mBackgroundPixmap.size()); + scaledSize.scale(mViewport.size(), mBackgroundScaledMode); + if (mScaledBackgroundPixmap.size() != scaledSize) + mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mViewport.size(), mBackgroundScaledMode, Qt::SmoothTransformation); + painter->drawPixmap(mViewport.topLeft(), mScaledBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height()) & mScaledBackgroundPixmap.rect()); + } else + { + painter->drawPixmap(mViewport.topLeft(), mBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height())); + } + } +} + +/*! \internal + + Goes through the layers and makes sure this QCustomPlot instance holds the correct number of + paint buffers and that they have the correct configuration (size, pixel ratio, etc.). + Allocations, reallocations and deletions of paint buffers are performed as necessary. It also + associates the paint buffers with the layers, so they draw themselves into the right buffer when + \ref QCPLayer::drawToPaintBuffer is called. This means it associates adjacent \ref + QCPLayer::lmLogical layers to a mutual paint buffer and creates dedicated paint buffers for + layers in \ref QCPLayer::lmBuffered mode. + + This method uses \ref createPaintBuffer to create new paint buffers. + + After this method, the paint buffers are empty (filled with \c Qt::transparent) and invalidated + (so an attempt to replot only a single buffered layer causes a full replot). + + This method is called in every \ref replot call, prior to actually drawing the layers (into their + associated paint buffer). If the paint buffers don't need changing/reallocating, this method + basically leaves them alone and thus finishes very fast. +*/ +void QCustomPlot::setupPaintBuffers() +{ + int bufferIndex = 0; + if (mPaintBuffers.isEmpty()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + + for (int layerIndex = 0; layerIndex < mLayers.size(); ++layerIndex) + { + QCPLayer *layer = mLayers.at(layerIndex); + if (layer->mode() == QCPLayer::lmLogical) + { + layer->mPaintBuffer = mPaintBuffers.at(bufferIndex).toWeakRef(); + } else if (layer->mode() == QCPLayer::lmBuffered) + { + ++bufferIndex; + if (bufferIndex >= mPaintBuffers.size()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + layer->mPaintBuffer = mPaintBuffers.at(bufferIndex).toWeakRef(); + if (layerIndex < mLayers.size()-1 && mLayers.at(layerIndex+1)->mode() == QCPLayer::lmLogical) // not last layer, and next one is logical, so prepare another buffer for next layerables + { + ++bufferIndex; + if (bufferIndex >= mPaintBuffers.size()) + mPaintBuffers.append(QSharedPointer(createPaintBuffer())); + } + } + } + // remove unneeded buffers: + while (mPaintBuffers.size()-1 > bufferIndex) + mPaintBuffers.removeLast(); + // resize buffers to viewport size and clear contents: + for (int i=0; isetSize(viewport().size()); // won't do anything if already correct size + mPaintBuffers.at(i)->clear(Qt::transparent); + mPaintBuffers.at(i)->setInvalidated(); + } +} + +/*! \internal + + This method is used by \ref setupPaintBuffers when it needs to create new paint buffers. + + Depending on the current setting of \ref setOpenGl, and the current Qt version, different + backends (subclasses of \ref QCPAbstractPaintBuffer) are created, initialized with the proper + size and device pixel ratio, and returned. +*/ +QCPAbstractPaintBuffer *QCustomPlot::createPaintBuffer() +{ + if (mOpenGl) + { +#if defined(QCP_OPENGL_FBO) + return new QCPPaintBufferGlFbo(viewport().size(), mBufferDevicePixelRatio, mGlContext, mGlPaintDevice); +#elif defined(QCP_OPENGL_PBUFFER) + return new QCPPaintBufferGlPbuffer(viewport().size(), mBufferDevicePixelRatio, mOpenGlMultisamples); +#else + qDebug() << Q_FUNC_INFO << "OpenGL enabled even though no support for it compiled in, this shouldn't have happened. Falling back to pixmap paint buffer."; + return new QCPPaintBufferPixmap(viewport().size(), mBufferDevicePixelRatio); +#endif + } else + return new QCPPaintBufferPixmap(viewport().size(), mBufferDevicePixelRatio); +} + +/*! + This method returns whether any of the paint buffers held by this QCustomPlot instance are + invalidated. + + If any buffer is invalidated, a partial replot (\ref QCPLayer::replot) is not allowed and always + causes a full replot (\ref QCustomPlot::replot) of all layers. This is the case when for example + the layer order has changed, new layers were added, layers were removed, or layer modes were + changed (\ref QCPLayer::setMode). + + \see QCPAbstractPaintBuffer::setInvalidated +*/ +bool QCustomPlot::hasInvalidatedPaintBuffers() +{ + for (int i=0; iinvalidated()) + return true; + } + return false; +} + +/*! \internal + + When \ref setOpenGl is set to true, this method is used to initialize OpenGL (create a context, + surface, paint device). + + Returns true on success. + + If this method is successful, all paint buffers should be deleted and then reallocated by calling + \ref setupPaintBuffers, so the OpenGL-based paint buffer subclasses (\ref + QCPPaintBufferGlPbuffer, \ref QCPPaintBufferGlFbo) are used for subsequent replots. + + \see freeOpenGl +*/ +bool QCustomPlot::setupOpenGl() +{ +#ifdef QCP_OPENGL_FBO + freeOpenGl(); + QSurfaceFormat proposedSurfaceFormat; + proposedSurfaceFormat.setSamples(mOpenGlMultisamples); +#ifdef QCP_OPENGL_OFFSCREENSURFACE + QOffscreenSurface *surface = new QOffscreenSurface; +#else + QWindow *surface = new QWindow; + surface->setSurfaceType(QSurface::OpenGLSurface); +#endif + surface->setFormat(proposedSurfaceFormat); + surface->create(); + mGlSurface = QSharedPointer(surface); + mGlContext = QSharedPointer(new QOpenGLContext); + mGlContext->setFormat(mGlSurface->format()); + if (!mGlContext->create()) + { + qDebug() << Q_FUNC_INFO << "Failed to create OpenGL context"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + if (!mGlContext->makeCurrent(mGlSurface.data())) // context needs to be current to create paint device + { + qDebug() << Q_FUNC_INFO << "Failed to make opengl context current"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) + { + qDebug() << Q_FUNC_INFO << "OpenGL of this system doesn't support frame buffer objects"; + mGlContext.clear(); + mGlSurface.clear(); + return false; + } + mGlPaintDevice = QSharedPointer(new QOpenGLPaintDevice); + return true; +#elif defined(QCP_OPENGL_PBUFFER) + return QGLFormat::hasOpenGL(); +#else + return false; +#endif +} + +/*! \internal + + When \ref setOpenGl is set to false, this method is used to deinitialize OpenGL (releases the + context and frees resources). + + After OpenGL is disabled, all paint buffers should be deleted and then reallocated by calling + \ref setupPaintBuffers, so the standard software rendering paint buffer subclass (\ref + QCPPaintBufferPixmap) is used for subsequent replots. + + \see setupOpenGl +*/ +void QCustomPlot::freeOpenGl() +{ +#ifdef QCP_OPENGL_FBO + mGlPaintDevice.clear(); + mGlContext.clear(); + mGlSurface.clear(); +#endif +} + +/*! \internal + + This method is used by \ref QCPAxisRect::removeAxis to report removed axes to the QCustomPlot + so it may clear its QCustomPlot::xAxis, yAxis, xAxis2 and yAxis2 members accordingly. +*/ +void QCustomPlot::axisRemoved(QCPAxis *axis) +{ + if (xAxis == axis) + xAxis = 0; + if (xAxis2 == axis) + xAxis2 = 0; + if (yAxis == axis) + yAxis = 0; + if (yAxis2 == axis) + yAxis2 = 0; + + // Note: No need to take care of range drag axes and range zoom axes, because they are stored in smart pointers +} + +/*! \internal + + This method is used by the QCPLegend destructor to report legend removal to the QCustomPlot so + it may clear its QCustomPlot::legend member accordingly. +*/ +void QCustomPlot::legendRemoved(QCPLegend *legend) +{ + if (this->legend == legend) + this->legend = 0; +} + +/*! \internal + + This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref + setSelectionRectMode is set to \ref QCP::srmSelect. + + First, it determines which axis rect was the origin of the selection rect judging by the starting + point of the selection. Then it goes through the plottables (\ref QCPAbstractPlottable1D to be + precise) associated with that axis rect and finds the data points that are in \a rect. It does + this by querying their \ref QCPAbstractPlottable1D::selectTestRect method. + + Then, the actual selection is done by calling the plottables' \ref + QCPAbstractPlottable::selectEvent, placing the found selected data points in the \a details + parameter as QVariant(\ref QCPDataSelection). All plottables that weren't touched by \a + rect receive a \ref QCPAbstractPlottable::deselectEvent. + + \see processRectZoom +*/ +void QCustomPlot::processRectSelection(QRect rect, QMouseEvent *event) +{ + bool selectionStateChanged = false; + + if (mInteractions.testFlag(QCP::iSelectPlottables)) + { + QMap > potentialSelections; // map key is number of selected data points, so we have selections sorted by size + QRectF rectF(rect.normalized()); + if (QCPAxisRect *affectedAxisRect = axisRectAt(rectF.topLeft())) + { + // determine plottables that were hit by the rect and thus are candidates for selection: + foreach (QCPAbstractPlottable *plottable, affectedAxisRect->plottables()) + { + if (QCPPlottableInterface1D *plottableInterface = plottable->interface1D()) + { + QCPDataSelection dataSel = plottableInterface->selectTestRect(rectF, true); + if (!dataSel.isEmpty()) + potentialSelections.insertMulti(dataSel.dataPointCount(), QPair(plottable, dataSel)); + } + } + + if (!mInteractions.testFlag(QCP::iMultiSelect)) + { + // only leave plottable with most selected points in map, since we will only select a single plottable: + if (!potentialSelections.isEmpty()) + { + QMap >::iterator it = potentialSelections.begin(); + while (it != potentialSelections.end()-1) // erase all except last element + it = potentialSelections.erase(it); + } + } + + bool additive = event->modifiers().testFlag(mMultiSelectModifier); + // deselect all other layerables if not additive selection: + if (!additive) + { + // emit deselection except to those plottables who will be selected afterwards: + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + { + if ((potentialSelections.isEmpty() || potentialSelections.constBegin()->first != layerable) && mInteractions.testFlag(layerable->selectionCategory())) + { + bool selChanged = false; + layerable->deselectEvent(&selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + + // go through selections in reverse (largest selection first) and emit select events: + QMap >::const_iterator it = potentialSelections.constEnd(); + while (it != potentialSelections.constBegin()) + { + --it; + if (mInteractions.testFlag(it.value().first->selectionCategory())) + { + bool selChanged = false; + it.value().first->selectEvent(event, additive, QVariant::fromValue(it.value().second), &selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + + if (selectionStateChanged) + { + emit selectionChangedByUser(); + replot(rpQueuedReplot); + } else if (mSelectionRect) + mSelectionRect->layer()->replot(); +} + +/*! \internal + + This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref + setSelectionRectMode is set to \ref QCP::srmZoom. + + It determines which axis rect was the origin of the selection rect judging by the starting point + of the selection, and then zooms the axes defined via \ref QCPAxisRect::setRangeZoomAxes to the + provided \a rect (see \ref QCPAxisRect::zoom). + + \see processRectSelection +*/ +void QCustomPlot::processRectZoom(QRect rect, QMouseEvent *event) +{ + Q_UNUSED(event) + if (QCPAxisRect *axisRect = axisRectAt(rect.topLeft())) + { + QList affectedAxes = QList() << axisRect->rangeZoomAxes(Qt::Horizontal) << axisRect->rangeZoomAxes(Qt::Vertical); + affectedAxes.removeAll(static_cast(0)); + axisRect->zoom(QRectF(rect), affectedAxes); + } + replot(rpQueuedReplot); // always replot to make selection rect disappear +} + +/*! \internal + + This method is called when a simple left mouse click was detected on the QCustomPlot surface. + + It first determines the layerable that was hit by the click, and then calls its \ref + QCPLayerable::selectEvent. All other layerables receive a QCPLayerable::deselectEvent (unless the + multi-select modifier was pressed, see \ref setMultiSelectModifier). + + In this method the hit layerable is determined a second time using \ref layerableAt (after the + one in \ref mousePressEvent), because we want \a onlySelectable set to true this time. This + implies that the mouse event grabber (mMouseEventLayerable) may be a different one from the + clicked layerable determined here. For example, if a non-selectable layerable is in front of a + selectable layerable at the click position, the front layerable will receive mouse events but the + selectable one in the back will receive the \ref QCPLayerable::selectEvent. + + \see processRectSelection, QCPLayerable::selectTest +*/ +void QCustomPlot::processPointSelection(QMouseEvent *event) +{ + QVariant details; + QCPLayerable *clickedLayerable = layerableAt(event->pos(), true, &details); + bool selectionStateChanged = false; + bool additive = mInteractions.testFlag(QCP::iMultiSelect) && event->modifiers().testFlag(mMultiSelectModifier); + // deselect all other layerables if not additive selection: + if (!additive) + { + foreach (QCPLayer *layer, mLayers) + { + foreach (QCPLayerable *layerable, layer->children()) + { + if (layerable != clickedLayerable && mInteractions.testFlag(layerable->selectionCategory())) + { + bool selChanged = false; + layerable->deselectEvent(&selChanged); + selectionStateChanged |= selChanged; + } + } + } + } + if (clickedLayerable && mInteractions.testFlag(clickedLayerable->selectionCategory())) + { + // a layerable was actually clicked, call its selectEvent: + bool selChanged = false; + clickedLayerable->selectEvent(event, additive, details, &selChanged); + selectionStateChanged |= selChanged; + } + if (selectionStateChanged) + { + emit selectionChangedByUser(); + replot(rpQueuedReplot); + } +} + +/*! \internal + + Registers the specified plottable with this QCustomPlot and, if \ref setAutoAddPlottableToLegend + is enabled, adds it to the legend (QCustomPlot::legend). QCustomPlot takes ownership of the + plottable. + + Returns true on success, i.e. when \a plottable isn't already in this plot and the parent plot of + \a plottable is this QCustomPlot. + + This method is called automatically in the QCPAbstractPlottable base class constructor. +*/ +bool QCustomPlot::registerPlottable(QCPAbstractPlottable *plottable) +{ + if (mPlottables.contains(plottable)) + { + qDebug() << Q_FUNC_INFO << "plottable already added to this QCustomPlot:" << reinterpret_cast(plottable); + return false; + } + if (plottable->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "plottable not created with this QCustomPlot as parent:" << reinterpret_cast(plottable); + return false; + } + + mPlottables.append(plottable); + // possibly add plottable to legend: + if (mAutoAddPlottableToLegend) + plottable->addToLegend(); + if (!plottable->layer()) // usually the layer is already set in the constructor of the plottable (via QCPLayerable constructor) + plottable->setLayer(currentLayer()); + return true; +} + +/*! \internal + + In order to maintain the simplified graph interface of QCustomPlot, this method is called by the + QCPGraph constructor to register itself with this QCustomPlot's internal graph list. Returns true + on success, i.e. if \a graph is valid and wasn't already registered with this QCustomPlot. + + This graph specific registration happens in addition to the call to \ref registerPlottable by the + QCPAbstractPlottable base class. +*/ +bool QCustomPlot::registerGraph(QCPGraph *graph) +{ + if (!graph) + { + qDebug() << Q_FUNC_INFO << "passed graph is zero"; + return false; + } + if (mGraphs.contains(graph)) + { + qDebug() << Q_FUNC_INFO << "graph already registered with this QCustomPlot"; + return false; + } + + mGraphs.append(graph); + return true; +} + + +/*! \internal + + Registers the specified item with this QCustomPlot. QCustomPlot takes ownership of the item. + + Returns true on success, i.e. when \a item wasn't already in the plot and the parent plot of \a + item is this QCustomPlot. + + This method is called automatically in the QCPAbstractItem base class constructor. +*/ +bool QCustomPlot::registerItem(QCPAbstractItem *item) +{ + if (mItems.contains(item)) + { + qDebug() << Q_FUNC_INFO << "item already added to this QCustomPlot:" << reinterpret_cast(item); + return false; + } + if (item->parentPlot() != this) + { + qDebug() << Q_FUNC_INFO << "item not created with this QCustomPlot as parent:" << reinterpret_cast(item); + return false; + } + + mItems.append(item); + if (!item->layer()) // usually the layer is already set in the constructor of the item (via QCPLayerable constructor) + item->setLayer(currentLayer()); + return true; +} + +/*! \internal + + Assigns all layers their index (QCPLayer::mIndex) in the mLayers list. This method is thus called + after every operation that changes the layer indices, like layer removal, layer creation, layer + moving. +*/ +void QCustomPlot::updateLayerIndices() const +{ + for (int i=0; imIndex = i; +} + +/*! \internal + + Returns the top-most layerable at pixel position \a pos. If \a onlySelectable is set to true, + only those layerables that are selectable will be considered. (Layerable subclasses communicate + their selectability via the QCPLayerable::selectTest method, by returning -1.) + + \a selectionDetails is an output parameter that contains selection specifics of the affected + layerable. This is useful if the respective layerable shall be given a subsequent + QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains + information about which part of the layerable was hit, in multi-part layerables (e.g. + QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref + QCPDataSelection instance with the single data point which is closest to \a pos. + + \see layerableListAt, layoutElementAt, axisRectAt +*/ +QCPLayerable *QCustomPlot::layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails) const +{ + QList details; + QList candidates = layerableListAt(pos, onlySelectable, selectionDetails ? &details : 0); + if (selectionDetails && !details.isEmpty()) + *selectionDetails = details.first(); + if (!candidates.isEmpty()) + return candidates.first(); + else + return 0; +} + +/*! \internal + + Returns the layerables at pixel position \a pos. If \a onlySelectable is set to true, only those + layerables that are selectable will be considered. (Layerable subclasses communicate their + selectability via the QCPLayerable::selectTest method, by returning -1.) + + The returned list is sorted by the layerable/drawing order. If you only need to know the top-most + layerable, rather use \ref layerableAt. + + \a selectionDetails is an output parameter that contains selection specifics of the affected + layerable. This is useful if the respective layerable shall be given a subsequent + QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains + information about which part of the layerable was hit, in multi-part layerables (e.g. + QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref + QCPDataSelection instance with the single data point which is closest to \a pos. + + \see layerableAt, layoutElementAt, axisRectAt +*/ +QList QCustomPlot::layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails) const +{ + QList result; + for (int layerIndex=mLayers.size()-1; layerIndex>=0; --layerIndex) + { + const QList layerables = mLayers.at(layerIndex)->children(); + for (int i=layerables.size()-1; i>=0; --i) + { + if (!layerables.at(i)->realVisibility()) + continue; + QVariant details; + double dist = layerables.at(i)->selectTest(pos, onlySelectable, selectionDetails ? &details : 0); + if (dist >= 0 && dist < selectionTolerance()) + { + result.append(layerables.at(i)); + if (selectionDetails) + selectionDetails->append(details); + } + } + } + return result; +} + +/*! + Saves the plot to a rastered image file \a fileName in the image format \a format. The plot is + sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and scale 2.0 lead + to a full resolution file with width 200.) If the \a format supports compression, \a quality may + be between 0 and 100 to control it. + + Returns true on success. If this function fails, most likely the given \a format isn't supported + by the system, see Qt docs about QImageWriter::supportedImageFormats(). + + The \a resolution will be written to the image file header (if the file format supports this) and + has no direct consequence for the quality or the pixel size. However, if opening the image with a + tool which respects the metadata, it will be able to scale the image to match either a given size + in real units of length (inch, centimeters, etc.), or the target display DPI. You can specify in + which units \a resolution is given, by setting \a resolutionUnit. The \a resolution is converted + to the format's expected resolution unit internally. + + \see saveBmp, saveJpg, savePng, savePdf +*/ +bool QCustomPlot::saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality, int resolution, QCP::ResolutionUnit resolutionUnit) +{ + QImage buffer = toPixmap(width, height, scale).toImage(); + + int dotsPerMeter = 0; + switch (resolutionUnit) + { + case QCP::ruDotsPerMeter: dotsPerMeter = resolution; break; + case QCP::ruDotsPerCentimeter: dotsPerMeter = resolution*100; break; + case QCP::ruDotsPerInch: dotsPerMeter = resolution/0.0254; break; + } + buffer.setDotsPerMeterX(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools + buffer.setDotsPerMeterY(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools + if (!buffer.isNull()) + return buffer.save(fileName, format, quality); + else + return false; +} + +/*! + Renders the plot to a pixmap and returns it. + + The plot is sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and + scale 2.0 lead to a full resolution pixmap with width 200.) + + \see toPainter, saveRastered, saveBmp, savePng, saveJpg, savePdf +*/ +QPixmap QCustomPlot::toPixmap(int width, int height, double scale) +{ + // this method is somewhat similar to toPainter. Change something here, and a change in toPainter might be necessary, too. + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + int scaledWidth = qRound(scale*newWidth); + int scaledHeight = qRound(scale*newHeight); + + QPixmap result(scaledWidth, scaledHeight); + result.fill(mBackgroundBrush.style() == Qt::SolidPattern ? mBackgroundBrush.color() : Qt::transparent); // if using non-solid pattern, make transparent now and draw brush pattern later + QCPPainter painter; + painter.begin(&result); + if (painter.isActive()) + { + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); + painter.setMode(QCPPainter::pmNoCaching); + if (!qFuzzyCompare(scale, 1.0)) + { + if (scale > 1.0) // for scale < 1 we always want cosmetic pens where possible, because else lines might disappear for very small scales + painter.setMode(QCPPainter::pmNonCosmetic); + painter.scale(scale, scale); + } + if (mBackgroundBrush.style() != Qt::SolidPattern && mBackgroundBrush.style() != Qt::NoBrush) // solid fills were done a few lines above with QPixmap::fill + painter.fillRect(mViewport, mBackgroundBrush); + draw(&painter); + setViewport(oldViewport); + painter.end(); + } else // might happen if pixmap has width or height zero + { + qDebug() << Q_FUNC_INFO << "Couldn't activate painter on pixmap"; + return QPixmap(); + } + return result; +} + +/*! + Renders the plot using the passed \a painter. + + The plot is sized to \a width and \a height in pixels. If the \a painter's scale is not 1.0, the resulting plot will + appear scaled accordingly. + + \note If you are restricted to using a QPainter (instead of QCPPainter), create a temporary QPicture and open a QCPPainter + on it. Then call \ref toPainter with this QCPPainter. After ending the paint operation on the picture, draw it with + the QPainter. This will reproduce the painter actions the QCPPainter took, with a QPainter. + + \see toPixmap +*/ +void QCustomPlot::toPainter(QCPPainter *painter, int width, int height) +{ + // this method is somewhat similar to toPixmap. Change something here, and a change in toPixmap might be necessary, too. + int newWidth, newHeight; + if (width == 0 || height == 0) + { + newWidth = this->width(); + newHeight = this->height(); + } else + { + newWidth = width; + newHeight = height; + } + + if (painter->isActive()) + { + QRect oldViewport = viewport(); + setViewport(QRect(0, 0, newWidth, newHeight)); + painter->setMode(QCPPainter::pmNoCaching); + if (mBackgroundBrush.style() != Qt::NoBrush) // unlike in toPixmap, we can't do QPixmap::fill for Qt::SolidPattern brush style, so we also draw solid fills with fillRect here + painter->fillRect(mViewport, mBackgroundBrush); + draw(painter); + setViewport(oldViewport); + } else + qDebug() << Q_FUNC_INFO << "Passed painter is not active"; +} +/* end of 'src/core.cpp' */ + +//amalgamation: add plottable1d.cpp + +/* including file 'src/colorgradient.cpp', size 24646 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorGradient +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorGradient + \brief Defines a color gradient for use with e.g. \ref QCPColorMap + + This class describes a color gradient which can be used to encode data with color. For example, + QCPColorMap and QCPColorScale have \ref QCPColorMap::setGradient "setGradient" methods which + take an instance of this class. Colors are set with \ref setColorStopAt(double position, const QColor &color) + with a \a position from 0 to 1. In between these defined color positions, the + color will be interpolated linearly either in RGB or HSV space, see \ref setColorInterpolation. + + Alternatively, load one of the preset color gradients shown in the image below, with \ref + loadPreset, or by directly specifying the preset in the constructor. + + Apart from red, green and blue components, the gradient also interpolates the alpha values of the + configured color stops. This allows to display some portions of the data range as transparent in + the plot. + + \image html QCPColorGradient.png + + The \ref QCPColorGradient(GradientPreset preset) constructor allows directly converting a \ref + GradientPreset to a QCPColorGradient. This means that you can directly pass \ref GradientPreset + to all the \a setGradient methods, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorgradient-setgradient + + The total number of levels used in the gradient can be set with \ref setLevelCount. Whether the + color gradient shall be applied periodically (wrapping around) to data values that lie outside + the data range specified on the plottable instance can be controlled with \ref setPeriodic. +*/ + +/*! + Constructs a new, empty QCPColorGradient with no predefined color stops. You can add own color + stops with \ref setColorStopAt. + + The color level count is initialized to 350. +*/ +QCPColorGradient::QCPColorGradient() : + mLevelCount(350), + mColorInterpolation(ciRGB), + mPeriodic(false), + mColorBufferInvalidated(true) +{ + mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); +} + +/*! + Constructs a new QCPColorGradient initialized with the colors and color interpolation according + to \a preset. + + The color level count is initialized to 350. +*/ +QCPColorGradient::QCPColorGradient(GradientPreset preset) : + mLevelCount(350), + mColorInterpolation(ciRGB), + mPeriodic(false), + mColorBufferInvalidated(true) +{ + mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount); + loadPreset(preset); +} + +/* undocumented operator */ +bool QCPColorGradient::operator==(const QCPColorGradient &other) const +{ + return ((other.mLevelCount == this->mLevelCount) && + (other.mColorInterpolation == this->mColorInterpolation) && + (other.mPeriodic == this->mPeriodic) && + (other.mColorStops == this->mColorStops)); +} + +/*! + Sets the number of discretization levels of the color gradient to \a n. The default is 350 which + is typically enough to create a smooth appearance. The minimum number of levels is 2. + + \image html QCPColorGradient-levelcount.png +*/ +void QCPColorGradient::setLevelCount(int n) +{ + if (n < 2) + { + qDebug() << Q_FUNC_INFO << "n must be greater or equal 2 but was" << n; + n = 2; + } + if (n != mLevelCount) + { + mLevelCount = n; + mColorBufferInvalidated = true; + } +} + +/*! + Sets at which positions from 0 to 1 which color shall occur. The positions are the keys, the + colors are the values of the passed QMap \a colorStops. In between these color stops, the color + is interpolated according to \ref setColorInterpolation. + + A more convenient way to create a custom gradient may be to clear all color stops with \ref + clearColorStops (or creating a new, empty QCPColorGradient) and then adding them one by one with + \ref setColorStopAt. + + \see clearColorStops +*/ +void QCPColorGradient::setColorStops(const QMap &colorStops) +{ + mColorStops = colorStops; + mColorBufferInvalidated = true; +} + +/*! + Sets the \a color the gradient will have at the specified \a position (from 0 to 1). In between + these color stops, the color is interpolated according to \ref setColorInterpolation. + + \see setColorStops, clearColorStops +*/ +void QCPColorGradient::setColorStopAt(double position, const QColor &color) +{ + mColorStops.insert(position, color); + mColorBufferInvalidated = true; +} + +/*! + Sets whether the colors in between the configured color stops (see \ref setColorStopAt) shall be + interpolated linearly in RGB or in HSV color space. + + For example, a sweep in RGB space from red to green will have a muddy brown intermediate color, + whereas in HSV space the intermediate color is yellow. +*/ +void QCPColorGradient::setColorInterpolation(QCPColorGradient::ColorInterpolation interpolation) +{ + if (interpolation != mColorInterpolation) + { + mColorInterpolation = interpolation; + mColorBufferInvalidated = true; + } +} + +/*! + Sets whether data points that are outside the configured data range (e.g. \ref + QCPColorMap::setDataRange) are colored by periodically repeating the color gradient or whether + they all have the same color, corresponding to the respective gradient boundary color. + + \image html QCPColorGradient-periodic.png + + As shown in the image above, gradients that have the same start and end color are especially + suitable for a periodic gradient mapping, since they produce smooth color transitions throughout + the color map. A preset that has this property is \ref gpHues. + + In practice, using periodic color gradients makes sense when the data corresponds to a periodic + dimension, such as an angle or a phase. If this is not the case, the color encoding might become + ambiguous, because multiple different data values are shown as the same color. +*/ +void QCPColorGradient::setPeriodic(bool enabled) +{ + mPeriodic = enabled; +} + +/*! \overload + + This method is used to quickly convert a \a data array to colors. The colors will be output in + the array \a scanLine. Both \a data and \a scanLine must have the length \a n when passed to this + function. The data range that shall be used for mapping the data value to the gradient is passed + in \a range. \a logarithmic indicates whether the data values shall be mapped to colors + logarithmically. + + if \a data actually contains 2D-data linearized via [row*columnCount + column], you can + set \a dataIndexFactor to columnCount to convert a column instead of a row of the data + array, in \a scanLine. \a scanLine will remain a regular (1D) array. This works because \a data + is addressed data[i*dataIndexFactor]. + + Use the overloaded method to additionally provide alpha map data. + + The QRgb values that are placed in \a scanLine have their r, g and b components premultiplied + with alpha (see QImage::Format_ARGB32_Premultiplied). +*/ +void QCPColorGradient::colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic) +{ + // If you change something here, make sure to also adapt color() and the other colorize() overload + if (!data) + { + qDebug() << Q_FUNC_INFO << "null pointer given as data"; + return; + } + if (!scanLine) + { + qDebug() << Q_FUNC_INFO << "null pointer given as scanLine"; + return; + } + if (mColorBufferInvalidated) + updateColorBuffer(); + + if (!logarithmic) + { + const double posToIndexFactor = (mLevelCount-1)/range.size(); + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + scanLine[i] = mColorBuffer.at(index); + } + } + } else // logarithmic == true + { + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + scanLine[i] = mColorBuffer.at(index); + } + } + } +} + +/*! \overload + + Additionally to the other overload of \ref colorize, this method takes the array \a alpha, which + has the same size and structure as \a data and encodes the alpha information per data point. + + The QRgb values that are placed in \a scanLine have their r, g and b components premultiplied + with alpha (see QImage::Format_ARGB32_Premultiplied). +*/ +void QCPColorGradient::colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic) +{ + // If you change something here, make sure to also adapt color() and the other colorize() overload + if (!data) + { + qDebug() << Q_FUNC_INFO << "null pointer given as data"; + return; + } + if (!alpha) + { + qDebug() << Q_FUNC_INFO << "null pointer given as alpha"; + return; + } + if (!scanLine) + { + qDebug() << Q_FUNC_INFO << "null pointer given as scanLine"; + return; + } + if (mColorBufferInvalidated) + updateColorBuffer(); + + if (!logarithmic) + { + const double posToIndexFactor = (mLevelCount-1)/range.size(); + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + if (alpha[dataIndexFactor*i] == 255) + { + scanLine[i] = mColorBuffer.at(index); + } else + { + const QRgb rgb = mColorBuffer.at(index); + const float alphaF = alpha[dataIndexFactor*i]/255.0f; + scanLine[i] = qRgba(qRed(rgb)*alphaF, qGreen(rgb)*alphaF, qBlue(rgb)*alphaF, qAlpha(rgb)*alphaF); + } + } + } + } else // logarithmic == true + { + if (mPeriodic) + { + for (int i=0; i= mLevelCount) + index = mLevelCount-1; + if (alpha[dataIndexFactor*i] == 255) + { + scanLine[i] = mColorBuffer.at(index); + } else + { + const QRgb rgb = mColorBuffer.at(index); + const float alphaF = alpha[dataIndexFactor*i]/255.0f; + scanLine[i] = qRgba(qRed(rgb)*alphaF, qGreen(rgb)*alphaF, qBlue(rgb)*alphaF, qAlpha(rgb)*alphaF); + } + } + } + } +} + +/*! \internal + + This method is used to colorize a single data value given in \a position, to colors. The data + range that shall be used for mapping the data value to the gradient is passed in \a range. \a + logarithmic indicates whether the data value shall be mapped to a color logarithmically. + + If an entire array of data values shall be converted, rather use \ref colorize, for better + performance. + + The returned QRgb has its r, g and b components premultiplied with alpha (see + QImage::Format_ARGB32_Premultiplied). +*/ +QRgb QCPColorGradient::color(double position, const QCPRange &range, bool logarithmic) +{ + // If you change something here, make sure to also adapt ::colorize() + if (mColorBufferInvalidated) + updateColorBuffer(); + int index = 0; + if (!logarithmic) + index = (position-range.lower)*(mLevelCount-1)/range.size(); + else + index = qLn(position/range.lower)/qLn(range.upper/range.lower)*(mLevelCount-1); + if (mPeriodic) + { + index = index % mLevelCount; + if (index < 0) + index += mLevelCount; + } else + { + if (index < 0) + index = 0; + else if (index >= mLevelCount) + index = mLevelCount-1; + } + return mColorBuffer.at(index); +} + +/*! + Clears the current color stops and loads the specified \a preset. A preset consists of predefined + color stops and the corresponding color interpolation method. + + The available presets are: + \image html QCPColorGradient.png +*/ +void QCPColorGradient::loadPreset(GradientPreset preset) +{ + clearColorStops(); + switch (preset) + { + case gpGrayscale: + setColorInterpolation(ciRGB); + setColorStopAt(0, Qt::black); + setColorStopAt(1, Qt::white); + break; + case gpHot: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(50, 0, 0)); + setColorStopAt(0.2, QColor(180, 10, 0)); + setColorStopAt(0.4, QColor(245, 50, 0)); + setColorStopAt(0.6, QColor(255, 150, 10)); + setColorStopAt(0.8, QColor(255, 255, 50)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpCold: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 50)); + setColorStopAt(0.2, QColor(0, 10, 180)); + setColorStopAt(0.4, QColor(0, 50, 245)); + setColorStopAt(0.6, QColor(10, 150, 255)); + setColorStopAt(0.8, QColor(50, 255, 255)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpNight: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(10, 20, 30)); + setColorStopAt(1, QColor(250, 255, 250)); + break; + case gpCandy: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(0, 0, 255)); + setColorStopAt(1, QColor(255, 250, 250)); + break; + case gpGeography: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(70, 170, 210)); + setColorStopAt(0.20, QColor(90, 160, 180)); + setColorStopAt(0.25, QColor(45, 130, 175)); + setColorStopAt(0.30, QColor(100, 140, 125)); + setColorStopAt(0.5, QColor(100, 140, 100)); + setColorStopAt(0.6, QColor(130, 145, 120)); + setColorStopAt(0.7, QColor(140, 130, 120)); + setColorStopAt(0.9, QColor(180, 190, 190)); + setColorStopAt(1, QColor(210, 210, 230)); + break; + case gpIon: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(50, 10, 10)); + setColorStopAt(0.45, QColor(0, 0, 255)); + setColorStopAt(0.8, QColor(0, 255, 255)); + setColorStopAt(1, QColor(0, 255, 0)); + break; + case gpThermal: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 50)); + setColorStopAt(0.15, QColor(20, 0, 120)); + setColorStopAt(0.33, QColor(200, 30, 140)); + setColorStopAt(0.6, QColor(255, 100, 0)); + setColorStopAt(0.85, QColor(255, 255, 40)); + setColorStopAt(1, QColor(255, 255, 255)); + break; + case gpPolar: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(50, 255, 255)); + setColorStopAt(0.18, QColor(10, 70, 255)); + setColorStopAt(0.28, QColor(10, 10, 190)); + setColorStopAt(0.5, QColor(0, 0, 0)); + setColorStopAt(0.72, QColor(190, 10, 10)); + setColorStopAt(0.82, QColor(255, 70, 10)); + setColorStopAt(1, QColor(255, 255, 50)); + break; + case gpSpectrum: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(50, 0, 50)); + setColorStopAt(0.15, QColor(0, 0, 255)); + setColorStopAt(0.35, QColor(0, 255, 255)); + setColorStopAt(0.6, QColor(255, 255, 0)); + setColorStopAt(0.75, QColor(255, 30, 0)); + setColorStopAt(1, QColor(50, 0, 0)); + break; + case gpJet: + setColorInterpolation(ciRGB); + setColorStopAt(0, QColor(0, 0, 100)); + setColorStopAt(0.15, QColor(0, 50, 255)); + setColorStopAt(0.35, QColor(0, 255, 255)); + setColorStopAt(0.65, QColor(255, 255, 0)); + setColorStopAt(0.85, QColor(255, 30, 0)); + setColorStopAt(1, QColor(100, 0, 0)); + break; + case gpHues: + setColorInterpolation(ciHSV); + setColorStopAt(0, QColor(255, 0, 0)); + setColorStopAt(1.0/3.0, QColor(0, 0, 255)); + setColorStopAt(2.0/3.0, QColor(0, 255, 0)); + setColorStopAt(1, QColor(255, 0, 0)); + break; + } +} + +/*! + Clears all color stops. + + \see setColorStops, setColorStopAt +*/ +void QCPColorGradient::clearColorStops() +{ + mColorStops.clear(); + mColorBufferInvalidated = true; +} + +/*! + Returns an inverted gradient. The inverted gradient has all properties as this \ref + QCPColorGradient, but the order of the color stops is inverted. + + \see setColorStops, setColorStopAt +*/ +QCPColorGradient QCPColorGradient::inverted() const +{ + QCPColorGradient result(*this); + result.clearColorStops(); + for (QMap::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) + result.setColorStopAt(1.0-it.key(), it.value()); + return result; +} + +/*! \internal + + Returns true if the color gradient uses transparency, i.e. if any of the configured color stops + has an alpha value below 255. +*/ +bool QCPColorGradient::stopsUseAlpha() const +{ + for (QMap::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it) + { + if (it.value().alpha() < 255) + return true; + } + return false; +} + +/*! \internal + + Updates the internal color buffer which will be used by \ref colorize and \ref color, to quickly + convert positions to colors. This is where the interpolation between color stops is calculated. +*/ +void QCPColorGradient::updateColorBuffer() +{ + if (mColorBuffer.size() != mLevelCount) + mColorBuffer.resize(mLevelCount); + if (mColorStops.size() > 1) + { + double indexToPosFactor = 1.0/(double)(mLevelCount-1); + const bool useAlpha = stopsUseAlpha(); + for (int i=0; i::const_iterator it = mColorStops.lowerBound(position); + if (it == mColorStops.constEnd()) // position is on or after last stop, use color of last stop + { + mColorBuffer[i] = (it-1).value().rgba(); + } else if (it == mColorStops.constBegin()) // position is on or before first stop, use color of first stop + { + mColorBuffer[i] = it.value().rgba(); + } else // position is in between stops (or on an intermediate stop), interpolate color + { + QMap::const_iterator high = it; + QMap::const_iterator low = it-1; + double t = (position-low.key())/(high.key()-low.key()); // interpolation factor 0..1 + switch (mColorInterpolation) + { + case ciRGB: + { + if (useAlpha) + { + const int alpha = (1-t)*low.value().alpha() + t*high.value().alpha(); + const float alphaPremultiplier = alpha/255.0f; // since we use QImage::Format_ARGB32_Premultiplied + mColorBuffer[i] = qRgba(((1-t)*low.value().red() + t*high.value().red())*alphaPremultiplier, + ((1-t)*low.value().green() + t*high.value().green())*alphaPremultiplier, + ((1-t)*low.value().blue() + t*high.value().blue())*alphaPremultiplier, + alpha); + } else + { + mColorBuffer[i] = qRgb(((1-t)*low.value().red() + t*high.value().red()), + ((1-t)*low.value().green() + t*high.value().green()), + ((1-t)*low.value().blue() + t*high.value().blue())); + } + break; + } + case ciHSV: + { + QColor lowHsv = low.value().toHsv(); + QColor highHsv = high.value().toHsv(); + double hue = 0; + double hueDiff = highHsv.hueF()-lowHsv.hueF(); + if (hueDiff > 0.5) + hue = lowHsv.hueF() - t*(1.0-hueDiff); + else if (hueDiff < -0.5) + hue = lowHsv.hueF() + t*(1.0+hueDiff); + else + hue = lowHsv.hueF() + t*hueDiff; + if (hue < 0) hue += 1.0; + else if (hue >= 1.0) hue -= 1.0; + if (useAlpha) + { + const QRgb rgb = QColor::fromHsvF(hue, + (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), + (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); + const float alpha = (1-t)*lowHsv.alphaF() + t*highHsv.alphaF(); + mColorBuffer[i] = qRgba(qRed(rgb)*alpha, qGreen(rgb)*alpha, qBlue(rgb)*alpha, 255*alpha); + } + else + { + mColorBuffer[i] = QColor::fromHsvF(hue, + (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), + (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb(); + } + break; + } + } + } + } + } else if (mColorStops.size() == 1) + { + const QRgb rgb = mColorStops.constBegin().value().rgb(); + const float alpha = mColorStops.constBegin().value().alphaF(); + mColorBuffer.fill(qRgba(qRed(rgb)*alpha, qGreen(rgb)*alpha, qBlue(rgb)*alpha, 255*alpha)); + } else // mColorStops is empty, fill color buffer with black + { + mColorBuffer.fill(qRgb(0, 0, 0)); + } + mColorBufferInvalidated = false; +} +/* end of 'src/colorgradient.cpp' */ + + +/* including file 'src/selectiondecorator-bracket.cpp', size 12313 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPSelectionDecoratorBracket +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPSelectionDecoratorBracket + \brief A selection decorator which draws brackets around each selected data segment + + Additionally to the regular highlighting of selected segments via color, fill and scatter style, + this \ref QCPSelectionDecorator subclass draws markers at the begin and end of each selected data + segment of the plottable. + + The shape of the markers can be controlled with \ref setBracketStyle, \ref setBracketWidth and + \ref setBracketHeight. The color/fill can be controlled with \ref setBracketPen and \ref + setBracketBrush. + + To introduce custom bracket styles, it is only necessary to sublcass \ref + QCPSelectionDecoratorBracket and reimplement \ref drawBracket. The rest will be managed by the + base class. +*/ + +/*! + Creates a new QCPSelectionDecoratorBracket instance with default values. +*/ +QCPSelectionDecoratorBracket::QCPSelectionDecoratorBracket() : + mBracketPen(QPen(Qt::black)), + mBracketBrush(Qt::NoBrush), + mBracketWidth(5), + mBracketHeight(50), + mBracketStyle(bsSquareBracket), + mTangentToData(false), + mTangentAverage(2) +{ + +} + +QCPSelectionDecoratorBracket::~QCPSelectionDecoratorBracket() +{ +} + +/*! + Sets the pen that will be used to draw the brackets at the beginning and end of each selected + data segment. +*/ +void QCPSelectionDecoratorBracket::setBracketPen(const QPen &pen) +{ + mBracketPen = pen; +} + +/*! + Sets the brush that will be used to draw the brackets at the beginning and end of each selected + data segment. +*/ +void QCPSelectionDecoratorBracket::setBracketBrush(const QBrush &brush) +{ + mBracketBrush = brush; +} + +/*! + Sets the width of the drawn bracket. The width dimension is always parallel to the key axis of + the data, or the tangent direction of the current data slope, if \ref setTangentToData is + enabled. +*/ +void QCPSelectionDecoratorBracket::setBracketWidth(int width) +{ + mBracketWidth = width; +} + +/*! + Sets the height of the drawn bracket. The height dimension is always perpendicular to the key axis + of the data, or the tangent direction of the current data slope, if \ref setTangentToData is + enabled. +*/ +void QCPSelectionDecoratorBracket::setBracketHeight(int height) +{ + mBracketHeight = height; +} + +/*! + Sets the shape that the bracket/marker will have. + + \see setBracketWidth, setBracketHeight +*/ +void QCPSelectionDecoratorBracket::setBracketStyle(QCPSelectionDecoratorBracket::BracketStyle style) +{ + mBracketStyle = style; +} + +/*! + Sets whether the brackets will be rotated such that they align with the slope of the data at the + position that they appear in. + + For noisy data, it might be more visually appealing to average the slope over multiple data + points. This can be configured via \ref setTangentAverage. +*/ +void QCPSelectionDecoratorBracket::setTangentToData(bool enabled) +{ + mTangentToData = enabled; +} + +/*! + Controls over how many data points the slope shall be averaged, when brackets shall be aligned + with the data (if \ref setTangentToData is true). + + From the position of the bracket, \a pointCount points towards the selected data range will be + taken into account. The smallest value of \a pointCount is 1, which is effectively equivalent to + disabling \ref setTangentToData. +*/ +void QCPSelectionDecoratorBracket::setTangentAverage(int pointCount) +{ + mTangentAverage = pointCount; + if (mTangentAverage < 1) + mTangentAverage = 1; +} + +/*! + Draws the bracket shape with \a painter. The parameter \a direction is either -1 or 1 and + indicates whether the bracket shall point to the left or the right (i.e. is a closing or opening + bracket, respectively). + + The passed \a painter already contains all transformations that are necessary to position and + rotate the bracket appropriately. Painting operations can be performed as if drawing upright + brackets on flat data with horizontal key axis, with (0, 0) being the center of the bracket. + + If you wish to sublcass \ref QCPSelectionDecoratorBracket in order to provide custom bracket + shapes (see \ref QCPSelectionDecoratorBracket::bsUserStyle), this is the method you should + reimplement. +*/ +void QCPSelectionDecoratorBracket::drawBracket(QCPPainter *painter, int direction) const +{ + switch (mBracketStyle) + { + case bsSquareBracket: + { + painter->drawLine(QLineF(mBracketWidth*direction, -mBracketHeight*0.5, 0, -mBracketHeight*0.5)); + painter->drawLine(QLineF(mBracketWidth*direction, mBracketHeight*0.5, 0, mBracketHeight*0.5)); + painter->drawLine(QLineF(0, -mBracketHeight*0.5, 0, mBracketHeight*0.5)); + break; + } + case bsHalfEllipse: + { + painter->drawArc(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight, -90*16, -180*16*direction); + break; + } + case bsEllipse: + { + painter->drawEllipse(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight); + break; + } + case bsPlus: + { + painter->drawLine(QLineF(0, -mBracketHeight*0.5, 0, mBracketHeight*0.5)); + painter->drawLine(QLineF(-mBracketWidth*0.5, 0, mBracketWidth*0.5, 0)); + break; + } + default: + { + qDebug() << Q_FUNC_INFO << "unknown/custom bracket style can't be handeld by default implementation:" << static_cast(mBracketStyle); + break; + } + } +} + +/*! + Draws the bracket decoration on the data points at the begin and end of each selected data + segment given in \a seletion. + + It uses the method \ref drawBracket to actually draw the shapes. + + \seebaseclassmethod +*/ +void QCPSelectionDecoratorBracket::drawDecoration(QCPPainter *painter, QCPDataSelection selection) +{ + if (!mPlottable || selection.isEmpty()) return; + + if (QCPPlottableInterface1D *interface1d = mPlottable->interface1D()) + { + foreach (const QCPDataRange &dataRange, selection.dataRanges()) + { + // determine position and (if tangent mode is enabled) angle of brackets: + int openBracketDir = (mPlottable->keyAxis() && !mPlottable->keyAxis()->rangeReversed()) ? 1 : -1; + int closeBracketDir = -openBracketDir; + QPointF openBracketPos = getPixelCoordinates(interface1d, dataRange.begin()); + QPointF closeBracketPos = getPixelCoordinates(interface1d, dataRange.end()-1); + double openBracketAngle = 0; + double closeBracketAngle = 0; + if (mTangentToData) + { + openBracketAngle = getTangentAngle(interface1d, dataRange.begin(), openBracketDir); + closeBracketAngle = getTangentAngle(interface1d, dataRange.end()-1, closeBracketDir); + } + // draw opening bracket: + QTransform oldTransform = painter->transform(); + painter->setPen(mBracketPen); + painter->setBrush(mBracketBrush); + painter->translate(openBracketPos); + painter->rotate(openBracketAngle/M_PI*180.0); + drawBracket(painter, openBracketDir); + painter->setTransform(oldTransform); + // draw closing bracket: + painter->setPen(mBracketPen); + painter->setBrush(mBracketBrush); + painter->translate(closeBracketPos); + painter->rotate(closeBracketAngle/M_PI*180.0); + drawBracket(painter, closeBracketDir); + painter->setTransform(oldTransform); + } + } +} + +/*! \internal + + If \ref setTangentToData is enabled, brackets need to be rotated according to the data slope. + This method returns the angle in radians by which a bracket at the given \a dataIndex must be + rotated. + + The parameter \a direction must be set to either -1 or 1, representing whether it is an opening + or closing bracket. Since for slope calculation multiple data points are required, this defines + the direction in which the algorithm walks, starting at \a dataIndex, to average those data + points. (see \ref setTangentToData and \ref setTangentAverage) + + \a interface1d is the interface to the plottable's data which is used to query data coordinates. +*/ +double QCPSelectionDecoratorBracket::getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const +{ + if (!interface1d || dataIndex < 0 || dataIndex >= interface1d->dataCount()) + return 0; + direction = direction < 0 ? -1 : 1; // enforce direction is either -1 or 1 + + // how many steps we can actually go from index in the given direction without exceeding data bounds: + int averageCount; + if (direction < 0) + averageCount = qMin(mTangentAverage, dataIndex); + else + averageCount = qMin(mTangentAverage, interface1d->dataCount()-1-dataIndex); + qDebug() << averageCount; + // calculate point average of averageCount points: + QVector points(averageCount); + QPointF pointsAverage; + int currentIndex = dataIndex; + for (int i=0; ikeyAxis(); + QCPAxis *valueAxis = mPlottable->valueAxis(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(0, 0); } + + if (keyAxis->orientation() == Qt::Horizontal) + return QPointF(keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex)), valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex))); + else + return QPointF(valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex)), keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex))); +} +/* end of 'src/selectiondecorator-bracket.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-axisrect.cpp', size 47509 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAxisRect +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAxisRect + \brief Holds multiple axes and arranges them in a rectangular shape. + + This class represents an axis rect, a rectangular area that is bounded on all sides with an + arbitrary number of axes. + + Initially QCustomPlot has one axis rect, accessible via QCustomPlot::axisRect(). However, the + layout system allows to have multiple axis rects, e.g. arranged in a grid layout + (QCustomPlot::plotLayout). + + By default, QCPAxisRect comes with four axes, at bottom, top, left and right. They can be + accessed via \ref axis by providing the respective axis type (\ref QCPAxis::AxisType) and index. + If you need all axes in the axis rect, use \ref axes. The top and right axes are set to be + invisible initially (QCPAxis::setVisible). To add more axes to a side, use \ref addAxis or \ref + addAxes. To remove an axis, use \ref removeAxis. + + The axis rect layerable itself only draws a background pixmap or color, if specified (\ref + setBackground). It is placed on the "background" layer initially (see \ref QCPLayer for an + explanation of the QCustomPlot layer system). The axes that are held by the axis rect can be + placed on other layers, independently of the axis rect. + + Every axis rect has a child layout of type \ref QCPLayoutInset. It is accessible via \ref + insetLayout and can be used to have other layout elements (or even other layouts with multiple + elements) hovering inside the axis rect. + + If an axis rect is clicked and dragged, it processes this by moving certain axis ranges. The + behaviour can be controlled with \ref setRangeDrag and \ref setRangeDragAxes. If the mouse wheel + is scrolled while the cursor is on the axis rect, certain axes are scaled. This is controllable + via \ref setRangeZoom, \ref setRangeZoomAxes and \ref setRangeZoomFactor. These interactions are + only enabled if \ref QCustomPlot::setInteractions contains \ref QCP::iRangeDrag and \ref + QCP::iRangeZoom. + + \image html AxisRectSpacingOverview.png +
Overview of the spacings and paddings that define the geometry of an axis. The dashed + line on the far left indicates the viewport/widget border.
+*/ + +/* start documentation of inline functions */ + +/*! \fn QCPLayoutInset *QCPAxisRect::insetLayout() const + + Returns the inset layout of this axis rect. It can be used to place other layout elements (or + even layouts with multiple other elements) inside/on top of an axis rect. + + \see QCPLayoutInset +*/ + +/*! \fn int QCPAxisRect::left() const + + Returns the pixel position of the left border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::right() const + + Returns the pixel position of the right border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::top() const + + Returns the pixel position of the top border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::bottom() const + + Returns the pixel position of the bottom border of this axis rect. Margins are not taken into + account here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::width() const + + Returns the pixel width of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn int QCPAxisRect::height() const + + Returns the pixel height of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QSize QCPAxisRect::size() const + + Returns the pixel size of this axis rect. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::topLeft() const + + Returns the top left corner of this axis rect in pixels. Margins are not taken into account here, + so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::topRight() const + + Returns the top right corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::bottomLeft() const + + Returns the bottom left corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::bottomRight() const + + Returns the bottom right corner of this axis rect in pixels. Margins are not taken into account + here, so the returned value is with respect to the inner \ref rect. +*/ + +/*! \fn QPoint QCPAxisRect::center() const + + Returns the center of this axis rect in pixels. Margins are not taken into account here, so the + returned value is with respect to the inner \ref rect. +*/ + +/* end documentation of inline functions */ + +/*! + Creates a QCPAxisRect instance and sets default values. An axis is added for each of the four + sides, the top and right axes are set invisible initially. +*/ +QCPAxisRect::QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes) : + QCPLayoutElement(parentPlot), + mBackgroundBrush(Qt::NoBrush), + mBackgroundScaled(true), + mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding), + mInsetLayout(new QCPLayoutInset), + mRangeDrag(Qt::Horizontal|Qt::Vertical), + mRangeZoom(Qt::Horizontal|Qt::Vertical), + mRangeZoomFactorHorz(0.85), + mRangeZoomFactorVert(0.85), + mDragging(false) +{ + mInsetLayout->initializeParentPlot(mParentPlot); + mInsetLayout->setParentLayerable(this); + mInsetLayout->setParent(this); + + setMinimumSize(50, 50); + setMinimumMargins(QMargins(15, 15, 15, 15)); + mAxes.insert(QCPAxis::atLeft, QList()); + mAxes.insert(QCPAxis::atRight, QList()); + mAxes.insert(QCPAxis::atTop, QList()); + mAxes.insert(QCPAxis::atBottom, QList()); + + if (setupDefaultAxes) + { + QCPAxis *xAxis = addAxis(QCPAxis::atBottom); + QCPAxis *yAxis = addAxis(QCPAxis::atLeft); + QCPAxis *xAxis2 = addAxis(QCPAxis::atTop); + QCPAxis *yAxis2 = addAxis(QCPAxis::atRight); + setRangeDragAxes(xAxis, yAxis); + setRangeZoomAxes(xAxis, yAxis); + xAxis2->setVisible(false); + yAxis2->setVisible(false); + xAxis->grid()->setVisible(true); + yAxis->grid()->setVisible(true); + xAxis2->grid()->setVisible(false); + yAxis2->grid()->setVisible(false); + xAxis2->grid()->setZeroLinePen(Qt::NoPen); + yAxis2->grid()->setZeroLinePen(Qt::NoPen); + xAxis2->grid()->setVisible(false); + yAxis2->grid()->setVisible(false); + } +} + +QCPAxisRect::~QCPAxisRect() +{ + delete mInsetLayout; + mInsetLayout = 0; + + QList axesList = axes(); + for (int i=0; i ax(mAxes.value(type)); + if (index >= 0 && index < ax.size()) + { + return ax.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "Axis index out of bounds:" << index; + return 0; + } +} + +/*! + Returns all axes on the axis rect sides specified with \a types. + + \a types may be a single \ref QCPAxis::AxisType or an or-combination, to get the axes of + multiple sides. + + \see axis +*/ +QList QCPAxisRect::axes(QCPAxis::AxisTypes types) const +{ + QList result; + if (types.testFlag(QCPAxis::atLeft)) + result << mAxes.value(QCPAxis::atLeft); + if (types.testFlag(QCPAxis::atRight)) + result << mAxes.value(QCPAxis::atRight); + if (types.testFlag(QCPAxis::atTop)) + result << mAxes.value(QCPAxis::atTop); + if (types.testFlag(QCPAxis::atBottom)) + result << mAxes.value(QCPAxis::atBottom); + return result; +} + +/*! \overload + + Returns all axes of this axis rect. +*/ +QList QCPAxisRect::axes() const +{ + QList result; + QHashIterator > it(mAxes); + while (it.hasNext()) + { + it.next(); + result << it.value(); + } + return result; +} + +/*! + Adds a new axis to the axis rect side specified with \a type, and returns it. If \a axis is 0, a + new QCPAxis instance is created internally. QCustomPlot owns the returned axis, so if you want to + remove an axis, use \ref removeAxis instead of deleting it manually. + + You may inject QCPAxis instances (or sublasses of QCPAxis) by setting \a axis to an axis that was + previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership + of the axis, so you may not delete it afterwards. Further, the \a axis must have been created + with this axis rect as parent and with the same axis type as specified in \a type. If this is not + the case, a debug output is generated, the axis is not added, and the method returns 0. + + This method can not be used to move \a axis between axis rects. The same \a axis instance must + not be added multiple times to the same or different axis rects. + + If an axis rect side already contains one or more axes, the lower and upper endings of the new + axis (\ref QCPAxis::setLowerEnding, \ref QCPAxis::setUpperEnding) are set to \ref + QCPLineEnding::esHalfBar. + + \see addAxes, setupFullAxesBox +*/ +QCPAxis *QCPAxisRect::addAxis(QCPAxis::AxisType type, QCPAxis *axis) +{ + QCPAxis *newAxis = axis; + if (!newAxis) + { + newAxis = new QCPAxis(this, type); + } else // user provided existing axis instance, do some sanity checks + { + if (newAxis->axisType() != type) + { + qDebug() << Q_FUNC_INFO << "passed axis has different axis type than specified in type parameter"; + return 0; + } + if (newAxis->axisRect() != this) + { + qDebug() << Q_FUNC_INFO << "passed axis doesn't have this axis rect as parent axis rect"; + return 0; + } + if (axes().contains(newAxis)) + { + qDebug() << Q_FUNC_INFO << "passed axis is already owned by this axis rect"; + return 0; + } + } + if (mAxes[type].size() > 0) // multiple axes on one side, add half-bar axis ending to additional axes with offset + { + bool invert = (type == QCPAxis::atRight) || (type == QCPAxis::atBottom); + newAxis->setLowerEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, !invert)); + newAxis->setUpperEnding(QCPLineEnding(QCPLineEnding::esHalfBar, 6, 10, invert)); + } + mAxes[type].append(newAxis); + + // reset convenience axis pointers on parent QCustomPlot if they are unset: + if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) + { + switch (type) + { + case QCPAxis::atBottom: { if (!mParentPlot->xAxis) mParentPlot->xAxis = newAxis; break; } + case QCPAxis::atLeft: { if (!mParentPlot->yAxis) mParentPlot->yAxis = newAxis; break; } + case QCPAxis::atTop: { if (!mParentPlot->xAxis2) mParentPlot->xAxis2 = newAxis; break; } + case QCPAxis::atRight: { if (!mParentPlot->yAxis2) mParentPlot->yAxis2 = newAxis; break; } + } + } + + return newAxis; +} + +/*! + Adds a new axis with \ref addAxis to each axis rect side specified in \a types. This may be an + or-combination of QCPAxis::AxisType, so axes can be added to multiple sides at once. + + Returns a list of the added axes. + + \see addAxis, setupFullAxesBox +*/ +QList QCPAxisRect::addAxes(QCPAxis::AxisTypes types) +{ + QList result; + if (types.testFlag(QCPAxis::atLeft)) + result << addAxis(QCPAxis::atLeft); + if (types.testFlag(QCPAxis::atRight)) + result << addAxis(QCPAxis::atRight); + if (types.testFlag(QCPAxis::atTop)) + result << addAxis(QCPAxis::atTop); + if (types.testFlag(QCPAxis::atBottom)) + result << addAxis(QCPAxis::atBottom); + return result; +} + +/*! + Removes the specified \a axis from the axis rect and deletes it. + + Returns true on success, i.e. if \a axis was a valid axis in this axis rect. + + \see addAxis +*/ +bool QCPAxisRect::removeAxis(QCPAxis *axis) +{ + // don't access axis->axisType() to provide safety when axis is an invalid pointer, rather go through all axis containers: + QHashIterator > it(mAxes); + while (it.hasNext()) + { + it.next(); + if (it.value().contains(axis)) + { + mAxes[it.key()].removeOne(axis); + if (qobject_cast(parentPlot())) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the axis rect is not in any layout and thus QObject-child of QCustomPlot) + parentPlot()->axisRemoved(axis); + delete axis; + return true; + } + } + qDebug() << Q_FUNC_INFO << "Axis isn't in axis rect:" << reinterpret_cast(axis); + return false; +} + +/*! + Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. + + All axes of this axis rect will have their range zoomed accordingly. If you only wish to zoom + specific axes, use the overloaded version of this method. + + \see QCustomPlot::setSelectionRectMode +*/ +void QCPAxisRect::zoom(const QRectF &pixelRect) +{ + zoom(pixelRect, axes()); +} + +/*! \overload + + Zooms in (or out) to the passed rectangular region \a pixelRect, given in pixel coordinates. + + Only the axes passed in \a affectedAxes will have their ranges zoomed accordingly. + + \see QCustomPlot::setSelectionRectMode +*/ +void QCPAxisRect::zoom(const QRectF &pixelRect, const QList &affectedAxes) +{ + foreach (QCPAxis *axis, affectedAxes) + { + if (!axis) + { + qDebug() << Q_FUNC_INFO << "a passed axis was zero"; + continue; + } + QCPRange pixelRange; + if (axis->orientation() == Qt::Horizontal) + pixelRange = QCPRange(pixelRect.left(), pixelRect.right()); + else + pixelRange = QCPRange(pixelRect.top(), pixelRect.bottom()); + axis->setRange(axis->pixelToCoord(pixelRange.lower), axis->pixelToCoord(pixelRange.upper)); + } +} + +/*! + Convenience function to create an axis on each side that doesn't have any axes yet and set their + visibility to true. Further, the top/right axes are assigned the following properties of the + bottom/left axes: + + \li range (\ref QCPAxis::setRange) + \li range reversed (\ref QCPAxis::setRangeReversed) + \li scale type (\ref QCPAxis::setScaleType) + \li tick visibility (\ref QCPAxis::setTicks) + \li number format (\ref QCPAxis::setNumberFormat) + \li number precision (\ref QCPAxis::setNumberPrecision) + \li tick count of ticker (\ref QCPAxisTicker::setTickCount) + \li tick origin of ticker (\ref QCPAxisTicker::setTickOrigin) + + Tick label visibility (\ref QCPAxis::setTickLabels) of the right and top axes are set to false. + + If \a connectRanges is true, the \ref QCPAxis::rangeChanged "rangeChanged" signals of the bottom + and left axes are connected to the \ref QCPAxis::setRange slots of the top and right axes. +*/ +void QCPAxisRect::setupFullAxesBox(bool connectRanges) +{ + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; + if (axisCount(QCPAxis::atBottom) == 0) + xAxis = addAxis(QCPAxis::atBottom); + else + xAxis = axis(QCPAxis::atBottom); + + if (axisCount(QCPAxis::atLeft) == 0) + yAxis = addAxis(QCPAxis::atLeft); + else + yAxis = axis(QCPAxis::atLeft); + + if (axisCount(QCPAxis::atTop) == 0) + xAxis2 = addAxis(QCPAxis::atTop); + else + xAxis2 = axis(QCPAxis::atTop); + + if (axisCount(QCPAxis::atRight) == 0) + yAxis2 = addAxis(QCPAxis::atRight); + else + yAxis2 = axis(QCPAxis::atRight); + + xAxis->setVisible(true); + yAxis->setVisible(true); + xAxis2->setVisible(true); + yAxis2->setVisible(true); + xAxis2->setTickLabels(false); + yAxis2->setTickLabels(false); + + xAxis2->setRange(xAxis->range()); + xAxis2->setRangeReversed(xAxis->rangeReversed()); + xAxis2->setScaleType(xAxis->scaleType()); + xAxis2->setTicks(xAxis->ticks()); + xAxis2->setNumberFormat(xAxis->numberFormat()); + xAxis2->setNumberPrecision(xAxis->numberPrecision()); + xAxis2->ticker()->setTickCount(xAxis->ticker()->tickCount()); + xAxis2->ticker()->setTickOrigin(xAxis->ticker()->tickOrigin()); + + yAxis2->setRange(yAxis->range()); + yAxis2->setRangeReversed(yAxis->rangeReversed()); + yAxis2->setScaleType(yAxis->scaleType()); + yAxis2->setTicks(yAxis->ticks()); + yAxis2->setNumberFormat(yAxis->numberFormat()); + yAxis2->setNumberPrecision(yAxis->numberPrecision()); + yAxis2->ticker()->setTickCount(yAxis->ticker()->tickCount()); + yAxis2->ticker()->setTickOrigin(yAxis->ticker()->tickOrigin()); + + if (connectRanges) + { + connect(xAxis, SIGNAL(rangeChanged(QCPRange)), xAxis2, SLOT(setRange(QCPRange))); + connect(yAxis, SIGNAL(rangeChanged(QCPRange)), yAxis2, SLOT(setRange(QCPRange))); + } +} + +/*! + Returns a list of all the plottables that are associated with this axis rect. + + A plottable is considered associated with an axis rect if its key or value axis (or both) is in + this axis rect. + + \see graphs, items +*/ +QList QCPAxisRect::plottables() const +{ + // Note: don't append all QCPAxis::plottables() into a list, because we might get duplicate entries + QList result; + for (int i=0; imPlottables.size(); ++i) + { + if (mParentPlot->mPlottables.at(i)->keyAxis()->axisRect() == this || mParentPlot->mPlottables.at(i)->valueAxis()->axisRect() == this) + result.append(mParentPlot->mPlottables.at(i)); + } + return result; +} + +/*! + Returns a list of all the graphs that are associated with this axis rect. + + A graph is considered associated with an axis rect if its key or value axis (or both) is in + this axis rect. + + \see plottables, items +*/ +QList QCPAxisRect::graphs() const +{ + // Note: don't append all QCPAxis::graphs() into a list, because we might get duplicate entries + QList result; + for (int i=0; imGraphs.size(); ++i) + { + if (mParentPlot->mGraphs.at(i)->keyAxis()->axisRect() == this || mParentPlot->mGraphs.at(i)->valueAxis()->axisRect() == this) + result.append(mParentPlot->mGraphs.at(i)); + } + return result; +} + +/*! + Returns a list of all the items that are associated with this axis rect. + + An item is considered associated with an axis rect if any of its positions has key or value axis + set to an axis that is in this axis rect, or if any of its positions has \ref + QCPItemPosition::setAxisRect set to the axis rect, or if the clip axis rect (\ref + QCPAbstractItem::setClipAxisRect) is set to this axis rect. + + \see plottables, graphs +*/ +QList QCPAxisRect::items() const +{ + // Note: don't just append all QCPAxis::items() into a list, because we might get duplicate entries + // and miss those items that have this axis rect as clipAxisRect. + QList result; + for (int itemId=0; itemIdmItems.size(); ++itemId) + { + if (mParentPlot->mItems.at(itemId)->clipAxisRect() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + continue; + } + QList positions = mParentPlot->mItems.at(itemId)->positions(); + for (int posId=0; posIdaxisRect() == this || + positions.at(posId)->keyAxis()->axisRect() == this || + positions.at(posId)->valueAxis()->axisRect() == this) + { + result.append(mParentPlot->mItems.at(itemId)); + break; + } + } + } + return result; +} + +/*! + This method is called automatically upon replot and doesn't need to be called by users of + QCPAxisRect. + + Calls the base class implementation to update the margins (see \ref QCPLayoutElement::update), + and finally passes the \ref rect to the inset layout (\ref insetLayout) and calls its + QCPInsetLayout::update function. + + \seebaseclassmethod +*/ +void QCPAxisRect::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + + switch (phase) + { + case upPreparation: + { + QList allAxes = axes(); + for (int i=0; isetupTickVectors(); + break; + } + case upLayout: + { + mInsetLayout->setOuterRect(rect()); + break; + } + default: break; + } + + // pass update call on to inset layout (doesn't happen automatically, because QCPAxisRect doesn't derive from QCPLayout): + mInsetLayout->update(phase); +} + +/* inherits documentation from base class */ +QList QCPAxisRect::elements(bool recursive) const +{ + QList result; + if (mInsetLayout) + { + result << mInsetLayout; + if (recursive) + result << mInsetLayout->elements(recursive); + } + return result; +} + +/* inherits documentation from base class */ +void QCPAxisRect::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + painter->setAntialiasing(false); +} + +/* inherits documentation from base class */ +void QCPAxisRect::draw(QCPPainter *painter) +{ + drawBackground(painter); +} + +/*! + Sets \a pm as the axis background pixmap. The axis background pixmap will be drawn inside the + axis rect. Since axis rects place themselves on the "background" layer by default, the axis rect + backgrounds are usually drawn below everything else. + + For cases where the provided pixmap doesn't have the same size as the axis rect, scaling can be + enabled with \ref setBackgroundScaled and the scaling mode (i.e. whether and how the aspect ratio + is preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call, + consider using the overloaded version of this function. + + Below the pixmap, the axis rect may be optionally filled with a brush, if specified with \ref + setBackground(const QBrush &brush). + + \see setBackgroundScaled, setBackgroundScaledMode, setBackground(const QBrush &brush) +*/ +void QCPAxisRect::setBackground(const QPixmap &pm) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); +} + +/*! \overload + + Sets \a brush as the background brush. The axis rect background will be filled with this brush. + Since axis rects place themselves on the "background" layer by default, the axis rect backgrounds + are usually drawn below everything else. + + The brush will be drawn before (under) any background pixmap, which may be specified with \ref + setBackground(const QPixmap &pm). + + To disable drawing of a background brush, set \a brush to Qt::NoBrush. + + \see setBackground(const QPixmap &pm) +*/ +void QCPAxisRect::setBackground(const QBrush &brush) +{ + mBackgroundBrush = brush; +} + +/*! \overload + + Allows setting the background pixmap of the axis rect, whether it shall be scaled and how it + shall be scaled in one call. + + \see setBackground(const QPixmap &pm), setBackgroundScaled, setBackgroundScaledMode +*/ +void QCPAxisRect::setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode) +{ + mBackgroundPixmap = pm; + mScaledBackgroundPixmap = QPixmap(); + mBackgroundScaled = scaled; + mBackgroundScaledMode = mode; +} + +/*! + Sets whether the axis background pixmap shall be scaled to fit the axis rect or not. If \a scaled + is set to true, you may control whether and how the aspect ratio of the original pixmap is + preserved with \ref setBackgroundScaledMode. + + Note that the scaled version of the original pixmap is buffered, so there is no performance + penalty on replots. (Except when the axis rect dimensions are changed continuously.) + + \see setBackground, setBackgroundScaledMode +*/ +void QCPAxisRect::setBackgroundScaled(bool scaled) +{ + mBackgroundScaled = scaled; +} + +/*! + If scaling of the axis background pixmap is enabled (\ref setBackgroundScaled), use this function to + define whether and how the aspect ratio of the original pixmap passed to \ref setBackground is preserved. + \see setBackground, setBackgroundScaled +*/ +void QCPAxisRect::setBackgroundScaledMode(Qt::AspectRatioMode mode) +{ + mBackgroundScaledMode = mode; +} + +/*! + Returns the range drag axis of the \a orientation provided. If multiple axes were set, returns + the first one (use \ref rangeDragAxes to retrieve a list with all set axes). + + \see setRangeDragAxes +*/ +QCPAxis *QCPAxisRect::rangeDragAxis(Qt::Orientation orientation) +{ + if (orientation == Qt::Horizontal) + return mRangeDragHorzAxis.isEmpty() ? 0 : mRangeDragHorzAxis.first().data(); + else + return mRangeDragVertAxis.isEmpty() ? 0 : mRangeDragVertAxis.first().data(); +} + +/*! + Returns the range zoom axis of the \a orientation provided. If multiple axes were set, returns + the first one (use \ref rangeZoomAxes to retrieve a list with all set axes). + + \see setRangeZoomAxes +*/ +QCPAxis *QCPAxisRect::rangeZoomAxis(Qt::Orientation orientation) +{ + if (orientation == Qt::Horizontal) + return mRangeZoomHorzAxis.isEmpty() ? 0 : mRangeZoomHorzAxis.first().data(); + else + return mRangeZoomVertAxis.isEmpty() ? 0 : mRangeZoomVertAxis.first().data(); +} + +/*! + Returns all range drag axes of the \a orientation provided. + + \see rangeZoomAxis, setRangeZoomAxes +*/ +QList QCPAxisRect::rangeDragAxes(Qt::Orientation orientation) +{ + QList result; + if (orientation == Qt::Horizontal) + { + for (int i=0; i QCPAxisRect::rangeZoomAxes(Qt::Orientation orientation) +{ + QList result; + if (orientation == Qt::Horizontal) + { + for (int i=0; iQt::Horizontal | + Qt::Vertical as \a orientations. + + In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions + contains \ref QCP::iRangeDrag to enable the range dragging interaction. + + \see setRangeZoom, setRangeDragAxes, QCustomPlot::setNoAntialiasingOnDrag +*/ +void QCPAxisRect::setRangeDrag(Qt::Orientations orientations) +{ + mRangeDrag = orientations; +} + +/*! + Sets which axis orientation may be zoomed by the user with the mouse wheel. What orientation + corresponds to which specific axis can be set with \ref setRangeZoomAxes(QCPAxis *horizontal, + QCPAxis *vertical). By default, the horizontal axis is the bottom axis (xAxis) and the vertical + axis is the left axis (yAxis). + + To disable range zooming entirely, pass 0 as \a orientations or remove \ref QCP::iRangeZoom from \ref + QCustomPlot::setInteractions. To enable range zooming for both directions, pass Qt::Horizontal | + Qt::Vertical as \a orientations. + + In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions + contains \ref QCP::iRangeZoom to enable the range zooming interaction. + + \see setRangeZoomFactor, setRangeZoomAxes, setRangeDrag +*/ +void QCPAxisRect::setRangeZoom(Qt::Orientations orientations) +{ + mRangeZoom = orientations; +} + +/*! \overload + + Sets the axes whose range will be dragged when \ref setRangeDrag enables mouse range dragging on + the QCustomPlot widget. Pass 0 if no axis shall be dragged in the respective orientation. + + Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall + react to dragging interactions. + + \see setRangeZoomAxes +*/ +void QCPAxisRect::setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical) +{ + QList horz, vert; + if (horizontal) + horz.append(horizontal); + if (vertical) + vert.append(vertical); + setRangeDragAxes(horz, vert); +} + +/*! \overload + + This method allows to set up multiple axes to react to horizontal and vertical dragging. The drag + orientation that the respective axis will react to is deduced from its orientation (\ref + QCPAxis::orientation). + + In the unusual case that you wish to e.g. drag a vertically oriented axis with a horizontal drag + motion, use the overload taking two separate lists for horizontal and vertical dragging. +*/ +void QCPAxisRect::setRangeDragAxes(QList axes) +{ + QList horz, vert; + foreach (QCPAxis *ax, axes) + { + if (ax->orientation() == Qt::Horizontal) + horz.append(ax); + else + vert.append(ax); + } + setRangeDragAxes(horz, vert); +} + +/*! \overload + + This method allows to set multiple axes up to react to horizontal and vertical dragging, and + define specifically which axis reacts to which drag orientation (irrespective of the axis + orientation). +*/ +void QCPAxisRect::setRangeDragAxes(QList horizontal, QList vertical) +{ + mRangeDragHorzAxis.clear(); + foreach (QCPAxis *ax, horizontal) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeDragHorzAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast(ax); + } + mRangeDragVertAxis.clear(); + foreach (QCPAxis *ax, vertical) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeDragVertAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in vertical list:" << reinterpret_cast(ax); + } +} + +/*! + Sets the axes whose range will be zoomed when \ref setRangeZoom enables mouse wheel zooming on + the QCustomPlot widget. Pass 0 if no axis shall be zoomed in the respective orientation. + + The two axes can be zoomed with different strengths, when different factors are passed to \ref + setRangeZoomFactor(double horizontalFactor, double verticalFactor). + + Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall + react to zooming interactions. + + \see setRangeDragAxes +*/ +void QCPAxisRect::setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical) +{ + QList horz, vert; + if (horizontal) + horz.append(horizontal); + if (vertical) + vert.append(vertical); + setRangeZoomAxes(horz, vert); +} + +/*! \overload + + This method allows to set up multiple axes to react to horizontal and vertical range zooming. The + zoom orientation that the respective axis will react to is deduced from its orientation (\ref + QCPAxis::orientation). + + In the unusual case that you wish to e.g. zoom a vertically oriented axis with a horizontal zoom + interaction, use the overload taking two separate lists for horizontal and vertical zooming. +*/ +void QCPAxisRect::setRangeZoomAxes(QList axes) +{ + QList horz, vert; + foreach (QCPAxis *ax, axes) + { + if (ax->orientation() == Qt::Horizontal) + horz.append(ax); + else + vert.append(ax); + } + setRangeZoomAxes(horz, vert); +} + +/*! \overload + + This method allows to set multiple axes up to react to horizontal and vertical zooming, and + define specifically which axis reacts to which zoom orientation (irrespective of the axis + orientation). +*/ +void QCPAxisRect::setRangeZoomAxes(QList horizontal, QList vertical) +{ + mRangeZoomHorzAxis.clear(); + foreach (QCPAxis *ax, horizontal) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeZoomHorzAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast(ax); + } + mRangeZoomVertAxis.clear(); + foreach (QCPAxis *ax, vertical) + { + QPointer axPointer(ax); + if (!axPointer.isNull()) + mRangeZoomVertAxis.append(axPointer); + else + qDebug() << Q_FUNC_INFO << "invalid axis passed in vertical list:" << reinterpret_cast(ax); + } +} + +/*! + Sets how strong one rotation step of the mouse wheel zooms, when range zoom was activated with + \ref setRangeZoom. The two parameters \a horizontalFactor and \a verticalFactor provide a way to + let the horizontal axis zoom at different rates than the vertical axis. Which axis is horizontal + and which is vertical, can be set with \ref setRangeZoomAxes. + + When the zoom factor is greater than one, scrolling the mouse wheel backwards (towards the user) + will zoom in (make the currently visible range smaller). For zoom factors smaller than one, the + same scrolling direction will zoom out. +*/ +void QCPAxisRect::setRangeZoomFactor(double horizontalFactor, double verticalFactor) +{ + mRangeZoomFactorHorz = horizontalFactor; + mRangeZoomFactorVert = verticalFactor; +} + +/*! \overload + + Sets both the horizontal and vertical zoom \a factor. +*/ +void QCPAxisRect::setRangeZoomFactor(double factor) +{ + mRangeZoomFactorHorz = factor; + mRangeZoomFactorVert = factor; +} + +/*! \internal + + Draws the background of this axis rect. It may consist of a background fill (a QBrush) and a + pixmap. + + If a brush was given via \ref setBackground(const QBrush &brush), this function first draws an + according filling inside the axis rect with the provided \a painter. + + Then, if a pixmap was provided via \ref setBackground, this function buffers the scaled version + depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside + the axis rect with the provided \a painter. The scaled version is buffered in + mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when + the axis rect has changed in a way that requires a rescale of the background pixmap (this is + dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was + set. + + \see setBackground, setBackgroundScaled, setBackgroundScaledMode +*/ +void QCPAxisRect::drawBackground(QCPPainter *painter) +{ + // draw background fill: + if (mBackgroundBrush != Qt::NoBrush) + painter->fillRect(mRect, mBackgroundBrush); + + // draw background pixmap (on top of fill, if brush specified): + if (!mBackgroundPixmap.isNull()) + { + if (mBackgroundScaled) + { + // check whether mScaledBackground needs to be updated: + QSize scaledSize(mBackgroundPixmap.size()); + scaledSize.scale(mRect.size(), mBackgroundScaledMode); + if (mScaledBackgroundPixmap.size() != scaledSize) + mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mRect.size(), mBackgroundScaledMode, Qt::SmoothTransformation); + painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mScaledBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height()) & mScaledBackgroundPixmap.rect()); + } else + { + painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height())); + } + } +} + +/*! \internal + + This function makes sure multiple axes on the side specified with \a type don't collide, but are + distributed according to their respective space requirement (QCPAxis::calculateMargin). + + It does this by setting an appropriate offset (\ref QCPAxis::setOffset) on all axes except the + one with index zero. + + This function is called by \ref calculateAutoMargin. +*/ +void QCPAxisRect::updateAxesOffset(QCPAxis::AxisType type) +{ + const QList axesList = mAxes.value(type); + if (axesList.isEmpty()) + return; + + bool isFirstVisible = !axesList.first()->visible(); // if the first axis is visible, the second axis (which is where the loop starts) isn't the first visible axis, so initialize with false + for (int i=1; ioffset() + axesList.at(i-1)->calculateMargin(); + if (axesList.at(i)->visible()) // only add inner tick length to offset if this axis is visible and it's not the first visible one (might happen if true first axis is invisible) + { + if (!isFirstVisible) + offset += axesList.at(i)->tickLengthIn(); + isFirstVisible = false; + } + axesList.at(i)->setOffset(offset); + } +} + +/* inherits documentation from base class */ +int QCPAxisRect::calculateAutoMargin(QCP::MarginSide side) +{ + if (!mAutoMargins.testFlag(side)) + qDebug() << Q_FUNC_INFO << "Called with side that isn't specified as auto margin"; + + updateAxesOffset(QCPAxis::marginSideToAxisType(side)); + + // note: only need to look at the last (outer most) axis to determine the total margin, due to updateAxisOffset call + const QList axesList = mAxes.value(QCPAxis::marginSideToAxisType(side)); + if (axesList.size() > 0) + return axesList.last()->offset() + axesList.last()->calculateMargin(); + else + return 0; +} + +/*! \internal + + Reacts to a change in layout to potentially set the convenience axis pointers \ref + QCustomPlot::xAxis, \ref QCustomPlot::yAxis, etc. of the parent QCustomPlot to the respective + axes of this axis rect. This is only done if the respective convenience pointer is currently zero + and if there is no QCPAxisRect at position (0, 0) of the plot layout. + + This automation makes it simpler to replace the main axis rect with a newly created one, without + the need to manually reset the convenience pointers. +*/ +void QCPAxisRect::layoutChanged() +{ + if (mParentPlot && mParentPlot->axisRectCount() > 0 && mParentPlot->axisRect(0) == this) + { + if (axisCount(QCPAxis::atBottom) > 0 && !mParentPlot->xAxis) + mParentPlot->xAxis = axis(QCPAxis::atBottom); + if (axisCount(QCPAxis::atLeft) > 0 && !mParentPlot->yAxis) + mParentPlot->yAxis = axis(QCPAxis::atLeft); + if (axisCount(QCPAxis::atTop) > 0 && !mParentPlot->xAxis2) + mParentPlot->xAxis2 = axis(QCPAxis::atTop); + if (axisCount(QCPAxis::atRight) > 0 && !mParentPlot->yAxis2) + mParentPlot->yAxis2 = axis(QCPAxis::atRight); + } +} + +/*! \internal + + Event handler for when a mouse button is pressed on the axis rect. If the left mouse button is + pressed, the range dragging interaction is initialized (the actual range manipulation happens in + the \ref mouseMoveEvent). + + The mDragging flag is set to true and some anchor points are set that are needed to determine the + distance the mouse was dragged in the mouse move/release events later. + + \see mouseMoveEvent, mouseReleaseEvent +*/ +void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + mDragStart = event->pos(); // need this even when not LeftButton is pressed, to determine in releaseEvent whether it was a full click (no position change between press and release) + if (event->buttons() & Qt::LeftButton) + { + mDragging = true; + // initialize antialiasing backup in case we start dragging: + if (mParentPlot->noAntialiasingOnDrag()) + { + mAADragBackup = mParentPlot->antialiasedElements(); + mNotAADragBackup = mParentPlot->notAntialiasedElements(); + } + // Mouse range dragging interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + mDragStartHorzRange.clear(); + for (int i=0; irange()); + mDragStartVertRange.clear(); + for (int i=0; irange()); + } + } +} + +/*! \internal + + Event handler for when the mouse is moved on the axis rect. If range dragging was activated in a + preceding \ref mousePressEvent, the range is moved accordingly. + + \see mousePressEvent, mouseReleaseEvent +*/ +void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(startPos) + // Mouse range dragging interaction: + if (mDragging && mParentPlot->interactions().testFlag(QCP::iRangeDrag)) + { + + if (mRangeDrag.testFlag(Qt::Horizontal)) + { + for (int i=0; i= mDragStartHorzRange.size()) + break; + if (ax->mScaleType == QCPAxis::stLinear) + { + double diff = ax->pixelToCoord(mDragStart.x()) - ax->pixelToCoord(event->pos().x()); + ax->setRange(mDragStartHorzRange.at(i).lower+diff, mDragStartHorzRange.at(i).upper+diff); + } else if (ax->mScaleType == QCPAxis::stLogarithmic) + { + double diff = ax->pixelToCoord(mDragStart.x()) / ax->pixelToCoord(event->pos().x()); + ax->setRange(mDragStartHorzRange.at(i).lower*diff, mDragStartHorzRange.at(i).upper*diff); + } + } + } + + if (mRangeDrag.testFlag(Qt::Vertical)) + { + for (int i=0; i= mDragStartVertRange.size()) + break; + if (ax->mScaleType == QCPAxis::stLinear) + { + double diff = ax->pixelToCoord(mDragStart.y()) - ax->pixelToCoord(event->pos().y()); + ax->setRange(mDragStartVertRange.at(i).lower+diff, mDragStartVertRange.at(i).upper+diff); + } else if (ax->mScaleType == QCPAxis::stLogarithmic) + { + double diff = ax->pixelToCoord(mDragStart.y()) / ax->pixelToCoord(event->pos().y()); + ax->setRange(mDragStartVertRange.at(i).lower*diff, mDragStartVertRange.at(i).upper*diff); + } + } + } + + if (mRangeDrag != 0) // if either vertical or horizontal drag was enabled, do a replot + { + if (mParentPlot->noAntialiasingOnDrag()) + mParentPlot->setNotAntialiasedElements(QCP::aeAll); + mParentPlot->replot(); + } + + } +} + +/* inherits documentation from base class */ +void QCPAxisRect::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + Q_UNUSED(event) + Q_UNUSED(startPos) + mDragging = false; + if (mParentPlot->noAntialiasingOnDrag()) + { + mParentPlot->setAntialiasedElements(mAADragBackup); + mParentPlot->setNotAntialiasedElements(mNotAADragBackup); + } +} + +/*! \internal + + Event handler for mouse wheel events. If rangeZoom is Qt::Horizontal, Qt::Vertical or both, the + ranges of the axes defined as rangeZoomHorzAxis and rangeZoomVertAxis are scaled. The center of + the scaling operation is the current cursor position inside the axis rect. The scaling factor is + dependent on the mouse wheel delta (which direction the wheel was rotated) to provide a natural + zooming feel. The Strength of the zoom can be controlled via \ref setRangeZoomFactor. + + Note, that event->delta() is usually +/-120 for single rotation steps. However, if the mouse + wheel is turned rapidly, many steps may bunch up to one event, so the event->delta() may then be + multiples of 120. This is taken into account here, by calculating \a wheelSteps and using it as + exponent of the range zoom factor. This takes care of the wheel direction automatically, by + inverting the factor, when the wheel step is negative (f^-1 = 1/f). +*/ +void QCPAxisRect::wheelEvent(QWheelEvent *event) +{ + // Mouse range zooming interaction: + if (mParentPlot->interactions().testFlag(QCP::iRangeZoom)) + { + if (mRangeZoom != 0) + { + double factor; + double wheelSteps = event->delta()/120.0; // a single step delta is +/-120 usually + if (mRangeZoom.testFlag(Qt::Horizontal)) + { + factor = qPow(mRangeZoomFactorHorz, wheelSteps); + for (int i=0; iscaleRange(factor, mRangeZoomHorzAxis.at(i)->pixelToCoord(event->pos().x())); + } + } + if (mRangeZoom.testFlag(Qt::Vertical)) + { + factor = qPow(mRangeZoomFactorVert, wheelSteps); + for (int i=0; iscaleRange(factor, mRangeZoomVertAxis.at(i)->pixelToCoord(event->pos().y())); + } + } + mParentPlot->replot(); + } + } +} +/* end of 'src/layoutelements/layoutelement-axisrect.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-legend.cpp', size 30933 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractLegendItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractLegendItem + \brief The abstract base class for all entries in a QCPLegend. + + It defines a very basic interface for entries in a QCPLegend. For representing plottables in the + legend, the subclass \ref QCPPlottableLegendItem is more suitable. + + Only derive directly from this class when you need absolute freedom (e.g. a custom legend entry + that's not even associated with a plottable). + + You must implement the following pure virtual functions: + \li \ref draw (from QCPLayerable) + + You inherit the following members you may use: + + + + + + + + +
QCPLegend *\b mParentLegendA pointer to the parent QCPLegend.
QFont \b mFontThe generic font of the item. You should use this font for all or at least the most prominent text of the item.
+*/ + +/* start of documentation of signals */ + +/*! \fn void QCPAbstractLegendItem::selectionChanged(bool selected) + + This signal is emitted when the selection state of this legend item has changed, either by user + interaction or by a direct call to \ref setSelected. +*/ + +/* end of documentation of signals */ + +/*! + Constructs a QCPAbstractLegendItem and associates it with the QCPLegend \a parent. This does not + cause the item to be added to \a parent, so \ref QCPLegend::addItem must be called separately. +*/ +QCPAbstractLegendItem::QCPAbstractLegendItem(QCPLegend *parent) : + QCPLayoutElement(parent->parentPlot()), + mParentLegend(parent), + mFont(parent->font()), + mTextColor(parent->textColor()), + mSelectedFont(parent->selectedFont()), + mSelectedTextColor(parent->selectedTextColor()), + mSelectable(true), + mSelected(false) +{ + setLayer(QLatin1String("legend")); + setMargins(QMargins(0, 0, 0, 0)); +} + +/*! + Sets the default font of this specific legend item to \a font. + + \see setTextColor, QCPLegend::setFont +*/ +void QCPAbstractLegendItem::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the default text color of this specific legend item to \a color. + + \see setFont, QCPLegend::setTextColor +*/ +void QCPAbstractLegendItem::setTextColor(const QColor &color) +{ + mTextColor = color; +} + +/*! + When this legend item is selected, \a font is used to draw generic text, instead of the normal + font set with \ref setFont. + + \see setFont, QCPLegend::setSelectedFont +*/ +void QCPAbstractLegendItem::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + When this legend item is selected, \a color is used to draw generic text, instead of the normal + color set with \ref setTextColor. + + \see setTextColor, QCPLegend::setSelectedTextColor +*/ +void QCPAbstractLegendItem::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; +} + +/*! + Sets whether this specific legend item is selectable. + + \see setSelectedParts, QCustomPlot::setInteractions +*/ +void QCPAbstractLegendItem::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets whether this specific legend item is selected. + + It is possible to set the selection state of this item by calling this function directly, even if + setSelectable is set to false. + + \see setSelectableParts, QCustomPlot::setInteractions +*/ +void QCPAbstractLegendItem::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/* inherits documentation from base class */ +double QCPAbstractLegendItem::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (!mParentPlot) return -1; + if (onlySelectable && (!mSelectable || !mParentLegend->selectableParts().testFlag(QCPLegend::spItems))) + return -1; + + if (mRect.contains(pos.toPoint())) + return mParentPlot->selectionTolerance()*0.99; + else + return -1; +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeLegendItems); +} + +/* inherits documentation from base class */ +QRect QCPAbstractLegendItem::clipRect() const +{ + return mOuterRect; +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPAbstractLegendItem::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable && mParentLegend->selectableParts().testFlag(QCPLegend::spItems)) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPlottableLegendItem +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPlottableLegendItem + \brief A legend item representing a plottable with an icon and the plottable name. + + This is the standard legend item for plottables. It displays an icon of the plottable next to the + plottable name. The icon is drawn by the respective plottable itself (\ref + QCPAbstractPlottable::drawLegendIcon), and tries to give an intuitive symbol for the plottable. + For example, the QCPGraph draws a centered horizontal line and/or a single scatter point in the + middle. + + Legend items of this type are always associated with one plottable (retrievable via the + plottable() function and settable with the constructor). You may change the font of the plottable + name with \ref setFont. Icon padding and border pen is taken from the parent QCPLegend, see \ref + QCPLegend::setIconBorderPen and \ref QCPLegend::setIconTextPadding. + + The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend + creates/removes legend items of this type in the default implementation. However, these functions + may be reimplemented such that a different kind of legend item (e.g a direct subclass of + QCPAbstractLegendItem) is used for that plottable. + + Since QCPLegend is based on QCPLayoutGrid, a legend item itself is just a subclass of + QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout + interface, QCPLegend has specialized functions for handling legend items conveniently, see the + documentation of \ref QCPLegend. +*/ + +/*! + Creates a new legend item associated with \a plottable. + + Once it's created, it can be added to the legend via \ref QCPLegend::addItem. + + A more convenient way of adding/removing a plottable to/from the legend is via the functions \ref + QCPAbstractPlottable::addToLegend and \ref QCPAbstractPlottable::removeFromLegend. +*/ +QCPPlottableLegendItem::QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable) : + QCPAbstractLegendItem(parent), + mPlottable(plottable) +{ + setAntialiased(false); +} + +/*! \internal + + Returns the pen that shall be used to draw the icon border, taking into account the selection + state of this item. +*/ +QPen QCPPlottableLegendItem::getIconBorderPen() const +{ + return mSelected ? mParentLegend->selectedIconBorderPen() : mParentLegend->iconBorderPen(); +} + +/*! \internal + + Returns the text color that shall be used to draw text, taking into account the selection state + of this item. +*/ +QColor QCPPlottableLegendItem::getTextColor() const +{ + return mSelected ? mSelectedTextColor : mTextColor; +} + +/*! \internal + + Returns the font that shall be used to draw text, taking into account the selection state of this + item. +*/ +QFont QCPPlottableLegendItem::getFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Draws the item with \a painter. The size and position of the drawn legend item is defined by the + parent layout (typically a \ref QCPLegend) and the \ref minimumSizeHint and \ref maximumSizeHint + of this legend item. +*/ +void QCPPlottableLegendItem::draw(QCPPainter *painter) +{ + if (!mPlottable) return; + painter->setFont(getFont()); + painter->setPen(QPen(getTextColor())); + QSizeF iconSize = mParentLegend->iconSize(); + QRectF textRect = painter->fontMetrics().boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->name()); + QRectF iconRect(mRect.topLeft(), iconSize); + int textHeight = qMax(textRect.height(), iconSize.height()); // if text has smaller height than icon, center text vertically in icon height, else align tops + painter->drawText(mRect.x()+iconSize.width()+mParentLegend->iconTextPadding(), mRect.y(), textRect.width(), textHeight, Qt::TextDontClip, mPlottable->name()); + // draw icon: + painter->save(); + painter->setClipRect(iconRect, Qt::IntersectClip); + mPlottable->drawLegendIcon(painter, iconRect); + painter->restore(); + // draw icon border: + if (getIconBorderPen().style() != Qt::NoPen) + { + painter->setPen(getIconBorderPen()); + painter->setBrush(Qt::NoBrush); + int halfPen = qCeil(painter->pen().widthF()*0.5)+1; + painter->setClipRect(mOuterRect.adjusted(-halfPen, -halfPen, halfPen, halfPen)); // extend default clip rect so thicker pens (especially during selection) are not clipped + painter->drawRect(iconRect); + } +} + +/*! \internal + + Calculates and returns the size of this item. This includes the icon, the text and the padding in + between. + + \seebaseclassmethod +*/ +QSize QCPPlottableLegendItem::minimumSizeHint() const +{ + if (!mPlottable) return QSize(); + QSize result(0, 0); + QRect textRect; + QFontMetrics fontMetrics(getFont()); + QSize iconSize = mParentLegend->iconSize(); + textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->name()); + result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width() + mMargins.left() + mMargins.right()); + result.setHeight(qMax(textRect.height(), iconSize.height()) + mMargins.top() + mMargins.bottom()); + return result; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPLegend +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPLegend + \brief Manages a legend inside a QCustomPlot. + + A legend is a small box somewhere in the plot which lists plottables with their name and icon. + + Normally, the legend is populated by calling \ref QCPAbstractPlottable::addToLegend. The + respective legend item can be removed with \ref QCPAbstractPlottable::removeFromLegend. However, + QCPLegend also offers an interface to add and manipulate legend items directly: \ref item, \ref + itemWithPlottable, \ref itemCount, \ref addItem, \ref removeItem, etc. + + Since \ref QCPLegend derives from \ref QCPLayoutGrid, it can be placed in any position a \ref + QCPLayoutElement may be positioned. The legend items are themselves \ref QCPLayoutElement + "QCPLayoutElements" which are placed in the grid layout of the legend. \ref QCPLegend only adds + an interface specialized for handling child elements of type \ref QCPAbstractLegendItem, as + mentioned above. In principle, any other layout elements may also be added to a legend via the + normal \ref QCPLayoutGrid interface. See the special page about \link thelayoutsystem The Layout + System\endlink for examples on how to add other elements to the legend and move it outside the axis + rect. + + Use the methods \ref setFillOrder and \ref setWrap inherited from \ref QCPLayoutGrid to control + in which order (column first or row first) the legend is filled up when calling \ref addItem, and + at which column or row wrapping occurs. + + By default, every QCustomPlot has one legend (\ref QCustomPlot::legend) which is placed in the + inset layout of the main axis rect (\ref QCPAxisRect::insetLayout). To move the legend to another + position inside the axis rect, use the methods of the \ref QCPLayoutInset. To move the legend + outside of the axis rect, place it anywhere else with the \ref QCPLayout/\ref QCPLayoutElement + interface. +*/ + +/* start of documentation of signals */ + +/*! \fn void QCPLegend::selectionChanged(QCPLegend::SelectableParts selection); + + This signal is emitted when the selection state of this legend has changed. + + \see setSelectedParts, setSelectableParts +*/ + +/* end of documentation of signals */ + +/*! + Constructs a new QCPLegend instance with default values. + + Note that by default, QCustomPlot already contains a legend ready to be used as \ref + QCustomPlot::legend +*/ +QCPLegend::QCPLegend() +{ + setFillOrder(QCPLayoutGrid::foRowsFirst); + setWrap(0); + + setRowSpacing(3); + setColumnSpacing(8); + setMargins(QMargins(7, 5, 7, 4)); + setAntialiased(false); + setIconSize(32, 18); + + setIconTextPadding(7); + + setSelectableParts(spLegendBox | spItems); + setSelectedParts(spNone); + + setBorderPen(QPen(Qt::black, 0)); + setSelectedBorderPen(QPen(Qt::blue, 2)); + setIconBorderPen(Qt::NoPen); + setSelectedIconBorderPen(QPen(Qt::blue, 2)); + setBrush(Qt::white); + setSelectedBrush(Qt::white); + setTextColor(Qt::black); + setSelectedTextColor(Qt::blue); +} + +QCPLegend::~QCPLegend() +{ + clearItems(); + if (qobject_cast(mParentPlot)) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the legend is not in any layout and thus QObject-child of QCustomPlot) + mParentPlot->legendRemoved(this); +} + +/* no doc for getter, see setSelectedParts */ +QCPLegend::SelectableParts QCPLegend::selectedParts() const +{ + // check whether any legend elements selected, if yes, add spItems to return value + bool hasSelectedItems = false; + for (int i=0; iselected()) + { + hasSelectedItems = true; + break; + } + } + if (hasSelectedItems) + return mSelectedParts | spItems; + else + return mSelectedParts & ~spItems; +} + +/*! + Sets the pen, the border of the entire legend is drawn with. +*/ +void QCPLegend::setBorderPen(const QPen &pen) +{ + mBorderPen = pen; +} + +/*! + Sets the brush of the legend background. +*/ +void QCPLegend::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the default font of legend text. Legend items that draw text (e.g. the name of a graph) will + use this font by default. However, a different font can be specified on a per-item-basis by + accessing the specific legend item. + + This function will also set \a font on all already existing legend items. + + \see QCPAbstractLegendItem::setFont +*/ +void QCPLegend::setFont(const QFont &font) +{ + mFont = font; + for (int i=0; isetFont(mFont); + } +} + +/*! + Sets the default color of legend text. Legend items that draw text (e.g. the name of a graph) + will use this color by default. However, a different colors can be specified on a per-item-basis + by accessing the specific legend item. + + This function will also set \a color on all already existing legend items. + + \see QCPAbstractLegendItem::setTextColor +*/ +void QCPLegend::setTextColor(const QColor &color) +{ + mTextColor = color; + for (int i=0; isetTextColor(color); + } +} + +/*! + Sets the size of legend icons. Legend items that draw an icon (e.g. a visual + representation of the graph) will use this size by default. +*/ +void QCPLegend::setIconSize(const QSize &size) +{ + mIconSize = size; +} + +/*! \overload +*/ +void QCPLegend::setIconSize(int width, int height) +{ + mIconSize.setWidth(width); + mIconSize.setHeight(height); +} + +/*! + Sets the horizontal space in pixels between the legend icon and the text next to it. + Legend items that draw an icon (e.g. a visual representation of the graph) and text (e.g. the + name of the graph) will use this space by default. +*/ +void QCPLegend::setIconTextPadding(int padding) +{ + mIconTextPadding = padding; +} + +/*! + Sets the pen used to draw a border around each legend icon. Legend items that draw an + icon (e.g. a visual representation of the graph) will use this pen by default. + + If no border is wanted, set this to \a Qt::NoPen. +*/ +void QCPLegend::setIconBorderPen(const QPen &pen) +{ + mIconBorderPen = pen; +} + +/*! + Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface. + (When \ref QCustomPlot::setInteractions contains \ref QCP::iSelectLegend.) + + However, even when \a selectable is set to a value not allowing the selection of a specific part, + it is still possible to set the selection of this part manually, by calling \ref setSelectedParts + directly. + + \see SelectablePart, setSelectedParts +*/ +void QCPLegend::setSelectableParts(const SelectableParts &selectable) +{ + if (mSelectableParts != selectable) + { + mSelectableParts = selectable; + emit selectableChanged(mSelectableParts); + } +} + +/*! + Sets the selected state of the respective legend parts described by \ref SelectablePart. When a part + is selected, it uses a different pen/font and brush. If some legend items are selected and \a selected + doesn't contain \ref spItems, those items become deselected. + + The entire selection mechanism is handled automatically when \ref QCustomPlot::setInteractions + contains iSelectLegend. You only need to call this function when you wish to change the selection + state manually. + + This function can change the selection state of a part even when \ref setSelectableParts was set to a + value that actually excludes the part. + + emits the \ref selectionChanged signal when \a selected is different from the previous selection state. + + Note that it doesn't make sense to set the selected state \ref spItems here when it wasn't set + before, because there's no way to specify which exact items to newly select. Do this by calling + \ref QCPAbstractLegendItem::setSelected directly on the legend item you wish to select. + + \see SelectablePart, setSelectableParts, selectTest, setSelectedBorderPen, setSelectedIconBorderPen, setSelectedBrush, + setSelectedFont +*/ +void QCPLegend::setSelectedParts(const SelectableParts &selected) +{ + SelectableParts newSelected = selected; + mSelectedParts = this->selectedParts(); // update mSelectedParts in case item selection changed + + if (mSelectedParts != newSelected) + { + if (!mSelectedParts.testFlag(spItems) && newSelected.testFlag(spItems)) // attempt to set spItems flag (can't do that) + { + qDebug() << Q_FUNC_INFO << "spItems flag can not be set, it can only be unset with this function"; + newSelected &= ~spItems; + } + if (mSelectedParts.testFlag(spItems) && !newSelected.testFlag(spItems)) // spItems flag was unset, so clear item selection + { + for (int i=0; isetSelected(false); + } + } + mSelectedParts = newSelected; + emit selectionChanged(mSelectedParts); + } +} + +/*! + When the legend box is selected, this pen is used to draw the border instead of the normal pen + set via \ref setBorderPen. + + \see setSelectedParts, setSelectableParts, setSelectedBrush +*/ +void QCPLegend::setSelectedBorderPen(const QPen &pen) +{ + mSelectedBorderPen = pen; +} + +/*! + Sets the pen legend items will use to draw their icon borders, when they are selected. + + \see setSelectedParts, setSelectableParts, setSelectedFont +*/ +void QCPLegend::setSelectedIconBorderPen(const QPen &pen) +{ + mSelectedIconBorderPen = pen; +} + +/*! + When the legend box is selected, this brush is used to draw the legend background instead of the normal brush + set via \ref setBrush. + + \see setSelectedParts, setSelectableParts, setSelectedBorderPen +*/ +void QCPLegend::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the default font that is used by legend items when they are selected. + + This function will also set \a font on all already existing legend items. + + \see setFont, QCPAbstractLegendItem::setSelectedFont +*/ +void QCPLegend::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; + for (int i=0; isetSelectedFont(font); + } +} + +/*! + Sets the default text color that is used by legend items when they are selected. + + This function will also set \a color on all already existing legend items. + + \see setTextColor, QCPAbstractLegendItem::setSelectedTextColor +*/ +void QCPLegend::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; + for (int i=0; isetSelectedTextColor(color); + } +} + +/*! + Returns the item with index \a i. + + Note that the linear index depends on the current fill order (\ref setFillOrder). + + \see itemCount, addItem, itemWithPlottable +*/ +QCPAbstractLegendItem *QCPLegend::item(int index) const +{ + return qobject_cast(elementAt(index)); +} + +/*! + Returns the QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). + If such an item isn't in the legend, returns 0. + + \see hasItemWithPlottable +*/ +QCPPlottableLegendItem *QCPLegend::itemWithPlottable(const QCPAbstractPlottable *plottable) const +{ + for (int i=0; i(item(i))) + { + if (pli->plottable() == plottable) + return pli; + } + } + return 0; +} + +/*! + Returns the number of items currently in the legend. + + Note that if empty cells are in the legend (e.g. by calling methods of the \ref QCPLayoutGrid + base class which allows creating empty cells), they are included in the returned count. + + \see item +*/ +int QCPLegend::itemCount() const +{ + return elementCount(); +} + +/*! + Returns whether the legend contains \a item. + + \see hasItemWithPlottable +*/ +bool QCPLegend::hasItem(QCPAbstractLegendItem *item) const +{ + for (int i=0; iitem(i)) + return true; + } + return false; +} + +/*! + Returns whether the legend contains a QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*). + If such an item isn't in the legend, returns false. + + \see itemWithPlottable +*/ +bool QCPLegend::hasItemWithPlottable(const QCPAbstractPlottable *plottable) const +{ + return itemWithPlottable(plottable); +} + +/*! + Adds \a item to the legend, if it's not present already. The element is arranged according to the + current fill order (\ref setFillOrder) and wrapping (\ref setWrap). + + Returns true on sucess, i.e. if the item wasn't in the list already and has been successfuly added. + + The legend takes ownership of the item. + + \see removeItem, item, hasItem +*/ +bool QCPLegend::addItem(QCPAbstractLegendItem *item) +{ + return addElement(item); +} + +/*! \overload + + Removes the item with the specified \a index from the legend and deletes it. + + After successful removal, the legend is reordered according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap), so no empty cell remains where the removed \a item + was. If you don't want this, rather use the raw element interface of \ref QCPLayoutGrid. + + Returns true, if successful. Unlike \ref QCPLayoutGrid::removeAt, this method only removes + elements derived from \ref QCPAbstractLegendItem. + + \see itemCount, clearItems +*/ +bool QCPLegend::removeItem(int index) +{ + if (QCPAbstractLegendItem *ali = item(index)) + { + bool success = remove(ali); + if (success) + setFillOrder(fillOrder(), true); // gets rid of empty cell by reordering + return success; + } else + return false; +} + +/*! \overload + + Removes \a item from the legend and deletes it. + + After successful removal, the legend is reordered according to the current fill order (\ref + setFillOrder) and wrapping (\ref setWrap), so no empty cell remains where the removed \a item + was. If you don't want this, rather use the raw element interface of \ref QCPLayoutGrid. + + Returns true, if successful. + + \see clearItems +*/ +bool QCPLegend::removeItem(QCPAbstractLegendItem *item) +{ + bool success = remove(item); + if (success) + setFillOrder(fillOrder(), true); // gets rid of empty cell by reordering + return success; +} + +/*! + Removes all items from the legend. +*/ +void QCPLegend::clearItems() +{ + for (int i=itemCount()-1; i>=0; --i) + removeItem(i); +} + +/*! + Returns the legend items that are currently selected. If no items are selected, + the list is empty. + + \see QCPAbstractLegendItem::setSelected, setSelectable +*/ +QList QCPLegend::selectedItems() const +{ + QList result; + for (int i=0; iselected()) + result.append(ali); + } + } + return result; +} + +/*! \internal + + A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter + before drawing main legend elements. + + This is the antialiasing state the painter passed to the \ref draw method is in by default. + + This function takes into account the local setting of the antialiasing flag as well as the + overrides set with \ref QCustomPlot::setAntialiasedElements and \ref + QCustomPlot::setNotAntialiasedElements. + + \seebaseclassmethod + + \see setAntialiased +*/ +void QCPLegend::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeLegend); +} + +/*! \internal + + Returns the pen used to paint the border of the legend, taking into account the selection state + of the legend box. +*/ +QPen QCPLegend::getBorderPen() const +{ + return mSelectedParts.testFlag(spLegendBox) ? mSelectedBorderPen : mBorderPen; +} + +/*! \internal + + Returns the brush used to paint the background of the legend, taking into account the selection + state of the legend box. +*/ +QBrush QCPLegend::getBrush() const +{ + return mSelectedParts.testFlag(spLegendBox) ? mSelectedBrush : mBrush; +} + +/*! \internal + + Draws the legend box with the provided \a painter. The individual legend items are layerables + themselves, thus are drawn independently. +*/ +void QCPLegend::draw(QCPPainter *painter) +{ + // draw background rect: + painter->setBrush(getBrush()); + painter->setPen(getBorderPen()); + painter->drawRect(mOuterRect); +} + +/* inherits documentation from base class */ +double QCPLegend::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mParentPlot) return -1; + if (onlySelectable && !mSelectableParts.testFlag(spLegendBox)) + return -1; + + if (mOuterRect.contains(pos.toPoint())) + { + if (details) details->setValue(spLegendBox); + return mParentPlot->selectionTolerance()*0.99; + } + return -1; +} + +/* inherits documentation from base class */ +void QCPLegend::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + mSelectedParts = selectedParts(); // in case item selection has changed + if (details.value() == spLegendBox && mSelectableParts.testFlag(spLegendBox)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(additive ? mSelectedParts^spLegendBox : mSelectedParts|spLegendBox); // no need to unset spItems in !additive case, because they will be deselected by QCustomPlot (they're normal QCPLayerables with own deselectEvent) + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPLegend::deselectEvent(bool *selectionStateChanged) +{ + mSelectedParts = selectedParts(); // in case item selection has changed + if (mSelectableParts.testFlag(spLegendBox)) + { + SelectableParts selBefore = mSelectedParts; + setSelectedParts(selectedParts() & ~spLegendBox); + if (selectionStateChanged) + *selectionStateChanged = mSelectedParts != selBefore; + } +} + +/* inherits documentation from base class */ +QCP::Interaction QCPLegend::selectionCategory() const +{ + return QCP::iSelectLegend; +} + +/* inherits documentation from base class */ +QCP::Interaction QCPAbstractLegendItem::selectionCategory() const +{ + return QCP::iSelectLegend; +} + +/* inherits documentation from base class */ +void QCPLegend::parentPlotInitialized(QCustomPlot *parentPlot) +{ + if (parentPlot && !parentPlot->legend) + parentPlot->legend = this; +} +/* end of 'src/layoutelements/layoutelement-legend.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-textelement.cpp', size 12759 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPTextElement +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPTextElement + \brief A layout element displaying a text + + The text may be specified with \ref setText, the formatting can be controlled with \ref setFont, + \ref setTextColor, and \ref setTextFlags. + + A text element can be added as follows: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcptextelement-creation +*/ + +/* start documentation of signals */ + +/*! \fn void QCPTextElement::selectionChanged(bool selected) + + This signal is emitted when the selection state has changed to \a selected, either by user + interaction or by a direct call to \ref setSelected. + + \see setSelected, setSelectable +*/ + +/*! \fn void QCPTextElement::clicked(QMouseEvent *event) + + This signal is emitted when the text element is clicked. + + \see doubleClicked, selectTest +*/ + +/*! \fn void QCPTextElement::doubleClicked(QMouseEvent *event) + + This signal is emitted when the text element is double clicked. + + \see clicked, selectTest +*/ + +/* end documentation of signals */ + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. The initial text is empty (\ref + setText). +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot) : + QCPLayoutElement(parentPlot), + mText(), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + mFont = parentPlot->font(); + mSelectedFont = parentPlot->font(); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + mFont = parentPlot->font(); + mSelectedFont = parentPlot->font(); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with \a pointSize. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(QLatin1String("sans serif"), pointSize)), // will be taken from parentPlot if available, see below + mTextColor(Qt::black), + mSelectedFont(QFont(QLatin1String("sans serif"), pointSize)), // will be taken from parentPlot if available, see below + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + if (parentPlot) + { + mFont = parentPlot->font(); + mFont.setPointSizeF(pointSize); + mSelectedFont = parentPlot->font(); + mSelectedFont.setPointSizeF(pointSize); + } + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with \a pointSize and the specified \a fontFamily. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(QFont(fontFamily, pointSize)), + mTextColor(Qt::black), + mSelectedFont(QFont(fontFamily, pointSize)), + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! \overload + + Creates a new QCPTextElement instance and sets default values. + + The initial text is set to \a text with the specified \a font. +*/ +QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font) : + QCPLayoutElement(parentPlot), + mText(text), + mTextFlags(Qt::AlignCenter|Qt::TextWordWrap), + mFont(font), + mTextColor(Qt::black), + mSelectedFont(font), + mSelectedTextColor(Qt::blue), + mSelectable(false), + mSelected(false) +{ + setMargins(QMargins(2, 2, 2, 2)); +} + +/*! + Sets the text that will be displayed to \a text. Multiple lines can be created by insertion of "\n". + + \see setFont, setTextColor, setTextFlags +*/ +void QCPTextElement::setText(const QString &text) +{ + mText = text; +} + +/*! + Sets options for text alignment and wrapping behaviour. \a flags is a bitwise OR-combination of + \c Qt::AlignmentFlag and \c Qt::TextFlag enums. + + Possible enums are: + - Qt::AlignLeft + - Qt::AlignRight + - Qt::AlignHCenter + - Qt::AlignJustify + - Qt::AlignTop + - Qt::AlignBottom + - Qt::AlignVCenter + - Qt::AlignCenter + - Qt::TextDontClip + - Qt::TextSingleLine + - Qt::TextExpandTabs + - Qt::TextShowMnemonic + - Qt::TextWordWrap + - Qt::TextIncludeTrailingSpaces +*/ +void QCPTextElement::setTextFlags(int flags) +{ + mTextFlags = flags; +} + +/*! + Sets the \a font of the text. + + \see setTextColor, setSelectedFont +*/ +void QCPTextElement::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the \a color of the text. + + \see setFont, setSelectedTextColor +*/ +void QCPTextElement::setTextColor(const QColor &color) +{ + mTextColor = color; +} + +/*! + Sets the \a font of the text that will be used if the text element is selected (\ref setSelected). + + \see setFont +*/ +void QCPTextElement::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + Sets the \a color of the text that will be used if the text element is selected (\ref setSelected). + + \see setTextColor +*/ +void QCPTextElement::setSelectedTextColor(const QColor &color) +{ + mSelectedTextColor = color; +} + +/*! + Sets whether the user may select this text element. + + Note that even when \a selectable is set to false, the selection state may be changed + programmatically via \ref setSelected. +*/ +void QCPTextElement::setSelectable(bool selectable) +{ + if (mSelectable != selectable) + { + mSelectable = selectable; + emit selectableChanged(mSelectable); + } +} + +/*! + Sets the selection state of this text element to \a selected. If the selection has changed, \ref + selectionChanged is emitted. + + Note that this function can change the selection state independently of the current \ref + setSelectable state. +*/ +void QCPTextElement::setSelected(bool selected) +{ + if (mSelected != selected) + { + mSelected = selected; + emit selectionChanged(mSelected); + } +} + +/* inherits documentation from base class */ +void QCPTextElement::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + applyAntialiasingHint(painter, mAntialiased, QCP::aeOther); +} + +/* inherits documentation from base class */ +void QCPTextElement::draw(QCPPainter *painter) +{ + painter->setFont(mainFont()); + painter->setPen(QPen(mainTextColor())); + painter->drawText(mRect, Qt::AlignCenter, mText, &mTextBoundingRect); +} + +/* inherits documentation from base class */ +QSize QCPTextElement::minimumSizeHint() const +{ + QFontMetrics metrics(mFont); + QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size(); + result.rwidth() += mMargins.left() + mMargins.right(); + result.rheight() += mMargins.top() + mMargins.bottom(); + return result; +} + +/* inherits documentation from base class */ +QSize QCPTextElement::maximumSizeHint() const +{ + QFontMetrics metrics(mFont); + QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size(); + result.rheight() += mMargins.top() + mMargins.bottom(); + result.setWidth(QWIDGETSIZE_MAX); + return result; +} + +/* inherits documentation from base class */ +void QCPTextElement::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) +{ + Q_UNUSED(event) + Q_UNUSED(details) + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(additive ? !mSelected : true); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/* inherits documentation from base class */ +void QCPTextElement::deselectEvent(bool *selectionStateChanged) +{ + if (mSelectable) + { + bool selBefore = mSelected; + setSelected(false); + if (selectionStateChanged) + *selectionStateChanged = mSelected != selBefore; + } +} + +/*! + Returns 0.99*selectionTolerance (see \ref QCustomPlot::setSelectionTolerance) when \a pos is + within the bounding box of the text element's text. Note that this bounding box is updated in the + draw call. + + If \a pos is outside the text's bounding box or if \a onlySelectable is true and this text + element is not selectable (\ref setSelectable), returns -1. + + \seebaseclassmethod +*/ +double QCPTextElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + if (mTextBoundingRect.contains(pos.toPoint())) + return mParentPlot->selectionTolerance()*0.99; + else + return -1; +} + +/*! + Accepts the mouse event in order to emit the according click signal in the \ref + mouseReleaseEvent. + + \seebaseclassmethod +*/ +void QCPTextElement::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + event->accept(); +} + +/*! + Emits the \ref clicked signal if the cursor hasn't moved by more than a few pixels since the \ref + mousePressEvent. + + \seebaseclassmethod +*/ +void QCPTextElement::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + if ((QPointF(event->pos())-startPos).manhattanLength() <= 3) + emit clicked(event); +} + +/*! + Emits the \ref doubleClicked signal. + + \seebaseclassmethod +*/ +void QCPTextElement::mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) +{ + Q_UNUSED(details) + emit doubleClicked(event); +} + +/*! \internal + + Returns the main font to be used. This is mSelectedFont if \ref setSelected is set to + true, else mFont is returned. +*/ +QFont QCPTextElement::mainFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Returns the main color to be used. This is mSelectedTextColor if \ref setSelected is set to + true, else mTextColor is returned. +*/ +QColor QCPTextElement::mainTextColor() const +{ + return mSelected ? mSelectedTextColor : mTextColor; +} +/* end of 'src/layoutelements/layoutelement-textelement.cpp' */ + + +/* including file 'src/layoutelements/layoutelement-colorscale.cpp', size 25910 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorScale +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorScale + \brief A color scale for use with color coding data such as QCPColorMap + + This layout element can be placed on the plot to correlate a color gradient with data values. It + is usually used in combination with one or multiple \ref QCPColorMap "QCPColorMaps". + + \image html QCPColorScale.png + + The color scale can be either horizontal or vertical, as shown in the image above. The + orientation and the side where the numbers appear is controlled with \ref setType. + + Use \ref QCPColorMap::setColorScale to connect a color map with a color scale. Once they are + connected, they share their gradient, data range and data scale type (\ref setGradient, \ref + setDataRange, \ref setDataScaleType). Multiple color maps may be associated with a single color + scale, to make them all synchronize these properties. + + To have finer control over the number display and axis behaviour, you can directly access the + \ref axis. See the documentation of QCPAxis for details about configuring axes. For example, if + you want to change the number of automatically generated ticks, call + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-tickcount + + Placing a color scale next to the main axis rect works like with any other layout element: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-creation + In this case we have placed it to the right of the default axis rect, so it wasn't necessary to + call \ref setType, since \ref QCPAxis::atRight is already the default. The text next to the color + scale can be set with \ref setLabel. + + For optimum appearance (like in the image above), it may be desirable to line up the axis rect and + the borders of the color scale. Use a \ref QCPMarginGroup to achieve this: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcolorscale-margingroup + + Color scales are initialized with a non-zero minimum top and bottom margin (\ref + setMinimumMargins), because vertical color scales are most common and the minimum top/bottom + margin makes sure it keeps some distance to the top/bottom widget border. So if you change to a + horizontal color scale by setting \ref setType to \ref QCPAxis::atBottom or \ref QCPAxis::atTop, you + might want to also change the minimum margins accordingly, e.g. setMinimumMargins(QMargins(6, 0, 6, 0)). +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPAxis *QCPColorScale::axis() const + + Returns the internal \ref QCPAxis instance of this color scale. You can access it to alter the + appearance and behaviour of the axis. \ref QCPColorScale duplicates some properties in its + interface for convenience. Those are \ref setDataRange (\ref QCPAxis::setRange), \ref + setDataScaleType (\ref QCPAxis::setScaleType), and the method \ref setLabel (\ref + QCPAxis::setLabel). As they each are connected, it does not matter whether you use the method on + the QCPColorScale or on its QCPAxis. + + If the type of the color scale is changed with \ref setType, the axis returned by this method + will change, too, to either the left, right, bottom or top axis, depending on which type was set. +*/ + +/* end documentation of signals */ +/* start documentation of signals */ + +/*! \fn void QCPColorScale::dataRangeChanged(const QCPRange &newRange); + + This signal is emitted when the data range changes. + + \see setDataRange +*/ + +/*! \fn void QCPColorScale::dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + + This signal is emitted when the data scale type changes. + + \see setDataScaleType +*/ + +/*! \fn void QCPColorScale::gradientChanged(const QCPColorGradient &newGradient); + + This signal is emitted when the gradient changes. + + \see setGradient +*/ + +/* end documentation of signals */ + +/*! + Constructs a new QCPColorScale. +*/ +QCPColorScale::QCPColorScale(QCustomPlot *parentPlot) : + QCPLayoutElement(parentPlot), + mType(QCPAxis::atTop), // set to atTop such that setType(QCPAxis::atRight) below doesn't skip work because it thinks it's already atRight + mDataScaleType(QCPAxis::stLinear), + mBarWidth(20), + mAxisRect(new QCPColorScaleAxisRectPrivate(this)) +{ + setMinimumMargins(QMargins(0, 6, 0, 6)); // for default right color scale types, keep some room at bottom and top (important if no margin group is used) + setType(QCPAxis::atRight); + setDataRange(QCPRange(0, 6)); +} + +QCPColorScale::~QCPColorScale() +{ + delete mAxisRect; +} + +/* undocumented getter */ +QString QCPColorScale::label() const +{ + if (!mColorAxis) + { + qDebug() << Q_FUNC_INFO << "internal color axis undefined"; + return QString(); + } + + return mColorAxis.data()->label(); +} + +/* undocumented getter */ +bool QCPColorScale::rangeDrag() const +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return false; + } + + return mAxisRect.data()->rangeDrag().testFlag(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); +} + +/* undocumented getter */ +bool QCPColorScale::rangeZoom() const +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return false; + } + + return mAxisRect.data()->rangeZoom().testFlag(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType)) && + mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType); +} + +/*! + Sets at which side of the color scale the axis is placed, and thus also its orientation. + + Note that after setting \a type to a different value, the axis returned by \ref axis() will + be a different one. The new axis will adopt the following properties from the previous axis: The + range, scale type, label and ticker (the latter will be shared and not copied). +*/ +void QCPColorScale::setType(QCPAxis::AxisType type) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + if (mType != type) + { + mType = type; + QCPRange rangeTransfer(0, 6); + QString labelTransfer; + QSharedPointer tickerTransfer; + // transfer/revert some settings on old axis if it exists: + bool doTransfer = (bool)mColorAxis; + if (doTransfer) + { + rangeTransfer = mColorAxis.data()->range(); + labelTransfer = mColorAxis.data()->label(); + tickerTransfer = mColorAxis.data()->ticker(); + mColorAxis.data()->setLabel(QString()); + disconnect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + disconnect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } + QList allAxisTypes = QList() << QCPAxis::atLeft << QCPAxis::atRight << QCPAxis::atBottom << QCPAxis::atTop; + foreach (QCPAxis::AxisType atype, allAxisTypes) + { + mAxisRect.data()->axis(atype)->setTicks(atype == mType); + mAxisRect.data()->axis(atype)->setTickLabels(atype== mType); + } + // set new mColorAxis pointer: + mColorAxis = mAxisRect.data()->axis(mType); + // transfer settings to new axis: + if (doTransfer) + { + mColorAxis.data()->setRange(rangeTransfer); // range transfer necessary if axis changes from vertical to horizontal or vice versa (axes with same orientation are synchronized via signals) + mColorAxis.data()->setLabel(labelTransfer); + mColorAxis.data()->setTicker(tickerTransfer); + } + connect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + connect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + mAxisRect.data()->setRangeDragAxes(QList() << mColorAxis.data()); + } +} + +/*! + Sets the range spanned by the color gradient and that is shown by the axis in the color scale. + + It is equivalent to calling QCPColorMap::setDataRange on any of the connected color maps. It is + also equivalent to directly accessing the \ref axis and setting its range with \ref + QCPAxis::setRange. + + \see setDataScaleType, setGradient, rescaleDataRange +*/ +void QCPColorScale::setDataRange(const QCPRange &dataRange) +{ + if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) + { + mDataRange = dataRange; + if (mColorAxis) + mColorAxis.data()->setRange(mDataRange); + emit dataRangeChanged(mDataRange); + } +} + +/*! + Sets the scale type of the color scale, i.e. whether values are linearly associated with colors + or logarithmically. + + It is equivalent to calling QCPColorMap::setDataScaleType on any of the connected color maps. It is + also equivalent to directly accessing the \ref axis and setting its scale type with \ref + QCPAxis::setScaleType. + + \see setDataRange, setGradient +*/ +void QCPColorScale::setDataScaleType(QCPAxis::ScaleType scaleType) +{ + if (mDataScaleType != scaleType) + { + mDataScaleType = scaleType; + if (mColorAxis) + mColorAxis.data()->setScaleType(mDataScaleType); + if (mDataScaleType == QCPAxis::stLogarithmic) + setDataRange(mDataRange.sanitizedForLogScale()); + emit dataScaleTypeChanged(mDataScaleType); + } +} + +/*! + Sets the color gradient that will be used to represent data values. + + It is equivalent to calling QCPColorMap::setGradient on any of the connected color maps. + + \see setDataRange, setDataScaleType +*/ +void QCPColorScale::setGradient(const QCPColorGradient &gradient) +{ + if (mGradient != gradient) + { + mGradient = gradient; + if (mAxisRect) + mAxisRect.data()->mGradientImageInvalidated = true; + emit gradientChanged(mGradient); + } +} + +/*! + Sets the axis label of the color scale. This is equivalent to calling \ref QCPAxis::setLabel on + the internal \ref axis. +*/ +void QCPColorScale::setLabel(const QString &str) +{ + if (!mColorAxis) + { + qDebug() << Q_FUNC_INFO << "internal color axis undefined"; + return; + } + + mColorAxis.data()->setLabel(str); +} + +/*! + Sets the width (or height, for horizontal color scales) the bar where the gradient is displayed + will have. +*/ +void QCPColorScale::setBarWidth(int width) +{ + mBarWidth = width; +} + +/*! + Sets whether the user can drag the data range (\ref setDataRange). + + Note that \ref QCP::iRangeDrag must be in the QCustomPlot's interactions (\ref + QCustomPlot::setInteractions) to allow range dragging. +*/ +void QCPColorScale::setRangeDrag(bool enabled) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + if (enabled) + mAxisRect.data()->setRangeDrag(QCPAxis::orientation(mType)); + else + mAxisRect.data()->setRangeDrag(0); +} + +/*! + Sets whether the user can zoom the data range (\ref setDataRange) by scrolling the mouse wheel. + + Note that \ref QCP::iRangeZoom must be in the QCustomPlot's interactions (\ref + QCustomPlot::setInteractions) to allow range dragging. +*/ +void QCPColorScale::setRangeZoom(bool enabled) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + if (enabled) + mAxisRect.data()->setRangeZoom(QCPAxis::orientation(mType)); + else + mAxisRect.data()->setRangeZoom(0); +} + +/*! + Returns a list of all the color maps associated with this color scale. +*/ +QList QCPColorScale::colorMaps() const +{ + QList result; + for (int i=0; iplottableCount(); ++i) + { + if (QCPColorMap *cm = qobject_cast(mParentPlot->plottable(i))) + if (cm->colorScale() == this) + result.append(cm); + } + return result; +} + +/*! + Changes the data range such that all color maps associated with this color scale are fully mapped + to the gradient in the data dimension. + + \see setDataRange +*/ +void QCPColorScale::rescaleDataRange(bool onlyVisibleMaps) +{ + QList maps = colorMaps(); + QCPRange newRange; + bool haveRange = false; + QCP::SignDomain sign = QCP::sdBoth; + if (mDataScaleType == QCPAxis::stLogarithmic) + sign = (mDataRange.upper < 0 ? QCP::sdNegative : QCP::sdPositive); + for (int i=0; irealVisibility() && onlyVisibleMaps) + continue; + QCPRange mapRange; + if (maps.at(i)->colorScale() == this) + { + bool currentFoundRange = true; + mapRange = maps.at(i)->data()->dataBounds(); + if (sign == QCP::sdPositive) + { + if (mapRange.lower <= 0 && mapRange.upper > 0) + mapRange.lower = mapRange.upper*1e-3; + else if (mapRange.lower <= 0 && mapRange.upper <= 0) + currentFoundRange = false; + } else if (sign == QCP::sdNegative) + { + if (mapRange.upper >= 0 && mapRange.lower < 0) + mapRange.upper = mapRange.lower*1e-3; + else if (mapRange.upper >= 0 && mapRange.lower >= 0) + currentFoundRange = false; + } + if (currentFoundRange) + { + if (!haveRange) + newRange = mapRange; + else + newRange.expand(mapRange); + haveRange = true; + } + } + } + if (haveRange) + { + if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this dimension), shift current range to at least center the data + { + double center = (newRange.lower+newRange.upper)*0.5; // upper and lower should be equal anyway, but just to make sure, incase validRange returned false for other reason + if (mDataScaleType == QCPAxis::stLinear) + { + newRange.lower = center-mDataRange.size()/2.0; + newRange.upper = center+mDataRange.size()/2.0; + } else // mScaleType == stLogarithmic + { + newRange.lower = center/qSqrt(mDataRange.upper/mDataRange.lower); + newRange.upper = center*qSqrt(mDataRange.upper/mDataRange.lower); + } + } + setDataRange(newRange); + } +} + +/* inherits documentation from base class */ +void QCPColorScale::update(UpdatePhase phase) +{ + QCPLayoutElement::update(phase); + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + + mAxisRect.data()->update(phase); + + switch (phase) + { + case upMargins: + { + if (mType == QCPAxis::atBottom || mType == QCPAxis::atTop) + { + setMaximumSize(QWIDGETSIZE_MAX, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()+margins().top()+margins().bottom()); + setMinimumSize(0, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom()+margins().top()+margins().bottom()); + } else + { + setMaximumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right()+margins().left()+margins().right(), QWIDGETSIZE_MAX); + setMinimumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right()+margins().left()+margins().right(), 0); + } + break; + } + case upLayout: + { + mAxisRect.data()->setOuterRect(rect()); + break; + } + default: break; + } +} + +/* inherits documentation from base class */ +void QCPColorScale::applyDefaultAntialiasingHint(QCPPainter *painter) const +{ + painter->setAntialiasing(false); +} + +/* inherits documentation from base class */ +void QCPColorScale::mousePressEvent(QMouseEvent *event, const QVariant &details) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mousePressEvent(event, details); +} + +/* inherits documentation from base class */ +void QCPColorScale::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mouseMoveEvent(event, startPos); +} + +/* inherits documentation from base class */ +void QCPColorScale::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->mouseReleaseEvent(event, startPos); +} + +/* inherits documentation from base class */ +void QCPColorScale::wheelEvent(QWheelEvent *event) +{ + if (!mAxisRect) + { + qDebug() << Q_FUNC_INFO << "internal axis rect was deleted"; + return; + } + mAxisRect.data()->wheelEvent(event); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorScaleAxisRectPrivate +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorScaleAxisRectPrivate + + \internal + \brief An axis rect subclass for use in a QCPColorScale + + This is a private class and not part of the public QCustomPlot interface. + + It provides the axis rect functionality for the QCPColorScale class. +*/ + + +/*! + Creates a new instance, as a child of \a parentColorScale. +*/ +QCPColorScaleAxisRectPrivate::QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale) : + QCPAxisRect(parentColorScale->parentPlot(), true), + mParentColorScale(parentColorScale), + mGradientImageInvalidated(true) +{ + setParentLayerable(parentColorScale); + setMinimumMargins(QMargins(0, 0, 0, 0)); + QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + axis(type)->setVisible(true); + axis(type)->grid()->setVisible(false); + axis(type)->setPadding(0); + connect(axis(type), SIGNAL(selectionChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectionChanged(QCPAxis::SelectableParts))); + connect(axis(type), SIGNAL(selectableChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectableChanged(QCPAxis::SelectableParts))); + } + + connect(axis(QCPAxis::atLeft), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atRight), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atRight), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atLeft), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atTop), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atTop), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atBottom), SLOT(setRange(QCPRange))); + connect(axis(QCPAxis::atLeft), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atRight), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atRight), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atLeft), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atBottom), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atTop), SLOT(setScaleType(QCPAxis::ScaleType))); + connect(axis(QCPAxis::atTop), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atBottom), SLOT(setScaleType(QCPAxis::ScaleType))); + + // make layer transfers of color scale transfer to axis rect and axes + // the axes must be set after axis rect, such that they appear above color gradient drawn by axis rect: + connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), this, SLOT(setLayer(QCPLayer*))); + foreach (QCPAxis::AxisType type, allAxisTypes) + connect(parentColorScale, SIGNAL(layerChanged(QCPLayer*)), axis(type), SLOT(setLayer(QCPLayer*))); +} + +/*! \internal + + Updates the color gradient image if necessary, by calling \ref updateGradientImage, then draws + it. Then the axes are drawn by calling the \ref QCPAxisRect::draw base class implementation. + + \seebaseclassmethod +*/ +void QCPColorScaleAxisRectPrivate::draw(QCPPainter *painter) +{ + if (mGradientImageInvalidated) + updateGradientImage(); + + bool mirrorHorz = false; + bool mirrorVert = false; + if (mParentColorScale->mColorAxis) + { + mirrorHorz = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atBottom || mParentColorScale->type() == QCPAxis::atTop); + mirrorVert = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atLeft || mParentColorScale->type() == QCPAxis::atRight); + } + + painter->drawImage(rect().adjusted(0, -1, 0, -1), mGradientImage.mirrored(mirrorHorz, mirrorVert)); + QCPAxisRect::draw(painter); +} + +/*! \internal + + Uses the current gradient of the parent \ref QCPColorScale (specified in the constructor) to + generate a gradient image. This gradient image will be used in the \ref draw method. +*/ +void QCPColorScaleAxisRectPrivate::updateGradientImage() +{ + if (rect().isEmpty()) + return; + + const QImage::Format format = QImage::Format_ARGB32_Premultiplied; + int n = mParentColorScale->mGradient.levelCount(); + int w, h; + QVector data(n); + for (int i=0; imType == QCPAxis::atBottom || mParentColorScale->mType == QCPAxis::atTop) + { + w = n; + h = rect().height(); + mGradientImage = QImage(w, h, format); + QVector pixels; + for (int y=0; y(mGradientImage.scanLine(y))); + mParentColorScale->mGradient.colorize(data.constData(), QCPRange(0, n-1), pixels.first(), n); + for (int y=1; y(mGradientImage.scanLine(y)); + const QRgb lineColor = mParentColorScale->mGradient.color(data[h-1-y], QCPRange(0, n-1)); + for (int x=0; x allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + if (QCPAxis *senderAxis = qobject_cast(sender())) + if (senderAxis->axisType() == type) + continue; + + if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) + { + if (selectedParts.testFlag(QCPAxis::spAxis)) + axis(type)->setSelectedParts(axis(type)->selectedParts() | QCPAxis::spAxis); + else + axis(type)->setSelectedParts(axis(type)->selectedParts() & ~QCPAxis::spAxis); + } + } +} + +/*! \internal + + This slot is connected to the selectableChanged signals of the four axes in the constructor. It + synchronizes the selectability of the axes. +*/ +void QCPColorScaleAxisRectPrivate::axisSelectableChanged(QCPAxis::SelectableParts selectableParts) +{ + // synchronize axis base selectability: + QList allAxisTypes = QList() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight; + foreach (QCPAxis::AxisType type, allAxisTypes) + { + if (QCPAxis *senderAxis = qobject_cast(sender())) + if (senderAxis->axisType() == type) + continue; + + if (axis(type)->selectableParts().testFlag(QCPAxis::spAxis)) + { + if (selectableParts.testFlag(QCPAxis::spAxis)) + axis(type)->setSelectableParts(axis(type)->selectableParts() | QCPAxis::spAxis); + else + axis(type)->setSelectableParts(axis(type)->selectableParts() & ~QCPAxis::spAxis); + } + } +} +/* end of 'src/layoutelements/layoutelement-colorscale.cpp' */ + + +/* including file 'src/plottables/plottable-graph.cpp', size 72363 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGraphData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGraphData + \brief Holds the data of one single data point for QCPGraph. + + The stored data is: + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + \li \a value: coordinate on the value axis of this data point (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPGraphDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPGraphData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPGraphDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPGraphData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPGraphData QCPGraphData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPGraphData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPGraphData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPGraphData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPGraphData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and value set to zero. +*/ +QCPGraphData::QCPGraphData() : + key(0), + value(0) +{ +} + +/*! + Constructs a data point with the specified \a key and \a value. +*/ +QCPGraphData::QCPGraphData(double key, double value) : + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPGraph +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPGraph + \brief A plottable representing a graph in a plot. + + \image html QCPGraph.png + + Usually you create new graphs by calling QCustomPlot::addGraph. The resulting instance can be + accessed via QCustomPlot::graph. + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the data via the \ref data method, which returns a pointer to the internal + \ref QCPGraphDataContainer. + + Graphs are used to display single-valued data. Single-valued means that there should only be one + data point per unique key coordinate. In other words, the graph can't have \a loops. If you do + want to plot non-single-valued curves, rather use the QCPCurve plottable. + + Gaps in the graph line can be created by adding data points with NaN as value + (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be + separated. + + \section qcpgraph-appearance Changing the appearance + + The appearance of the graph is mainly determined by the line style, scatter style, brush and pen + of the graph (\ref setLineStyle, \ref setScatterStyle, \ref setBrush, \ref setPen). + + \subsection filling Filling under or between graphs + + QCPGraph knows two types of fills: Normal graph fills towards the zero-value-line parallel to + the key axis of the graph, and fills between two graphs, called channel fills. To enable a fill, + just set a brush with \ref setBrush which is neither Qt::NoBrush nor fully transparent. + + By default, a normal fill towards the zero-value-line will be drawn. To set up a channel fill + between this graph and another one, call \ref setChannelFillGraph with the other graph as + parameter. + + \see QCustomPlot::addGraph, QCustomPlot::graph +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPGraph::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPGraphDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a graph which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPGraph is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPGraph, so do not delete it manually + but use QCustomPlot::removePlottable() instead. + + To directly create a graph inside a plot, you can also use the simpler QCustomPlot::addGraph function. +*/ +QCPGraph::QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis) +{ + // special handling for QCPGraphs to maintain the simple graph interface: + mParentPlot->registerGraph(this); + + setPen(QPen(Qt::blue, 0)); + setBrush(Qt::NoBrush); + + setLineStyle(lsLine); + setScatterSkip(0); + setChannelFillGraph(0); + setAdaptiveSampling(true); +} + +QCPGraph::~QCPGraph() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPGraphs may share the same data container safely. + Modifying the data in the container will then affect all graphs that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the graph's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpgraph-datasharing-2 + + \see addData +*/ +void QCPGraph::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPGraph::setData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, values, alreadySorted); +} + +/*! + Sets how the single data points are connected in the plot. For scatter-only plots, set \a ls to + \ref lsNone and \ref setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPGraph::setLineStyle(LineStyle ls) +{ + mLineStyle = ls; +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref QCPScatterStyle::ssNone, no scatter points + are drawn (e.g. for line-only-plots with appropriate line style). + + \see QCPScatterStyle, setLineStyle +*/ +void QCPGraph::setScatterStyle(const QCPScatterStyle &style) +{ + mScatterStyle = style; +} + +/*! + If scatters are displayed (scatter style not \ref QCPScatterStyle::ssNone), \a skip number of + scatter points are skipped/not drawn after every drawn scatter point. + + This can be used to make the data appear sparser while for example still having a smooth line, + and to improve performance for very high density plots. + + If \a skip is set to 0 (default), all scatter points are drawn. + + \see setScatterStyle +*/ +void QCPGraph::setScatterSkip(int skip) +{ + mScatterSkip = qMax(0, skip); +} + +/*! + Sets the target graph for filling the area between this graph and \a targetGraph with the current + brush (\ref setBrush). + + When \a targetGraph is set to 0, a normal graph fill to the zero-value-line will be shown. To + disable any filling, set the brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPGraph::setChannelFillGraph(QCPGraph *targetGraph) +{ + // prevent setting channel target to this graph itself: + if (targetGraph == this) + { + qDebug() << Q_FUNC_INFO << "targetGraph is this graph itself"; + mChannelFillGraph = 0; + return; + } + // prevent setting channel target to a graph not in the plot: + if (targetGraph && targetGraph->mParentPlot != mParentPlot) + { + qDebug() << Q_FUNC_INFO << "targetGraph not in same plot"; + mChannelFillGraph = 0; + return; + } + + mChannelFillGraph = targetGraph; +} + +/*! + Sets whether adaptive sampling shall be used when plotting this graph. QCustomPlot's adaptive + sampling technique can drastically improve the replot performance for graphs with a larger number + of points (e.g. above 10,000), without notably changing the appearance of the graph. + + By default, adaptive sampling is enabled. Even if enabled, QCustomPlot decides whether adaptive + sampling shall actually be used on a per-graph basis. So leaving adaptive sampling enabled has no + disadvantage in almost all cases. + + \image html adaptive-sampling-line.png "A line plot of 500,000 points without and with adaptive sampling" + + As can be seen, line plots experience no visual degradation from adaptive sampling. Outliers are + reproduced reliably, as well as the overall shape of the data set. The replot time reduces + dramatically though. This allows QCustomPlot to display large amounts of data in realtime. + + \image html adaptive-sampling-scatter.png "A scatter plot of 100,000 points without and with adaptive sampling" + + Care must be taken when using high-density scatter plots in combination with adaptive sampling. + The adaptive sampling algorithm treats scatter plots more carefully than line plots which still + gives a significant reduction of replot times, but not quite as much as for line plots. This is + because scatter plots inherently need more data points to be preserved in order to still resemble + the original, non-adaptive-sampling plot. As shown above, the results still aren't quite + identical, as banding occurs for the outer data points. This is in fact intentional, such that + the boundaries of the data cloud stay visible to the viewer. How strong the banding appears, + depends on the point density, i.e. the number of points in the plot. + + For some situations with scatter plots it might thus be desirable to manually turn adaptive + sampling off. For example, when saving the plot to disk. This can be achieved by setting \a + enabled to false before issuing a command like \ref QCustomPlot::savePng, and setting \a enabled + back to true afterwards. +*/ +void QCPGraph::setAdaptiveSampling(bool enabled) +{ + mAdaptiveSampling = enabled; +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPGraph::addData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + const int n = qMin(keys.size(), values.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPGraph::addData(double key, double value) +{ + mDataContainer->add(QCPGraphData(key, value)); +} + +/* inherits documentation from base class */ +double QCPGraph::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + QCPGraphDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPGraph::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + return mDataContainer->keyRange(foundRange, inSignDomain); +} + +/* inherits documentation from base class */ +QCPRange QCPGraph::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPGraph::draw(QCPPainter *painter) +{ + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; + if (mLineStyle == lsNone && mScatterStyle.isNone()) return; + + QVector lines, scatters; // line and (if necessary) scatter pixel coordinates will be stored here while iterating over segments + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + // get line pixel points appropriate to line style: + QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getLines takes care) + getLines(&lines, lineDataRange); + + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + QCPGraphDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); + } +#endif + + // draw fill of graph: + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyBrush(painter); + else + painter->setBrush(mBrush); + painter->setPen(Qt::NoPen); + drawFill(painter, &lines); + + // draw line: + if (mLineStyle != lsNone) + { + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else + painter->setPen(mPen); + painter->setBrush(Qt::NoBrush); + if (mLineStyle == lsImpulse) + drawImpulsePlot(painter, lines); + else + drawLinePlot(painter, lines); // also step plots can be drawn as a line plot + } + + // draw scatters: + QCPScatterStyle finalScatterStyle = mScatterStyle; + if (isSelectedSegment && mSelectionDecorator) + finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); + if (!finalScatterStyle.isNone()) + { + getScatters(&scatters, allSegments.at(i)); + drawScatterPlot(painter, scatters, finalScatterStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPGraph::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw fill: + if (mBrush.style() != Qt::NoBrush) + { + applyFillAntialiasingHint(painter); + painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (!mScatterStyle.isNone()) + { + applyScattersAntialiasingHint(painter); + // scale scatter pixmap if it's too large to fit in legend icon rect: + if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) + { + QCPScatterStyle scaledStyle(mScatterStyle); + scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + scaledStyle.applyTo(painter, mPen); + scaledStyle.drawShape(painter, QRectF(rect).center()); + } else + { + mScatterStyle.applyTo(painter, mPen); + mScatterStyle.drawShape(painter, QRectF(rect).center()); + } + } +} + +/*! \internal + + This method retrieves an optimized set of data points via \ref getOptimizedLineData, an branches + out to the line style specific functions such as \ref dataToLines, \ref dataToStepLeftLines, etc. + according to the line style of the graph. + + \a lines will be filled with points in pixel coordinates, that can be drawn with the according + draw functions like \ref drawLinePlot and \ref drawImpulsePlot. The points returned in \a lines + aren't necessarily the original data points. For example, step line styles require additional + points to form the steps when drawn. If the line style of the graph is \ref lsNone, the \a + lines vector will be empty. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. In this function, the specified range may exceed the total data bounds without harm: + a correspondingly trimmed data range will be used. This takes the burden off the user of this + function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref + getDataSegments. + + \see getScatters +*/ +void QCPGraph::getLines(QVector *lines, const QCPDataRange &dataRange) const +{ + if (!lines) return; + QCPGraphDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, dataRange); + if (begin == end) + { + lines->clear(); + return; + } + + QVector lineData; + if (mLineStyle != lsNone) + getOptimizedLineData(&lineData, begin, end); + + switch (mLineStyle) + { + case lsNone: lines->clear(); break; + case lsLine: *lines = dataToLines(lineData); break; + case lsStepLeft: *lines = dataToStepLeftLines(lineData); break; + case lsStepRight: *lines = dataToStepRightLines(lineData); break; + case lsStepCenter: *lines = dataToStepCenterLines(lineData); break; + case lsImpulse: *lines = dataToImpulseLines(lineData); break; + } +} + +/*! \internal + + This method retrieves an optimized set of data points via \ref getOptimizedScatterData and then + converts them to pixel coordinates. The resulting points are returned in \a scatters, and can be + passed to \ref drawScatterPlot. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. In this function, the specified range may exceed the total data bounds without harm: + a correspondingly trimmed data range will be used. This takes the burden off the user of this + function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref + getDataSegments. +*/ +void QCPGraph::getScatters(QVector *scatters, const QCPDataRange &dataRange) const +{ + if (!scatters) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; scatters->clear(); return; } + + QCPGraphDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, dataRange); + if (begin == end) + { + scatters->clear(); + return; + } + + QVector data; + getOptimizedScatterData(&data, begin, end); + scatters->resize(data.size()); + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).value)); + (*scatters)[i].setY(keyAxis->coordToPixel(data.at(i).key)); + } + } + } else + { + for (int i=0; icoordToPixel(data.at(i).key)); + (*scatters)[i].setY(valueAxis->coordToPixel(data.at(i).value)); + } + } + } +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsLine. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +QVector QCPGraph::dataToLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.reserve(data.size()+2); // added 2 to reserve memory for lower/upper fill base points that might be needed for fill + result.resize(data.size()); + + // transform data points to pixels: + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).value)); + result[i].setY(keyAxis->coordToPixel(data.at(i).key)); + } + } else // key axis is horizontal + { + for (int i=0; icoordToPixel(data.at(i).key)); + result[i].setY(valueAxis->coordToPixel(data.at(i).value)); + } + } + return result; +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepLeft. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +QVector QCPGraph::dataToStepLeftLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.reserve(data.size()*2+2); // added 2 to reserve memory for lower/upper fill base points that might be needed for fill + result.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastValue = valueAxis->coordToPixel(data.first().value); + for (int i=0; icoordToPixel(data.at(i).key); + result[i*2+0].setX(lastValue); + result[i*2+0].setY(key); + lastValue = valueAxis->coordToPixel(data.at(i).value); + result[i*2+1].setX(lastValue); + result[i*2+1].setY(key); + } + } else // key axis is horizontal + { + double lastValue = valueAxis->coordToPixel(data.first().value); + for (int i=0; icoordToPixel(data.at(i).key); + result[i*2+0].setX(key); + result[i*2+0].setY(lastValue); + lastValue = valueAxis->coordToPixel(data.at(i).value); + result[i*2+1].setX(key); + result[i*2+1].setY(lastValue); + } + } + return result; +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepRight. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot +*/ +QVector QCPGraph::dataToStepRightLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.reserve(data.size()*2+2); // added 2 to reserve memory for lower/upper fill base points that might be needed for fill + result.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastKey = keyAxis->coordToPixel(data.first().key); + for (int i=0; icoordToPixel(data.at(i).value); + result[i*2+0].setX(value); + result[i*2+0].setY(lastKey); + lastKey = keyAxis->coordToPixel(data.at(i).key); + result[i*2+1].setX(value); + result[i*2+1].setY(lastKey); + } + } else // key axis is horizontal + { + double lastKey = keyAxis->coordToPixel(data.first().key); + for (int i=0; icoordToPixel(data.at(i).value); + result[i*2+0].setX(lastKey); + result[i*2+0].setY(value); + lastKey = keyAxis->coordToPixel(data.at(i).key); + result[i*2+1].setX(lastKey); + result[i*2+1].setY(value); + } + } + return result; +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsStepCenter. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToImpulseLines, getLines, drawLinePlot +*/ +QVector QCPGraph::dataToStepCenterLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.reserve(data.size()*2+2); // added 2 to reserve memory for lower/upper fill base points that might be needed for fill + result.resize(data.size()*2); + + // calculate steps from data and transform to pixel coordinates: + if (keyAxis->orientation() == Qt::Vertical) + { + double lastKey = keyAxis->coordToPixel(data.first().key); + double lastValue = valueAxis->coordToPixel(data.first().value); + result[0].setX(lastValue); + result[0].setY(lastKey); + for (int i=1; icoordToPixel(data.at(i).key)+lastKey)*0.5; + result[i*2-1].setX(lastValue); + result[i*2-1].setY(key); + lastValue = valueAxis->coordToPixel(data.at(i).value); + lastKey = keyAxis->coordToPixel(data.at(i).key); + result[i*2+0].setX(lastValue); + result[i*2+0].setY(key); + } + result[data.size()*2-1].setX(lastValue); + result[data.size()*2-1].setY(lastKey); + } else // key axis is horizontal + { + double lastKey = keyAxis->coordToPixel(data.first().key); + double lastValue = valueAxis->coordToPixel(data.first().value); + result[0].setX(lastKey); + result[0].setY(lastValue); + for (int i=1; icoordToPixel(data.at(i).key)+lastKey)*0.5; + result[i*2-1].setX(key); + result[i*2-1].setY(lastValue); + lastValue = valueAxis->coordToPixel(data.at(i).value); + lastKey = keyAxis->coordToPixel(data.at(i).key); + result[i*2+0].setX(key); + result[i*2+0].setY(lastValue); + } + result[data.size()*2-1].setX(lastKey); + result[data.size()*2-1].setY(lastValue); + } + return result; +} + +/*! \internal + + Takes raw data points in plot coordinates as \a data, and returns a vector containing pixel + coordinate points which are suitable for drawing the line style \ref lsImpulse. + + The source of \a data is usually \ref getOptimizedLineData, and this method is called in \a + getLines if the line style is set accordingly. + + \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, getLines, drawImpulsePlot +*/ +QVector QCPGraph::dataToImpulseLines(const QVector &data) const +{ + QVector result; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return result; } + + result.resize(data.size()*2); // no need to reserve 2 extra points because impulse plot has no fill + + // transform data points to pixels: + if (keyAxis->orientation() == Qt::Vertical) + { + for (int i=0; icoordToPixel(data.at(i).key); + result[i*2+0].setX(valueAxis->coordToPixel(0)); + result[i*2+0].setY(key); + result[i*2+1].setX(valueAxis->coordToPixel(data.at(i).value)); + result[i*2+1].setY(key); + } + } else // key axis is horizontal + { + for (int i=0; icoordToPixel(data.at(i).key); + result[i*2+0].setX(key); + result[i*2+0].setY(valueAxis->coordToPixel(0)); + result[i*2+1].setX(key); + result[i*2+1].setY(valueAxis->coordToPixel(data.at(i).value)); + } + } + return result; +} + +/*! \internal + + Draws the fill of the graph using the specified \a painter, with the currently set brush. + + \a lines contains the points of the graph line, in pixel coordinates. + + If the fill is a normal fill towards the zero-value-line, only the points in \a lines are + required and two extra points at the zero-value-line, which are added by \ref addFillBasePoints + and removed by \ref removeFillBasePoints after the fill drawing is done. + + On the other hand if the fill is a channel fill between this QCPGraph and another QCPGraph (\a + mChannelFillGraph), the more complex polygon is calculated with the \ref getChannelFillPolygon + function, and then drawn. + + \see drawLinePlot, drawImpulsePlot, drawScatterPlot +*/ +void QCPGraph::drawFill(QCPPainter *painter, QVector *lines) const +{ + if (mLineStyle == lsImpulse) return; // fill doesn't make sense for impulse plot + if (painter->brush().style() == Qt::NoBrush || painter->brush().color().alpha() == 0) return; + + applyFillAntialiasingHint(painter); + if (!mChannelFillGraph) + { + // draw base fill under graph, fill goes all the way to the zero-value-line: + addFillBasePoints(lines); + painter->drawPolygon(QPolygonF(*lines)); + removeFillBasePoints(lines); + } else + { + // draw channel fill between this graph and mChannelFillGraph: + painter->drawPolygon(getChannelFillPolygon(lines)); + } +} + +/*! \internal + + Draws scatter symbols at every point passed in \a scatters, given in pixel coordinates. The + scatters will be drawn with \a painter and have the appearance as specified in \a style. + + \see drawLinePlot, drawImpulsePlot +*/ +void QCPGraph::drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const +{ + applyScattersAntialiasingHint(painter); + style.applyTo(painter, mPen); + for (int i=0; i &lines) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + drawPolyline(painter, lines); + } +} + +/*! \internal + + Draws impulses from the provided data, i.e. it connects all line pairs in \a lines, given in + pixel coordinates. The \a lines necessary for impulses are generated by \ref dataToImpulseLines + from the regular graph data points. + + \see drawLinePlot, drawScatterPlot +*/ +void QCPGraph::drawImpulsePlot(QCPPainter *painter, const QVector &lines) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + QPen oldPen = painter->pen(); + QPen newPen = painter->pen(); + newPen.setCapStyle(Qt::FlatCap); // so impulse line doesn't reach beyond zero-line + painter->setPen(newPen); + painter->drawLines(lines); + painter->setPen(oldPen); + } +} + +/*! \internal + + Returns via \a lineData the data points that need to be visualized for this graph when plotting + graph lines, taking into consideration the currently visible axis ranges and, if \ref + setAdaptiveSampling is enabled, local point densities. The considered data can be restricted + further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref + getDataSegments). + + This method is used by \ref getLines to retrieve the basic working set of data. + + \see getOptimizedScatterData +*/ +void QCPGraph::getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const +{ + if (!lineData) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (begin == end) return; + + int dataCount = end-begin; + int maxCount = std::numeric_limits::max(); + if (mAdaptiveSampling) + { + double keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key)); + if (2*keyPixelSpan+2 < (double)std::numeric_limits::max()) + maxCount = 2*keyPixelSpan+2; + } + + if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average + { + QCPGraphDataContainer::const_iterator it = begin; + double minValue = it->value; + double maxValue = it->value; + QCPGraphDataContainer::const_iterator currentIntervalFirstPoint = it; + int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction + int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey + double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(begin->key)+reversedRound)); + double lastIntervalEndKey = currentIntervalStartKey; + double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates + bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) + int intervalDataCount = 1; + ++it; // advance iterator to second data point because adaptive sampling works in 1 point retrospect + while (it != end) + { + if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this cluster if necessary + { + if (it->value < minValue) + minValue = it->value; + else if (it->value > maxValue) + maxValue = it->value; + ++intervalDataCount; + } else // new pixel interval started + { + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster + { + if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point is further away, so first point of this cluster must be at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); + if (it->key > currentIntervalStartKey+keyEpsilon*2) // new pixel started further away from previous cluster, so make sure the last point of the cluster is at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.8, (it-1)->value)); + } else + lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); + lastIntervalEndKey = (it-1)->key; + minValue = it->value; + maxValue = it->value; + currentIntervalFirstPoint = it; + currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it->key)+reversedRound)); + if (keyEpsilonVariable) + keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); + intervalDataCount = 1; + } + ++it; + } + // handle last interval: + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster + { + if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point wasn't a cluster, so first point of this cluster must be at a real data point + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue)); + lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue)); + } else + lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value)); + + } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output + { + QCPGraphDataContainer::const_iterator it = begin; + lineData->reserve(dataCount+2); // +2 for possible fill end points + while (it != end) + { + lineData->append(*it); + ++it; + } + } +} + +/*! \internal + + Returns via \a scatterData the data points that need to be visualized for this graph when + plotting scatter points, taking into consideration the currently visible axis ranges and, if \ref + setAdaptiveSampling is enabled, local point densities. The considered data can be restricted + further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref + getDataSegments). + + This method is used by \ref getScatters to retrieve the basic working set of data. + + \see getOptimizedLineData +*/ +void QCPGraph::getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const +{ + if (!scatterData) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + const int scatterModulo = mScatterSkip+1; + const bool doScatterSkip = mScatterSkip > 0; + int beginIndex = begin-mDataContainer->constBegin(); + int endIndex = end-mDataContainer->constBegin(); + while (doScatterSkip && begin != end && beginIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter + { + ++beginIndex; + ++begin; + } + if (begin == end) return; + int dataCount = end-begin; + int maxCount = std::numeric_limits::max(); + if (mAdaptiveSampling) + { + int keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key)); + maxCount = 2*keyPixelSpan+2; + } + + if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average + { + double valueMaxRange = valueAxis->range().upper; + double valueMinRange = valueAxis->range().lower; + QCPGraphDataContainer::const_iterator it = begin; + int itIndex = beginIndex; + double minValue = it->value; + double maxValue = it->value; + QCPGraphDataContainer::const_iterator minValueIt = it; + QCPGraphDataContainer::const_iterator maxValueIt = it; + QCPGraphDataContainer::const_iterator currentIntervalStart = it; + int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction + int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey + double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(begin->key)+reversedRound)); + double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates + bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes) + int intervalDataCount = 1; + // advance iterator to second (non-skipped) data point because adaptive sampling works in 1 point retrospect: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + // main loop over data points: + while (it != end) + { + if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this pixel if necessary + { + if (it->value < minValue && it->value > valueMinRange && it->value < valueMaxRange) + { + minValue = it->value; + minValueIt = it; + } else if (it->value > maxValue && it->value > valueMinRange && it->value < valueMaxRange) + { + maxValue = it->value; + maxValueIt = it; + } + ++intervalDataCount; + } else // new pixel started + { + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them + { + // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): + double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); + int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average + QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart; + int c = 0; + while (intervalIt != it) + { + if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange) + scatterData->append(*intervalIt); + ++c; + if (!doScatterSkip) + ++intervalIt; + else + intervalIt += scatterModulo; // since we know indices of "currentIntervalStart", "intervalIt" and "it" are multiples of scatterModulo, we can't accidentally jump over "it" here + } + } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) + scatterData->append(*currentIntervalStart); + minValue = it->value; + maxValue = it->value; + currentIntervalStart = it; + currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it->key)+reversedRound)); + if (keyEpsilonVariable) + keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); + intervalDataCount = 1; + } + // advance to next data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + // handle last interval: + if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them + { + // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot): + double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue)); + int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average + QCPGraphDataContainer::const_iterator intervalIt = currentIntervalStart; + int intervalItIndex = intervalIt-mDataContainer->constBegin(); + int c = 0; + while (intervalIt != it) + { + if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange) + scatterData->append(*intervalIt); + ++c; + if (!doScatterSkip) + ++intervalIt; + else // here we can't guarantee that adding scatterModulo doesn't exceed "it" (because "it" is equal to "end" here, and "end" isn't scatterModulo-aligned), so check via index comparison: + { + intervalItIndex += scatterModulo; + if (intervalItIndex < itIndex) + intervalIt += scatterModulo; + else + { + intervalIt = it; + intervalItIndex = itIndex; + } + } + } + } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange) + scatterData->append(*currentIntervalStart); + + } else // don't use adaptive sampling algorithm, transfer points one-to-one from the data container into the output + { + QCPGraphDataContainer::const_iterator it = begin; + int itIndex = beginIndex; + scatterData->reserve(dataCount); + while (it != end) + { + scatterData->append(*it); + // advance to next data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } +} + +/*! + This method outputs the currently visible data range via \a begin and \a end. The returned range + will also never exceed \a rangeRestriction. + + This method takes into account that the drawing of data lines at the axis rect border always + requires the points just outside the visible axis range. So \a begin and \a end may actually + indicate a range that contains one additional data point to the left and right of the visible + axis range. +*/ +void QCPGraph::getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const +{ + if (rangeRestriction.isEmpty()) + { + end = mDataContainer->constEnd(); + begin = end; + } else + { + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + // get visible data range: + begin = mDataContainer->findBegin(keyAxis->range().lower); + end = mDataContainer->findEnd(keyAxis->range().upper); + // limit lower/upperEnd to rangeRestriction: + mDataContainer->limitIteratorsToDataRange(begin, end, rangeRestriction); // this also ensures rangeRestriction outside data bounds doesn't break anything + } +} + +/*! \internal + + The line vector generated by e.g. \ref getLines describes only the line that connects the data + points. If the graph needs to be filled, two additional points need to be added at the + value-zero-line in the lower and upper key positions of the graph. This function calculates these + points and adds them to the end of \a lineData. Since the fill is typically drawn before the line + stroke, these added points need to be removed again after the fill is done, with the + removeFillBasePoints function. + + The expanding of \a lines by two points will not cause unnecessary memory reallocations, because + the data vector generation functions (e.g. \ref getLines) reserve two extra points when they + allocate memory for \a lines. + + \see removeFillBasePoints, lowerFillBasePoint, upperFillBasePoint +*/ +void QCPGraph::addFillBasePoints(QVector *lines) const +{ + if (!mKeyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; } + if (!lines) { qDebug() << Q_FUNC_INFO << "passed null as lineData"; return; } + if (lines->isEmpty()) return; + + // append points that close the polygon fill at the key axis: + if (mKeyAxis.data()->orientation() == Qt::Vertical) + { + *lines << upperFillBasePoint(lines->last().y()); + *lines << lowerFillBasePoint(lines->first().y()); + } else + { + *lines << upperFillBasePoint(lines->last().x()); + *lines << lowerFillBasePoint(lines->first().x()); + } +} + +/*! \internal + + removes the two points from \a lines that were added by \ref addFillBasePoints. + + \see addFillBasePoints, lowerFillBasePoint, upperFillBasePoint +*/ +void QCPGraph::removeFillBasePoints(QVector *lines) const +{ + if (!lines) { qDebug() << Q_FUNC_INFO << "passed null as lineData"; return; } + if (lines->isEmpty()) return; + + lines->remove(lines->size()-2, 2); +} + +/*! \internal + + called by \ref addFillBasePoints to conveniently assign the point which closes the fill polygon + on the lower side of the zero-value-line parallel to the key axis. The logarithmic axis scale + case is a bit special, since the zero-value-line in pixel coordinates is in positive or negative + infinity. So this case is handled separately by just closing the fill polygon on the axis which + lies in the direction towards the zero value. + + \a lowerKey will be the the key (in pixels) of the returned point. Depending on whether the key + axis is horizontal or vertical, \a lowerKey will end up as the x or y value of the returned + point, respectively. + + \see upperFillBasePoint, addFillBasePoints +*/ +QPointF QCPGraph::lowerFillBasePoint(double lowerKey) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + QPointF point; + if (valueAxis->scaleType() == QCPAxis::stLinear) + { + if (keyAxis->axisType() == QCPAxis::atLeft) + { + point.setX(valueAxis->coordToPixel(0)); + point.setY(lowerKey); + } else if (keyAxis->axisType() == QCPAxis::atRight) + { + point.setX(valueAxis->coordToPixel(0)); + point.setY(lowerKey); + } else if (keyAxis->axisType() == QCPAxis::atTop) + { + point.setX(lowerKey); + point.setY(valueAxis->coordToPixel(0)); + } else if (keyAxis->axisType() == QCPAxis::atBottom) + { + point.setX(lowerKey); + point.setY(valueAxis->coordToPixel(0)); + } + } else // valueAxis->mScaleType == QCPAxis::stLogarithmic + { + // In logarithmic scaling we can't just draw to value zero so we just fill all the way + // to the axis which is in the direction towards zero + if (keyAxis->orientation() == Qt::Vertical) + { + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + point.setX(keyAxis->axisRect()->right()); + else + point.setX(keyAxis->axisRect()->left()); + point.setY(lowerKey); + } else if (keyAxis->axisType() == QCPAxis::atTop || keyAxis->axisType() == QCPAxis::atBottom) + { + point.setX(lowerKey); + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + point.setY(keyAxis->axisRect()->top()); + else + point.setY(keyAxis->axisRect()->bottom()); + } + } + return point; +} + +/*! \internal + + called by \ref addFillBasePoints to conveniently assign the point which closes the fill + polygon on the upper side of the zero-value-line parallel to the key axis. The logarithmic axis + scale case is a bit special, since the zero-value-line in pixel coordinates is in positive or + negative infinity. So this case is handled separately by just closing the fill polygon on the + axis which lies in the direction towards the zero value. + + \a upperKey will be the the key (in pixels) of the returned point. Depending on whether the key + axis is horizontal or vertical, \a upperKey will end up as the x or y value of the returned + point, respectively. + + \see lowerFillBasePoint, addFillBasePoints +*/ +QPointF QCPGraph::upperFillBasePoint(double upperKey) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + QPointF point; + if (valueAxis->scaleType() == QCPAxis::stLinear) + { + if (keyAxis->axisType() == QCPAxis::atLeft) + { + point.setX(valueAxis->coordToPixel(0)); + point.setY(upperKey); + } else if (keyAxis->axisType() == QCPAxis::atRight) + { + point.setX(valueAxis->coordToPixel(0)); + point.setY(upperKey); + } else if (keyAxis->axisType() == QCPAxis::atTop) + { + point.setX(upperKey); + point.setY(valueAxis->coordToPixel(0)); + } else if (keyAxis->axisType() == QCPAxis::atBottom) + { + point.setX(upperKey); + point.setY(valueAxis->coordToPixel(0)); + } + } else // valueAxis->mScaleType == QCPAxis::stLogarithmic + { + // In logarithmic scaling we can't just draw to value 0 so we just fill all the way + // to the axis which is in the direction towards 0 + if (keyAxis->orientation() == Qt::Vertical) + { + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + point.setX(keyAxis->axisRect()->right()); + else + point.setX(keyAxis->axisRect()->left()); + point.setY(upperKey); + } else if (keyAxis->axisType() == QCPAxis::atTop || keyAxis->axisType() == QCPAxis::atBottom) + { + point.setX(upperKey); + if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) || + (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis + point.setY(keyAxis->axisRect()->top()); + else + point.setY(keyAxis->axisRect()->bottom()); + } + } + return point; +} + +/*! \internal + + Generates the polygon needed for drawing channel fills between this graph and the graph specified + in \a mChannelFillGraph (see \ref setChannelFillGraph). The data points representing the line of + this graph in pixel coordinates must be passed in \a lines, the corresponding points of the other + graph are generated by calling its \ref getLines method. + + This method may return an empty polygon if the key ranges of the two graphs have no overlap of if + they don't have the same orientation (e.g. one key axis vertical, the other horizontal). For + increased performance (due to implicit sharing), it is recommended to keep the returned QPolygonF + const. +*/ +const QPolygonF QCPGraph::getChannelFillPolygon(const QVector *lines) const +{ + if (!mChannelFillGraph) + return QPolygonF(); + + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPolygonF(); } + if (!mChannelFillGraph.data()->mKeyAxis) { qDebug() << Q_FUNC_INFO << "channel fill target key axis invalid"; return QPolygonF(); } + + if (mChannelFillGraph.data()->mKeyAxis.data()->orientation() != keyAxis->orientation()) + return QPolygonF(); // don't have same axis orientation, can't fill that (Note: if keyAxis fits, valueAxis will fit too, because it's always orthogonal to keyAxis) + + if (lines->isEmpty()) return QPolygonF(); + QVector otherData; + mChannelFillGraph.data()->getLines(&otherData, QCPDataRange(0, mChannelFillGraph.data()->dataCount())); + if (otherData.isEmpty()) return QPolygonF(); + QVector thisData; + thisData.reserve(lines->size()+otherData.size()); // because we will join both vectors at end of this function + for (int i=0; isize(); ++i) // don't use the vector<<(vector), it squeezes internally, which ruins the performance tuning with reserve() + thisData << lines->at(i); + + // pointers to be able to swap them, depending which data range needs cropping: + QVector *staticData = &thisData; + QVector *croppedData = &otherData; + + // crop both vectors to ranges in which the keys overlap (which coord is key, depends on axisType): + if (keyAxis->orientation() == Qt::Horizontal) + { + // x is key + // if an axis range is reversed, the data point keys will be descending. Reverse them, since following algorithm assumes ascending keys: + if (staticData->first().x() > staticData->last().x()) + { + int size = staticData->size(); + for (int i=0; ifirst().x() > croppedData->last().x()) + { + int size = croppedData->size(); + for (int i=0; ifirst().x() < croppedData->first().x()) // other one must be cropped + qSwap(staticData, croppedData); + int lowBound = findIndexBelowX(croppedData, staticData->first().x()); + if (lowBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(0, lowBound); + // set lowest point of cropped data to fit exactly key position of first static data + // point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + double slope; + if (croppedData->at(1).x()-croppedData->at(0).x() != 0) + slope = (croppedData->at(1).y()-croppedData->at(0).y())/(croppedData->at(1).x()-croppedData->at(0).x()); + else + slope = 0; + (*croppedData)[0].setY(croppedData->at(0).y()+slope*(staticData->first().x()-croppedData->at(0).x())); + (*croppedData)[0].setX(staticData->first().x()); + + // crop upper bound: + if (staticData->last().x() > croppedData->last().x()) // other one must be cropped + qSwap(staticData, croppedData); + int highBound = findIndexAboveX(croppedData, staticData->last().x()); + if (highBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); + // set highest point of cropped data to fit exactly key position of last static data + // point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + int li = croppedData->size()-1; // last index + if (croppedData->at(li).x()-croppedData->at(li-1).x() != 0) + slope = (croppedData->at(li).y()-croppedData->at(li-1).y())/(croppedData->at(li).x()-croppedData->at(li-1).x()); + else + slope = 0; + (*croppedData)[li].setY(croppedData->at(li-1).y()+slope*(staticData->last().x()-croppedData->at(li-1).x())); + (*croppedData)[li].setX(staticData->last().x()); + } else // mKeyAxis->orientation() == Qt::Vertical + { + // y is key + // similar to "x is key" but switched x,y. Further, lower/upper meaning is inverted compared to x, + // because in pixel coordinates, y increases from top to bottom, not bottom to top like data coordinate. + // if an axis range is reversed, the data point keys will be descending. Reverse them, since following algorithm assumes ascending keys: + if (staticData->first().y() < staticData->last().y()) + { + int size = staticData->size(); + for (int i=0; ifirst().y() < croppedData->last().y()) + { + int size = croppedData->size(); + for (int i=0; ifirst().y() > croppedData->first().y()) // other one must be cropped + qSwap(staticData, croppedData); + int lowBound = findIndexAboveY(croppedData, staticData->first().y()); + if (lowBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(0, lowBound); + // set lowest point of cropped data to fit exactly key position of first static data + // point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + double slope; + if (croppedData->at(1).y()-croppedData->at(0).y() != 0) // avoid division by zero in step plots + slope = (croppedData->at(1).x()-croppedData->at(0).x())/(croppedData->at(1).y()-croppedData->at(0).y()); + else + slope = 0; + (*croppedData)[0].setX(croppedData->at(0).x()+slope*(staticData->first().y()-croppedData->at(0).y())); + (*croppedData)[0].setY(staticData->first().y()); + + // crop upper bound: + if (staticData->last().y() < croppedData->last().y()) // other one must be cropped + qSwap(staticData, croppedData); + int highBound = findIndexBelowY(croppedData, staticData->last().y()); + if (highBound == -1) return QPolygonF(); // key ranges have no overlap + croppedData->remove(highBound+1, croppedData->size()-(highBound+1)); + // set highest point of cropped data to fit exactly key position of last static data + // point via linear interpolation: + if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation + int li = croppedData->size()-1; // last index + if (croppedData->at(li).y()-croppedData->at(li-1).y() != 0) // avoid division by zero in step plots + slope = (croppedData->at(li).x()-croppedData->at(li-1).x())/(croppedData->at(li).y()-croppedData->at(li-1).y()); + else + slope = 0; + (*croppedData)[li].setX(croppedData->at(li-1).x()+slope*(staticData->last().y()-croppedData->at(li-1).y())); + (*croppedData)[li].setY(staticData->last().y()); + } + + // return joined: + for (int i=otherData.size()-1; i>=0; --i) // insert reversed, otherwise the polygon will be twisted + thisData << otherData.at(i); + return QPolygonF(thisData); +} + +/*! \internal + + Finds the smallest index of \a data, whose points x value is just above \a x. Assumes x values in + \a data points are ordered ascending, as is the case when plotting with horizontal key axis. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexAboveX(const QVector *data, double x) const +{ + for (int i=data->size()-1; i>=0; --i) + { + if (data->at(i).x() < x) + { + if (isize()-1) + return i+1; + else + return data->size()-1; + } + } + return -1; +} + +/*! \internal + + Finds the highest index of \a data, whose points x value is just below \a x. Assumes x values in + \a data points are ordered ascending, as is the case when plotting with horizontal key axis. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexBelowX(const QVector *data, double x) const +{ + for (int i=0; isize(); ++i) + { + if (data->at(i).x() > x) + { + if (i>0) + return i-1; + else + return 0; + } + } + return -1; +} + +/*! \internal + + Finds the smallest index of \a data, whose points y value is just above \a y. Assumes y values in + \a data points are ordered descending, as is the case when plotting with vertical key axis. + + Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. +*/ +int QCPGraph::findIndexAboveY(const QVector *data, double y) const +{ + for (int i=0; isize(); ++i) + { + if (data->at(i).y() < y) + { + if (i>0) + return i-1; + else + return 0; + } + } + return -1; +} + +/*! \internal + + Calculates the minimum distance in pixels the graph's representation has from the given \a + pixelPoint. This is used to determine whether the graph was clicked or not, e.g. in \ref + selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that if + the graph has a line representation, the returned distance may be smaller than the distance to + the \a closestData point, since the distance to the graph line is also taken into account. + + If either the graph has no data or if the line style is \ref lsNone and the scatter style's shape + is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the graph), returns -1.0. +*/ +double QCPGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (mDataContainer->isEmpty()) + return -1.0; + if (mLineStyle == lsNone && mScatterStyle.isNone()) + return -1.0; + + // calculate minimum distances to graph data points and find closestData iterator: + double minDistSqr = std::numeric_limits::max(); + // determine which key range comes into question, taking selection tolerance around pos into account: + double posKeyMin, posKeyMax, dummy; + pixelsToCoords(pixelPoint-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); + pixelsToCoords(pixelPoint+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); + if (posKeyMin > posKeyMax) + qSwap(posKeyMin, posKeyMax); + // iterate over found data points and then choose the one with the shortest distance to pos: + QCPGraphDataContainer::const_iterator begin = mDataContainer->findBegin(posKeyMin, true); + QCPGraphDataContainer::const_iterator end = mDataContainer->findEnd(posKeyMax, true); + for (QCPGraphDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestData = it; + } + } + + // calculate distance to graph line if there is one (if so, will probably be smaller than distance to closest data point): + if (mLineStyle != lsNone) + { + // line displayed, calculate distance to line segments: + QVector lineData; + getLines(&lineData, QCPDataRange(0, dataCount())); + QCPVector2D p(pixelPoint); + const int step = mLineStyle==lsImpulse ? 2 : 1; // impulse plot differs from other line styles in that the lineData points are only pairwise connected + for (int i=0; i *data, double y) const +{ + for (int i=data->size()-1; i>=0; --i) + { + if (data->at(i).y() > y) + { + if (isize()-1) + return i+1; + else + return data->size()-1; + } + } + return -1; +} +/* end of 'src/plottables/plottable-graph.cpp' */ + + +/* including file 'src/plottables/plottable-curve.cpp', size 60009 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPCurveData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPCurveData + \brief Holds the data of one single data point for QCPCurve. + + The stored data is: + \li \a t: the free ordering parameter of this curve point, like in the mathematical vector (x(t), y(t)). (This is the \a sortKey) + \li \a key: coordinate on the key axis of this curve point (this is the \a mainKey) + \li \a value: coordinate on the value axis of this curve point (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPCurveDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPCurveData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPCurveDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPCurveData::sortKey() const + + Returns the \a t member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPCurveData QCPCurveData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey (assigned to the data point's \a t member). + All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPCurveData::sortKeyIsMainKey() + + Since the member \a key is the data point key coordinate and the member \a t is the data ordering + parameter, this method returns false. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPCurveData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPCurveData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPCurveData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a curve data point with t, key and value set to zero. +*/ +QCPCurveData::QCPCurveData() : + t(0), + key(0), + value(0) +{ +} + +/*! + Constructs a curve data point with the specified \a t, \a key and \a value. +*/ +QCPCurveData::QCPCurveData(double t, double key, double value) : + t(t), + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPCurve +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPCurve + \brief A plottable representing a parametric curve in a plot. + + \image html QCPCurve.png + + Unlike QCPGraph, plottables of this type may have multiple points with the same key coordinate, + so their visual representation can have \a loops. This is realized by introducing a third + coordinate \a t, which defines the order of the points described by the other two coordinates \a + x and \a y. + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the curve's data via the \ref data method, which returns a pointer to the + internal \ref QCPCurveDataContainer. + + Gaps in the curve can be created by adding data points with NaN as key and value + (qQNaN() or std::numeric_limits::quiet_NaN()) in between the two data points that shall be + separated. + + \section qcpcurve-appearance Changing the appearance + + The appearance of the curve is determined by the pen and the brush (\ref setPen, \ref setBrush). + + \section qcpcurve-usage Usage + + Like all data representing objects in QCustomPlot, the QCPCurve is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-creation-2 +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPCurve::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPCurveDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a curve which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPCurve is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPCurve, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPCurve::QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis) +{ + // modify inherited properties from abstract plottable: + setPen(QPen(Qt::blue, 0)); + setBrush(Qt::NoBrush); + + setScatterStyle(QCPScatterStyle()); + setLineStyle(lsLine); +} + +QCPCurve::~QCPCurve() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPCurves may share the same data container safely. + Modifying the data in the container will then affect all curves that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the curve's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpcurve-datasharing-2 + + \see addData +*/ +void QCPCurve::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a t, \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a t in ascending order, you can + set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPCurve::setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) +{ + mDataContainer->clear(); + addData(t, keys, values, alreadySorted); +} + + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + The t parameter of each data point will be set to the integer index of the respective key/value + pair. + + \see addData +*/ +void QCPCurve::setData(const QVector &keys, const QVector &values) +{ + mDataContainer->clear(); + addData(keys, values); +} + +/*! + Sets the visual appearance of single data points in the plot. If set to \ref + QCPScatterStyle::ssNone, no scatter points are drawn (e.g. for line-only plots with appropriate + line style). + + \see QCPScatterStyle, setLineStyle +*/ +void QCPCurve::setScatterStyle(const QCPScatterStyle &style) +{ + mScatterStyle = style; +} + +/*! + If scatters are displayed (scatter style not \ref QCPScatterStyle::ssNone), \a skip number of + scatter points are skipped/not drawn after every drawn scatter point. + + This can be used to make the data appear sparser while for example still having a smooth line, + and to improve performance for very high density plots. + + If \a skip is set to 0 (default), all scatter points are drawn. + + \see setScatterStyle +*/ +void QCPCurve::setScatterSkip(int skip) +{ + mScatterSkip = qMax(0, skip); +} + +/*! + Sets how the single data points are connected in the plot or how they are represented visually + apart from the scatter symbol. For scatter-only plots, set \a style to \ref lsNone and \ref + setScatterStyle to the desired scatter style. + + \see setScatterStyle +*/ +void QCPCurve::setLineStyle(QCPCurve::LineStyle style) +{ + mLineStyle = style; +} + +/*! \overload + + Adds the provided points in \a t, \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted) +{ + if (t.size() != keys.size() || t.size() != values.size()) + qDebug() << Q_FUNC_INFO << "ts, keys and values have different sizes:" << t.size() << keys.size() << values.size(); + const int n = qMin(qMin(t.size(), keys.size()), values.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->t = t[i]; + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + The t parameter of each data point will be set to the integer index of the respective key/value + pair. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(const QVector &keys, const QVector &values) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + const int n = qMin(keys.size(), values.size()); + double tStart; + if (!mDataContainer->isEmpty()) + tStart = (mDataContainer->constEnd()-1)->t + 1.0; + else + tStart = 0; + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->t = tStart + i; + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, true); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + Adds the provided data point as \a t, \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(double t, double key, double value) +{ + mDataContainer->add(QCPCurveData(t, key, value)); +} + +/*! \overload + + Adds the provided data point as \a key and \a value to the current data. + + The t parameter is generated automatically by increments of 1 for each point, starting at the + highest t of previously existing data or 0, if the curve data is empty. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPCurve::addData(double key, double value) +{ + if (!mDataContainer->isEmpty()) + mDataContainer->add(QCPCurveData((mDataContainer->constEnd()-1)->t + 1.0, key, value)); + else + mDataContainer->add(QCPCurveData(0.0, key, value)); +} + +/* inherits documentation from base class */ +double QCPCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + QCPCurveDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPCurve::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + return mDataContainer->keyRange(foundRange, inSignDomain); +} + +/* inherits documentation from base class */ +QCPRange QCPCurve::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPCurve::draw(QCPPainter *painter) +{ + if (mDataContainer->isEmpty()) return; + + // allocate line vector: + QVector lines, scatters; + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + + // fill with curve data: + QPen finalCurvePen = mPen; // determine the final pen already here, because the line optimization depends on its stroke width + if (isSelectedSegment && mSelectionDecorator) + finalCurvePen = mSelectionDecorator->pen(); + + QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getCurveLines takes care) + getCurveLines(&lines, lineDataRange, finalCurvePen.widthF()); + + // check data validity if flag set: + #ifdef QCUSTOMPLOT_CHECK_DATA + for (QCPCurveDataContainer::const_iterator it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->t) || + QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "invalid." << "Plottable name:" << name(); + } + #endif + + // draw curve fill: + applyFillAntialiasingHint(painter); + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyBrush(painter); + else + painter->setBrush(mBrush); + painter->setPen(Qt::NoPen); + if (painter->brush().style() != Qt::NoBrush && painter->brush().color().alpha() != 0) + painter->drawPolygon(QPolygonF(lines)); + + // draw curve line: + if (mLineStyle != lsNone) + { + painter->setPen(finalCurvePen); + painter->setBrush(Qt::NoBrush); + drawCurveLine(painter, lines); + } + + // draw scatters: + QCPScatterStyle finalScatterStyle = mScatterStyle; + if (isSelectedSegment && mSelectionDecorator) + finalScatterStyle = mSelectionDecorator->getFinalScatterStyle(mScatterStyle); + if (!finalScatterStyle.isNone()) + { + getScatters(&scatters, allSegments.at(i), finalScatterStyle.size()); + drawScatterPlot(painter, scatters, finalScatterStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPCurve::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw fill: + if (mBrush.style() != Qt::NoBrush) + { + applyFillAntialiasingHint(painter); + painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush); + } + // draw line vertically centered: + if (mLineStyle != lsNone) + { + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens + } + // draw scatter symbol: + if (!mScatterStyle.isNone()) + { + applyScattersAntialiasingHint(painter); + // scale scatter pixmap if it's too large to fit in legend icon rect: + if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height())) + { + QCPScatterStyle scaledStyle(mScatterStyle); + scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + scaledStyle.applyTo(painter, mPen); + scaledStyle.drawShape(painter, QRectF(rect).center()); + } else + { + mScatterStyle.applyTo(painter, mPen); + mScatterStyle.drawShape(painter, QRectF(rect).center()); + } + } +} + +/*! \internal + + Draws lines between the points in \a lines, given in pixel coordinates. + + \see drawScatterPlot, getCurveLines +*/ +void QCPCurve::drawCurveLine(QCPPainter *painter, const QVector &lines) const +{ + if (painter->pen().style() != Qt::NoPen && painter->pen().color().alpha() != 0) + { + applyDefaultAntialiasingHint(painter); + drawPolyline(painter, lines); + } +} + +/*! \internal + + Draws scatter symbols at every point passed in \a points, given in pixel coordinates. The + scatters will be drawn with \a painter and have the appearance as specified in \a style. + + \see drawCurveLine, getCurveLines +*/ +void QCPCurve::drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const +{ + // draw scatter point symbols: + applyScattersAntialiasingHint(painter); + style.applyTo(painter, mPen); + for (int i=0; i *lines, const QCPDataRange &dataRange, double penWidth) const +{ + if (!lines) return; + lines->clear(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + // add margins to rect to compensate for stroke width + const double strokeMargin = qMax(qreal(1.0), qreal(penWidth*0.75)); // stroke radius + 50% safety + const double keyMin = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().lower)-strokeMargin*keyAxis->pixelOrientation()); + const double keyMax = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().upper)+strokeMargin*keyAxis->pixelOrientation()); + const double valueMin = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().lower)-strokeMargin*valueAxis->pixelOrientation()); + const double valueMax = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().upper)+strokeMargin*valueAxis->pixelOrientation()); + QCPCurveDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + mDataContainer->limitIteratorsToDataRange(itBegin, itEnd, dataRange); + if (itBegin == itEnd) + return; + QCPCurveDataContainer::const_iterator it = itBegin; + QCPCurveDataContainer::const_iterator prevIt = itEnd-1; + int prevRegion = getRegion(prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin); + QVector trailingPoints; // points that must be applied after all other points (are generated only when handling first point to get virtual segment between last and first point right) + while (it != itEnd) + { + const int currentRegion = getRegion(it->key, it->value, keyMin, valueMax, keyMax, valueMin); + if (currentRegion != prevRegion) // changed region, possibly need to add some optimized edge points or original points if entering R + { + if (currentRegion != 5) // segment doesn't end in R, so it's a candidate for removal + { + QPointF crossA, crossB; + if (prevRegion == 5) // we're coming from R, so add this point optimized + { + lines->append(getOptimizedPoint(currentRegion, it->key, it->value, prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin)); + // in the situations 5->1/7/9/3 the segment may leave R and directly cross through two outer regions. In these cases we need to add an additional corner point + *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + } else if (mayTraverse(prevRegion, currentRegion) && + getTraverse(prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin, crossA, crossB)) + { + // add the two cross points optimized if segment crosses R and if segment isn't virtual zeroth segment between last and first curve point: + QVector beforeTraverseCornerPoints, afterTraverseCornerPoints; + getTraverseCornerPoints(prevRegion, currentRegion, keyMin, valueMax, keyMax, valueMin, beforeTraverseCornerPoints, afterTraverseCornerPoints); + if (it != itBegin) + { + *lines << beforeTraverseCornerPoints; + lines->append(crossA); + lines->append(crossB); + *lines << afterTraverseCornerPoints; + } else + { + lines->append(crossB); + *lines << afterTraverseCornerPoints; + trailingPoints << beforeTraverseCornerPoints << crossA ; + } + } else // doesn't cross R, line is just moving around in outside regions, so only need to add optimized point(s) at the boundary corner(s) + { + *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + } + } else // segment does end in R, so we add previous point optimized and this point at original position + { + if (it == itBegin) // it is first point in curve and prevIt is last one. So save optimized point for adding it to the lineData in the end + trailingPoints << getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin); + else + lines->append(getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin)); + lines->append(coordsToPixels(it->key, it->value)); + } + } else // region didn't change + { + if (currentRegion == 5) // still in R, keep adding original points + { + lines->append(coordsToPixels(it->key, it->value)); + } else // still outside R, no need to add anything + { + // see how this is not doing anything? That's the main optimization... + } + } + prevIt = it; + prevRegion = currentRegion; + ++it; + } + *lines << trailingPoints; +} + +/*! \internal + + Called by \ref draw to generate points in pixel coordinates which represent the scatters of the + curve. If a scatter skip is configured (\ref setScatterSkip), the returned points are accordingly + sparser. + + Scatters that aren't visible in the current axis rect are optimized away. + + \a scatters will be filled with points in pixel coordinates, that can be drawn with \ref + drawScatterPlot. + + \a dataRange specifies the beginning and ending data indices that will be taken into account for + conversion. + + \a scatterWidth specifies the scatter width that will be used to later draw the scatters at pixel + coordinates generated by this function. This is needed here to calculate an accordingly wider + margin around the axis rect when performing the data point reduction. + + \see draw, drawScatterPlot +*/ +void QCPCurve::getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const +{ + if (!scatters) return; + scatters->clear(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); + mDataContainer->limitIteratorsToDataRange(begin, end, dataRange); + if (begin == end) + return; + const int scatterModulo = mScatterSkip+1; + const bool doScatterSkip = mScatterSkip > 0; + int endIndex = end-mDataContainer->constBegin(); + + QCPRange keyRange = keyAxis->range(); + QCPRange valueRange = valueAxis->range(); + // extend range to include width of scatter symbols: + keyRange.lower = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.lower)-scatterWidth*keyAxis->pixelOrientation()); + keyRange.upper = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.upper)+scatterWidth*keyAxis->pixelOrientation()); + valueRange.lower = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.lower)-scatterWidth*valueAxis->pixelOrientation()); + valueRange.upper = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.upper)+scatterWidth*valueAxis->pixelOrientation()); + + QCPCurveDataContainer::const_iterator it = begin; + int itIndex = begin-mDataContainer->constBegin(); + while (doScatterSkip && it != end && itIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter + { + ++itIndex; + ++it; + } + if (keyAxis->orientation() == Qt::Vertical) + { + while (it != end) + { + if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) + scatters->append(QPointF(valueAxis->coordToPixel(it->value), keyAxis->coordToPixel(it->key))); + + // advance iterator to next (non-skipped) data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } else + { + while (it != end) + { + if (!qIsNaN(it->value) && keyRange.contains(it->key) && valueRange.contains(it->value)) + scatters->append(QPointF(keyAxis->coordToPixel(it->key), valueAxis->coordToPixel(it->value))); + + // advance iterator to next (non-skipped) data point: + if (!doScatterSkip) + ++it; + else + { + itIndex += scatterModulo; + if (itIndex < endIndex) // make sure we didn't jump over end + it += scatterModulo; + else + { + it = end; + itIndex = endIndex; + } + } + } + } +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + It returns the region of the given point (\a key, \a value) with respect to a rectangle defined + by \a keyMin, \a keyMax, \a valueMin, and \a valueMax. + + The regions are enumerated from top to bottom (\a valueMin to \a valueMax) and left to right (\a + keyMin to \a keyMax): + + + + + +
147
258
369
+ + With the rectangle being region 5, and the outer regions extending infinitely outwards. In the + curve optimization algorithm, region 5 is considered to be the visible portion of the plot. +*/ +int QCPCurve::getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + if (key < keyMin) // region 123 + { + if (value > valueMax) + return 1; + else if (value < valueMin) + return 3; + else + return 2; + } else if (key > keyMax) // region 789 + { + if (value > valueMax) + return 7; + else if (value < valueMin) + return 9; + else + return 8; + } else // region 456 + { + if (value > valueMax) + return 4; + else if (value < valueMin) + return 6; + else + return 5; + } +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method is used in case the current segment passes from inside the visible rect (region 5, + see \ref getRegion) to any of the outer regions (\a otherRegion). The current segment is given by + the line connecting (\a key, \a value) with (\a otherKey, \a otherValue). + + It returns the intersection point of the segment with the border of region 5. + + For this function it doesn't matter whether (\a key, \a value) is the point inside region 5 or + whether it's (\a otherKey, \a otherValue), i.e. whether the segment is coming from region 5 or + leaving it. It is important though that \a otherRegion correctly identifies the other region not + equal to 5. +*/ +QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double otherValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + double intersectKey = keyMin; // initial value is just fail-safe + double intersectValue = valueMax; // initial value is just fail-safe + switch (otherRegion) + { + case 1: // top and left edge + { + intersectValue = valueMax; + intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue); + if (intersectKey < keyMin || intersectKey > keyMax) // doesn't intersect, so must intersect other: + { + intersectKey = keyMin; + intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey); + } + break; + } + case 2: // left edge + { + intersectKey = keyMin; + intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey); + break; + } + case 3: // bottom and left edge + { + intersectValue = valueMin; + intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue); + if (intersectKey < keyMin || intersectKey > keyMax) // doesn't intersect, so must intersect other: + { + intersectKey = keyMin; + intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey); + } + break; + } + case 4: // top edge + { + intersectValue = valueMax; + intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue); + break; + } + case 5: + { + break; // case 5 shouldn't happen for this function but we add it anyway to prevent potential discontinuity in branch table + } + case 6: // bottom edge + { + intersectValue = valueMin; + intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue); + break; + } + case 7: // top and right edge + { + intersectValue = valueMax; + intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue); + if (intersectKey < keyMin || intersectKey > keyMax) // doesn't intersect, so must intersect other: + { + intersectKey = keyMax; + intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey); + } + break; + } + case 8: // right edge + { + intersectKey = keyMax; + intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey); + break; + } + case 9: // bottom and right edge + { + intersectValue = valueMin; + intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue); + if (intersectKey < keyMin || intersectKey > keyMax) // doesn't intersect, so must intersect other: + { + intersectKey = keyMax; + intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey); + } + break; + } + } + return coordsToPixels(intersectKey, intersectValue); +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + In situations where a single segment skips over multiple regions it might become necessary to add + extra points at the corners of region 5 (see \ref getRegion) such that the optimized segment + doesn't unintentionally cut through the visible area of the axis rect and create plot artifacts. + This method provides these points that must be added, assuming the original segment doesn't + start, end, or traverse region 5. (Corner points where region 5 is traversed are calculated by + \ref getTraverseCornerPoints.) + + For example, consider a segment which directly goes from region 4 to 2 but originally is far out + to the top left such that it doesn't cross region 5. Naively optimizing these points by + projecting them on the top and left borders of region 5 will create a segment that surely crosses + 5, creating a visual artifact in the plot. This method prevents this by providing extra points at + the top left corner, making the optimized curve correctly pass from region 4 to 1 to 2 without + traversing 5. +*/ +QVector QCPCurve::getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const +{ + QVector result; + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 2: { result << coordsToPixels(keyMin, valueMax); break; } + case 4: { result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); break; } + case 7: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); break; } + case 6: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 9: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMin-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); } + else + { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); } + break; + } + } + break; + } + case 2: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + case 4: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 7: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 3: + { + switch (currentRegion) + { + case 2: { result << coordsToPixels(keyMin, valueMin); break; } + case 6: { result << coordsToPixels(keyMin, valueMin); break; } + case 1: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); break; } + case 9: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); break; } + case 4: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 7: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMax-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); } + else + { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); } + break; + } + } + break; + } + case 4: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 2: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 3: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; } + case 9: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 5: + { + switch (currentRegion) + { + case 1: { result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 6: + { + switch (currentRegion) + { + case 3: { result << coordsToPixels(keyMin, valueMin); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 2: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 8: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 1: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; } + case 7: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 7: + { + switch (currentRegion) + { + case 4: { result << coordsToPixels(keyMax, valueMax); break; } + case 8: { result << coordsToPixels(keyMax, valueMax); break; } + case 1: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); break; } + case 2: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 3: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMax-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); } + else + { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); } + break; + } + } + break; + } + case 8: + { + switch (currentRegion) + { + case 7: { result << coordsToPixels(keyMax, valueMax); break; } + case 9: { result << coordsToPixels(keyMax, valueMin); break; } + case 4: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 6: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; } + case 1: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; } + case 3: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 9: + { + switch (currentRegion) + { + case 6: { result << coordsToPixels(keyMax, valueMin); break; } + case 8: { result << coordsToPixels(keyMax, valueMin); break; } + case 3: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); break; } + case 7: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); break; } + case 2: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; } + case 4: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; } + case 1: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points + if ((value-prevValue)/(key-prevKey)*(keyMin-key)+value < valueMin) // segment passes below R + { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); } + else + { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); } + break; + } + } + break; + } + } + return result; +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method returns whether a segment going from \a prevRegion to \a currentRegion (see \ref + getRegion) may traverse the visible region 5. This function assumes that neither \a prevRegion + nor \a currentRegion is 5 itself. + + If this method returns false, the segment for sure doesn't pass region 5. If it returns true, the + segment may or may not pass region 5 and a more fine-grained calculation must be used (\ref + getTraverse). +*/ +bool QCPCurve::mayTraverse(int prevRegion, int currentRegion) const +{ + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 4: + case 7: + case 2: + case 3: return false; + default: return true; + } + } + case 2: + { + switch (currentRegion) + { + case 1: + case 3: return false; + default: return true; + } + } + case 3: + { + switch (currentRegion) + { + case 1: + case 2: + case 6: + case 9: return false; + default: return true; + } + } + case 4: + { + switch (currentRegion) + { + case 1: + case 7: return false; + default: return true; + } + } + case 5: return false; // should never occur + case 6: + { + switch (currentRegion) + { + case 3: + case 9: return false; + default: return true; + } + } + case 7: + { + switch (currentRegion) + { + case 1: + case 4: + case 8: + case 9: return false; + default: return true; + } + } + case 8: + { + switch (currentRegion) + { + case 7: + case 9: return false; + default: return true; + } + } + case 9: + { + switch (currentRegion) + { + case 3: + case 6: + case 8: + case 7: return false; + default: return true; + } + } + default: return true; + } +} + + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method assumes that the \ref mayTraverse test has returned true, so there is a chance the + segment defined by (\a prevKey, \a prevValue) and (\a key, \a value) goes through the visible + region 5. + + The return value of this method indicates whether the segment actually traverses region 5 or not. + + If the segment traverses 5, the output parameters \a crossA and \a crossB indicate the entry and + exit points of region 5. They will become the optimized points for that segment. +*/ +bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const +{ + QList intersections; // x of QPointF corresponds to key and y to value + if (qFuzzyIsNull(key-prevKey)) // line is parallel to value axis + { + // due to region filter in mayTraverseR(), if line is parallel to value or key axis, R is traversed here + intersections.append(QPointF(key, valueMin)); // direction will be taken care of at end of method + intersections.append(QPointF(key, valueMax)); + } else if (qFuzzyIsNull(value-prevValue)) // line is parallel to key axis + { + // due to region filter in mayTraverseR(), if line is parallel to value or key axis, R is traversed here + intersections.append(QPointF(keyMin, value)); // direction will be taken care of at end of method + intersections.append(QPointF(keyMax, value)); + } else // line is skewed + { + double gamma; + double keyPerValue = (key-prevKey)/(value-prevValue); + // check top of rect: + gamma = prevKey + (valueMax-prevValue)*keyPerValue; + if (gamma >= keyMin && gamma <= keyMax) + intersections.append(QPointF(gamma, valueMax)); + // check bottom of rect: + gamma = prevKey + (valueMin-prevValue)*keyPerValue; + if (gamma >= keyMin && gamma <= keyMax) + intersections.append(QPointF(gamma, valueMin)); + double valuePerKey = 1.0/keyPerValue; + // check left of rect: + gamma = prevValue + (keyMin-prevKey)*valuePerKey; + if (gamma >= valueMin && gamma <= valueMax) + intersections.append(QPointF(keyMin, gamma)); + // check right of rect: + gamma = prevValue + (keyMax-prevKey)*valuePerKey; + if (gamma >= valueMin && gamma <= valueMax) + intersections.append(QPointF(keyMax, gamma)); + } + + // handle cases where found points isn't exactly 2: + if (intersections.size() > 2) + { + // line probably goes through corner of rect, and we got duplicate points there. single out the point pair with greatest distance in between: + double distSqrMax = 0; + QPointF pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = intersections.at(i); + pv2 = intersections.at(k); + distSqrMax = distSqr; + } + } + } + intersections = QList() << pv1 << pv2; + } else if (intersections.size() != 2) + { + // one or even zero points found (shouldn't happen unless line perfectly tangent to corner), no need to draw segment + return false; + } + + // possibly re-sort points so optimized point segment has same direction as original segment: + if ((key-prevKey)*(intersections.at(1).x()-intersections.at(0).x()) + (value-prevValue)*(intersections.at(1).y()-intersections.at(0).y()) < 0) // scalar product of both segments < 0 -> opposite direction + intersections.move(0, 1); + crossA = coordsToPixels(intersections.at(0).x(), intersections.at(0).y()); + crossB = coordsToPixels(intersections.at(1).x(), intersections.at(1).y()); + return true; +} + +/*! \internal + + This function is part of the curve optimization algorithm of \ref getCurveLines. + + This method assumes that the \ref getTraverse test has returned true, so the segment definitely + traverses the visible region 5 when going from \a prevRegion to \a currentRegion. + + In certain situations it is not sufficient to merely generate the entry and exit points of the + segment into/out of region 5, as \ref getTraverse provides. It may happen that a single segment, in + addition to traversing region 5, skips another region outside of region 5, which makes it + necessary to add an optimized corner point there (very similar to the job \ref + getOptimizedCornerPoints does for segments that are completely in outside regions and don't + traverse 5). + + As an example, consider a segment going from region 1 to region 6, traversing the lower left + corner of region 5. In this configuration, the segment additionally crosses the border between + region 1 and 2 before entering region 5. This makes it necessary to add an additional point in + the top left corner, before adding the optimized traverse points. So in this case, the output + parameter \a beforeTraverse will contain the top left corner point, and \a afterTraverse will be + empty. + + In some cases, such as when going from region 1 to 9, it may even be necessary to add additional + corner points before and after the traverse. Then both \a beforeTraverse and \a afterTraverse + return the respective corner points. +*/ +void QCPCurve::getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const +{ + switch (prevRegion) + { + case 1: + { + switch (currentRegion) + { + case 6: { beforeTraverse << coordsToPixels(keyMin, valueMax); break; } + case 9: { beforeTraverse << coordsToPixels(keyMin, valueMax); afterTraverse << coordsToPixels(keyMax, valueMin); break; } + case 8: { beforeTraverse << coordsToPixels(keyMin, valueMax); break; } + } + break; + } + case 2: + { + switch (currentRegion) + { + case 7: { afterTraverse << coordsToPixels(keyMax, valueMax); break; } + case 9: { afterTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 3: + { + switch (currentRegion) + { + case 4: { beforeTraverse << coordsToPixels(keyMin, valueMin); break; } + case 7: { beforeTraverse << coordsToPixels(keyMin, valueMin); afterTraverse << coordsToPixels(keyMax, valueMax); break; } + case 8: { beforeTraverse << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 4: + { + switch (currentRegion) + { + case 3: { afterTraverse << coordsToPixels(keyMin, valueMin); break; } + case 9: { afterTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + case 5: { break; } // shouldn't happen because this method only handles full traverses + case 6: + { + switch (currentRegion) + { + case 1: { afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 7: { afterTraverse << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 7: + { + switch (currentRegion) + { + case 2: { beforeTraverse << coordsToPixels(keyMax, valueMax); break; } + case 3: { beforeTraverse << coordsToPixels(keyMax, valueMax); afterTraverse << coordsToPixels(keyMin, valueMin); break; } + case 6: { beforeTraverse << coordsToPixels(keyMax, valueMax); break; } + } + break; + } + case 8: + { + switch (currentRegion) + { + case 1: { afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 3: { afterTraverse << coordsToPixels(keyMin, valueMin); break; } + } + break; + } + case 9: + { + switch (currentRegion) + { + case 2: { beforeTraverse << coordsToPixels(keyMax, valueMin); break; } + case 1: { beforeTraverse << coordsToPixels(keyMax, valueMin); afterTraverse << coordsToPixels(keyMin, valueMax); break; } + case 4: { beforeTraverse << coordsToPixels(keyMax, valueMin); break; } + } + break; + } + } +} + +/*! \internal + + Calculates the (minimum) distance (in pixels) the curve's representation has from the given \a + pixelPoint in pixels. This is used to determine whether the curve was clicked or not, e.g. in + \ref selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that + if the curve has a line representation, the returned distance may be smaller than the distance to + the \a closestData point, since the distance to the curve line is also taken into account. + + If either the curve has no data or if the line style is \ref lsNone and the scatter style's shape + is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the curve), returns + -1.0. +*/ +double QCPCurve::pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (mDataContainer->isEmpty()) + return -1.0; + if (mLineStyle == lsNone && mScatterStyle.isNone()) + return -1.0; + + if (mDataContainer->size() == 1) + { + QPointF dataPoint = coordsToPixels(mDataContainer->constBegin()->key, mDataContainer->constBegin()->value); + closestData = mDataContainer->constBegin(); + return QCPVector2D(dataPoint-pixelPoint).length(); + } + + // calculate minimum distances to curve data points and find closestData iterator: + double minDistSqr = std::numeric_limits::max(); + // iterate over found data points and then choose the one with the shortest distance to pos: + QCPCurveDataContainer::const_iterator begin = mDataContainer->constBegin(); + QCPCurveDataContainer::const_iterator end = mDataContainer->constEnd(); + for (QCPCurveDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestData = it; + } + } + + // calculate distance to line if there is one (if so, will probably be smaller than distance to closest data point): + if (mLineStyle != lsNone) + { + QVector lines; + getCurveLines(&lines, QCPDataRange(0, dataCount()), mParentPlot->selectionTolerance()*1.2); // optimized lines outside axis rect shouldn't respond to clicks at the edge, so use 1.2*tolerance as pen width + for (int i=0; i QCPBarsGroup::bars() const + + Returns all bars currently in this group. + + \see bars(int index) +*/ + +/*! \fn int QCPBarsGroup::size() const + + Returns the number of QCPBars plottables that are part of this group. + +*/ + +/*! \fn bool QCPBarsGroup::isEmpty() const + + Returns whether this bars group is empty. + + \see size +*/ + +/*! \fn bool QCPBarsGroup::contains(QCPBars *bars) + + Returns whether the specified \a bars plottable is part of this group. + +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a new bars group for the specified QCustomPlot instance. +*/ +QCPBarsGroup::QCPBarsGroup(QCustomPlot *parentPlot) : + QObject(parentPlot), + mParentPlot(parentPlot), + mSpacingType(stAbsolute), + mSpacing(4) +{ +} + +QCPBarsGroup::~QCPBarsGroup() +{ + clear(); +} + +/*! + Sets how the spacing between adjacent bars is interpreted. See \ref SpacingType. + + The actual spacing can then be specified with \ref setSpacing. + + \see setSpacing +*/ +void QCPBarsGroup::setSpacingType(SpacingType spacingType) +{ + mSpacingType = spacingType; +} + +/*! + Sets the spacing between adjacent bars. What the number passed as \a spacing actually means, is + defined by the current \ref SpacingType, which can be set with \ref setSpacingType. + + \see setSpacingType +*/ +void QCPBarsGroup::setSpacing(double spacing) +{ + mSpacing = spacing; +} + +/*! + Returns the QCPBars instance with the specified \a index in this group. If no such QCPBars + exists, returns 0. + + \see bars(), size +*/ +QCPBars *QCPBarsGroup::bars(int index) const +{ + if (index >= 0 && index < mBars.size()) + { + return mBars.at(index); + } else + { + qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; + return 0; + } +} + +/*! + Removes all QCPBars plottables from this group. + + \see isEmpty +*/ +void QCPBarsGroup::clear() +{ + foreach (QCPBars *bars, mBars) // since foreach takes a copy, removing bars in the loop is okay + bars->setBarsGroup(0); // removes itself via removeBars +} + +/*! + Adds the specified \a bars plottable to this group. Alternatively, you can also use \ref + QCPBars::setBarsGroup on the \a bars instance. + + \see insert, remove +*/ +void QCPBarsGroup::append(QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + if (!mBars.contains(bars)) + bars->setBarsGroup(this); + else + qDebug() << Q_FUNC_INFO << "bars plottable is already in this bars group:" << reinterpret_cast(bars); +} + +/*! + Inserts the specified \a bars plottable into this group at the specified index position \a i. + This gives you full control over the ordering of the bars. + + \a bars may already be part of this group. In that case, \a bars is just moved to the new index + position. + + \see append, remove +*/ +void QCPBarsGroup::insert(int i, QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + // first append to bars list normally: + if (!mBars.contains(bars)) + bars->setBarsGroup(this); + // then move to according position: + mBars.move(mBars.indexOf(bars), qBound(0, i, mBars.size()-1)); +} + +/*! + Removes the specified \a bars plottable from this group. + + \see contains, clear +*/ +void QCPBarsGroup::remove(QCPBars *bars) +{ + if (!bars) + { + qDebug() << Q_FUNC_INFO << "bars is 0"; + return; + } + + if (mBars.contains(bars)) + bars->setBarsGroup(0); + else + qDebug() << Q_FUNC_INFO << "bars plottable is not in this bars group:" << reinterpret_cast(bars); +} + +/*! \internal + + Adds the specified \a bars to the internal mBars list of bars. This method does not change the + barsGroup property on \a bars. + + \see unregisterBars +*/ +void QCPBarsGroup::registerBars(QCPBars *bars) +{ + if (!mBars.contains(bars)) + mBars.append(bars); +} + +/*! \internal + + Removes the specified \a bars from the internal mBars list of bars. This method does not change + the barsGroup property on \a bars. + + \see registerBars +*/ +void QCPBarsGroup::unregisterBars(QCPBars *bars) +{ + mBars.removeOne(bars); +} + +/*! \internal + + Returns the pixel offset in the key dimension the specified \a bars plottable should have at the + given key coordinate \a keyCoord. The offset is relative to the pixel position of the key + coordinate \a keyCoord. +*/ +double QCPBarsGroup::keyPixelOffset(const QCPBars *bars, double keyCoord) +{ + // find list of all base bars in case some mBars are stacked: + QList baseBars; + foreach (const QCPBars *b, mBars) + { + while (b->barBelow()) + b = b->barBelow(); + if (!baseBars.contains(b)) + baseBars.append(b); + } + // find base bar this "bars" is stacked on: + const QCPBars *thisBase = bars; + while (thisBase->barBelow()) + thisBase = thisBase->barBelow(); + + // determine key pixel offset of this base bars considering all other base bars in this barsgroup: + double result = 0; + int index = baseBars.indexOf(thisBase); + if (index >= 0) + { + if (baseBars.size() % 2 == 1 && index == (baseBars.size()-1)/2) // is center bar (int division on purpose) + { + return result; + } else + { + double lowerPixelWidth, upperPixelWidth; + int startIndex; + int dir = (index <= (baseBars.size()-1)/2) ? -1 : 1; // if bar is to lower keys of center, dir is negative + if (baseBars.size() % 2 == 0) // even number of bars + { + startIndex = baseBars.size()/2 + (dir < 0 ? -1 : 0); + result += getPixelSpacing(baseBars.at(startIndex), keyCoord)*0.5; // half of middle spacing + } else // uneven number of bars + { + startIndex = (baseBars.size()-1)/2+dir; + baseBars.at((baseBars.size()-1)/2)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; // half of center bar + result += getPixelSpacing(baseBars.at((baseBars.size()-1)/2), keyCoord); // center bar spacing + } + for (int i = startIndex; i != index; i += dir) // add widths and spacings of bars in between center and our bars + { + baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth); + result += getPixelSpacing(baseBars.at(i), keyCoord); + } + // finally half of our bars width: + baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth); + result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5; + // correct sign of result depending on orientation and direction of key axis: + result *= dir*thisBase->keyAxis()->pixelOrientation(); + } + } + return result; +} + +/*! \internal + + Returns the spacing in pixels which is between this \a bars and the following one, both at the + key coordinate \a keyCoord. + + \note Typically the returned value doesn't depend on \a bars or \a keyCoord. \a bars is only + needed to get access to the key axis transformation and axis rect for the modes \ref + stAxisRectRatio and \ref stPlotCoords. The \a keyCoord is only relevant for spacings given in + \ref stPlotCoords on a logarithmic axis. +*/ +double QCPBarsGroup::getPixelSpacing(const QCPBars *bars, double keyCoord) +{ + switch (mSpacingType) + { + case stAbsolute: + { + return mSpacing; + } + case stAxisRectRatio: + { + if (bars->keyAxis()->orientation() == Qt::Horizontal) + return bars->keyAxis()->axisRect()->width()*mSpacing; + else + return bars->keyAxis()->axisRect()->height()*mSpacing; + } + case stPlotCoords: + { + double keyPixel = bars->keyAxis()->coordToPixel(keyCoord); + return qAbs(bars->keyAxis()->coordToPixel(keyCoord+mSpacing)-keyPixel); + } + } + return 0; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPBarsData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPBarsData + \brief Holds the data of one single data point (one bar) for QCPBars. + + The stored data is: + \li \a key: coordinate on the key axis of this bar (this is the \a mainKey and the \a sortKey) + \li \a value: height coordinate on the value axis of this bar (this is the \a mainValue) + + The container for storing multiple data points is \ref QCPBarsDataContainer. It is a typedef for + \ref QCPDataContainer with \ref QCPBarsData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPBarsDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPBarsData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPBarsData QCPBarsData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPBarsData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPBarsData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPBarsData::mainValue() const + + Returns the \a value member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPBarsData::valueRange() const + + Returns a QCPRange with both lower and upper boundary set to \a value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a bar data point with key and value set to zero. +*/ +QCPBarsData::QCPBarsData() : + key(0), + value(0) +{ +} + +/*! + Constructs a bar data point with the specified \a key and \a value. +*/ +QCPBarsData::QCPBarsData(double key, double value) : + key(key), + value(value) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPBars +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPBars + \brief A plottable representing a bar chart in a plot. + + \image html QCPBars.png + + To plot data, assign it with the \ref setData or \ref addData functions. + + \section qcpbars-appearance Changing the appearance + + The appearance of the bars is determined by the pen and the brush (\ref setPen, \ref setBrush). + The width of the individual bars can be controlled with \ref setWidthType and \ref setWidth. + + Bar charts are stackable. This means, two QCPBars plottables can be placed on top of each other + (see \ref QCPBars::moveAbove). So when two bars are at the same key position, they will appear + stacked. + + If you would like to group multiple QCPBars plottables together so they appear side by side as + shown below, use QCPBarsGroup. + + \image html QCPBarsGroup.png + + \section qcpbars-usage Usage + + Like all data representing objects in QCustomPlot, the QCPBars is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-creation-2 +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPBars::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPBarsDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods. +*/ + +/*! \fn QCPBars *QCPBars::barBelow() const + Returns the bars plottable that is directly below this bars plottable. + If there is no such plottable, returns 0. + + \see barAbove, moveBelow, moveAbove +*/ + +/*! \fn QCPBars *QCPBars::barAbove() const + Returns the bars plottable that is directly above this bars plottable. + If there is no such plottable, returns 0. + + \see barBelow, moveBelow, moveAbove +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a bar chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPBars is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPBars, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPBars::QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mWidth(0.75), + mWidthType(wtPlotCoords), + mBarsGroup(0), + mBaseValue(0), + mStackingGap(0) +{ + // modify inherited properties from abstract plottable: + mPen.setColor(Qt::blue); + mPen.setStyle(Qt::SolidLine); + mBrush.setColor(QColor(40, 50, 255, 30)); + mBrush.setStyle(Qt::SolidPattern); + mSelectionDecorator->setBrush(QBrush(QColor(160, 160, 255))); +} + +QCPBars::~QCPBars() +{ + setBarsGroup(0); + if (mBarBelow || mBarAbove) + connectBars(mBarBelow.data(), mBarAbove.data()); // take this bar out of any stacking +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPBars may share the same data container safely. + Modifying the data in the container will then affect all bars that share the container. Sharing + can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the bar's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpbars-datasharing-2 + + \see addData +*/ +void QCPBars::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys and \a values. The provided + vectors should have equal length. Else, the number of added points will be the size of the + smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPBars::setData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, values, alreadySorted); +} + +/*! + Sets the width of the bars. + + How the number passed as \a width is interpreted (e.g. screen pixels, plot coordinates,...), + depends on the currently set width type, see \ref setWidthType and \ref WidthType. +*/ +void QCPBars::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets how the width of the bars is defined. See the documentation of \ref WidthType for an + explanation of the possible values for \a widthType. + + The default value is \ref wtPlotCoords. + + \see setWidth +*/ +void QCPBars::setWidthType(QCPBars::WidthType widthType) +{ + mWidthType = widthType; +} + +/*! + Sets to which QCPBarsGroup this QCPBars instance belongs to. Alternatively, you can also use \ref + QCPBarsGroup::append. + + To remove this QCPBars from any group, set \a barsGroup to 0. +*/ +void QCPBars::setBarsGroup(QCPBarsGroup *barsGroup) +{ + // deregister at old group: + if (mBarsGroup) + mBarsGroup->unregisterBars(this); + mBarsGroup = barsGroup; + // register at new group: + if (mBarsGroup) + mBarsGroup->registerBars(this); +} + +/*! + Sets the base value of this bars plottable. + + The base value defines where on the value coordinate the bars start. How far the bars extend from + the base value is given by their individual value data. For example, if the base value is set to + 1, a bar with data value 2 will have its lowest point at value coordinate 1 and highest point at + 3. + + For stacked bars, only the base value of the bottom-most QCPBars has meaning. + + The default base value is 0. +*/ +void QCPBars::setBaseValue(double baseValue) +{ + mBaseValue = baseValue; +} + +/*! + If this bars plottable is stacked on top of another bars plottable (\ref moveAbove), this method + allows specifying a distance in \a pixels, by which the drawn bar rectangles will be separated by + the bars below it. +*/ +void QCPBars::setStackingGap(double pixels) +{ + mStackingGap = pixels; +} + +/*! \overload + + Adds the provided points in \a keys and \a values to the current data. The provided vectors + should have equal length. Else, the number of added points will be the size of the smallest + vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPBars::addData(const QVector &keys, const QVector &values, bool alreadySorted) +{ + if (keys.size() != values.size()) + qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size(); + const int n = qMin(keys.size(), values.size()); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->value = values[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + Adds the provided data point as \a key and \a value to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPBars::addData(double key, double value) +{ + mDataContainer->add(QCPBarsData(key, value)); +} + +/*! + Moves this bars plottable below \a bars. In other words, the bars of this plottable will appear + below the bars of \a bars. The move target \a bars must use the same key and value axis as this + plottable. + + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already + has a bars object below itself, this bars object is inserted between the two. If this bars object + is already between two other bars, the two other bars will be stacked on top of each other after + the operation. + + To remove this bars plottable from any stacking, set \a bars to 0. + + \see moveBelow, barAbove, barBelow +*/ +void QCPBars::moveBelow(QCPBars *bars) +{ + if (bars == this) return; + if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) + { + qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; + return; + } + // remove from stacking: + connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 + // if new bar given, insert this bar below it: + if (bars) + { + if (bars->mBarBelow) + connectBars(bars->mBarBelow.data(), this); + connectBars(this, bars); + } +} + +/*! + Moves this bars plottable above \a bars. In other words, the bars of this plottable will appear + above the bars of \a bars. The move target \a bars must use the same key and value axis as this + plottable. + + Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already + has a bars object above itself, this bars object is inserted between the two. If this bars object + is already between two other bars, the two other bars will be stacked on top of each other after + the operation. + + To remove this bars plottable from any stacking, set \a bars to 0. + + \see moveBelow, barBelow, barAbove +*/ +void QCPBars::moveAbove(QCPBars *bars) +{ + if (bars == this) return; + if (bars && (bars->keyAxis() != mKeyAxis.data() || bars->valueAxis() != mValueAxis.data())) + { + qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars"; + return; + } + // remove from stacking: + connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0 + // if new bar given, insert this bar above it: + if (bars) + { + if (bars->mBarAbove) + connectBars(this, bars->mBarAbove.data()); + connectBars(bars, this); + } +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPBars::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(getBarRect(it->key, it->value))) + result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +double QCPBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + // get visible data range: + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + for (QCPBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (getBarRect(it->key, it->value).contains(pos)) + { + if (details) + { + int pointIndex = it-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return mParentPlot->selectionTolerance()*0.99; + } + } + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + /* Note: If this QCPBars uses absolute pixels as width (or is in a QCPBarsGroup with spacing in + absolute pixels), using this method to adapt the key axis range to fit the bars into the + currently visible axis range will not work perfectly. Because in the moment the axis range is + changed to the new range, the fixed pixel widths/spacings will represent different coordinate + spans than before, which in turn would require a different key range to perfectly fit, and so on. + The only solution would be to iteratively approach the perfect fitting axis range, but the + mismatch isn't large enough in most applications, to warrant this here. If a user does need a + better fit, he should call the corresponding axis rescale multiple times in a row. + */ + QCPRange range; + range = mDataContainer->keyRange(foundRange, inSignDomain); + + // determine exact range of bars by including bar width and barsgroup offset: + if (foundRange && mKeyAxis) + { + double lowerPixelWidth, upperPixelWidth, keyPixel; + // lower range bound: + getPixelWidth(range.lower, lowerPixelWidth, upperPixelWidth); + keyPixel = mKeyAxis.data()->coordToPixel(range.lower) + lowerPixelWidth; + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, range.lower); + const double lowerCorrected = mKeyAxis.data()->pixelToCoord(keyPixel); + if (!qIsNaN(lowerCorrected) && qIsFinite(lowerCorrected) && range.lower > lowerCorrected) + range.lower = lowerCorrected; + // upper range bound: + getPixelWidth(range.upper, lowerPixelWidth, upperPixelWidth); + keyPixel = mKeyAxis.data()->coordToPixel(range.upper) + upperPixelWidth; + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, range.upper); + const double upperCorrected = mKeyAxis.data()->pixelToCoord(keyPixel); + if (!qIsNaN(upperCorrected) && qIsFinite(upperCorrected) && range.upper < upperCorrected) + range.upper = upperCorrected; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + // Note: can't simply use mDataContainer->valueRange here because we need to + // take into account bar base value and possible stacking of multiple bars + QCPRange range; + range.lower = mBaseValue; + range.upper = mBaseValue; + bool haveLower = true; // set to true, because baseValue should always be visible in bar charts + bool haveUpper = true; // set to true, because baseValue should always be visible in bar charts + QCPBarsDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPBarsDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + if (inKeyRange != QCPRange()) + { + itBegin = mDataContainer->findBegin(inKeyRange.lower); + itEnd = mDataContainer->findEnd(inKeyRange.upper); + } + for (QCPBarsDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + const double current = it->value + getStackedBaseValue(it->key, it->value >= 0); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } + + foundRange = true; // return true because bar charts always have the 0-line visible + return range; +} + +/* inherits documentation from base class */ +QPointF QCPBars::dataPixelPosition(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); } + + const QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; + const double valuePixel = valueAxis->coordToPixel(getStackedBaseValue(it->key, it->value >= 0) + it->value); + const double keyPixel = keyAxis->coordToPixel(it->key) + (mBarsGroup ? mBarsGroup->keyPixelOffset(this, it->key) : 0); + if (keyAxis->orientation() == Qt::Horizontal) + return QPointF(keyPixel, valuePixel); + else + return QPointF(valuePixel, keyPixel); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return QPointF(); + } +} + +/* inherits documentation from base class */ +void QCPBars::draw(QCPPainter *painter) +{ + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mDataContainer->isEmpty()) return; + + QCPBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPBarsDataContainer::const_iterator begin = visibleBegin; + QCPBarsDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + for (QCPBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + if (QCP::isInvalidData(it->key, it->value)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); +#endif + // draw bar: + if (isSelectedSegment && mSelectionDecorator) + { + mSelectionDecorator->applyBrush(painter); + mSelectionDecorator->applyPen(painter); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + } + applyDefaultAntialiasingHint(painter); + painter->drawPolygon(getBarRect(it->key, it->value)); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw filled rect: + applyDefaultAntialiasingHint(painter); + painter->setBrush(mBrush); + painter->setPen(mPen); + QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); + r.moveCenter(rect.center()); + painter->drawRect(r); +} + +/*! \internal + + called by \ref draw to determine which data (key) range is visible at the current key axis range + setting, so only that needs to be processed. It also takes into account the bar width. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + lower may still be just outside the visible range. + + \a end returns an iterator one higher than the highest visible data point. Same as before, \a end + may also lie just outside of the visible range. + + if the plottable contains no data, both \a begin and \a end point to constEnd. +*/ +void QCPBars::getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + if (mDataContainer->isEmpty()) + { + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + + // get visible data range as QMap iterators + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower); + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper); + double lowerPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().lower); + double upperPixelBound = mKeyAxis.data()->coordToPixel(mKeyAxis.data()->range().upper); + bool isVisible = false; + // walk left from begin to find lower bar that actually is completely outside visible pixel range: + QCPBarsDataContainer::const_iterator it = begin; + while (it != mDataContainer->constBegin()) + { + --it; + const QRectF barRect = getBarRect(it->key, it->value); + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.right() >= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.left() <= lowerPixelBound)); + else // keyaxis is vertical + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.top() <= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.bottom() >= lowerPixelBound)); + if (isVisible) + begin = it; + else + break; + } + // walk right from ubound to find upper bar that actually is completely outside visible pixel range: + it = end; + while (it != mDataContainer->constEnd()) + { + const QRectF barRect = getBarRect(it->key, it->value); + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.left() <= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.right() >= upperPixelBound)); + else // keyaxis is vertical + isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.bottom() >= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.top() <= upperPixelBound)); + if (isVisible) + end = it+1; + else + break; + ++it; + } +} + +/*! \internal + + Returns the rect in pixel coordinates of a single bar with the specified \a key and \a value. The + rect is shifted according to the bar stacking (see \ref moveAbove) and base value (see \ref + setBaseValue), and to have non-overlapping border lines with the bars stacked below. +*/ +QRectF QCPBars::getBarRect(double key, double value) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QRectF(); } + + double lowerPixelWidth, upperPixelWidth; + getPixelWidth(key, lowerPixelWidth, upperPixelWidth); + double base = getStackedBaseValue(key, value >= 0); + double basePixel = valueAxis->coordToPixel(base); + double valuePixel = valueAxis->coordToPixel(base+value); + double keyPixel = keyAxis->coordToPixel(key); + if (mBarsGroup) + keyPixel += mBarsGroup->keyPixelOffset(this, key); + double bottomOffset = (mBarBelow && mPen != Qt::NoPen ? 1 : 0)*(mPen.isCosmetic() ? 1 : mPen.widthF()); + bottomOffset += mBarBelow ? mStackingGap : 0; + bottomOffset *= (value<0 ? -1 : 1)*valueAxis->pixelOrientation(); + if (qAbs(valuePixel-basePixel) <= qAbs(bottomOffset)) + bottomOffset = valuePixel-basePixel; + if (keyAxis->orientation() == Qt::Horizontal) + { + return QRectF(QPointF(keyPixel+lowerPixelWidth, valuePixel), QPointF(keyPixel+upperPixelWidth, basePixel+bottomOffset)).normalized(); + } else + { + return QRectF(QPointF(basePixel+bottomOffset, keyPixel+lowerPixelWidth), QPointF(valuePixel, keyPixel+upperPixelWidth)).normalized(); + } +} + +/*! \internal + + This function is used to determine the width of the bar at coordinate \a key, according to the + specified width (\ref setWidth) and width type (\ref setWidthType). + + The output parameters \a lower and \a upper return the number of pixels the bar extends to lower + and higher keys, relative to the \a key coordinate (so with a non-reversed horizontal axis, \a + lower is negative and \a upper positive). +*/ +void QCPBars::getPixelWidth(double key, double &lower, double &upper) const +{ + lower = 0; + upper = 0; + switch (mWidthType) + { + case wtAbsolute: + { + upper = mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + lower = -upper; + break; + } + case wtAxisRectRatio: + { + if (mKeyAxis && mKeyAxis.data()->axisRect()) + { + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + upper = mKeyAxis.data()->axisRect()->width()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + else + upper = mKeyAxis.data()->axisRect()->height()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + lower = -upper; + } else + qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; + break; + } + case wtPlotCoords: + { + if (mKeyAxis) + { + double keyPixel = mKeyAxis.data()->coordToPixel(key); + upper = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; + lower = mKeyAxis.data()->coordToPixel(key-mWidth*0.5)-keyPixel; + // no need to qSwap(lower, higher) when range reversed, because higher/lower are gained by + // coordinate transform which includes range direction + } else + qDebug() << Q_FUNC_INFO << "No key axis defined"; + break; + } + } +} + +/*! \internal + + This function is called to find at which value to start drawing the base of a bar at \a key, when + it is stacked on top of another QCPBars (e.g. with \ref moveAbove). + + positive and negative bars are separated per stack (positive are stacked above baseValue upwards, + negative are stacked below baseValue downwards). This can be indicated with \a positive. So if the + bar for which we need the base value is negative, set \a positive to false. +*/ +double QCPBars::getStackedBaseValue(double key, bool positive) const +{ + if (mBarBelow) + { + double max = 0; // don't initialize with mBaseValue here because only base value of bottom-most bar has meaning in a bar stack + // find bars of mBarBelow that are approximately at key and find largest one: + double epsilon = qAbs(key)*(sizeof(key)==4 ? 1e-6 : 1e-14); // should be safe even when changed to use float at some point + if (key == 0) + epsilon = (sizeof(key)==4 ? 1e-6 : 1e-14); + QCPBarsDataContainer::const_iterator it = mBarBelow.data()->mDataContainer->findBegin(key-epsilon); + QCPBarsDataContainer::const_iterator itEnd = mBarBelow.data()->mDataContainer->findEnd(key+epsilon); + while (it != itEnd) + { + if (it->key > key-epsilon && it->key < key+epsilon) + { + if ((positive && it->value > max) || + (!positive && it->value < max)) + max = it->value; + } + ++it; + } + // recurse down the bar-stack to find the total height: + return max + mBarBelow.data()->getStackedBaseValue(key, positive); + } else + return mBaseValue; +} + +/*! \internal + + Connects \a below and \a above to each other via their mBarAbove/mBarBelow properties. The bar(s) + currently above lower and below upper will become disconnected to lower/upper. + + If lower is zero, upper will be disconnected at the bottom. + If upper is zero, lower will be disconnected at the top. +*/ +void QCPBars::connectBars(QCPBars *lower, QCPBars *upper) +{ + if (!lower && !upper) return; + + if (!lower) // disconnect upper at bottom + { + // disconnect old bar below upper: + if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) + upper->mBarBelow.data()->mBarAbove = 0; + upper->mBarBelow = 0; + } else if (!upper) // disconnect lower at top + { + // disconnect old bar above lower: + if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) + lower->mBarAbove.data()->mBarBelow = 0; + lower->mBarAbove = 0; + } else // connect lower and upper + { + // disconnect old bar above lower: + if (lower->mBarAbove && lower->mBarAbove.data()->mBarBelow.data() == lower) + lower->mBarAbove.data()->mBarBelow = 0; + // disconnect old bar below upper: + if (upper->mBarBelow && upper->mBarBelow.data()->mBarAbove.data() == upper) + upper->mBarBelow.data()->mBarAbove = 0; + lower->mBarAbove = upper; + upper->mBarBelow = lower; + } +} +/* end of 'src/plottables/plottable-bars.cpp' */ + + +/* including file 'src/plottables/plottable-statisticalbox.cpp', size 28622 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPStatisticalBoxData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPStatisticalBoxData + \brief Holds the data of one single data point for QCPStatisticalBox. + + The stored data is: + + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + + \li \a minimum: the position of the lower whisker, typically the minimum measurement of the + sample that's not considered an outlier. + + \li \a lowerQuartile: the lower end of the box. The lower and the upper quartiles are the two + statistical quartiles around the median of the sample, they should contain 50% of the sample + data. + + \li \a median: the value of the median mark inside the quartile box. The median separates the + sample data in half (50% of the sample data is below/above the median). (This is the \a mainValue) + + \li \a upperQuartile: the upper end of the box. The lower and the upper quartiles are the two + statistical quartiles around the median of the sample, they should contain 50% of the sample + data. + + \li \a maximum: the position of the upper whisker, typically the maximum measurement of the + sample that's not considered an outlier. + + \li \a outliers: a QVector of outlier values that will be drawn as scatter points at the \a key + coordinate of this data point (see \ref QCPStatisticalBox::setOutlierStyle) + + The container for storing multiple data points is \ref QCPStatisticalBoxDataContainer. It is a + typedef for \ref QCPDataContainer with \ref QCPStatisticalBoxData as the DataType template + parameter. See the documentation there for an explanation regarding the data type's generic + methods. + + \see QCPStatisticalBoxDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPStatisticalBoxData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPStatisticalBoxData QCPStatisticalBoxData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPStatisticalBoxData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPStatisticalBoxData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPStatisticalBoxData::mainValue() const + + Returns the \a median member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPStatisticalBoxData::valueRange() const + + Returns a QCPRange spanning from the \a minimum to the \a maximum member of this statistical box + data point, possibly further expanded by outliers. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and all values set to zero. +*/ +QCPStatisticalBoxData::QCPStatisticalBoxData() : + key(0), + minimum(0), + lowerQuartile(0), + median(0), + upperQuartile(0), + maximum(0) +{ +} + +/*! + Constructs a data point with the specified \a key, \a minimum, \a lowerQuartile, \a median, \a + upperQuartile, \a maximum and optionally a number of \a outliers. +*/ +QCPStatisticalBoxData::QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) : + key(key), + minimum(minimum), + lowerQuartile(lowerQuartile), + median(median), + upperQuartile(upperQuartile), + maximum(maximum), + outliers(outliers) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPStatisticalBox +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPStatisticalBox + \brief A plottable representing a single statistical box in a plot. + + \image html QCPStatisticalBox.png + + To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can + also access and modify the data via the \ref data method, which returns a pointer to the internal + \ref QCPStatisticalBoxDataContainer. + + Additionally each data point can itself have a list of outliers, drawn as scatter points at the + key coordinate of the respective statistical box data point. They can either be set by using the + respective \ref addData(double,double,double,double,double,double,const QVector&) + "addData" method or accessing the individual data points through \ref data, and setting the + QVector outliers of the data points directly. + + \section qcpstatisticalbox-appearance Changing the appearance + + The appearance of each data point box, ranging from the lower to the upper quartile, is + controlled via \ref setPen and \ref setBrush. You may change the width of the boxes with \ref + setWidth in plot coordinates. + + Each data point's visual representation also consists of two whiskers. Whiskers are the lines + which reach from the upper quartile to the maximum, and from the lower quartile to the minimum. + The appearance of the whiskers can be modified with: \ref setWhiskerPen, \ref setWhiskerBarPen, + \ref setWhiskerWidth. The whisker width is the width of the bar perpendicular to the whisker at + the top (for maximum) and bottom (for minimum). If the whisker pen is changed, make sure to set + the \c capStyle to \c Qt::FlatCap. Otherwise the backbone line might exceed the whisker bars by a + few pixels due to the pen cap being not perfectly flat. + + The median indicator line inside the box has its own pen, \ref setMedianPen. + + The outlier data points are drawn as normal scatter points. Their look can be controlled with + \ref setOutlierStyle + + \section qcpstatisticalbox-usage Usage + + Like all data representing objects in QCustomPlot, the QCPStatisticalBox is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes + ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead. + The newly created plottable can be modified, e.g.: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-creation-2 +*/ + +/* start documentation of inline functions */ + +/*! \fn QSharedPointer QCPStatisticalBox::data() const + + Returns a shared pointer to the internal data storage of type \ref + QCPStatisticalBoxDataContainer. You may use it to directly manipulate the data, which may be more + convenient and faster than using the regular \ref setData or \ref addData methods. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a statistical box which uses \a keyAxis as its key axis ("x") and \a valueAxis as its + value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and + not have the same orientation. If either of these restrictions is violated, a corresponding + message is printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPStatisticalBox is automatically registered with the QCustomPlot instance inferred + from \a keyAxis. This QCustomPlot instance takes ownership of the QCPStatisticalBox, so do not + delete it manually but use QCustomPlot::removePlottable() instead. +*/ +QCPStatisticalBox::QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mWidth(0.5), + mWhiskerWidth(0.2), + mWhiskerPen(Qt::black, 0, Qt::DashLine, Qt::FlatCap), + mWhiskerBarPen(Qt::black), + mWhiskerAntialiased(false), + mMedianPen(Qt::black, 3, Qt::SolidLine, Qt::FlatCap), + mOutlierStyle(QCPScatterStyle::ssCircle, Qt::blue, 6) +{ + setPen(QPen(Qt::black)); + setBrush(Qt::NoBrush); +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPStatisticalBoxes may share the same data container + safely. Modifying the data in the container will then affect all statistical boxes that share the + container. Sharing can be achieved by simply exchanging the data containers wrapped in shared + pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the statistical box data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpstatisticalbox-datasharing-2 + + \see addData +*/ +void QCPStatisticalBox::setData(QSharedPointer data) +{ + mDataContainer = data; +} +/*! \overload + + Replaces the current data with the provided points in \a keys, \a minimum, \a lowerQuartile, \a + median, \a upperQuartile and \a maximum. The provided vectors should have equal length. Else, the + number of added points will be the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData +*/ +void QCPStatisticalBox::setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, minimum, lowerQuartile, median, upperQuartile, maximum, alreadySorted); +} + +/*! + Sets the width of the boxes in key coordinates. + + \see setWhiskerWidth +*/ +void QCPStatisticalBox::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets the width of the whiskers in key coordinates. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + \see setWidth +*/ +void QCPStatisticalBox::setWhiskerWidth(double width) +{ + mWhiskerWidth = width; +} + +/*! + Sets the pen used for drawing the whisker backbone. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + Make sure to set the \c capStyle of the passed \a pen to \c Qt::FlatCap. Otherwise the backbone + line might exceed the whisker bars by a few pixels due to the pen cap being not perfectly flat. + + \see setWhiskerBarPen +*/ +void QCPStatisticalBox::setWhiskerPen(const QPen &pen) +{ + mWhiskerPen = pen; +} + +/*! + Sets the pen used for drawing the whisker bars. Those are the lines parallel to the key axis at + each end of the whisker backbone. + + Whiskers are the lines which reach from the upper quartile to the maximum, and from the lower + quartile to the minimum. + + \see setWhiskerPen +*/ +void QCPStatisticalBox::setWhiskerBarPen(const QPen &pen) +{ + mWhiskerBarPen = pen; +} + +/*! + Sets whether the statistical boxes whiskers are drawn with antialiasing or not. + + Note that antialiasing settings may be overridden by QCustomPlot::setAntialiasedElements and + QCustomPlot::setNotAntialiasedElements. +*/ +void QCPStatisticalBox::setWhiskerAntialiased(bool enabled) +{ + mWhiskerAntialiased = enabled; +} + +/*! + Sets the pen used for drawing the median indicator line inside the statistical boxes. +*/ +void QCPStatisticalBox::setMedianPen(const QPen &pen) +{ + mMedianPen = pen; +} + +/*! + Sets the appearance of the outlier data points. + + Outliers can be specified with the method + \ref addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) +*/ +void QCPStatisticalBox::setOutlierStyle(const QCPScatterStyle &style) +{ + mOutlierStyle = style; +} + +/*! \overload + + Adds the provided points in \a keys, \a minimum, \a lowerQuartile, \a median, \a upperQuartile and + \a maximum to the current data. The provided vectors should have equal length. Else, the number + of added points will be the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPStatisticalBox::addData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted) +{ + if (keys.size() != minimum.size() || minimum.size() != lowerQuartile.size() || lowerQuartile.size() != median.size() || + median.size() != upperQuartile.size() || upperQuartile.size() != maximum.size() || maximum.size() != keys.size()) + qDebug() << Q_FUNC_INFO << "keys, minimum, lowerQuartile, median, upperQuartile, maximum have different sizes:" + << keys.size() << minimum.size() << lowerQuartile.size() << median.size() << upperQuartile.size() << maximum.size(); + const int n = qMin(keys.size(), qMin(minimum.size(), qMin(lowerQuartile.size(), qMin(median.size(), qMin(upperQuartile.size(), maximum.size()))))); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->minimum = minimum[i]; + it->lowerQuartile = lowerQuartile[i]; + it->median = median[i]; + it->upperQuartile = upperQuartile[i]; + it->maximum = maximum[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key, \a minimum, \a lowerQuartile, \a median, \a upperQuartile + and \a maximum to the current data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. +*/ +void QCPStatisticalBox::addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers) +{ + mDataContainer->add(QCPStatisticalBoxData(key, minimum, lowerQuartile, median, upperQuartile, maximum, outliers)); +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPStatisticalBox::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPStatisticalBoxDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(getQuartileBox(it))) + result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +double QCPStatisticalBox::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis->axisRect()->rect().contains(pos.toPoint())) + { + // get visible data range: + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + QCPStatisticalBoxDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + getVisibleDataBounds(visibleBegin, visibleEnd); + double minDistSqr = std::numeric_limits::max(); + for (QCPStatisticalBoxDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (getQuartileBox(it).contains(pos)) // quartile box + { + double currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } else // whiskers + { + const QVector whiskerBackbones(getWhiskerBackboneLines(it)); + for (int i=0; iconstBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return qSqrt(minDistSqr); + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPStatisticalBox::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + QCPRange range = mDataContainer->keyRange(foundRange, inSignDomain); + // determine exact range by including width of bars/flags: + if (foundRange) + { + if (inSignDomain != QCP::sdPositive || range.lower-mWidth*0.5 > 0) + range.lower -= mWidth*0.5; + if (inSignDomain != QCP::sdNegative || range.upper+mWidth*0.5 < 0) + range.upper += mWidth*0.5; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPStatisticalBox::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::draw(QCPPainter *painter) +{ + if (mDataContainer->isEmpty()) return; + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + QCPStatisticalBoxDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPStatisticalBoxDataContainer::const_iterator begin = visibleBegin; + QCPStatisticalBoxDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + for (QCPStatisticalBoxDataContainer::const_iterator it=begin; it!=end; ++it) + { + // check data validity if flag set: +# ifdef QCUSTOMPLOT_CHECK_DATA + if (QCP::isInvalidData(it->key, it->minimum) || + QCP::isInvalidData(it->lowerQuartile, it->median) || + QCP::isInvalidData(it->upperQuartile, it->maximum)) + qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range has invalid data." << "Plottable name:" << name(); + for (int i=0; ioutliers.size(); ++i) + if (QCP::isInvalidData(it->outliers.at(i))) + qDebug() << Q_FUNC_INFO << "Data point outlier at" << it->key << "of drawn range invalid." << "Plottable name:" << name(); +# endif + + if (isSelectedSegment && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + QCPScatterStyle finalOutlierStyle = mOutlierStyle; + if (isSelectedSegment && mSelectionDecorator) + finalOutlierStyle = mSelectionDecorator->getFinalScatterStyle(mOutlierStyle); + drawStatisticalBox(painter, it, finalOutlierStyle); + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPStatisticalBox::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + // draw filled rect: + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + painter->setBrush(mBrush); + QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67); + r.moveCenter(rect.center()); + painter->drawRect(r); +} + +/*! + Draws the graphical representation of a single statistical box with the data given by the + iterator \a it with the provided \a painter. + + If the statistical box has a set of outlier data points, they are drawn with \a outlierStyle. + + \see getQuartileBox, getWhiskerBackboneLines, getWhiskerBarLines +*/ +void QCPStatisticalBox::drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const +{ + // draw quartile box: + applyDefaultAntialiasingHint(painter); + const QRectF quartileBox = getQuartileBox(it); + painter->drawRect(quartileBox); + // draw median line with cliprect set to quartile box: + painter->save(); + painter->setClipRect(quartileBox, Qt::IntersectClip); + painter->setPen(mMedianPen); + painter->drawLine(QLineF(coordsToPixels(it->key-mWidth*0.5, it->median), coordsToPixels(it->key+mWidth*0.5, it->median))); + painter->restore(); + // draw whisker lines: + applyAntialiasingHint(painter, mWhiskerAntialiased, QCP::aePlottables); + painter->setPen(mWhiskerPen); + painter->drawLines(getWhiskerBackboneLines(it)); + painter->setPen(mWhiskerBarPen); + painter->drawLines(getWhiskerBarLines(it)); + // draw outliers: + applyScattersAntialiasingHint(painter); + outlierStyle.applyTo(painter, mPen); + for (int i=0; ioutliers.size(); ++i) + outlierStyle.drawShape(painter, coordsToPixels(it->key, it->outliers.at(i))); +} + +/*! \internal + + called by \ref draw to determine which data (key) range is visible at the current key axis range + setting, so only that needs to be processed. It also takes into account the bar width. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + lower may still be just outside the visible range. + + \a end returns an iterator one higher than the highest visible data point. Same as before, \a end + may also lie just outside of the visible range. + + if the plottable contains no data, both \a begin and \a end point to constEnd. +*/ +void QCPStatisticalBox::getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of box to include partially visible data points + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper+mWidth*0.5); // add half width of box to include partially visible data points +} + +/*! \internal + + Returns the box in plot coordinates (keys in x, values in y of the returned rect) that covers the + value range from the lower to the upper quartile, of the data given by \a it. + + \see drawStatisticalBox, getWhiskerBackboneLines, getWhiskerBarLines +*/ +QRectF QCPStatisticalBox::getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QRectF result; + result.setTopLeft(coordsToPixels(it->key-mWidth*0.5, it->upperQuartile)); + result.setBottomRight(coordsToPixels(it->key+mWidth*0.5, it->lowerQuartile)); + return result; +} + +/*! \internal + + Returns the whisker backbones (keys in x, values in y of the returned lines) that cover the value + range from the minimum to the lower quartile, and from the upper quartile to the maximum of the + data given by \a it. + + \see drawStatisticalBox, getQuartileBox, getWhiskerBarLines +*/ +QVector QCPStatisticalBox::getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QVector result(2); + result[0].setPoints(coordsToPixels(it->key, it->lowerQuartile), coordsToPixels(it->key, it->minimum)); // min backbone + result[1].setPoints(coordsToPixels(it->key, it->upperQuartile), coordsToPixels(it->key, it->maximum)); // max backbone + return result; +} + +/*! \internal + + Returns the whisker bars (keys in x, values in y of the returned lines) that are placed at the + end of the whisker backbones, at the minimum and maximum of the data given by \a it. + + \see drawStatisticalBox, getQuartileBox, getWhiskerBackboneLines +*/ +QVector QCPStatisticalBox::getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const +{ + QVector result(2); + result[0].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->minimum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->minimum)); // min bar + result[1].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->maximum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->maximum)); // max bar + return result; +} +/* end of 'src/plottables/plottable-statisticalbox.cpp' */ + + +/* including file 'src/plottables/plottable-colormap.cpp', size 47531 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPColorMapData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPColorMapData + \brief Holds the two-dimensional data of a QCPColorMap plottable. + + This class is a data storage for \ref QCPColorMap. It holds a two-dimensional array, which \ref + QCPColorMap then displays as a 2D image in the plot, where the array values are represented by a + color, depending on the value. + + The size of the array can be controlled via \ref setSize (or \ref setKeySize, \ref setValueSize). + Which plot coordinates these cells correspond to can be configured with \ref setRange (or \ref + setKeyRange, \ref setValueRange). + + The data cells can be accessed in two ways: They can be directly addressed by an integer index + with \ref setCell. This is the fastest method. Alternatively, they can be addressed by their plot + coordinate with \ref setData. plot coordinate to cell index transformations and vice versa are + provided by the functions \ref coordToCell and \ref cellToCoord. + + A \ref QCPColorMapData also holds an on-demand two-dimensional array of alpha values which (if + allocated) has the same size as the data map. It can be accessed via \ref setAlpha, \ref + fillAlpha and \ref clearAlpha. The memory for the alpha map is only allocated if needed, i.e. on + the first call of \ref setAlpha. \ref clearAlpha restores full opacity and frees the alpha map. + + This class also buffers the minimum and maximum values that are in the data set, to provide + QCPColorMap::rescaleDataRange with the necessary information quickly. Setting a cell to a value + that is greater than the current maximum increases this maximum to the new value. However, + setting the cell that currently holds the maximum value to a smaller value doesn't decrease the + maximum again, because finding the true new maximum would require going through the entire data + array, which might be time consuming. The same holds for the data minimum. This functionality is + given by \ref recalculateDataBounds, such that you can decide when it is sensible to find the + true current minimum and maximum. The method QCPColorMap::rescaleDataRange offers a convenience + parameter \a recalculateDataBounds which may be set to true to automatically call \ref + recalculateDataBounds internally. +*/ + +/* start of documentation of inline functions */ + +/*! \fn bool QCPColorMapData::isEmpty() const + + Returns whether this instance carries no data. This is equivalent to having a size where at least + one of the dimensions is 0 (see \ref setSize). +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a new QCPColorMapData instance. The instance has \a keySize cells in the key direction + and \a valueSize cells in the value direction. These cells will be displayed by the \ref QCPColorMap + at the coordinates \a keyRange and \a valueRange. + + \see setSize, setKeySize, setValueSize, setRange, setKeyRange, setValueRange +*/ +QCPColorMapData::QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange) : + mKeySize(0), + mValueSize(0), + mKeyRange(keyRange), + mValueRange(valueRange), + mIsEmpty(true), + mData(0), + mAlpha(0), + mDataModified(true) +{ + setSize(keySize, valueSize); + fill(0); +} + +QCPColorMapData::~QCPColorMapData() +{ + if (mData) + delete[] mData; + if (mAlpha) + delete[] mAlpha; +} + +/*! + Constructs a new QCPColorMapData instance copying the data and range of \a other. +*/ +QCPColorMapData::QCPColorMapData(const QCPColorMapData &other) : + mKeySize(0), + mValueSize(0), + mIsEmpty(true), + mData(0), + mAlpha(0), + mDataModified(true) +{ + *this = other; +} + +/*! + Overwrites this color map data instance with the data stored in \a other. The alpha map state is + transferred, too. +*/ +QCPColorMapData &QCPColorMapData::operator=(const QCPColorMapData &other) +{ + if (&other != this) + { + const int keySize = other.keySize(); + const int valueSize = other.valueSize(); + if (!other.mAlpha && mAlpha) + clearAlpha(); + setSize(keySize, valueSize); + if (other.mAlpha && !mAlpha) + createAlpha(false); + setRange(other.keyRange(), other.valueRange()); + if (!isEmpty()) + { + memcpy(mData, other.mData, sizeof(mData[0])*keySize*valueSize); + if (mAlpha) + memcpy(mAlpha, other.mAlpha, sizeof(mAlpha[0])*keySize*valueSize); + } + mDataBounds = other.mDataBounds; + mDataModified = true; + } + return *this; +} + +/* undocumented getter */ +double QCPColorMapData::data(double key, double value) +{ + int keyCell = (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5; + int valueCell = (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5; + if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) + return mData[valueCell*mKeySize + keyCell]; + else + return 0; +} + +/* undocumented getter */ +double QCPColorMapData::cell(int keyIndex, int valueIndex) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + return mData[valueIndex*mKeySize + keyIndex]; + else + return 0; +} + +/*! + Returns the alpha map value of the cell with the indices \a keyIndex and \a valueIndex. + + If this color map data doesn't have an alpha map (because \ref setAlpha was never called after + creation or after a call to \ref clearAlpha), returns 255, which corresponds to full opacity. + + \see setAlpha +*/ +unsigned char QCPColorMapData::alpha(int keyIndex, int valueIndex) +{ + if (mAlpha && keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + return mAlpha[valueIndex*mKeySize + keyIndex]; + else + return 255; +} + +/*! + Resizes the data array to have \a keySize cells in the key dimension and \a valueSize cells in + the value dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting at least one of \a keySize or \a valueSize to zero frees the internal data array and \ref + isEmpty returns true. + + \see setRange, setKeySize, setValueSize +*/ +void QCPColorMapData::setSize(int keySize, int valueSize) +{ + if (keySize != mKeySize || valueSize != mValueSize) + { + mKeySize = keySize; + mValueSize = valueSize; + if (mData) + delete[] mData; + mIsEmpty = mKeySize == 0 || mValueSize == 0; + if (!mIsEmpty) + { +#ifdef __EXCEPTIONS + try { // 2D arrays get memory intensive fast. So if the allocation fails, at least output debug message +#endif + mData = new double[mKeySize*mValueSize]; +#ifdef __EXCEPTIONS + } catch (...) { mData = 0; } +#endif + if (mData) + fill(0); + else + qDebug() << Q_FUNC_INFO << "out of memory for data dimensions "<< mKeySize << "*" << mValueSize; + } else + mData = 0; + + if (mAlpha) // if we had an alpha map, recreate it with new size + createAlpha(); + + mDataModified = true; + } +} + +/*! + Resizes the data array to have \a keySize cells in the key dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting \a keySize to zero frees the internal data array and \ref isEmpty returns true. + + \see setKeyRange, setSize, setValueSize +*/ +void QCPColorMapData::setKeySize(int keySize) +{ + setSize(keySize, mValueSize); +} + +/*! + Resizes the data array to have \a valueSize cells in the value dimension. + + The current data is discarded and the map cells are set to 0, unless the map had already the + requested size. + + Setting \a valueSize to zero frees the internal data array and \ref isEmpty returns true. + + \see setValueRange, setSize, setKeySize +*/ +void QCPColorMapData::setValueSize(int valueSize) +{ + setSize(mKeySize, valueSize); +} + +/*! + Sets the coordinate ranges the data shall be distributed over. This defines the rectangular area + covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will + be cells centered on the key coordinates 2, 2.5 and 3. + + \see setSize +*/ +void QCPColorMapData::setRange(const QCPRange &keyRange, const QCPRange &valueRange) +{ + setKeyRange(keyRange); + setValueRange(valueRange); +} + +/*! + Sets the coordinate range the data shall be distributed over in the key dimension. Together with + the value range, This defines the rectangular area covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the key size (\ref setKeySize) is 3 and \a keyRange is set to QCPRange(2, 3) there will + be cells centered on the key coordinates 2, 2.5 and 3. + + \see setRange, setValueRange, setSize +*/ +void QCPColorMapData::setKeyRange(const QCPRange &keyRange) +{ + mKeyRange = keyRange; +} + +/*! + Sets the coordinate range the data shall be distributed over in the value dimension. Together with + the key range, This defines the rectangular area covered by the color map in plot coordinates. + + The outer cells will be centered on the range boundaries given to this function. For example, if + the value size (\ref setValueSize) is 3 and \a valueRange is set to QCPRange(2, 3) there + will be cells centered on the value coordinates 2, 2.5 and 3. + + \see setRange, setKeyRange, setSize +*/ +void QCPColorMapData::setValueRange(const QCPRange &valueRange) +{ + mValueRange = valueRange; +} + +/*! + Sets the data of the cell, which lies at the plot coordinates given by \a key and \a value, to \a + z. + + \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or + value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes, + you shouldn't use the \ref QCPColorMapData::setData method as it uses a linear transformation to + determine the cell index. Rather directly access the cell index with \ref + QCPColorMapData::setCell. + + \see setCell, setRange +*/ +void QCPColorMapData::setData(double key, double value, double z) +{ + int keyCell = (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5; + int valueCell = (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5; + if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell < mValueSize) + { + mData[valueCell*mKeySize + keyCell] = z; + if (z < mDataBounds.lower) + mDataBounds.lower = z; + if (z > mDataBounds.upper) + mDataBounds.upper = z; + mDataModified = true; + } +} + +/*! + Sets the data of the cell with indices \a keyIndex and \a valueIndex to \a z. The indices + enumerate the cells starting from zero, up to the map's size-1 in the respective dimension (see + \ref setSize). + + In the standard plot configuration (horizontal key axis and vertical value axis, both not + range-reversed), the cell with indices (0, 0) is in the bottom left corner and the cell with + indices (keySize-1, valueSize-1) is in the top right corner of the color map. + + \see setData, setSize +*/ +void QCPColorMapData::setCell(int keyIndex, int valueIndex, double z) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + { + mData[valueIndex*mKeySize + keyIndex] = z; + if (z < mDataBounds.lower) + mDataBounds.lower = z; + if (z > mDataBounds.upper) + mDataBounds.upper = z; + mDataModified = true; + } else + qDebug() << Q_FUNC_INFO << "index out of bounds:" << keyIndex << valueIndex; +} + +/*! + Sets the alpha of the color map cell given by \a keyIndex and \a valueIndex to \a alpha. A value + of 0 for \a alpha results in a fully transparent cell, and a value of 255 results in a fully + opaque cell. + + If an alpha map doesn't exist yet for this color map data, it will be created here. If you wish + to restore full opacity and free any allocated memory of the alpha map, call \ref clearAlpha. + + Note that the cell-wise alpha which can be configured here is independent of any alpha configured + in the color map's gradient (\ref QCPColorGradient). If a cell is affected both by the cell-wise + and gradient alpha, the alpha values will be blended accordingly during rendering of the color + map. + + \see fillAlpha, clearAlpha +*/ +void QCPColorMapData::setAlpha(int keyIndex, int valueIndex, unsigned char alpha) +{ + if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex < mValueSize) + { + if (mAlpha || createAlpha()) + { + mAlpha[valueIndex*mKeySize + keyIndex] = alpha; + mDataModified = true; + } + } else + qDebug() << Q_FUNC_INFO << "index out of bounds:" << keyIndex << valueIndex; +} + +/*! + Goes through the data and updates the buffered minimum and maximum data values. + + Calling this method is only advised if you are about to call \ref QCPColorMap::rescaleDataRange + and can not guarantee that the cells holding the maximum or minimum data haven't been overwritten + with a smaller or larger value respectively, since the buffered maximum/minimum values have been + updated the last time. Why this is the case is explained in the class description (\ref + QCPColorMapData). + + Note that the method \ref QCPColorMap::rescaleDataRange provides a parameter \a + recalculateDataBounds for convenience. Setting this to true will call this method for you, before + doing the rescale. +*/ +void QCPColorMapData::recalculateDataBounds() +{ + if (mKeySize > 0 && mValueSize > 0) + { + double minHeight = mData[0]; + double maxHeight = mData[0]; + const int dataCount = mValueSize*mKeySize; + for (int i=0; i maxHeight) + maxHeight = mData[i]; + if (mData[i] < minHeight) + minHeight = mData[i]; + } + mDataBounds.lower = minHeight; + mDataBounds.upper = maxHeight; + } +} + +/*! + Frees the internal data memory. + + This is equivalent to calling \ref setSize "setSize(0, 0)". +*/ +void QCPColorMapData::clear() +{ + setSize(0, 0); +} + +/*! + Frees the internal alpha map. The color map will have full opacity again. +*/ +void QCPColorMapData::clearAlpha() +{ + if (mAlpha) + { + delete[] mAlpha; + mAlpha = 0; + mDataModified = true; + } +} + +/*! + Sets all cells to the value \a z. +*/ +void QCPColorMapData::fill(double z) +{ + const int dataCount = mValueSize*mKeySize; + for (int i=0; i(data); + return; + } + if (copy) + { + *mMapData = *data; + } else + { + delete mMapData; + mMapData = data; + } + mMapImageInvalidated = true; +} + +/*! + Sets the data range of this color map to \a dataRange. The data range defines which data values + are mapped to the color gradient. + + To make the data range span the full range of the data set, use \ref rescaleDataRange. + + \see QCPColorScale::setDataRange +*/ +void QCPColorMap::setDataRange(const QCPRange &dataRange) +{ + if (!QCPRange::validRange(dataRange)) return; + if (mDataRange.lower != dataRange.lower || mDataRange.upper != dataRange.upper) + { + if (mDataScaleType == QCPAxis::stLogarithmic) + mDataRange = dataRange.sanitizedForLogScale(); + else + mDataRange = dataRange.sanitizedForLinScale(); + mMapImageInvalidated = true; + emit dataRangeChanged(mDataRange); + } +} + +/*! + Sets whether the data is correlated with the color gradient linearly or logarithmically. + + \see QCPColorScale::setDataScaleType +*/ +void QCPColorMap::setDataScaleType(QCPAxis::ScaleType scaleType) +{ + if (mDataScaleType != scaleType) + { + mDataScaleType = scaleType; + mMapImageInvalidated = true; + emit dataScaleTypeChanged(mDataScaleType); + if (mDataScaleType == QCPAxis::stLogarithmic) + setDataRange(mDataRange.sanitizedForLogScale()); + } +} + +/*! + Sets the color gradient that is used to represent the data. For more details on how to create an + own gradient or use one of the preset gradients, see \ref QCPColorGradient. + + The colors defined by the gradient will be used to represent data values in the currently set + data range, see \ref setDataRange. Data points that are outside this data range will either be + colored uniformly with the respective gradient boundary color, or the gradient will repeat, + depending on \ref QCPColorGradient::setPeriodic. + + \see QCPColorScale::setGradient +*/ +void QCPColorMap::setGradient(const QCPColorGradient &gradient) +{ + if (mGradient != gradient) + { + mGradient = gradient; + mMapImageInvalidated = true; + emit gradientChanged(mGradient); + } +} + +/*! + Sets whether the color map image shall use bicubic interpolation when displaying the color map + shrinked or expanded, and not at a 1:1 pixel-to-data scale. + + \image html QCPColorMap-interpolate.png "A 10*10 color map, with interpolation and without interpolation enabled" +*/ +void QCPColorMap::setInterpolate(bool enabled) +{ + mInterpolate = enabled; + mMapImageInvalidated = true; // because oversampling factors might need to change +} + +/*! + Sets whether the outer most data rows and columns are clipped to the specified key and value + range (see \ref QCPColorMapData::setKeyRange, \ref QCPColorMapData::setValueRange). + + if \a enabled is set to false, the data points at the border of the color map are drawn with the + same width and height as all other data points. Since the data points are represented by + rectangles of one color centered on the data coordinate, this means that the shown color map + extends by half a data point over the specified key/value range in each direction. + + \image html QCPColorMap-tightboundary.png "A color map, with tight boundary enabled and disabled" +*/ +void QCPColorMap::setTightBoundary(bool enabled) +{ + mTightBoundary = enabled; +} + +/*! + Associates the color scale \a colorScale with this color map. + + This means that both the color scale and the color map synchronize their gradient, data range and + data scale type (\ref setGradient, \ref setDataRange, \ref setDataScaleType). Multiple color maps + can be associated with one single color scale. This causes the color maps to also synchronize + those properties, via the mutual color scale. + + This function causes the color map to adopt the current color gradient, data range and data scale + type of \a colorScale. After this call, you may change these properties at either the color map + or the color scale, and the setting will be applied to both. + + Pass 0 as \a colorScale to disconnect the color scale from this color map again. +*/ +void QCPColorMap::setColorScale(QCPColorScale *colorScale) +{ + if (mColorScale) // unconnect signals from old color scale + { + disconnect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); + disconnect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); + disconnect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); + disconnect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + disconnect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); + disconnect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } + mColorScale = colorScale; + if (mColorScale) // connect signals to new color scale + { + setGradient(mColorScale.data()->gradient()); + setDataRange(mColorScale.data()->dataRange()); + setDataScaleType(mColorScale.data()->dataScaleType()); + connect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange))); + connect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType))); + connect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient))); + connect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange))); + connect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient))); + connect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType))); + } +} + +/*! + Sets the data range (\ref setDataRange) to span the minimum and maximum values that occur in the + current data set. This corresponds to the \ref rescaleKeyAxis or \ref rescaleValueAxis methods, + only for the third data dimension of the color map. + + The minimum and maximum values of the data set are buffered in the internal QCPColorMapData + instance (\ref data). As data is updated via its \ref QCPColorMapData::setCell or \ref + QCPColorMapData::setData, the buffered minimum and maximum values are updated, too. For + performance reasons, however, they are only updated in an expanding fashion. So the buffered + maximum can only increase and the buffered minimum can only decrease. In consequence, changes to + the data that actually lower the maximum of the data set (by overwriting the cell holding the + current maximum with a smaller value), aren't recognized and the buffered maximum overestimates + the true maximum of the data set. The same happens for the buffered minimum. To recalculate the + true minimum and maximum by explicitly looking at each cell, the method + QCPColorMapData::recalculateDataBounds can be used. For convenience, setting the parameter \a + recalculateDataBounds calls this method before setting the data range to the buffered minimum and + maximum. + + \see setDataRange +*/ +void QCPColorMap::rescaleDataRange(bool recalculateDataBounds) +{ + if (recalculateDataBounds) + mMapData->recalculateDataBounds(); + setDataRange(mMapData->dataBounds()); +} + +/*! + Takes the current appearance of the color map and updates the legend icon, which is used to + represent this color map in the legend (see \ref QCPLegend). + + The \a transformMode specifies whether the rescaling is done by a faster, low quality image + scaling algorithm (Qt::FastTransformation) or by a slower, higher quality algorithm + (Qt::SmoothTransformation). + + The current color map appearance is scaled down to \a thumbSize. Ideally, this should be equal to + the size of the legend icon (see \ref QCPLegend::setIconSize). If it isn't exactly the configured + legend icon size, the thumb will be rescaled during drawing of the legend item. + + \see setDataRange +*/ +void QCPColorMap::updateLegendIcon(Qt::TransformationMode transformMode, const QSize &thumbSize) +{ + if (mMapImage.isNull() && !data()->isEmpty()) + updateMapImage(); // try to update map image if it's null (happens if no draw has happened yet) + + if (!mMapImage.isNull()) // might still be null, e.g. if data is empty, so check here again + { + bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); + bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); + mLegendIcon = QPixmap::fromImage(mMapImage.mirrored(mirrorX, mirrorY)).scaled(thumbSize, Qt::KeepAspectRatio, transformMode); + } +} + +/* inherits documentation from base class */ +double QCPColorMap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mMapData->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (mMapData->keyRange().contains(posKey) && mMapData->valueRange().contains(posValue)) + { + if (details) + details->setValue(QCPDataSelection(QCPDataRange(0, 1))); // temporary solution, to facilitate whole-plottable selection. Replace in future version with segmented 2D selection. + return mParentPlot->selectionTolerance()*0.99; + } + } + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPColorMap::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + foundRange = true; + QCPRange result = mMapData->keyRange(); + result.normalize(); + if (inSignDomain == QCP::sdPositive) + { + if (result.lower <= 0 && result.upper > 0) + result.lower = result.upper*1e-3; + else if (result.lower <= 0 && result.upper <= 0) + foundRange = false; + } else if (inSignDomain == QCP::sdNegative) + { + if (result.upper >= 0 && result.lower < 0) + result.upper = result.lower*1e-3; + else if (result.upper >= 0 && result.lower >= 0) + foundRange = false; + } + return result; +} + +/* inherits documentation from base class */ +QCPRange QCPColorMap::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + if (inKeyRange != QCPRange()) + { + if (mMapData->keyRange().upper < inKeyRange.lower || mMapData->keyRange().lower > inKeyRange.upper) + { + foundRange = false; + return QCPRange(); + } + } + + foundRange = true; + QCPRange result = mMapData->valueRange(); + result.normalize(); + if (inSignDomain == QCP::sdPositive) + { + if (result.lower <= 0 && result.upper > 0) + result.lower = result.upper*1e-3; + else if (result.lower <= 0 && result.upper <= 0) + foundRange = false; + } else if (inSignDomain == QCP::sdNegative) + { + if (result.upper >= 0 && result.lower < 0) + result.upper = result.lower*1e-3; + else if (result.upper >= 0 && result.lower >= 0) + foundRange = false; + } + return result; +} + +/*! \internal + + Updates the internal map image buffer by going through the internal \ref QCPColorMapData and + turning the data values into color pixels with \ref QCPColorGradient::colorize. + + This method is called by \ref QCPColorMap::draw if either the data has been modified or the map image + has been invalidated for a different reason (e.g. a change of the data range with \ref + setDataRange). + + If the map cell count is low, the image created will be oversampled in order to avoid a + QPainter::drawImage bug which makes inner pixel boundaries jitter when stretch-drawing images + without smooth transform enabled. Accordingly, oversampling isn't performed if \ref + setInterpolate is true. +*/ +void QCPColorMap::updateMapImage() +{ + QCPAxis *keyAxis = mKeyAxis.data(); + if (!keyAxis) return; + if (mMapData->isEmpty()) return; + + const QImage::Format format = QImage::Format_ARGB32_Premultiplied; + const int keySize = mMapData->keySize(); + const int valueSize = mMapData->valueSize(); + int keyOversamplingFactor = mInterpolate ? 1 : (int)(1.0+100.0/(double)keySize); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on + int valueOversamplingFactor = mInterpolate ? 1 : (int)(1.0+100.0/(double)valueSize); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on + + // resize mMapImage to correct dimensions including possible oversampling factors, according to key/value axes orientation: + if (keyAxis->orientation() == Qt::Horizontal && (mMapImage.width() != keySize*keyOversamplingFactor || mMapImage.height() != valueSize*valueOversamplingFactor)) + mMapImage = QImage(QSize(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor), format); + else if (keyAxis->orientation() == Qt::Vertical && (mMapImage.width() != valueSize*valueOversamplingFactor || mMapImage.height() != keySize*keyOversamplingFactor)) + mMapImage = QImage(QSize(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor), format); + + QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates. Either the final mMapImage, or if we need oversampling, mUndersampledMapImage + if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) + { + // resize undersampled map image to actual key/value cell sizes: + if (keyAxis->orientation() == Qt::Horizontal && (mUndersampledMapImage.width() != keySize || mUndersampledMapImage.height() != valueSize)) + mUndersampledMapImage = QImage(QSize(keySize, valueSize), format); + else if (keyAxis->orientation() == Qt::Vertical && (mUndersampledMapImage.width() != valueSize || mUndersampledMapImage.height() != keySize)) + mUndersampledMapImage = QImage(QSize(valueSize, keySize), format); + localMapImage = &mUndersampledMapImage; // make the colorization run on the undersampled image + } else if (!mUndersampledMapImage.isNull()) + mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size has changed) but mUndersampledMapImage still has nonzero size, free it + + const double *rawData = mMapData->mData; + const unsigned char *rawAlpha = mMapData->mAlpha; + if (keyAxis->orientation() == Qt::Horizontal) + { + const int lineCount = valueSize; + const int rowCount = keySize; + for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) + if (rawAlpha) + mGradient.colorize(rawData+line*rowCount, rawAlpha+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); + else + mGradient.colorize(rawData+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic); + } + } else // keyAxis->orientation() == Qt::Vertical + { + const int lineCount = keySize; + const int rowCount = valueSize; + for (int line=0; line(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system) + if (rawAlpha) + mGradient.colorize(rawData+line, rawAlpha+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); + else + mGradient.colorize(rawData+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic); + } + } + + if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) + { + if (keyAxis->orientation() == Qt::Horizontal) + mMapImage = mUndersampledMapImage.scaled(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); + else + mMapImage = mUndersampledMapImage.scaled(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation); + } + mMapData->mDataModified = false; + mMapImageInvalidated = false; +} + +/* inherits documentation from base class */ +void QCPColorMap::draw(QCPPainter *painter) +{ + if (mMapData->isEmpty()) return; + if (!mKeyAxis || !mValueAxis) return; + applyDefaultAntialiasingHint(painter); + + if (mMapData->mDataModified || mMapImageInvalidated) + updateMapImage(); + + // use buffer if painting vectorized (PDF): + const bool useBuffer = painter->modes().testFlag(QCPPainter::pmVectorized); + QCPPainter *localPainter = painter; // will be redirected to paint on mapBuffer if painting vectorized + QRectF mapBufferTarget; // the rect in absolute widget coordinates where the visible map portion/buffer will end up in + QPixmap mapBuffer; + if (useBuffer) + { + const double mapBufferPixelRatio = 3; // factor by which DPI is increased in embedded bitmaps + mapBufferTarget = painter->clipRegion().boundingRect(); + mapBuffer = QPixmap((mapBufferTarget.size()*mapBufferPixelRatio).toSize()); + mapBuffer.fill(Qt::transparent); + localPainter = new QCPPainter(&mapBuffer); + localPainter->scale(mapBufferPixelRatio, mapBufferPixelRatio); + localPainter->translate(-mapBufferTarget.topLeft()); + } + + QRectF imageRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), + coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); + // extend imageRect to contain outer halves/quarters of bordering/cornering pixels (cells are centered on map range boundary): + double halfCellWidth = 0; // in pixels + double halfCellHeight = 0; // in pixels + if (keyAxis()->orientation() == Qt::Horizontal) + { + if (mMapData->keySize() > 1) + halfCellWidth = 0.5*imageRect.width()/(double)(mMapData->keySize()-1); + if (mMapData->valueSize() > 1) + halfCellHeight = 0.5*imageRect.height()/(double)(mMapData->valueSize()-1); + } else // keyAxis orientation is Qt::Vertical + { + if (mMapData->keySize() > 1) + halfCellHeight = 0.5*imageRect.height()/(double)(mMapData->keySize()-1); + if (mMapData->valueSize() > 1) + halfCellWidth = 0.5*imageRect.width()/(double)(mMapData->valueSize()-1); + } + imageRect.adjust(-halfCellWidth, -halfCellHeight, halfCellWidth, halfCellHeight); + const bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed(); + const bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed(); + const bool smoothBackup = localPainter->renderHints().testFlag(QPainter::SmoothPixmapTransform); + localPainter->setRenderHint(QPainter::SmoothPixmapTransform, mInterpolate); + QRegion clipBackup; + if (mTightBoundary) + { + clipBackup = localPainter->clipRegion(); + QRectF tightClipRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower), + coordsToPixels(mMapData->keyRange().upper, mMapData->valueRange().upper)).normalized(); + localPainter->setClipRect(tightClipRect, Qt::IntersectClip); + } + localPainter->drawImage(imageRect, mMapImage.mirrored(mirrorX, mirrorY)); + if (mTightBoundary) + localPainter->setClipRegion(clipBackup); + localPainter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup); + + if (useBuffer) // localPainter painted to mapBuffer, so now draw buffer with original painter + { + delete localPainter; + painter->drawPixmap(mapBufferTarget.toRect(), mapBuffer); + } +} + +/* inherits documentation from base class */ +void QCPColorMap::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + applyDefaultAntialiasingHint(painter); + // draw map thumbnail: + if (!mLegendIcon.isNull()) + { + QPixmap scaledIcon = mLegendIcon.scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::FastTransformation); + QRectF iconRect = QRectF(0, 0, scaledIcon.width(), scaledIcon.height()); + iconRect.moveCenter(rect.center()); + painter->drawPixmap(iconRect.topLeft(), scaledIcon); + } + /* + // draw frame: + painter->setBrush(Qt::NoBrush); + painter->setPen(Qt::black); + painter->drawRect(rect.adjusted(1, 1, 0, 0)); + */ +} +/* end of 'src/plottables/plottable-colormap.cpp' */ + + +/* including file 'src/plottables/plottable-financial.cpp', size 42610 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPFinancialData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPFinancialData + \brief Holds the data of one single data point for QCPFinancial. + + The stored data is: + \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey) + \li \a open: The opening value at the data point (this is the \a mainValue) + \li \a high: The high/maximum value at the data point + \li \a low: The low/minimum value at the data point + \li \a close: The closing value at the data point + + The container for storing multiple data points is \ref QCPFinancialDataContainer. It is a typedef + for \ref QCPDataContainer with \ref QCPFinancialData as the DataType template parameter. See the + documentation there for an explanation regarding the data type's generic methods. + + \see QCPFinancialDataContainer +*/ + +/* start documentation of inline functions */ + +/*! \fn double QCPFinancialData::sortKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static QCPFinancialData QCPFinancialData::fromSortKey(double sortKey) + + Returns a data point with the specified \a sortKey. All other members are set to zero. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn static static bool QCPFinancialData::sortKeyIsMainKey() + + Since the member \a key is both the data point key coordinate and the data ordering parameter, + this method returns true. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPFinancialData::mainKey() const + + Returns the \a key member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn double QCPFinancialData::mainValue() const + + Returns the \a open member of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/*! \fn QCPRange QCPFinancialData::valueRange() const + + Returns a QCPRange spanning from the \a low to the \a high value of this data point. + + For a general explanation of what this method is good for in the context of the data container, + see the documentation of \ref QCPDataContainer. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a data point with key and all values set to zero. +*/ +QCPFinancialData::QCPFinancialData() : + key(0), + open(0), + high(0), + low(0), + close(0) +{ +} + +/*! + Constructs a data point with the specified \a key and OHLC values. +*/ +QCPFinancialData::QCPFinancialData(double key, double open, double high, double low, double close) : + key(key), + open(open), + high(high), + low(low), + close(close) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPFinancial +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPFinancial + \brief A plottable representing a financial stock chart + + \image html QCPFinancial.png + + This plottable represents time series data binned to certain intervals, mainly used for stock + charts. The two common representations OHLC (Open-High-Low-Close) bars and Candlesticks can be + set via \ref setChartStyle. + + The data is passed via \ref setData as a set of open/high/low/close values at certain keys + (typically times). This means the data must be already binned appropriately. If data is only + available as a series of values (e.g. \a price against \a time), you can use the static + convenience function \ref timeSeriesToOhlc to generate binned OHLC-data which can then be passed + to \ref setData. + + The width of the OHLC bars/candlesticks can be controlled with \ref setWidth and \ref + setWidthType. A typical choice is to set the width type to \ref wtPlotCoords (the default) and + the width to (or slightly less than) one time bin interval width. + + \section qcpfinancial-appearance Changing the appearance + + Charts can be either single- or two-colored (\ref setTwoColored). If set to be single-colored, + lines are drawn with the plottable's pen (\ref setPen) and fills with the brush (\ref setBrush). + + If set to two-colored, positive changes of the value during an interval (\a close >= \a open) are + represented with a different pen and brush than negative changes (\a close < \a open). These can + be configured with \ref setPenPositive, \ref setPenNegative, \ref setBrushPositive, and \ref + setBrushNegative. In two-colored mode, the normal plottable pen/brush is ignored. Upon selection + however, the normal selected pen/brush (provided by the \ref selectionDecorator) is used, + irrespective of whether the chart is single- or two-colored. + + \section qcpfinancial-usage Usage + + Like all data representing objects in QCustomPlot, the QCPFinancial is a plottable + (QCPAbstractPlottable). So the plottable-interface of QCustomPlot applies + (QCustomPlot::plottable, QCustomPlot::removePlottable, etc.) + + Usually, you first create an instance: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-creation-1 + which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot + instance takes ownership of the plottable, so do not delete it manually but use + QCustomPlot::removePlottable() instead. The newly created plottable can be modified, e.g.: + + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-creation-2 + Here we have used the static helper method \ref timeSeriesToOhlc, to turn a time-price data + series into a 24-hour binned open-high-low-close data series as QCPFinancial uses. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QCPFinancialDataContainer *QCPFinancial::data() const + + Returns a pointer to the internal data storage of type \ref QCPFinancialDataContainer. You may + use it to directly manipulate the data, which may be more convenient and faster than using the + regular \ref setData or \ref addData methods, in certain situations. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs a financial chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + The created QCPFinancial is automatically registered with the QCustomPlot instance inferred from \a + keyAxis. This QCustomPlot instance takes ownership of the QCPFinancial, so do not delete it manually + but use QCustomPlot::removePlottable() instead. +*/ +QCPFinancial::QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable1D(keyAxis, valueAxis), + mChartStyle(csCandlestick), + mWidth(0.5), + mWidthType(wtPlotCoords), + mTwoColored(true), + mBrushPositive(QBrush(QColor(50, 160, 0))), + mBrushNegative(QBrush(QColor(180, 0, 15))), + mPenPositive(QPen(QColor(40, 150, 0))), + mPenNegative(QPen(QColor(170, 5, 5))) +{ + mSelectionDecorator->setBrush(QBrush(QColor(160, 160, 255))); +} + +QCPFinancial::~QCPFinancial() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple QCPFinancials may share the same data container safely. + Modifying the data in the container will then affect all financials that share the container. + Sharing can be achieved by simply exchanging the data containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, rather use + the \ref QCPDataContainer::set method on the financial's data container directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcpfinancial-datasharing-2 + + \see addData, timeSeriesToOhlc +*/ +void QCPFinancial::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Replaces the current data with the provided points in \a keys, \a open, \a high, \a low and \a + close. The provided vectors should have equal length. Else, the number of added points will be + the size of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + \see addData, timeSeriesToOhlc +*/ +void QCPFinancial::setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) +{ + mDataContainer->clear(); + addData(keys, open, high, low, close, alreadySorted); +} + +/*! + Sets which representation style shall be used to display the OHLC data. +*/ +void QCPFinancial::setChartStyle(QCPFinancial::ChartStyle style) +{ + mChartStyle = style; +} + +/*! + Sets the width of the individual bars/candlesticks to \a width in plot key coordinates. + + A typical choice is to set it to (or slightly less than) one bin interval width. +*/ +void QCPFinancial::setWidth(double width) +{ + mWidth = width; +} + +/*! + Sets how the width of the financial bars is defined. See the documentation of \ref WidthType for + an explanation of the possible values for \a widthType. + + The default value is \ref wtPlotCoords. + + \see setWidth +*/ +void QCPFinancial::setWidthType(QCPFinancial::WidthType widthType) +{ + mWidthType = widthType; +} + +/*! + Sets whether this chart shall contrast positive from negative trends per data point by using two + separate colors to draw the respective bars/candlesticks. + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenPositive, setPenNegative, setBrushPositive, setBrushNegative +*/ +void QCPFinancial::setTwoColored(bool twoColored) +{ + mTwoColored = twoColored; +} + +/*! + If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills + of data points with a positive trend (i.e. bars/candlesticks with close >= open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setBrushNegative, setPenPositive, setPenNegative +*/ +void QCPFinancial::setBrushPositive(const QBrush &brush) +{ + mBrushPositive = brush; +} + +/*! + If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills + of data points with a negative trend (i.e. bars/candlesticks with close < open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setBrushPositive, setPenNegative, setPenPositive +*/ +void QCPFinancial::setBrushNegative(const QBrush &brush) +{ + mBrushNegative = brush; +} + +/*! + If \ref setTwoColored is set to true, this function controls the pen that is used to draw + outlines of data points with a positive trend (i.e. bars/candlesticks with close >= open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenNegative, setBrushPositive, setBrushNegative +*/ +void QCPFinancial::setPenPositive(const QPen &pen) +{ + mPenPositive = pen; +} + +/*! + If \ref setTwoColored is set to true, this function controls the pen that is used to draw + outlines of data points with a negative trend (i.e. bars/candlesticks with close < open). + + If \a twoColored is false, the normal plottable's pen and brush are used (\ref setPen, \ref + setBrush). + + \see setPenPositive, setBrushNegative, setBrushPositive +*/ +void QCPFinancial::setPenNegative(const QPen &pen) +{ + mPenNegative = pen; +} + +/*! \overload + + Adds the provided points in \a keys, \a open, \a high, \a low and \a close to the current data. + The provided vectors should have equal length. Else, the number of added points will be the size + of the smallest vector. + + If you can guarantee that the passed data points are sorted by \a keys in ascending order, you + can set \a alreadySorted to true, to improve performance by saving a sorting run. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. + + \see timeSeriesToOhlc +*/ +void QCPFinancial::addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted) +{ + if (keys.size() != open.size() || open.size() != high.size() || high.size() != low.size() || low.size() != close.size() || close.size() != keys.size()) + qDebug() << Q_FUNC_INFO << "keys, open, high, low, close have different sizes:" << keys.size() << open.size() << high.size() << low.size() << close.size(); + const int n = qMin(keys.size(), qMin(open.size(), qMin(high.size(), qMin(low.size(), close.size())))); + QVector tempData(n); + QVector::iterator it = tempData.begin(); + const QVector::iterator itEnd = tempData.end(); + int i = 0; + while (it != itEnd) + { + it->key = keys[i]; + it->open = open[i]; + it->high = high[i]; + it->low = low[i]; + it->close = close[i]; + ++it; + ++i; + } + mDataContainer->add(tempData, alreadySorted); // don't modify tempData beyond this to prevent copy on write +} + +/*! \overload + + Adds the provided data point as \a key, \a open, \a high, \a low and \a close to the current + data. + + Alternatively, you can also access and modify the data directly via the \ref data method, which + returns a pointer to the internal data container. + + \see timeSeriesToOhlc +*/ +void QCPFinancial::addData(double key, double open, double high, double low, double close) +{ + mDataContainer->add(QCPFinancialData(key, open, high, low, close)); +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPFinancial::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + for (QCPFinancialDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + if (rect.intersects(selectionHitBox(it))) + result.addDataRange(QCPDataRange(it-mDataContainer->constBegin(), it-mDataContainer->constBegin()+1), false); + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +double QCPFinancial::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + // get visible data range: + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + QCPFinancialDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + getVisibleDataBounds(visibleBegin, visibleEnd); + // perform select test according to configured style: + double result = -1; + switch (mChartStyle) + { + case QCPFinancial::csOhlc: + result = ohlcSelectTest(pos, visibleBegin, visibleEnd, closestDataPoint); break; + case QCPFinancial::csCandlestick: + result = candlestickSelectTest(pos, visibleBegin, visibleEnd, closestDataPoint); break; + } + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } + + return -1; +} + +/* inherits documentation from base class */ +QCPRange QCPFinancial::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + QCPRange range = mDataContainer->keyRange(foundRange, inSignDomain); + // determine exact range by including width of bars/flags: + if (foundRange) + { + if (inSignDomain != QCP::sdPositive || range.lower-mWidth*0.5 > 0) + range.lower -= mWidth*0.5; + if (inSignDomain != QCP::sdNegative || range.upper+mWidth*0.5 < 0) + range.upper += mWidth*0.5; + } + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPFinancial::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange); +} + +/*! + A convenience function that converts time series data (\a value against \a time) to OHLC binned + data points. The return value can then be passed on to \ref QCPFinancialDataContainer::set(const + QCPFinancialDataContainer&). + + The size of the bins can be controlled with \a timeBinSize in the same units as \a time is given. + For example, if the unit of \a time is seconds and single OHLC/Candlesticks should span an hour + each, set \a timeBinSize to 3600. + + \a timeBinOffset allows to control precisely at what \a time coordinate a bin should start. The + value passed as \a timeBinOffset doesn't need to be in the range encompassed by the \a time keys. + It merely defines the mathematical offset/phase of the bins that will be used to process the + data. +*/ +QCPFinancialDataContainer QCPFinancial::timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset) +{ + QCPFinancialDataContainer data; + int count = qMin(time.size(), value.size()); + if (count == 0) + return QCPFinancialDataContainer(); + + QCPFinancialData currentBinData(0, value.first(), value.first(), value.first(), value.first()); + int currentBinIndex = qFloor((time.first()-timeBinOffset)/timeBinSize+0.5); + for (int i=0; i currentBinData.high) currentBinData.high = value.at(i); + if (i == count-1) // last data point is in current bin, finalize bin: + { + currentBinData.close = value.at(i); + currentBinData.key = timeBinOffset+(index)*timeBinSize; + data.add(currentBinData); + } + } else // data point not anymore in current bin, set close of old and open of new bin, and add old to map: + { + // finalize current bin: + currentBinData.close = value.at(i-1); + currentBinData.key = timeBinOffset+(index-1)*timeBinSize; + data.add(currentBinData); + // start next bin: + currentBinIndex = index; + currentBinData.open = value.at(i); + currentBinData.high = value.at(i); + currentBinData.low = value.at(i); + } + } + + return data; +} + +/* inherits documentation from base class */ +void QCPFinancial::draw(QCPPainter *painter) +{ + // get visible data range: + QCPFinancialDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd); + + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + for (int i=0; i= unselectedSegments.size(); + QCPFinancialDataContainer::const_iterator begin = visibleBegin; + QCPFinancialDataContainer::const_iterator end = visibleEnd; + mDataContainer->limitIteratorsToDataRange(begin, end, allSegments.at(i)); + if (begin == end) + continue; + + // draw data segment according to configured style: + switch (mChartStyle) + { + case QCPFinancial::csOhlc: + drawOhlcPlot(painter, begin, end, isSelectedSegment); break; + case QCPFinancial::csCandlestick: + drawCandlestickPlot(painter, begin, end, isSelectedSegment); break; + } + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPFinancial::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + painter->setAntialiasing(false); // legend icon especially of csCandlestick looks better without antialiasing + if (mChartStyle == csOhlc) + { + if (mTwoColored) + { + // draw upper left half icon with positive color: + painter->setBrush(mBrushPositive); + painter->setPen(mPenPositive); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + // draw bottom right half icon with negative color: + painter->setBrush(mBrushNegative); + painter->setPen(mPenNegative); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft())); + } + } else if (mChartStyle == csCandlestick) + { + if (mTwoColored) + { + // draw upper left half icon with positive color: + painter->setBrush(mBrushPositive); + painter->setPen(mPenPositive); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + // draw bottom right half icon with negative color: + painter->setBrush(mBrushNegative); + painter->setPen(mPenNegative); + painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint())); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + } else + { + painter->setBrush(mBrush); + painter->setPen(mPen); + painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft())); + painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft())); + painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft())); + } + } +} + +/*! \internal + + Draws the data from \a begin to \a end-1 as OHLC bars with the provided \a painter. + + This method is a helper function for \ref draw. It is used when the chart style is \ref csOhlc. +*/ +void QCPFinancial::drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected) +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else if (mTwoColored) + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + else + painter->setPen(mPen); + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw backbone: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(it->low))); + // draw open: + double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides + painter->drawLine(QPointF(keyPixel-pixelWidth, openPixel), QPointF(keyPixel, openPixel)); + // draw close: + painter->drawLine(QPointF(keyPixel, closePixel), QPointF(keyPixel+pixelWidth, closePixel)); + } + } else + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else if (mTwoColored) + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + else + painter->setPen(mPen); + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw backbone: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(it->low), keyPixel)); + // draw open: + double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides + painter->drawLine(QPointF(openPixel, keyPixel-pixelWidth), QPointF(openPixel, keyPixel)); + // draw close: + painter->drawLine(QPointF(closePixel, keyPixel), QPointF(closePixel, keyPixel+pixelWidth)); + } + } +} + +/*! \internal + + Draws the data from \a begin to \a end-1 as Candlesticks with the provided \a painter. + + This method is a helper function for \ref draw. It is used when the chart style is \ref csCandlestick. +*/ +void QCPFinancial::drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected) +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else if (mTwoColored) + { + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + painter->setBrush(it->close >= it->open ? mBrushPositive : mBrushNegative); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw high: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close)))); + // draw low: + painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->low)), QPointF(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close)))); + // draw open-close box: + double pixelWidth = getPixelWidth(it->key, keyPixel); + painter->drawRect(QRectF(QPointF(keyPixel-pixelWidth, closePixel), QPointF(keyPixel+pixelWidth, openPixel))); + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it = begin; it != end; ++it) + { + if (isSelected && mSelectionDecorator) + { + mSelectionDecorator->applyPen(painter); + mSelectionDecorator->applyBrush(painter); + } else if (mTwoColored) + { + painter->setPen(it->close >= it->open ? mPenPositive : mPenNegative); + painter->setBrush(it->close >= it->open ? mBrushPositive : mBrushNegative); + } else + { + painter->setPen(mPen); + painter->setBrush(mBrush); + } + double keyPixel = keyAxis->coordToPixel(it->key); + double openPixel = valueAxis->coordToPixel(it->open); + double closePixel = valueAxis->coordToPixel(it->close); + // draw high: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel)); + // draw low: + painter->drawLine(QPointF(valueAxis->coordToPixel(it->low), keyPixel), QPointF(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel)); + // draw open-close box: + double pixelWidth = getPixelWidth(it->key, keyPixel); + painter->drawRect(QRectF(QPointF(closePixel, keyPixel-pixelWidth), QPointF(openPixel, keyPixel+pixelWidth))); + } + } +} + +/*! \internal + + This function is used to determine the width of the bar at coordinate \a key, according to the + specified width (\ref setWidth) and width type (\ref setWidthType). Provide the pixel position of + \a key in \a keyPixel (because usually this was already calculated via \ref QCPAxis::coordToPixel + when this function is called). + + It returns the number of pixels the bar extends to higher keys, relative to the \a key + coordinate. So with a non-reversed horizontal axis, the return value is positive. With a reversed + horizontal axis, the return value is negative. This is important so the open/close flags on the + \ref csOhlc bar are drawn to the correct side. +*/ +double QCPFinancial::getPixelWidth(double key, double keyPixel) const +{ + double result = 0; + switch (mWidthType) + { + case wtAbsolute: + { + if (mKeyAxis) + result = mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + break; + } + case wtAxisRectRatio: + { + if (mKeyAxis && mKeyAxis.data()->axisRect()) + { + if (mKeyAxis.data()->orientation() == Qt::Horizontal) + result = mKeyAxis.data()->axisRect()->width()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + else + result = mKeyAxis.data()->axisRect()->height()*mWidth*0.5*mKeyAxis.data()->pixelOrientation(); + } else + qDebug() << Q_FUNC_INFO << "No key axis or axis rect defined"; + break; + } + case wtPlotCoords: + { + if (mKeyAxis) + result = mKeyAxis.data()->coordToPixel(key+mWidth*0.5)-keyPixel; + else + qDebug() << Q_FUNC_INFO << "No key axis defined"; + break; + } + } + return result; +} + +/*! \internal + + This method is a helper function for \ref selectTest. It is used to test for selection when the + chart style is \ref csOhlc. It only tests against the data points between \a begin and \a end. + + Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical + representation of the plottable, and \a closestDataPoint will point to the respective data point. +*/ +double QCPFinancial::ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const +{ + closestDataPoint = mDataContainer->constEnd(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + double minDistSqr = std::numeric_limits::max(); + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double keyPixel = keyAxis->coordToPixel(it->key); + // calculate distance to backbone: + double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low))); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double keyPixel = keyAxis->coordToPixel(it->key); + // calculate distance to backbone: + double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel)); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } + return qSqrt(minDistSqr); +} + +/*! \internal + + This method is a helper function for \ref selectTest. It is used to test for selection when the + chart style is \ref csCandlestick. It only tests against the data points between \a begin and \a + end. + + Like \ref selectTest, this method returns the shortest distance of \a pos to the graphical + representation of the plottable, and \a closestDataPoint will point to the respective data point. +*/ +double QCPFinancial::candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const +{ + closestDataPoint = mDataContainer->constEnd(); + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; } + + double minDistSqr = std::numeric_limits::max(); + if (keyAxis->orientation() == Qt::Horizontal) + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double currentDistSqr; + // determine whether pos is in open-close-box: + QCPRange boxKeyRange(it->key-mWidth*0.5, it->key+mWidth*0.5); + QCPRange boxValueRange(it->close, it->open); + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box + { + currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + } else + { + // calculate distance to high/low lines: + double keyPixel = keyAxis->coordToPixel(it->key); + double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close)))); + double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close)))); + currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); + } + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } else // keyAxis->orientation() == Qt::Vertical + { + for (QCPFinancialDataContainer::const_iterator it=begin; it!=end; ++it) + { + double currentDistSqr; + // determine whether pos is in open-close-box: + QCPRange boxKeyRange(it->key-mWidth*0.5, it->key+mWidth*0.5); + QCPRange boxValueRange(it->close, it->open); + double posKey, posValue; + pixelsToCoords(pos, posKey, posValue); + if (boxKeyRange.contains(posKey) && boxValueRange.contains(posValue)) // is in open-close-box + { + currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99; + } else + { + // calculate distance to high/low lines: + double keyPixel = keyAxis->coordToPixel(it->key); + double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel)); + double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel)); + currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr); + } + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + closestDataPoint = it; + } + } + } + return qSqrt(minDistSqr); +} + +/*! \internal + + called by the drawing methods to determine which data (key) range is visible at the current key + axis range setting, so only that needs to be processed. + + \a begin returns an iterator to the lowest data point that needs to be taken into account when + plotting. Note that in order to get a clean plot all the way to the edge of the axis rect, \a + begin may still be just outside the visible range. + + \a end returns the iterator just above the highest data point that needs to be taken into + account. Same as before, \a end may also lie just outside of the visible range + + if the plottable contains no data, both \a begin and \a end point to \c constEnd. +*/ +void QCPFinancial::getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const +{ + if (!mKeyAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key axis"; + begin = mDataContainer->constEnd(); + end = mDataContainer->constEnd(); + return; + } + begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of ohlc/candlestick to include partially visible data points + end = mDataContainer->findEnd(mKeyAxis.data()->range().upper+mWidth*0.5); // add half width of ohlc/candlestick to include partially visible data points +} + +/*! \internal + + Returns the hit box in pixel coordinates that will be used for data selection with the selection + rect (\ref selectTestRect), of the data point given by \a it. +*/ +QRectF QCPFinancial::selectionHitBox(QCPFinancialDataContainer::const_iterator it) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QRectF(); } + + double keyPixel = keyAxis->coordToPixel(it->key); + double highPixel = valueAxis->coordToPixel(it->high); + double lowPixel = valueAxis->coordToPixel(it->low); + double keyWidthPixels = keyPixel-keyAxis->coordToPixel(it->key-mWidth*0.5); + if (keyAxis->orientation() == Qt::Horizontal) + return QRectF(keyPixel-keyWidthPixels, highPixel, keyWidthPixels*2, lowPixel-highPixel).normalized(); + else + return QRectF(highPixel, keyPixel-keyWidthPixels, lowPixel-highPixel, keyWidthPixels*2).normalized(); +} +/* end of 'src/plottables/plottable-financial.cpp' */ + + +/* including file 'src/plottables/plottable-errorbar.cpp', size 37210 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPErrorBarsData +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPErrorBarsData + \brief Holds the data of one single error bar for QCPErrorBars. + + The stored data is: + \li \a errorMinus: how much the error bar extends towards negative coordinates from the data + point position + \li \a errorPlus: how much the error bar extends towards positive coordinates from the data point + position + + The container for storing the error bar information is \ref QCPErrorBarsDataContainer. It is a + typedef for QVector<\ref QCPErrorBarsData>. + + \see QCPErrorBarsDataContainer +*/ + +/*! + Constructs an error bar with errors set to zero. +*/ +QCPErrorBarsData::QCPErrorBarsData() : + errorMinus(0), + errorPlus(0) +{ +} + +/*! + Constructs an error bar with equal \a error in both negative and positive direction. +*/ +QCPErrorBarsData::QCPErrorBarsData(double error) : + errorMinus(error), + errorPlus(error) +{ +} + +/*! + Constructs an error bar with negative and positive errors set to \a errorMinus and \a errorPlus, + respectively. +*/ +QCPErrorBarsData::QCPErrorBarsData(double errorMinus, double errorPlus) : + errorMinus(errorMinus), + errorPlus(errorPlus) +{ +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPErrorBars +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPErrorBars + \brief A plottable that adds a set of error bars to other plottables. + + \image html QCPErrorBars.png + + The \ref QCPErrorBars plottable can be attached to other one-dimensional plottables (e.g. \ref + QCPGraph, \ref QCPCurve, \ref QCPBars, etc.) and equips them with error bars. + + Use \ref setDataPlottable to define for which plottable the \ref QCPErrorBars shall display the + error bars. The orientation of the error bars can be controlled with \ref setErrorType. + + By using \ref setData, you can supply the actual error data, either as symmetric error or + plus/minus asymmetric errors. \ref QCPErrorBars only stores the error data. The absolute + key/value position of each error bar will be adopted from the configured data plottable. The + error data of the \ref QCPErrorBars are associated one-to-one via their index to the data points + of the data plottable. You can directly access and manipulate the error bar data via \ref data. + + Set either of the plus/minus errors to NaN (qQNaN() or + std::numeric_limits::quiet_NaN()) to not show the respective error bar on the data point at + that index. + + \section qcperrorbars-appearance Changing the appearance + + The appearance of the error bars is defined by the pen (\ref setPen), and the width of the + whiskers (\ref setWhiskerWidth). Further, the error bar backbones may leave a gap around the data + point center to prevent that error bars are drawn too close to or even through scatter points. + This gap size can be controlled via \ref setSymbolGap. +*/ + +/* start of documentation of inline functions */ + +/*! \fn QSharedPointer QCPErrorBars::data() const + + Returns a shared pointer to the internal data storage of type \ref QCPErrorBarsDataContainer. You + may use it to directly manipulate the error values, which may be more convenient and faster than + using the regular \ref setData methods. +*/ + +/* end of documentation of inline functions */ + +/*! + Constructs an error bars plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value + axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have + the same orientation. If either of these restrictions is violated, a corresponding message is + printed to the debug output (qDebug), the construction is not aborted, though. + + It is also important that the \a keyAxis and \a valueAxis are the same for the error bars + plottable and the data plottable that the error bars shall be drawn on (\ref setDataPlottable). + + The created \ref QCPErrorBars is automatically registered with the QCustomPlot instance inferred + from \a keyAxis. This QCustomPlot instance takes ownership of the \ref QCPErrorBars, so do not + delete it manually but use \ref QCustomPlot::removePlottable() instead. +*/ +QCPErrorBars::QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mDataContainer(new QVector), + mErrorType(etValueError), + mWhiskerWidth(9), + mSymbolGap(10) +{ + setPen(QPen(Qt::black, 0)); + setBrush(Qt::NoBrush); +} + +QCPErrorBars::~QCPErrorBars() +{ +} + +/*! \overload + + Replaces the current data container with the provided \a data container. + + Since a QSharedPointer is used, multiple \ref QCPErrorBars instances may share the same data + container safely. Modifying the data in the container will then affect all \ref QCPErrorBars + instances that share the container. Sharing can be achieved by simply exchanging the data + containers wrapped in shared pointers: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcperrorbars-datasharing-1 + + If you do not wish to share containers, but create a copy from an existing container, assign the + data containers directly: + \snippet documentation/doc-code-snippets/mainwindow.cpp qcperrorbars-datasharing-2 + (This uses different notation compared with other plottables, because the \ref QCPErrorBars + uses a \c QVector as its data container, instead of a \ref QCPDataContainer.) + + \see addData +*/ +void QCPErrorBars::setData(QSharedPointer data) +{ + mDataContainer = data; +} + +/*! \overload + + Sets symmetrical error values as specified in \a error. The errors will be associated one-to-one + by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see addData +*/ +void QCPErrorBars::setData(const QVector &error) +{ + mDataContainer->clear(); + addData(error); +} + +/*! \overload + + Sets asymmetrical errors as specified in \a errorMinus and \a errorPlus. The errors will be + associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see addData +*/ +void QCPErrorBars::setData(const QVector &errorMinus, const QVector &errorPlus) +{ + mDataContainer->clear(); + addData(errorMinus, errorPlus); +} + +/*! + Sets the data plottable to which the error bars will be applied. The error values specified e.g. + via \ref setData will be associated one-to-one by the data point index to the data points of \a + plottable. This means that the error bars will adopt the key/value coordinates of the data point + with the same index. + + The passed \a plottable must be a one-dimensional plottable, i.e. it must implement the \ref + QCPPlottableInterface1D. Further, it must not be a \ref QCPErrorBars instance itself. If either + of these restrictions is violated, a corresponding qDebug output is generated, and the data + plottable of this \ref QCPErrorBars instance is set to zero. + + For proper display, care must also be taken that the key and value axes of the \a plottable match + those configured for this \ref QCPErrorBars instance. +*/ +void QCPErrorBars::setDataPlottable(QCPAbstractPlottable *plottable) +{ + if (plottable && qobject_cast(plottable)) + { + mDataPlottable = 0; + qDebug() << Q_FUNC_INFO << "can't set another QCPErrorBars instance as data plottable"; + return; + } + if (plottable && !plottable->interface1D()) + { + mDataPlottable = 0; + qDebug() << Q_FUNC_INFO << "passed plottable doesn't implement 1d interface, can't associate with QCPErrorBars"; + return; + } + + mDataPlottable = plottable; +} + +/*! + Sets in which orientation the error bars shall appear on the data points. If your data needs both + error dimensions, create two \ref QCPErrorBars with different \a type. +*/ +void QCPErrorBars::setErrorType(ErrorType type) +{ + mErrorType = type; +} + +/*! + Sets the width of the whiskers (the short bars at the end of the actual error bar backbones) to + \a pixels. +*/ +void QCPErrorBars::setWhiskerWidth(double pixels) +{ + mWhiskerWidth = pixels; +} + +/*! + Sets the gap diameter around the data points that will be left out when drawing the error bar + backbones. This gap prevents that error bars are drawn too close to or even through scatter + points. +*/ +void QCPErrorBars::setSymbolGap(double pixels) +{ + mSymbolGap = pixels; +} + +/*! \overload + + Adds symmetrical error values as specified in \a error. The errors will be associated one-to-one + by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(const QVector &error) +{ + addData(error, error); +} + +/*! \overload + + Adds asymmetrical errors as specified in \a errorMinus and \a errorPlus. The errors will be + associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(const QVector &errorMinus, const QVector &errorPlus) +{ + if (errorMinus.size() != errorPlus.size()) + qDebug() << Q_FUNC_INFO << "minus and plus error vectors have different sizes:" << errorMinus.size() << errorPlus.size(); + const int n = qMin(errorMinus.size(), errorPlus.size()); + mDataContainer->reserve(n); + for (int i=0; iappend(QCPErrorBarsData(errorMinus.at(i), errorPlus.at(i))); +} + +/*! \overload + + Adds a single symmetrical error bar as specified in \a error. The errors will be associated + one-to-one by the data point index to the associated data plottable (\ref setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(double error) +{ + mDataContainer->append(QCPErrorBarsData(error)); +} + +/*! \overload + + Adds a single asymmetrical error bar as specified in \a errorMinus and \a errorPlus. The errors + will be associated one-to-one by the data point index to the associated data plottable (\ref + setDataPlottable). + + You can directly access and manipulate the error bar data via \ref data. + + \see setData +*/ +void QCPErrorBars::addData(double errorMinus, double errorPlus) +{ + mDataContainer->append(QCPErrorBarsData(errorMinus, errorPlus)); +} + +/* inherits documentation from base class */ +int QCPErrorBars::dataCount() const +{ + return mDataContainer->size(); +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataMainKey(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataMainKey(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataSortKey(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataSortKey(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +double QCPErrorBars::dataMainValue(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataMainValue(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::dataValueRange(int index) const +{ + if (mDataPlottable) + { + const double value = mDataPlottable->interface1D()->dataMainValue(index); + if (index >= 0 && index < mDataContainer->size() && mErrorType == etValueError) + return QCPRange(value-mDataContainer->at(index).errorMinus, value+mDataContainer->at(index).errorPlus); + else + return QCPRange(value, value); + } else + { + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return QCPRange(); + } +} + +/* inherits documentation from base class */ +QPointF QCPErrorBars::dataPixelPosition(int index) const +{ + if (mDataPlottable) + return mDataPlottable->interface1D()->dataPixelPosition(index); + else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return QPointF(); +} + +/* inherits documentation from base class */ +bool QCPErrorBars::sortKeyIsMainKey() const +{ + if (mDataPlottable) + { + return mDataPlottable->interface1D()->sortKeyIsMainKey(); + } else + { + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return true; + } +} + +/*! + \copydoc QCPPlottableInterface1D::selectTestRect +*/ +QCPDataSelection QCPErrorBars::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if (!mDataPlottable) + return result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + QCPErrorBarsDataContainer::const_iterator visibleBegin, visibleEnd; + getVisibleDataBounds(visibleBegin, visibleEnd, QCPDataRange(0, dataCount())); + + QVector backbones, whiskers; + for (QCPErrorBarsDataContainer::const_iterator it=visibleBegin; it!=visibleEnd; ++it) + { + backbones.clear(); + whiskers.clear(); + getErrorBarLines(it, backbones, whiskers); + for (int i=0; iconstBegin(), it-mDataContainer->constBegin()+1), false); + break; + } + } + } + result.simplify(); + return result; +} + +/* inherits documentation from base class */ +int QCPErrorBars::findBegin(double sortKey, bool expandedRange) const +{ + if (mDataPlottable) + { + if (mDataContainer->isEmpty()) + return 0; + int beginIndex = mDataPlottable->interface1D()->findBegin(sortKey, expandedRange); + if (beginIndex >= mDataContainer->size()) + beginIndex = mDataContainer->size()-1; + return beginIndex; + } else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +int QCPErrorBars::findEnd(double sortKey, bool expandedRange) const +{ + if (mDataPlottable) + { + if (mDataContainer->isEmpty()) + return 0; + int endIndex = mDataPlottable->interface1D()->findEnd(sortKey, expandedRange); + if (endIndex > mDataContainer->size()) + endIndex = mDataContainer->size(); + return endIndex; + } else + qDebug() << Q_FUNC_INFO << "no data plottable set"; + return 0; +} + +/* inherits documentation from base class */ +double QCPErrorBars::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if (!mDataPlottable) return -1; + + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) + { + QCPErrorBarsDataContainer::const_iterator closestDataPoint = mDataContainer->constEnd(); + double result = pointDistance(pos, closestDataPoint); + if (details) + { + int pointIndex = closestDataPoint-mDataContainer->constBegin(); + details->setValue(QCPDataSelection(QCPDataRange(pointIndex, pointIndex+1))); + } + return result; + } else + return -1; +} + +/* inherits documentation from base class */ +void QCPErrorBars::draw(QCPPainter *painter) +{ + if (!mDataPlottable) return; + if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; } + if (mKeyAxis.data()->range().size() <= 0 || mDataContainer->isEmpty()) return; + + // if the sort key isn't the main key, we must check the visibility for each data point/error bar individually + // (getVisibleDataBounds applies range restriction, but otherwise can only return full data range): + bool checkPointVisibility = !mDataPlottable->interface1D()->sortKeyIsMainKey(); + + // check data validity if flag set: +#ifdef QCUSTOMPLOT_CHECK_DATA + QCPErrorBarsDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (QCP::isInvalidData(it->errorMinus, it->errorPlus)) + qDebug() << Q_FUNC_INFO << "Data point at index" << it-mDataContainer->constBegin() << "invalid." << "Plottable name:" << name(); + } +#endif + + applyDefaultAntialiasingHint(painter); + painter->setBrush(Qt::NoBrush); + // loop over and draw segments of unselected/selected data: + QList selectedSegments, unselectedSegments, allSegments; + getDataSegments(selectedSegments, unselectedSegments); + allSegments << unselectedSegments << selectedSegments; + QVector backbones, whiskers; + for (int i=0; i= unselectedSegments.size(); + if (isSelectedSegment && mSelectionDecorator) + mSelectionDecorator->applyPen(painter); + else + painter->setPen(mPen); + if (painter->pen().capStyle() == Qt::SquareCap) + { + QPen capFixPen(painter->pen()); + capFixPen.setCapStyle(Qt::FlatCap); + painter->setPen(capFixPen); + } + backbones.clear(); + whiskers.clear(); + for (QCPErrorBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + if (!checkPointVisibility || errorBarVisible(it-mDataContainer->constBegin())) + getErrorBarLines(it, backbones, whiskers); + } + painter->drawLines(backbones); + painter->drawLines(whiskers); + } + + // draw other selection decoration that isn't just line/scatter pens and brushes: + if (mSelectionDecorator) + mSelectionDecorator->drawDecoration(painter, selection()); +} + +/* inherits documentation from base class */ +void QCPErrorBars::drawLegendIcon(QCPPainter *painter, const QRectF &rect) const +{ + applyDefaultAntialiasingHint(painter); + painter->setPen(mPen); + if (mErrorType == etValueError && mValueAxis && mValueAxis->orientation() == Qt::Vertical) + { + painter->drawLine(QLineF(rect.center().x(), rect.top()+2, rect.center().x(), rect.bottom()-1)); + painter->drawLine(QLineF(rect.center().x()-4, rect.top()+2, rect.center().x()+4, rect.top()+2)); + painter->drawLine(QLineF(rect.center().x()-4, rect.bottom()-1, rect.center().x()+4, rect.bottom()-1)); + } else + { + painter->drawLine(QLineF(rect.left()+2, rect.center().y(), rect.right()-2, rect.center().y())); + painter->drawLine(QLineF(rect.left()+2, rect.center().y()-4, rect.left()+2, rect.center().y()+4)); + painter->drawLine(QLineF(rect.right()-2, rect.center().y()-4, rect.right()-2, rect.center().y()+4)); + } +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const +{ + if (!mDataPlottable) + { + foundRange = false; + return QCPRange(); + } + + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + QCPErrorBarsDataContainer::const_iterator it; + for (it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it) + { + if (mErrorType == etValueError) + { + // error bar doesn't extend in key dimension (except whisker but we ignore that here), so only use data point center + const double current = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } else // mErrorType == etKeyError + { + const double dataKey = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); + if (qIsNaN(dataKey)) continue; + // plus error: + double current = dataKey + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + // minus error: + current = dataKey - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + } + } + } + + if (haveUpper && !haveLower) + { + range.lower = range.upper; + haveLower = true; + } else if (haveLower && !haveUpper) + { + range.upper = range.lower; + haveUpper = true; + } + + foundRange = haveLower && haveUpper; + return range; +} + +/* inherits documentation from base class */ +QCPRange QCPErrorBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const +{ + if (!mDataPlottable) + { + foundRange = false; + return QCPRange(); + } + + QCPRange range; + const bool restrictKeyRange = inKeyRange != QCPRange(); + bool haveLower = false; + bool haveUpper = false; + QCPErrorBarsDataContainer::const_iterator itBegin = mDataContainer->constBegin(); + QCPErrorBarsDataContainer::const_iterator itEnd = mDataContainer->constEnd(); + if (mDataPlottable->interface1D()->sortKeyIsMainKey() && restrictKeyRange) + { + itBegin = mDataContainer->constBegin()+findBegin(inKeyRange.lower); + itEnd = mDataContainer->constBegin()+findEnd(inKeyRange.upper); + } + for (QCPErrorBarsDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange) + { + const double dataKey = mDataPlottable->interface1D()->dataMainKey(it-mDataContainer->constBegin()); + if (dataKey < inKeyRange.lower || dataKey > inKeyRange.upper) + continue; + } + if (mErrorType == etValueError) + { + const double dataValue = mDataPlottable->interface1D()->dataMainValue(it-mDataContainer->constBegin()); + if (qIsNaN(dataValue)) continue; + // plus error: + double current = dataValue + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + // minus error: + current = dataValue - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus); + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + } + } else // mErrorType == etKeyError + { + // error bar doesn't extend in value dimension (except whisker but we ignore that here), so only use data point center + const double current = mDataPlottable->interface1D()->dataMainValue(it-mDataContainer->constBegin()); + if (qIsNaN(current)) continue; + if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0)) + { + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + } + } + + if (haveUpper && !haveLower) + { + range.lower = range.upper; + haveLower = true; + } else if (haveLower && !haveUpper) + { + range.upper = range.lower; + haveUpper = true; + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! \internal + + Calculates the lines that make up the error bar belonging to the data point \a it. + + The resulting lines are added to \a backbones and \a whiskers. The vectors are not cleared, so + calling this method with different \a it but the same \a backbones and \a whiskers allows to + accumulate lines for multiple data points. + + This method assumes that \a it is a valid iterator within the bounds of this \ref QCPErrorBars + instance and within the bounds of the associated data plottable. +*/ +void QCPErrorBars::getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const +{ + if (!mDataPlottable) return; + + int index = it-mDataContainer->constBegin(); + QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); + if (qIsNaN(centerPixel.x()) || qIsNaN(centerPixel.y())) + return; + QCPAxis *errorAxis = mErrorType == etValueError ? mValueAxis : mKeyAxis; + QCPAxis *orthoAxis = mErrorType == etValueError ? mKeyAxis : mValueAxis; + const double centerErrorAxisPixel = errorAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + const double centerOrthoAxisPixel = orthoAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + const double centerErrorAxisCoord = errorAxis->pixelToCoord(centerErrorAxisPixel); // depending on plottable, this might be different from just mDataPlottable->interface1D()->dataMainKey/Value + const double symbolGap = mSymbolGap*0.5*errorAxis->pixelOrientation(); + // plus error: + double errorStart, errorEnd; + if (!qIsNaN(it->errorPlus)) + { + errorStart = centerErrorAxisPixel+symbolGap; + errorEnd = errorAxis->coordToPixel(centerErrorAxisCoord+it->errorPlus); + if (errorAxis->orientation() == Qt::Vertical) + { + if ((errorStart > errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(centerOrthoAxisPixel, errorStart, centerOrthoAxisPixel, errorEnd)); + whiskers.append(QLineF(centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5, errorEnd)); + } else + { + if ((errorStart < errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(errorStart, centerOrthoAxisPixel, errorEnd, centerOrthoAxisPixel)); + whiskers.append(QLineF(errorEnd, centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5)); + } + } + // minus error: + if (!qIsNaN(it->errorMinus)) + { + errorStart = centerErrorAxisPixel-symbolGap; + errorEnd = errorAxis->coordToPixel(centerErrorAxisCoord-it->errorMinus); + if (errorAxis->orientation() == Qt::Vertical) + { + if ((errorStart < errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(centerOrthoAxisPixel, errorStart, centerOrthoAxisPixel, errorEnd)); + whiskers.append(QLineF(centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5, errorEnd)); + } else + { + if ((errorStart > errorEnd) != errorAxis->rangeReversed()) + backbones.append(QLineF(errorStart, centerOrthoAxisPixel, errorEnd, centerOrthoAxisPixel)); + whiskers.append(QLineF(errorEnd, centerOrthoAxisPixel-mWhiskerWidth*0.5, errorEnd, centerOrthoAxisPixel+mWhiskerWidth*0.5)); + } + } +} + +/*! \internal + + This method outputs the currently visible data range via \a begin and \a end. The returned range + will also never exceed \a rangeRestriction. + + Since error bars with type \ref etKeyError may extend to arbitrarily positive and negative key + coordinates relative to their data point key, this method checks all outer error bars whether + they truly don't reach into the visible portion of the axis rect, by calling \ref + errorBarVisible. On the other hand error bars with type \ref etValueError that are associated + with data plottables whose sort key is equal to the main key (see \ref qcpdatacontainer-datatype + "QCPDataContainer DataType") can be handled very efficiently by finding the visible range of + error bars through binary search (\ref QCPPlottableInterface1D::findBegin and \ref + QCPPlottableInterface1D::findEnd). + + If the plottable's sort key is not equal to the main key, this method returns the full data + range, only restricted by \a rangeRestriction. Drawing optimization then has to be done on a + point-by-point basis in the \ref draw method. +*/ +void QCPErrorBars::getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const +{ + QCPAxis *keyAxis = mKeyAxis.data(); + QCPAxis *valueAxis = mValueAxis.data(); + if (!keyAxis || !valueAxis) + { + qDebug() << Q_FUNC_INFO << "invalid key or value axis"; + end = mDataContainer->constEnd(); + begin = end; + return; + } + if (!mDataPlottable || rangeRestriction.isEmpty()) + { + end = mDataContainer->constEnd(); + begin = end; + return; + } + if (!mDataPlottable->interface1D()->sortKeyIsMainKey()) + { + // if the sort key isn't the main key, it's not possible to find a contiguous range of visible + // data points, so this method then only applies the range restriction and otherwise returns + // the full data range. Visibility checks must be done on a per-datapoin-basis during drawing + QCPDataRange dataRange(0, mDataContainer->size()); + dataRange = dataRange.bounded(rangeRestriction); + begin = mDataContainer->constBegin()+dataRange.begin(); + end = mDataContainer->constBegin()+dataRange.end(); + return; + } + + // get visible data range via interface from data plottable, and then restrict to available error data points: + const int n = qMin(mDataContainer->size(), mDataPlottable->interface1D()->dataCount()); + int beginIndex = mDataPlottable->interface1D()->findBegin(keyAxis->range().lower); + int endIndex = mDataPlottable->interface1D()->findEnd(keyAxis->range().upper); + int i = beginIndex; + while (i > 0 && i < n && i > rangeRestriction.begin()) + { + if (errorBarVisible(i)) + beginIndex = i; + --i; + } + i = endIndex; + while (i >= 0 && i < n && i < rangeRestriction.end()) + { + if (errorBarVisible(i)) + endIndex = i+1; + ++i; + } + QCPDataRange dataRange(beginIndex, endIndex); + dataRange = dataRange.bounded(rangeRestriction.bounded(QCPDataRange(0, mDataContainer->size()))); + begin = mDataContainer->constBegin()+dataRange.begin(); + end = mDataContainer->constBegin()+dataRange.end(); +} + +/*! \internal + + Calculates the minimum distance in pixels the error bars' representation has from the given \a + pixelPoint. This is used to determine whether the error bar was clicked or not, e.g. in \ref + selectTest. The closest data point to \a pixelPoint is returned in \a closestData. +*/ +double QCPErrorBars::pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const +{ + closestData = mDataContainer->constEnd(); + if (!mDataPlottable || mDataContainer->isEmpty()) + return -1.0; + + QCPErrorBarsDataContainer::const_iterator begin, end; + getVisibleDataBounds(begin, end, QCPDataRange(0, dataCount())); + + // calculate minimum distances to error backbones (whiskers are ignored for speed) and find closestData iterator: + double minDistSqr = std::numeric_limits::max(); + QVector backbones, whiskers; + for (QCPErrorBarsDataContainer::const_iterator it=begin; it!=end; ++it) + { + getErrorBarLines(it, backbones, whiskers); + for (int i=0; i &selectedSegments, QList &unselectedSegments) const +{ + selectedSegments.clear(); + unselectedSegments.clear(); + if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty + { + if (selected()) + selectedSegments << QCPDataRange(0, dataCount()); + else + unselectedSegments << QCPDataRange(0, dataCount()); + } else + { + QCPDataSelection sel(selection()); + sel.simplify(); + selectedSegments = sel.dataRanges(); + unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); + } +} + +/*! \internal + + Returns whether the error bar at the specified \a index is visible within the current key axis + range. + + This method assumes for performance reasons without checking that the key axis, the value axis, + and the data plottable (\ref setDataPlottable) are not zero and that \a index is within valid + bounds of this \ref QCPErrorBars instance and the bounds of the data plottable. +*/ +bool QCPErrorBars::errorBarVisible(int index) const +{ + QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); + const double centerKeyPixel = mKeyAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); + if (qIsNaN(centerKeyPixel)) + return false; + + double keyMin, keyMax; + if (mErrorType == etKeyError) + { + const double centerKey = mKeyAxis->pixelToCoord(centerKeyPixel); + const double errorPlus = mDataContainer->at(index).errorPlus; + const double errorMinus = mDataContainer->at(index).errorMinus; + keyMax = centerKey+(qIsNaN(errorPlus) ? 0 : errorPlus); + keyMin = centerKey-(qIsNaN(errorMinus) ? 0 : errorMinus); + } else // mErrorType == etValueError + { + keyMax = mKeyAxis->pixelToCoord(centerKeyPixel+mWhiskerWidth*0.5*mKeyAxis->pixelOrientation()); + keyMin = mKeyAxis->pixelToCoord(centerKeyPixel-mWhiskerWidth*0.5*mKeyAxis->pixelOrientation()); + } + return ((keyMax > mKeyAxis->range().lower) && (keyMin < mKeyAxis->range().upper)); +} + +/*! \internal + + Returns whether \a line intersects (or is contained in) \a pixelRect. + + \a line is assumed to be either perfectly horizontal or perfectly vertical, as is the case for + error bar lines. +*/ +bool QCPErrorBars::rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const +{ + if (pixelRect.left() > line.x1() && pixelRect.left() > line.x2()) + return false; + else if (pixelRect.right() < line.x1() && pixelRect.right() < line.x2()) + return false; + else if (pixelRect.top() > line.y1() && pixelRect.top() > line.y2()) + return false; + else if (pixelRect.bottom() < line.y1() && pixelRect.bottom() < line.y2()) + return false; + else + return true; +} +/* end of 'src/plottables/plottable-errorbar.cpp' */ + + +/* including file 'src/items/item-straightline.cpp', size 7592 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemStraightLine +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemStraightLine + \brief A straight line that spans infinitely in both directions + + \image html QCPItemStraightLine.png "Straight line example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a point1 and \a point2, which define the straight line. +*/ + +/*! + Creates a straight line item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemStraightLine::QCPItemStraightLine(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + point1(createPosition(QLatin1String("point1"))), + point2(createPosition(QLatin1String("point2"))) +{ + point1->setCoords(0, 0); + point2->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemStraightLine::~QCPItemStraightLine() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemStraightLine::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemStraightLine::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/* inherits documentation from base class */ +double QCPItemStraightLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return QCPVector2D(pos).distanceToStraightLine(point1->pixelPosition(), point2->pixelPosition()-point1->pixelPosition()); +} + +/* inherits documentation from base class */ +void QCPItemStraightLine::draw(QCPPainter *painter) +{ + QCPVector2D start(point1->pixelPosition()); + QCPVector2D end(point2->pixelPosition()); + // get visible segment of straight line inside clipRect: + double clipPad = mainPen().widthF(); + QLineF line = getRectClippedStraightLine(start, end-start, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); + // paint visible segment, if existent: + if (!line.isNull()) + { + painter->setPen(mainPen()); + painter->drawLine(line); + } +} + +/*! \internal + + Returns the section of the straight line defined by \a base and direction vector \a + vec, that is visible in the specified \a rect. + + This is a helper function for \ref draw. +*/ +QLineF QCPItemStraightLine::getRectClippedStraightLine(const QCPVector2D &base, const QCPVector2D &vec, const QRect &rect) const +{ + double bx, by; + double gamma; + QLineF result; + if (vec.x() == 0 && vec.y() == 0) + return result; + if (qFuzzyIsNull(vec.x())) // line is vertical + { + // check top of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + result.setLine(bx+gamma, rect.top(), bx+gamma, rect.bottom()); // no need to check bottom because we know line is vertical + } else if (qFuzzyIsNull(vec.y())) // line is horizontal + { + // check left of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + result.setLine(rect.left(), by+gamma, rect.right(), by+gamma); // no need to check right because we know line is horizontal + } else // line is skewed + { + QList pointVectors; + // check top of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + // check bottom of rect: + bx = rect.left(); + by = rect.bottom(); + gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + // check left of rect: + bx = rect.left(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + // check right of rect: + bx = rect.right(); + by = rect.top(); + gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + + // evaluate points: + if (pointVectors.size() == 2) + { + result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); + } else if (pointVectors.size() > 2) + { + // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: + double distSqrMax = 0; + QCPVector2D pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = pointVectors.at(i); + pv2 = pointVectors.at(k); + distSqrMax = distSqr; + } + } + } + result.setPoints(pv1.toPointF(), pv2.toPointF()); + } + } + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemStraightLine::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-straightline.cpp' */ + + +/* including file 'src/items/item-line.cpp', size 8498 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemLine +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemLine + \brief A line from one point to another + + \image html QCPItemLine.png "Line example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a start and \a end, which define the end points of the line. + + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an arrow. +*/ + +/*! + Creates a line item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemLine::QCPItemLine(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + start(createPosition(QLatin1String("start"))), + end(createPosition(QLatin1String("end"))) +{ + start->setCoords(0, 0); + end->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemLine::~QCPItemLine() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemLine::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemLine::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the line ending style of the head. The head corresponds to the \a end position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode + + \see setTail +*/ +void QCPItemLine::setHead(const QCPLineEnding &head) +{ + mHead = head; +} + +/*! + Sets the line ending style of the tail. The tail corresponds to the \a start position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode + + \see setHead +*/ +void QCPItemLine::setTail(const QCPLineEnding &tail) +{ + mTail = tail; +} + +/* inherits documentation from base class */ +double QCPItemLine::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return qSqrt(QCPVector2D(pos).distanceSquaredToLine(start->pixelPosition(), end->pixelPosition())); +} + +/* inherits documentation from base class */ +void QCPItemLine::draw(QCPPainter *painter) +{ + QCPVector2D startVec(start->pixelPosition()); + QCPVector2D endVec(end->pixelPosition()); + if (qFuzzyIsNull((startVec-endVec).lengthSquared())) + return; + // get visible segment of straight line inside clipRect: + double clipPad = qMax(mHead.boundingDistance(), mTail.boundingDistance()); + clipPad = qMax(clipPad, (double)mainPen().widthF()); + QLineF line = getRectClippedLine(startVec, endVec, clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad)); + // paint visible segment, if existent: + if (!line.isNull()) + { + painter->setPen(mainPen()); + painter->drawLine(line); + painter->setBrush(Qt::SolidPattern); + if (mTail.style() != QCPLineEnding::esNone) + mTail.draw(painter, startVec, startVec-endVec); + if (mHead.style() != QCPLineEnding::esNone) + mHead.draw(painter, endVec, endVec-startVec); + } +} + +/*! \internal + + Returns the section of the line defined by \a start and \a end, that is visible in the specified + \a rect. + + This is a helper function for \ref draw. +*/ +QLineF QCPItemLine::getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const +{ + bool containsStart = rect.contains(start.x(), start.y()); + bool containsEnd = rect.contains(end.x(), end.y()); + if (containsStart && containsEnd) + return QLineF(start.toPointF(), end.toPointF()); + + QCPVector2D base = start; + QCPVector2D vec = end-start; + double bx, by; + double gamma, mu; + QLineF result; + QList pointVectors; + + if (!qFuzzyIsNull(vec.y())) // line is not horizontal + { + // check top of rect: + bx = rect.left(); + by = rect.top(); + mu = (by-base.y())/vec.y(); + if (mu >= 0 && mu <= 1) + { + gamma = base.x()-bx + mu*vec.x(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + } + // check bottom of rect: + bx = rect.left(); + by = rect.bottom(); + mu = (by-base.y())/vec.y(); + if (mu >= 0 && mu <= 1) + { + gamma = base.x()-bx + mu*vec.x(); + if (gamma >= 0 && gamma <= rect.width()) + pointVectors.append(QCPVector2D(bx+gamma, by)); + } + } + if (!qFuzzyIsNull(vec.x())) // line is not vertical + { + // check left of rect: + bx = rect.left(); + by = rect.top(); + mu = (bx-base.x())/vec.x(); + if (mu >= 0 && mu <= 1) + { + gamma = base.y()-by + mu*vec.y(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + } + // check right of rect: + bx = rect.right(); + by = rect.top(); + mu = (bx-base.x())/vec.x(); + if (mu >= 0 && mu <= 1) + { + gamma = base.y()-by + mu*vec.y(); + if (gamma >= 0 && gamma <= rect.height()) + pointVectors.append(QCPVector2D(bx, by+gamma)); + } + } + + if (containsStart) + pointVectors.append(start); + if (containsEnd) + pointVectors.append(end); + + // evaluate points: + if (pointVectors.size() == 2) + { + result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF()); + } else if (pointVectors.size() > 2) + { + // line probably goes through corner of rect, and we got two points there. single out the point pair with greatest distance: + double distSqrMax = 0; + QCPVector2D pv1, pv2; + for (int i=0; i distSqrMax) + { + pv1 = pointVectors.at(i); + pv2 = pointVectors.at(k); + distSqrMax = distSqr; + } + } + } + result.setPoints(pv1.toPointF(), pv2.toPointF()); + } + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemLine::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-line.cpp' */ + + +/* including file 'src/items/item-curve.cpp', size 7159 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemCurve +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemCurve + \brief A curved line from one point to another + + \image html QCPItemCurve.png "Curve example. Blue dotted circles are anchors, solid blue discs are positions." + + It has four positions, \a start and \a end, which define the end points of the line, and two + control points which define the direction the line exits from the start and the direction from + which it approaches the end: \a startDir and \a endDir. + + With \ref setHead and \ref setTail you may set different line ending styles, e.g. to create an + arrow. + + Often it is desirable for the control points to stay at fixed relative positions to the start/end + point. This can be achieved by setting the parent anchor e.g. of \a startDir simply to \a start, + and then specify the desired pixel offset with QCPItemPosition::setCoords on \a startDir. +*/ + +/*! + Creates a curve item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemCurve::QCPItemCurve(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + start(createPosition(QLatin1String("start"))), + startDir(createPosition(QLatin1String("startDir"))), + endDir(createPosition(QLatin1String("endDir"))), + end(createPosition(QLatin1String("end"))) +{ + start->setCoords(0, 0); + startDir->setCoords(0.5, 0); + endDir->setCoords(0, 0.5); + end->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); +} + +QCPItemCurve::~QCPItemCurve() +{ +} + +/*! + Sets the pen that will be used to draw the line + + \see setSelectedPen +*/ +void QCPItemCurve::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line when selected + + \see setPen, setSelected +*/ +void QCPItemCurve::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the line ending style of the head. The head corresponds to the \a end position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setHead(QCPLineEnding::esSpikeArrow) \endcode + + \see setTail +*/ +void QCPItemCurve::setHead(const QCPLineEnding &head) +{ + mHead = head; +} + +/*! + Sets the line ending style of the tail. The tail corresponds to the \a start position. + + Note that due to the overloaded QCPLineEnding constructor, you may directly specify + a QCPLineEnding::EndingStyle here, e.g. \code setTail(QCPLineEnding::esSpikeArrow) \endcode + + \see setHead +*/ +void QCPItemCurve::setTail(const QCPLineEnding &tail) +{ + mTail = tail; +} + +/* inherits documentation from base class */ +double QCPItemCurve::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF startVec(start->pixelPosition()); + QPointF startDirVec(startDir->pixelPosition()); + QPointF endDirVec(endDir->pixelPosition()); + QPointF endVec(end->pixelPosition()); + + QPainterPath cubicPath(startVec); + cubicPath.cubicTo(startDirVec, endDirVec, endVec); + + QPolygonF polygon = cubicPath.toSubpathPolygons().first(); + QCPVector2D p(pos); + double minDistSqr = std::numeric_limits::max(); + for (int i=1; ipixelPosition()); + QCPVector2D startDirVec(startDir->pixelPosition()); + QCPVector2D endDirVec(endDir->pixelPosition()); + QCPVector2D endVec(end->pixelPosition()); + if ((endVec-startVec).length() > 1e10) // too large curves cause crash + return; + + QPainterPath cubicPath(startVec.toPointF()); + cubicPath.cubicTo(startDirVec.toPointF(), endDirVec.toPointF(), endVec.toPointF()); + + // paint visible segment, if existent: + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + QRect cubicRect = cubicPath.controlPointRect().toRect(); + if (cubicRect.isEmpty()) // may happen when start and end exactly on same x or y position + cubicRect.adjust(0, 0, 1, 1); + if (clip.intersects(cubicRect)) + { + painter->setPen(mainPen()); + painter->drawPath(cubicPath); + painter->setBrush(Qt::SolidPattern); + if (mTail.style() != QCPLineEnding::esNone) + mTail.draw(painter, startVec, M_PI-cubicPath.angleAtPercent(0)/180.0*M_PI); + if (mHead.style() != QCPLineEnding::esNone) + mHead.draw(painter, endVec, -cubicPath.angleAtPercent(1)/180.0*M_PI); + } +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemCurve::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-curve.cpp' */ + + +/* including file 'src/items/item-rect.cpp', size 6479 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemRect +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemRect + \brief A rectangle + + \image html QCPItemRect.png "Rectangle example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rectangle. +*/ + +/*! + Creates a rectangle item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemRect::QCPItemRect(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue,2)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPItemRect::~QCPItemRect() +{ +} + +/*! + Sets the pen that will be used to draw the line of the rectangle + + \see setSelectedPen, setBrush +*/ +void QCPItemRect::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the rectangle when selected + + \see setPen, setSelected +*/ +void QCPItemRect::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to fill the rectangle. To disable filling, set \a brush to + Qt::NoBrush. + + \see setSelectedBrush, setPen +*/ +void QCPItemRect::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to fill the rectangle when selected. To disable filling, set \a + brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemRect::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/* inherits documentation from base class */ +double QCPItemRect::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()).normalized(); + bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; + return rectDistance(rect, pos, filledRect); +} + +/* inherits documentation from base class */ +void QCPItemRect::draw(QCPPainter *painter) +{ + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + if (p1.toPoint() == p2.toPoint()) + return; + QRectF rect = QRectF(p1, p2).normalized(); + double clipPad = mainPen().widthF(); + QRectF boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (boundingRect.intersects(clipRect())) // only draw if bounding rect of rect item is visible in cliprect + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(rect); + } +} + +/* inherits documentation from base class */ +QPointF QCPItemRect::anchorPixelPosition(int anchorId) const +{ + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()); + switch (anchorId) + { + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRight: return rect.topRight(); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeft: return rect.bottomLeft(); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemRect::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemRect::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-rect.cpp' */ + + +/* including file 'src/items/item-text.cpp', size 13338 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemText +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemText + \brief A text label + + \image html QCPItemText.png "Text example. Blue dotted circles are anchors, solid blue discs are positions." + + Its position is defined by the member \a position and the setting of \ref setPositionAlignment. + The latter controls which part of the text rect shall be aligned with \a position. + + The text alignment itself (i.e. left, center, right) can be controlled with \ref + setTextAlignment. + + The text may be rotated around the \a position point with \ref setRotation. +*/ + +/*! + Creates a text item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemText::QCPItemText(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + topLeft(createAnchor(QLatin1String("topLeft"), aiTopLeft)), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottomRight(createAnchor(QLatin1String("bottomRight"), aiBottomRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)), + mText(QLatin1String("text")), + mPositionAlignment(Qt::AlignCenter), + mTextAlignment(Qt::AlignTop|Qt::AlignHCenter), + mRotation(0) +{ + position->setCoords(0, 0); + + setPen(Qt::NoPen); + setSelectedPen(Qt::NoPen); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); + setColor(Qt::black); + setSelectedColor(Qt::blue); +} + +QCPItemText::~QCPItemText() +{ +} + +/*! + Sets the color of the text. +*/ +void QCPItemText::setColor(const QColor &color) +{ + mColor = color; +} + +/*! + Sets the color of the text that will be used when the item is selected. +*/ +void QCPItemText::setSelectedColor(const QColor &color) +{ + mSelectedColor = color; +} + +/*! + Sets the pen that will be used do draw a rectangular border around the text. To disable the + border, set \a pen to Qt::NoPen. + + \see setSelectedPen, setBrush, setPadding +*/ +void QCPItemText::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used do draw a rectangular border around the text, when the item is + selected. To disable the border, set \a pen to Qt::NoPen. + + \see setPen +*/ +void QCPItemText::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used do fill the background of the text. To disable the + background, set \a brush to Qt::NoBrush. + + \see setSelectedBrush, setPen, setPadding +*/ +void QCPItemText::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used do fill the background of the text, when the item is selected. To disable the + background, set \a brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemText::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the font of the text. + + \see setSelectedFont, setColor +*/ +void QCPItemText::setFont(const QFont &font) +{ + mFont = font; +} + +/*! + Sets the font of the text that will be used when the item is selected. + + \see setFont +*/ +void QCPItemText::setSelectedFont(const QFont &font) +{ + mSelectedFont = font; +} + +/*! + Sets the text that will be displayed. Multi-line texts are supported by inserting a line break + character, e.g. '\n'. + + \see setFont, setColor, setTextAlignment +*/ +void QCPItemText::setText(const QString &text) +{ + mText = text; +} + +/*! + Sets which point of the text rect shall be aligned with \a position. + + Examples: + \li If \a alignment is Qt::AlignHCenter | Qt::AlignTop, the text will be positioned such + that the top of the text rect will be horizontally centered on \a position. + \li If \a alignment is Qt::AlignLeft | Qt::AlignBottom, \a position will indicate the + bottom left corner of the text rect. + + If you want to control the alignment of (multi-lined) text within the text rect, use \ref + setTextAlignment. +*/ +void QCPItemText::setPositionAlignment(Qt::Alignment alignment) +{ + mPositionAlignment = alignment; +} + +/*! + Controls how (multi-lined) text is aligned inside the text rect (typically Qt::AlignLeft, Qt::AlignCenter or Qt::AlignRight). +*/ +void QCPItemText::setTextAlignment(Qt::Alignment alignment) +{ + mTextAlignment = alignment; +} + +/*! + Sets the angle in degrees by which the text (and the text rectangle, if visible) will be rotated + around \a position. +*/ +void QCPItemText::setRotation(double degrees) +{ + mRotation = degrees; +} + +/*! + Sets the distance between the border of the text rectangle and the text. The appearance (and + visibility) of the text rectangle can be controlled with \ref setPen and \ref setBrush. +*/ +void QCPItemText::setPadding(const QMargins &padding) +{ + mPadding = padding; +} + +/* inherits documentation from base class */ +double QCPItemText::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + // The rect may be rotated, so we transform the actual clicked pos to the rotated + // coordinate system, so we can use the normal rectDistance function for non-rotated rects: + QPointF positionPixels(position->pixelPosition()); + QTransform inputTransform; + inputTransform.translate(positionPixels.x(), positionPixels.y()); + inputTransform.rotate(-mRotation); + inputTransform.translate(-positionPixels.x(), -positionPixels.y()); + QPointF rotatedPos = inputTransform.map(pos); + QFontMetrics fontMetrics(mFont); + QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(positionPixels, textBoxRect, mPositionAlignment); + textBoxRect.moveTopLeft(textPos.toPoint()); + + return rectDistance(textBoxRect, rotatedPos, true); +} + +/* inherits documentation from base class */ +void QCPItemText::draw(QCPPainter *painter) +{ + QPointF pos(position->pixelPosition()); + QTransform transform = painter->transform(); + transform.translate(pos.x(), pos.y()); + if (!qFuzzyIsNull(mRotation)) + transform.rotate(mRotation); + painter->setFont(mainFont()); + QRect textRect = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation + textRect.moveTopLeft(textPos.toPoint()+QPoint(mPadding.left(), mPadding.top())); + textBoxRect.moveTopLeft(textPos.toPoint()); + double clipPad = mainPen().widthF(); + QRect boundingRect = textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (transform.mapRect(boundingRect).intersects(painter->transform().mapRect(clipRect()))) + { + painter->setTransform(transform); + if ((mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0) || + (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0)) + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + painter->drawRect(textBoxRect); + } + painter->setBrush(Qt::NoBrush); + painter->setPen(QPen(mainColor())); + painter->drawText(textRect, Qt::TextDontClip|mTextAlignment, mText); + } +} + +/* inherits documentation from base class */ +QPointF QCPItemText::anchorPixelPosition(int anchorId) const +{ + // get actual rect points (pretty much copied from draw function): + QPointF pos(position->pixelPosition()); + QTransform transform; + transform.translate(pos.x(), pos.y()); + if (!qFuzzyIsNull(mRotation)) + transform.rotate(mRotation); + QFontMetrics fontMetrics(mainFont()); + QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText); + QRectF textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom()); + QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation + textBoxRect.moveTopLeft(textPos.toPoint()); + QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect)); + + switch (anchorId) + { + case aiTopLeft: return rectPoly.at(0); + case aiTop: return (rectPoly.at(0)+rectPoly.at(1))*0.5; + case aiTopRight: return rectPoly.at(1); + case aiRight: return (rectPoly.at(1)+rectPoly.at(2))*0.5; + case aiBottomRight: return rectPoly.at(2); + case aiBottom: return (rectPoly.at(2)+rectPoly.at(3))*0.5; + case aiBottomLeft: return rectPoly.at(3); + case aiLeft: return (rectPoly.at(3)+rectPoly.at(0))*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the point that must be given to the QPainter::drawText function (which expects the top + left point of the text rect), according to the position \a pos, the text bounding box \a rect and + the requested \a positionAlignment. + + For example, if \a positionAlignment is Qt::AlignLeft | Qt::AlignBottom the returned point + will be shifted upward by the height of \a rect, starting from \a pos. So if the text is finally + drawn at that point, the lower left corner of the resulting text rect is at \a pos. +*/ +QPointF QCPItemText::getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const +{ + if (positionAlignment == 0 || positionAlignment == (Qt::AlignLeft|Qt::AlignTop)) + return pos; + + QPointF result = pos; // start at top left + if (positionAlignment.testFlag(Qt::AlignHCenter)) + result.rx() -= rect.width()/2.0; + else if (positionAlignment.testFlag(Qt::AlignRight)) + result.rx() -= rect.width(); + if (positionAlignment.testFlag(Qt::AlignVCenter)) + result.ry() -= rect.height()/2.0; + else if (positionAlignment.testFlag(Qt::AlignBottom)) + result.ry() -= rect.height(); + return result; +} + +/*! \internal + + Returns the font that should be used for drawing text. Returns mFont when the item is not selected + and mSelectedFont when it is. +*/ +QFont QCPItemText::mainFont() const +{ + return mSelected ? mSelectedFont : mFont; +} + +/*! \internal + + Returns the color that should be used for drawing text. Returns mColor when the item is not + selected and mSelectedColor when it is. +*/ +QColor QCPItemText::mainColor() const +{ + return mSelected ? mSelectedColor : mColor; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemText::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemText::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-text.cpp' */ + + +/* including file 'src/items/item-ellipse.cpp', size 7863 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemEllipse +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemEllipse + \brief An ellipse + + \image html QCPItemEllipse.png "Ellipse example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rect the ellipse will be drawn in. +*/ + +/*! + Creates an ellipse item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemEllipse::QCPItemEllipse(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + topLeftRim(createAnchor(QLatin1String("topLeftRim"), aiTopLeftRim)), + top(createAnchor(QLatin1String("top"), aiTop)), + topRightRim(createAnchor(QLatin1String("topRightRim"), aiTopRightRim)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottomRightRim(createAnchor(QLatin1String("bottomRightRim"), aiBottomRightRim)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeftRim(createAnchor(QLatin1String("bottomLeftRim"), aiBottomLeftRim)), + left(createAnchor(QLatin1String("left"), aiLeft)), + center(createAnchor(QLatin1String("center"), aiCenter)) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); +} + +QCPItemEllipse::~QCPItemEllipse() +{ +} + +/*! + Sets the pen that will be used to draw the line of the ellipse + + \see setSelectedPen, setBrush +*/ +void QCPItemEllipse::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the ellipse when selected + + \see setPen, setSelected +*/ +void QCPItemEllipse::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to fill the ellipse. To disable filling, set \a brush to + Qt::NoBrush. + + \see setSelectedBrush, setPen +*/ +void QCPItemEllipse::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to fill the ellipse when selected. To disable filling, set \a + brush to Qt::NoBrush. + + \see setBrush +*/ +void QCPItemEllipse::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/* inherits documentation from base class */ +double QCPItemEllipse::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + QPointF center((p1+p2)/2.0); + double a = qAbs(p1.x()-p2.x())/2.0; + double b = qAbs(p1.y()-p2.y())/2.0; + double x = pos.x()-center.x(); + double y = pos.y()-center.y(); + + // distance to border: + double c = 1.0/qSqrt(x*x/(a*a)+y*y/(b*b)); + double result = qAbs(c-1)*qSqrt(x*x+y*y); + // filled ellipse, allow click inside to count as hit: + if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) + { + if (x*x/(a*a) + y*y/(b*b) <= 1) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; +} + +/* inherits documentation from base class */ +void QCPItemEllipse::draw(QCPPainter *painter) +{ + QPointF p1 = topLeft->pixelPosition(); + QPointF p2 = bottomRight->pixelPosition(); + if (p1.toPoint() == p2.toPoint()) + return; + QRectF ellipseRect = QRectF(p1, p2).normalized(); + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + if (ellipseRect.intersects(clip)) // only draw if bounding rect of ellipse is visible in cliprect + { + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); +#ifdef __EXCEPTIONS + try // drawEllipse sometimes throws exceptions if ellipse is too big + { +#endif + painter->drawEllipse(ellipseRect); +#ifdef __EXCEPTIONS + } catch (...) + { + qDebug() << Q_FUNC_INFO << "Item too large for memory, setting invisible"; + setVisible(false); + } +#endif + } +} + +/* inherits documentation from base class */ +QPointF QCPItemEllipse::anchorPixelPosition(int anchorId) const +{ + QRectF rect = QRectF(topLeft->pixelPosition(), bottomRight->pixelPosition()); + switch (anchorId) + { + case aiTopLeftRim: return rect.center()+(rect.topLeft()-rect.center())*1/qSqrt(2); + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRightRim: return rect.center()+(rect.topRight()-rect.center())*1/qSqrt(2); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottomRightRim: return rect.center()+(rect.bottomRight()-rect.center())*1/qSqrt(2); + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeftRim: return rect.center()+(rect.bottomLeft()-rect.center())*1/qSqrt(2); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5; + case aiCenter: return (rect.topLeft()+rect.bottomRight())*0.5; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemEllipse::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemEllipse::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-ellipse.cpp' */ + + +/* including file 'src/items/item-pixmap.cpp', size 10615 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemPixmap +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemPixmap + \brief An arbitrary pixmap + + \image html QCPItemPixmap.png "Pixmap example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a topLeft and \a bottomRight, which define the rectangle the pixmap will + be drawn in. Depending on the scale setting (\ref setScaled), the pixmap will be either scaled to + fit the rectangle or be drawn aligned to the topLeft position. + + If scaling is enabled and \a topLeft is further to the bottom/right than \a bottomRight (as shown + on the right side of the example image), the pixmap will be flipped in the respective + orientations. +*/ + +/*! + Creates a rectangle item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemPixmap::QCPItemPixmap(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + topLeft(createPosition(QLatin1String("topLeft"))), + bottomRight(createPosition(QLatin1String("bottomRight"))), + top(createAnchor(QLatin1String("top"), aiTop)), + topRight(createAnchor(QLatin1String("topRight"), aiTopRight)), + right(createAnchor(QLatin1String("right"), aiRight)), + bottom(createAnchor(QLatin1String("bottom"), aiBottom)), + bottomLeft(createAnchor(QLatin1String("bottomLeft"), aiBottomLeft)), + left(createAnchor(QLatin1String("left"), aiLeft)), + mScaled(false), + mScaledPixmapInvalidated(true), + mAspectRatioMode(Qt::KeepAspectRatio), + mTransformationMode(Qt::SmoothTransformation) +{ + topLeft->setCoords(0, 1); + bottomRight->setCoords(1, 0); + + setPen(Qt::NoPen); + setSelectedPen(QPen(Qt::blue)); +} + +QCPItemPixmap::~QCPItemPixmap() +{ +} + +/*! + Sets the pixmap that will be displayed. +*/ +void QCPItemPixmap::setPixmap(const QPixmap &pixmap) +{ + mPixmap = pixmap; + mScaledPixmapInvalidated = true; + if (mPixmap.isNull()) + qDebug() << Q_FUNC_INFO << "pixmap is null"; +} + +/*! + Sets whether the pixmap will be scaled to fit the rectangle defined by the \a topLeft and \a + bottomRight positions. +*/ +void QCPItemPixmap::setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformationMode) +{ + mScaled = scaled; + mAspectRatioMode = aspectRatioMode; + mTransformationMode = transformationMode; + mScaledPixmapInvalidated = true; +} + +/*! + Sets the pen that will be used to draw a border around the pixmap. + + \see setSelectedPen, setBrush +*/ +void QCPItemPixmap::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw a border around the pixmap when selected + + \see setPen, setSelected +*/ +void QCPItemPixmap::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/* inherits documentation from base class */ +double QCPItemPixmap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + return rectDistance(getFinalRect(), pos, true); +} + +/* inherits documentation from base class */ +void QCPItemPixmap::draw(QCPPainter *painter) +{ + bool flipHorz = false; + bool flipVert = false; + QRect rect = getFinalRect(&flipHorz, &flipVert); + double clipPad = mainPen().style() == Qt::NoPen ? 0 : mainPen().widthF(); + QRect boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad); + if (boundingRect.intersects(clipRect())) + { + updateScaledPixmap(rect, flipHorz, flipVert); + painter->drawPixmap(rect.topLeft(), mScaled ? mScaledPixmap : mPixmap); + QPen pen = mainPen(); + if (pen.style() != Qt::NoPen) + { + painter->setPen(pen); + painter->setBrush(Qt::NoBrush); + painter->drawRect(rect); + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemPixmap::anchorPixelPosition(int anchorId) const +{ + bool flipHorz; + bool flipVert; + QRect rect = getFinalRect(&flipHorz, &flipVert); + // we actually want denormal rects (negative width/height) here, so restore + // the flipped state: + if (flipHorz) + rect.adjust(rect.width(), 0, -rect.width(), 0); + if (flipVert) + rect.adjust(0, rect.height(), 0, -rect.height()); + + switch (anchorId) + { + case aiTop: return (rect.topLeft()+rect.topRight())*0.5; + case aiTopRight: return rect.topRight(); + case aiRight: return (rect.topRight()+rect.bottomRight())*0.5; + case aiBottom: return (rect.bottomLeft()+rect.bottomRight())*0.5; + case aiBottomLeft: return rect.bottomLeft(); + case aiLeft: return (rect.topLeft()+rect.bottomLeft())*0.5;; + } + + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Creates the buffered scaled image (\a mScaledPixmap) to fit the specified \a finalRect. The + parameters \a flipHorz and \a flipVert control whether the resulting image shall be flipped + horizontally or vertically. (This is used when \a topLeft is further to the bottom/right than \a + bottomRight.) + + This function only creates the scaled pixmap when the buffered pixmap has a different size than + the expected result, so calling this function repeatedly, e.g. in the \ref draw function, does + not cause expensive rescaling every time. + + If scaling is disabled, sets mScaledPixmap to a null QPixmap. +*/ +void QCPItemPixmap::updateScaledPixmap(QRect finalRect, bool flipHorz, bool flipVert) +{ + if (mPixmap.isNull()) + return; + + if (mScaled) + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + double devicePixelRatio = mPixmap.devicePixelRatio(); +#else + double devicePixelRatio = 1.0; +#endif + if (finalRect.isNull()) + finalRect = getFinalRect(&flipHorz, &flipVert); + if (mScaledPixmapInvalidated || finalRect.size() != mScaledPixmap.size()/devicePixelRatio) + { + mScaledPixmap = mPixmap.scaled(finalRect.size()*devicePixelRatio, mAspectRatioMode, mTransformationMode); + if (flipHorz || flipVert) + mScaledPixmap = QPixmap::fromImage(mScaledPixmap.toImage().mirrored(flipHorz, flipVert)); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + mScaledPixmap.setDevicePixelRatio(devicePixelRatio); +#endif + } + } else if (!mScaledPixmap.isNull()) + mScaledPixmap = QPixmap(); + mScaledPixmapInvalidated = false; +} + +/*! \internal + + Returns the final (tight) rect the pixmap is drawn in, depending on the current item positions + and scaling settings. + + The output parameters \a flippedHorz and \a flippedVert return whether the pixmap should be drawn + flipped horizontally or vertically in the returned rect. (The returned rect itself is always + normalized, i.e. the top left corner of the rect is actually further to the top/left than the + bottom right corner). This is the case when the item position \a topLeft is further to the + bottom/right than \a bottomRight. + + If scaling is disabled, returns a rect with size of the original pixmap and the top left corner + aligned with the item position \a topLeft. The position \a bottomRight is ignored. +*/ +QRect QCPItemPixmap::getFinalRect(bool *flippedHorz, bool *flippedVert) const +{ + QRect result; + bool flipHorz = false; + bool flipVert = false; + QPoint p1 = topLeft->pixelPosition().toPoint(); + QPoint p2 = bottomRight->pixelPosition().toPoint(); + if (p1 == p2) + return QRect(p1, QSize(0, 0)); + if (mScaled) + { + QSize newSize = QSize(p2.x()-p1.x(), p2.y()-p1.y()); + QPoint topLeft = p1; + if (newSize.width() < 0) + { + flipHorz = true; + newSize.rwidth() *= -1; + topLeft.setX(p2.x()); + } + if (newSize.height() < 0) + { + flipVert = true; + newSize.rheight() *= -1; + topLeft.setY(p2.y()); + } + QSize scaledSize = mPixmap.size(); +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + scaledSize /= mPixmap.devicePixelRatio(); + scaledSize.scale(newSize*mPixmap.devicePixelRatio(), mAspectRatioMode); +#else + scaledSize.scale(newSize, mAspectRatioMode); +#endif + result = QRect(topLeft, scaledSize); + } else + { +#ifdef QCP_DEVICEPIXELRATIO_SUPPORTED + result = QRect(p1, mPixmap.size()/mPixmap.devicePixelRatio()); +#else + result = QRect(p1, mPixmap.size()); +#endif + } + if (flippedHorz) + *flippedHorz = flipHorz; + if (flippedVert) + *flippedVert = flipVert; + return result; +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemPixmap::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-pixmap.cpp' */ + + +/* including file 'src/items/item-tracer.cpp', size 14624 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemTracer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemTracer + \brief Item that sticks to QCPGraph data points + + \image html QCPItemTracer.png "Tracer example. Blue dotted circles are anchors, solid blue discs are positions." + + The tracer can be connected with a QCPGraph via \ref setGraph. Then it will automatically adopt + the coordinate axes of the graph and update its \a position to be on the graph's data. This means + the key stays controllable via \ref setGraphKey, but the value will follow the graph data. If a + QCPGraph is connected, note that setting the coordinates of the tracer item directly via \a + position will have no effect because they will be overriden in the next redraw (this is when the + coordinate update happens). + + If the specified key in \ref setGraphKey is outside the key bounds of the graph, the tracer will + stay at the corresponding end of the graph. + + With \ref setInterpolating you may specify whether the tracer may only stay exactly on data + points or whether it interpolates data points linearly, if given a key that lies between two data + points of the graph. + + The tracer has different visual styles, see \ref setStyle. It is also possible to make the tracer + have no own visual appearance (set the style to \ref tsNone), and just connect other item + positions to the tracer \a position (used as an anchor) via \ref + QCPItemPosition::setParentAnchor. + + \note The tracer position is only automatically updated upon redraws. So when the data of the + graph changes and immediately afterwards (without a redraw) the position coordinates of the + tracer are retrieved, they will not reflect the updated data of the graph. In this case \ref + updatePosition must be called manually, prior to reading the tracer coordinates. +*/ + +/*! + Creates a tracer item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemTracer::QCPItemTracer(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + position(createPosition(QLatin1String("position"))), + mSize(6), + mStyle(tsCrosshair), + mGraph(0), + mGraphKey(0), + mInterpolating(false) +{ + position->setCoords(0, 0); + + setBrush(Qt::NoBrush); + setSelectedBrush(Qt::NoBrush); + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); +} + +QCPItemTracer::~QCPItemTracer() +{ +} + +/*! + Sets the pen that will be used to draw the line of the tracer + + \see setSelectedPen, setBrush +*/ +void QCPItemTracer::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the line of the tracer when selected + + \see setPen, setSelected +*/ +void QCPItemTracer::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the brush that will be used to draw any fills of the tracer + + \see setSelectedBrush, setPen +*/ +void QCPItemTracer::setBrush(const QBrush &brush) +{ + mBrush = brush; +} + +/*! + Sets the brush that will be used to draw any fills of the tracer, when selected. + + \see setBrush, setSelected +*/ +void QCPItemTracer::setSelectedBrush(const QBrush &brush) +{ + mSelectedBrush = brush; +} + +/*! + Sets the size of the tracer in pixels, if the style supports setting a size (e.g. \ref tsSquare + does, \ref tsCrosshair does not). +*/ +void QCPItemTracer::setSize(double size) +{ + mSize = size; +} + +/*! + Sets the style/visual appearance of the tracer. + + If you only want to use the tracer \a position as an anchor for other items, set \a style to + \ref tsNone. +*/ +void QCPItemTracer::setStyle(QCPItemTracer::TracerStyle style) +{ + mStyle = style; +} + +/*! + Sets the QCPGraph this tracer sticks to. The tracer \a position will be set to type + QCPItemPosition::ptPlotCoords and the axes will be set to the axes of \a graph. + + To free the tracer from any graph, set \a graph to 0. The tracer \a position can then be placed + freely like any other item position. This is the state the tracer will assume when its graph gets + deleted while still attached to it. + + \see setGraphKey +*/ +void QCPItemTracer::setGraph(QCPGraph *graph) +{ + if (graph) + { + if (graph->parentPlot() == mParentPlot) + { + position->setType(QCPItemPosition::ptPlotCoords); + position->setAxes(graph->keyAxis(), graph->valueAxis()); + mGraph = graph; + updatePosition(); + } else + qDebug() << Q_FUNC_INFO << "graph isn't in same QCustomPlot instance as this item"; + } else + { + mGraph = 0; + } +} + +/*! + Sets the key of the graph's data point the tracer will be positioned at. This is the only free + coordinate of a tracer when attached to a graph. + + Depending on \ref setInterpolating, the tracer will be either positioned on the data point + closest to \a key, or will stay exactly at \a key and interpolate the value linearly. + + \see setGraph, setInterpolating +*/ +void QCPItemTracer::setGraphKey(double key) +{ + mGraphKey = key; +} + +/*! + Sets whether the value of the graph's data points shall be interpolated, when positioning the + tracer. + + If \a enabled is set to false and a key is given with \ref setGraphKey, the tracer is placed on + the data point of the graph which is closest to the key, but which is not necessarily exactly + there. If \a enabled is true, the tracer will be positioned exactly at the specified key, and + the appropriate value will be interpolated from the graph's data points linearly. + + \see setGraph, setGraphKey +*/ +void QCPItemTracer::setInterpolating(bool enabled) +{ + mInterpolating = enabled; +} + +/* inherits documentation from base class */ +double QCPItemTracer::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QPointF center(position->pixelPosition()); + double w = mSize/2.0; + QRect clip = clipRect(); + switch (mStyle) + { + case tsNone: return -1; + case tsPlus: + { + if (clipRect().intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + return qSqrt(qMin(QCPVector2D(pos).distanceSquaredToLine(center+QPointF(-w, 0), center+QPointF(w, 0)), + QCPVector2D(pos).distanceSquaredToLine(center+QPointF(0, -w), center+QPointF(0, w)))); + break; + } + case tsCrosshair: + { + return qSqrt(qMin(QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(clip.left(), center.y()), QCPVector2D(clip.right(), center.y())), + QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(center.x(), clip.top()), QCPVector2D(center.x(), clip.bottom())))); + } + case tsCircle: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + // distance to border: + double centerDist = QCPVector2D(center-pos).length(); + double circleLine = w; + double result = qAbs(centerDist-circleLine); + // filled ellipse, allow click inside to count as hit: + if (result > mParentPlot->selectionTolerance()*0.99 && mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0) + { + if (centerDist <= circleLine) + result = mParentPlot->selectionTolerance()*0.99; + } + return result; + } + break; + } + case tsSquare: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + QRectF rect = QRectF(center-QPointF(w, w), center+QPointF(w, w)); + bool filledRect = mBrush.style() != Qt::NoBrush && mBrush.color().alpha() != 0; + return rectDistance(rect, pos, filledRect); + } + break; + } + } + return -1; +} + +/* inherits documentation from base class */ +void QCPItemTracer::draw(QCPPainter *painter) +{ + updatePosition(); + if (mStyle == tsNone) + return; + + painter->setPen(mainPen()); + painter->setBrush(mainBrush()); + QPointF center(position->pixelPosition()); + double w = mSize/2.0; + QRect clip = clipRect(); + switch (mStyle) + { + case tsNone: return; + case tsPlus: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + { + painter->drawLine(QLineF(center+QPointF(-w, 0), center+QPointF(w, 0))); + painter->drawLine(QLineF(center+QPointF(0, -w), center+QPointF(0, w))); + } + break; + } + case tsCrosshair: + { + if (center.y() > clip.top() && center.y() < clip.bottom()) + painter->drawLine(QLineF(clip.left(), center.y(), clip.right(), center.y())); + if (center.x() > clip.left() && center.x() < clip.right()) + painter->drawLine(QLineF(center.x(), clip.top(), center.x(), clip.bottom())); + break; + } + case tsCircle: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + painter->drawEllipse(center, w, w); + break; + } + case tsSquare: + { + if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect())) + painter->drawRect(QRectF(center-QPointF(w, w), center+QPointF(w, w))); + break; + } + } +} + +/*! + If the tracer is connected with a graph (\ref setGraph), this function updates the tracer's \a + position to reside on the graph data, depending on the configured key (\ref setGraphKey). + + It is called automatically on every redraw and normally doesn't need to be called manually. One + exception is when you want to read the tracer coordinates via \a position and are not sure that + the graph's data (or the tracer key with \ref setGraphKey) hasn't changed since the last redraw. + In that situation, call this function before accessing \a position, to make sure you don't get + out-of-date coordinates. + + If there is no graph set on this tracer, this function does nothing. +*/ +void QCPItemTracer::updatePosition() +{ + if (mGraph) + { + if (mParentPlot->hasPlottable(mGraph)) + { + if (mGraph->data()->size() > 1) + { + QCPGraphDataContainer::const_iterator first = mGraph->data()->constBegin(); + QCPGraphDataContainer::const_iterator last = mGraph->data()->constEnd()-1; + if (mGraphKey <= first->key) + position->setCoords(first->key, first->value); + else if (mGraphKey >= last->key) + position->setCoords(last->key, last->value); + else + { + QCPGraphDataContainer::const_iterator it = mGraph->data()->findBegin(mGraphKey); + if (it != mGraph->data()->constEnd()) // mGraphKey is not exactly on last iterator, but somewhere between iterators + { + QCPGraphDataContainer::const_iterator prevIt = it; + ++it; // won't advance to constEnd because we handled that case (mGraphKey >= last->key) before + if (mInterpolating) + { + // interpolate between iterators around mGraphKey: + double slope = 0; + if (!qFuzzyCompare((double)it->key, (double)prevIt->key)) + slope = (it->value-prevIt->value)/(it->key-prevIt->key); + position->setCoords(mGraphKey, (mGraphKey-prevIt->key)*slope+prevIt->value); + } else + { + // find iterator with key closest to mGraphKey: + if (mGraphKey < (prevIt->key+it->key)*0.5) + position->setCoords(prevIt->key, prevIt->value); + else + position->setCoords(it->key, it->value); + } + } else // mGraphKey is exactly on last iterator (should actually be caught when comparing first/last keys, but this is a failsafe for fp uncertainty) + position->setCoords(it->key, it->value); + } + } else if (mGraph->data()->size() == 1) + { + QCPGraphDataContainer::const_iterator it = mGraph->data()->constBegin(); + position->setCoords(it->key, it->value); + } else + qDebug() << Q_FUNC_INFO << "graph has no data"; + } else + qDebug() << Q_FUNC_INFO << "graph not contained in QCustomPlot instance (anymore)"; + } +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the item is not selected + and mSelectedPen when it is. +*/ +QPen QCPItemTracer::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} + +/*! \internal + + Returns the brush that should be used for drawing fills of the item. Returns mBrush when the item + is not selected and mSelectedBrush when it is. +*/ +QBrush QCPItemTracer::mainBrush() const +{ + return mSelected ? mSelectedBrush : mBrush; +} +/* end of 'src/items/item-tracer.cpp' */ + + +/* including file 'src/items/item-bracket.cpp', size 10687 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPItemBracket +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPItemBracket + \brief A bracket for referencing/highlighting certain parts in the plot. + + \image html QCPItemBracket.png "Bracket example. Blue dotted circles are anchors, solid blue discs are positions." + + It has two positions, \a left and \a right, which define the span of the bracket. If \a left is + actually farther to the left than \a right, the bracket is opened to the bottom, as shown in the + example image. + + The bracket supports multiple styles via \ref setStyle. The length, i.e. how far the bracket + stretches away from the embraced span, can be controlled with \ref setLength. + + \image html QCPItemBracket-length.png +
Demonstrating the effect of different values for \ref setLength, for styles \ref + bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
+ + It provides an anchor \a center, to allow connection of other items, e.g. an arrow (QCPItemLine + or QCPItemCurve) or a text label (QCPItemText), to the bracket. +*/ + +/*! + Creates a bracket item and sets default values. + + The created item is automatically registered with \a parentPlot. This QCustomPlot instance takes + ownership of the item, so do not delete it manually but use QCustomPlot::removeItem() instead. +*/ +QCPItemBracket::QCPItemBracket(QCustomPlot *parentPlot) : + QCPAbstractItem(parentPlot), + left(createPosition(QLatin1String("left"))), + right(createPosition(QLatin1String("right"))), + center(createAnchor(QLatin1String("center"), aiCenter)), + mLength(8), + mStyle(bsCalligraphic) +{ + left->setCoords(0, 0); + right->setCoords(1, 1); + + setPen(QPen(Qt::black)); + setSelectedPen(QPen(Qt::blue, 2)); +} + +QCPItemBracket::~QCPItemBracket() +{ +} + +/*! + Sets the pen that will be used to draw the bracket. + + Note that when the style is \ref bsCalligraphic, only the color will be taken from the pen, the + stroke and width are ignored. To change the apparent stroke width of a calligraphic bracket, use + \ref setLength, which has a similar effect. + + \see setSelectedPen +*/ +void QCPItemBracket::setPen(const QPen &pen) +{ + mPen = pen; +} + +/*! + Sets the pen that will be used to draw the bracket when selected + + \see setPen, setSelected +*/ +void QCPItemBracket::setSelectedPen(const QPen &pen) +{ + mSelectedPen = pen; +} + +/*! + Sets the \a length in pixels how far the bracket extends in the direction towards the embraced + span of the bracket (i.e. perpendicular to the left-right-direction) + + \image html QCPItemBracket-length.png +
Demonstrating the effect of different values for \ref setLength, for styles \ref + bsCalligraphic and \ref bsSquare. Anchors and positions are displayed for reference.
+*/ +void QCPItemBracket::setLength(double length) +{ + mLength = length; +} + +/*! + Sets the style of the bracket, i.e. the shape/visual appearance. + + \see setPen +*/ +void QCPItemBracket::setStyle(QCPItemBracket::BracketStyle style) +{ + mStyle = style; +} + +/* inherits documentation from base class */ +double QCPItemBracket::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + Q_UNUSED(details) + if (onlySelectable && !mSelectable) + return -1; + + QCPVector2D p(pos); + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return -1; + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + switch (mStyle) + { + case QCPItemBracket::bsSquare: + case QCPItemBracket::bsRound: + { + double a = p.distanceSquaredToLine(centerVec-widthVec, centerVec+widthVec); + double b = p.distanceSquaredToLine(centerVec-widthVec+lengthVec, centerVec-widthVec); + double c = p.distanceSquaredToLine(centerVec+widthVec+lengthVec, centerVec+widthVec); + return qSqrt(qMin(qMin(a, b), c)); + } + case QCPItemBracket::bsCurly: + case QCPItemBracket::bsCalligraphic: + { + double a = p.distanceSquaredToLine(centerVec-widthVec*0.75+lengthVec*0.15, centerVec+lengthVec*0.3); + double b = p.distanceSquaredToLine(centerVec-widthVec+lengthVec*0.7, centerVec-widthVec*0.75+lengthVec*0.15); + double c = p.distanceSquaredToLine(centerVec+widthVec*0.75+lengthVec*0.15, centerVec+lengthVec*0.3); + double d = p.distanceSquaredToLine(centerVec+widthVec+lengthVec*0.7, centerVec+widthVec*0.75+lengthVec*0.15); + return qSqrt(qMin(qMin(a, b), qMin(c, d))); + } + } + return -1; +} + +/* inherits documentation from base class */ +void QCPItemBracket::draw(QCPPainter *painter) +{ + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return; + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + QPolygon boundingPoly; + boundingPoly << leftVec.toPoint() << rightVec.toPoint() + << (rightVec-lengthVec).toPoint() << (leftVec-lengthVec).toPoint(); + QRect clip = clipRect().adjusted(-mainPen().widthF(), -mainPen().widthF(), mainPen().widthF(), mainPen().widthF()); + if (clip.intersects(boundingPoly.boundingRect())) + { + painter->setPen(mainPen()); + switch (mStyle) + { + case bsSquare: + { + painter->drawLine((centerVec+widthVec).toPointF(), (centerVec-widthVec).toPointF()); + painter->drawLine((centerVec+widthVec).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); + painter->drawLine((centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + break; + } + case bsRound: + { + painter->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + path.cubicTo((centerVec+widthVec).toPointF(), (centerVec+widthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-widthVec).toPointF(), (centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + painter->drawPath(path); + break; + } + case bsCurly: + { + painter->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+lengthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-0.4*widthVec+lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + painter->drawPath(path); + break; + } + case bsCalligraphic: + { + painter->setPen(Qt::NoPen); + painter->setBrush(QBrush(mainPen().color())); + QPainterPath path; + path.moveTo((centerVec+widthVec+lengthVec).toPointF()); + + path.cubicTo((centerVec+widthVec-lengthVec*0.8).toPointF(), (centerVec+0.4*widthVec+0.8*lengthVec).toPointF(), centerVec.toPointF()); + path.cubicTo((centerVec-0.4*widthVec+0.8*lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8).toPointF(), (centerVec-widthVec+lengthVec).toPointF()); + + path.cubicTo((centerVec-widthVec-lengthVec*0.5).toPointF(), (centerVec-0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+lengthVec*0.2).toPointF()); + path.cubicTo((centerVec+0.2*widthVec+1.2*lengthVec).toPointF(), (centerVec+widthVec-lengthVec*0.5).toPointF(), (centerVec+widthVec+lengthVec).toPointF()); + + painter->drawPath(path); + break; + } + } + } +} + +/* inherits documentation from base class */ +QPointF QCPItemBracket::anchorPixelPosition(int anchorId) const +{ + QCPVector2D leftVec(left->pixelPosition()); + QCPVector2D rightVec(right->pixelPosition()); + if (leftVec.toPoint() == rightVec.toPoint()) + return leftVec.toPointF(); + + QCPVector2D widthVec = (rightVec-leftVec)*0.5; + QCPVector2D lengthVec = widthVec.perpendicular().normalized()*mLength; + QCPVector2D centerVec = (rightVec+leftVec)*0.5-lengthVec; + + switch (anchorId) + { + case aiCenter: + return centerVec.toPointF(); + } + qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId; + return QPointF(); +} + +/*! \internal + + Returns the pen that should be used for drawing lines. Returns mPen when the + item is not selected and mSelectedPen when it is. +*/ +QPen QCPItemBracket::mainPen() const +{ + return mSelected ? mSelectedPen : mPen; +} +/* end of 'src/items/item-bracket.cpp' */ + + diff --git a/Desktop_Interface/ui_elements/qcp2/qcustomplot.cpp.REMOVED.git-id b/Desktop_Interface/ui_elements/qcp2/qcustomplot.cpp.REMOVED.git-id deleted file mode 100644 index d39f6d42..00000000 --- a/Desktop_Interface/ui_elements/qcp2/qcustomplot.cpp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e55d10a39dab7e3ff4d7cba95f88b504b6a53cb8 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/qcp2/qcustomplot.h b/Desktop_Interface/ui_elements/qcp2/qcustomplot.h new file mode 100644 index 00000000..25316bf8 --- /dev/null +++ b/Desktop_Interface/ui_elements/qcp2/qcustomplot.h @@ -0,0 +1,6629 @@ +/*************************************************************************** +** ** +** QCustomPlot, an easy to use, modern plotting widget for Qt ** +** Copyright (C) 2011-2016 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.qcustomplot.com/ ** +** Date: 13.09.16 ** +** Version: 2.0.0-beta ** +****************************************************************************/ + +#ifndef QCUSTOMPLOT_H +#define QCUSTOMPLOT_H + +#include + +// some Qt version/configuration dependent macros to include or exclude certain code paths: +#ifdef QCUSTOMPLOT_USE_OPENGL +# if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# define QCP_OPENGL_PBUFFER +# else +# define QCP_OPENGL_FBO +# endif +# if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) +# define QCP_OPENGL_OFFSCREENSURFACE +# endif +#endif + +#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) + #define QCP_DEVICEPIXELRATIO_SUPPORTED +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef QCP_OPENGL_FBO +# include +# include +# ifdef QCP_OPENGL_OFFSCREENSURFACE +# include +# else +# include +# endif +#endif +#ifdef QCP_OPENGL_PBUFFER +# include +#endif +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# include +# include +# include +# include +#else +# include +# include +# include +# include +#endif + +class QCPPainter; +class QCustomPlot; +class QCPLayerable; +class QCPLayoutElement; +class QCPLayout; +class QCPAxis; +class QCPAxisRect; +class QCPAxisPainterPrivate; +class QCPAbstractPlottable; +class QCPGraph; +class QCPAbstractItem; +class QCPPlottableInterface1D; +class QCPLegend; +class QCPItemPosition; +class QCPLayer; +class QCPAbstractLegendItem; +class QCPSelectionRect; +class QCPColorMap; +class QCPColorScale; +class QCPBars; + +/* including file 'src/global.h', size 16131 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +// decl definitions for shared library compilation/usage: +#if defined(QCUSTOMPLOT_COMPILE_LIBRARY) +# define QCP_LIB_DECL Q_DECL_EXPORT +#elif defined(QCUSTOMPLOT_USE_LIBRARY) +# define QCP_LIB_DECL Q_DECL_IMPORT +#else +# define QCP_LIB_DECL +#endif + +// define empty macro for Q_DECL_OVERRIDE if it doesn't exist (Qt < 5) +#ifndef Q_DECL_OVERRIDE +# define Q_DECL_OVERRIDE +#endif + +/*! + The QCP Namespace contains general enums, QFlags and functions used throughout the QCustomPlot + library. + + It provides QMetaObject-based reflection of its enums and flags via \a QCP::staticMetaObject. +*/ +#ifndef Q_MOC_RUN +namespace QCP { +#else +class QCP { // when in moc-run, make it look like a class, so we get Q_GADGET, Q_ENUMS/Q_FLAGS features in namespace + Q_GADGET + Q_ENUMS(ExportPen) + Q_ENUMS(ResolutionUnit) + Q_ENUMS(SignDomain) + Q_ENUMS(MarginSide) + Q_FLAGS(MarginSides) + Q_ENUMS(AntialiasedElement) + Q_FLAGS(AntialiasedElements) + Q_ENUMS(PlottingHint) + Q_FLAGS(PlottingHints) + Q_ENUMS(Interaction) + Q_FLAGS(Interactions) + Q_ENUMS(SelectionRectMode) + Q_ENUMS(SelectionType) +public: +#endif + +/*! + Defines the different units in which the image resolution can be specified in the export + functions. + + \see QCustomPlot::savePng, QCustomPlot::saveJpg, QCustomPlot::saveBmp, QCustomPlot::saveRastered +*/ +enum ResolutionUnit { ruDotsPerMeter ///< Resolution is given in dots per meter (dpm) + ,ruDotsPerCentimeter ///< Resolution is given in dots per centimeter (dpcm) + ,ruDotsPerInch ///< Resolution is given in dots per inch (DPI/PPI) + }; + +/*! + Defines how cosmetic pens (pens with numerical width 0) are handled during export. + + \see QCustomPlot::savePdf +*/ +enum ExportPen { epNoCosmetic ///< Cosmetic pens are converted to pens with pixel width 1 when exporting + ,epAllowCosmetic ///< Cosmetic pens are exported normally (e.g. in PDF exports, cosmetic pens always appear as 1 pixel on screen, independent of viewer zoom level) + }; + +/*! + Represents negative and positive sign domain, e.g. for passing to \ref + QCPAbstractPlottable::getKeyRange and \ref QCPAbstractPlottable::getValueRange. + + This is primarily needed when working with logarithmic axis scales, since only one of the sign + domains can be visible at a time. +*/ +enum SignDomain { sdNegative ///< The negative sign domain, i.e. numbers smaller than zero + ,sdBoth ///< Both sign domains, including zero, i.e. all numbers + ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero + }; + +/*! + Defines the sides of a rectangular entity to which margins can be applied. + + \see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins +*/ +enum MarginSide { msLeft = 0x01 ///< 0x01 left margin + ,msRight = 0x02 ///< 0x02 right margin + ,msTop = 0x04 ///< 0x04 top margin + ,msBottom = 0x08 ///< 0x08 bottom margin + ,msAll = 0xFF ///< 0xFF all margins + ,msNone = 0x00 ///< 0x00 no margin + }; +Q_DECLARE_FLAGS(MarginSides, MarginSide) + +/*! + Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is + neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective + element how it is drawn. Typically it provides a \a setAntialiased function for this. + + \c AntialiasedElements is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements +*/ +enum AntialiasedElement { aeAxes = 0x0001 ///< 0x0001 Axis base line and tick marks + ,aeGrid = 0x0002 ///< 0x0002 Grid lines + ,aeSubGrid = 0x0004 ///< 0x0004 Sub grid lines + ,aeLegend = 0x0008 ///< 0x0008 Legend box + ,aeLegendItems = 0x0010 ///< 0x0010 Legend items + ,aePlottables = 0x0020 ///< 0x0020 Main lines of plottables + ,aeItems = 0x0040 ///< 0x0040 Main lines of items + ,aeScatters = 0x0080 ///< 0x0080 Scatter symbols of plottables (excluding scatter symbols of type ssPixmap) + ,aeFills = 0x0100 ///< 0x0100 Borders of fills (e.g. under or between graphs) + ,aeZeroLine = 0x0200 ///< 0x0200 Zero-lines, see \ref QCPGrid::setZeroLinePen + ,aeOther = 0x8000 ///< 0x8000 Other elements that don't fit into any of the existing categories + ,aeAll = 0xFFFF ///< 0xFFFF All elements + ,aeNone = 0x0000 ///< 0x0000 No elements + }; +Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement) + +/*! + Defines plotting hints that control various aspects of the quality and speed of plotting. + + \see QCustomPlot::setPlottingHints +*/ +enum PlottingHint { phNone = 0x000 ///< 0x000 No hints are set + ,phFastPolylines = 0x001 ///< 0x001 Graph/Curve lines are drawn with a faster method. This reduces the quality especially of the line segment + ///< joins, thus is most effective for pen sizes larger than 1. It is only used for solid line pens. + ,phImmediateRefresh = 0x002 ///< 0x002 causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpRefreshHint. + ///< This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse). + ,phCacheLabels = 0x004 ///< 0x004 axis (tick) labels will be cached as pixmaps, increasing replot performance. + }; +Q_DECLARE_FLAGS(PlottingHints, PlottingHint) + +/*! + Defines the mouse interactions possible with QCustomPlot. + + \c Interactions is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setInteractions +*/ +enum Interaction { iRangeDrag = 0x001 ///< 0x001 Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes) + ,iRangeZoom = 0x002 ///< 0x002 Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes) + ,iMultiSelect = 0x004 ///< 0x004 The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking + ,iSelectPlottables = 0x008 ///< 0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable) + ,iSelectAxes = 0x010 ///< 0x010 Axes are selectable (or parts of them, see QCPAxis::setSelectableParts) + ,iSelectLegend = 0x020 ///< 0x020 Legends are selectable (or their child items, see QCPLegend::setSelectableParts) + ,iSelectItems = 0x040 ///< 0x040 Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem) + ,iSelectOther = 0x080 ///< 0x080 All other objects are selectable (e.g. your own derived layerables, other layout elements,...) + }; +Q_DECLARE_FLAGS(Interactions, Interaction) + +/*! + Defines the behaviour of the selection rect. + + \see QCustomPlot::setSelectionRectMode, QCustomPlot::selectionRect, QCPSelectionRect +*/ +enum SelectionRectMode { srmNone ///< The selection rect is disabled, and all mouse events are forwarded to the underlying objects, e.g. for axis range dragging + ,srmZoom ///< When dragging the mouse, a selection rect becomes active. Upon releasing, the axes that are currently set as range zoom axes (\ref QCPAxisRect::setRangeZoomAxes) will have their ranges zoomed accordingly. + ,srmSelect ///< When dragging the mouse, a selection rect becomes active. Upon releasing, plottable data points that were within the selection rect are selected, if the plottable's selectability setting permits. (See \ref dataselection "data selection mechanism" for details.) + ,srmCustom ///< When dragging the mouse, a selection rect becomes active. It is the programmer's responsibility to connect according slots to the selection rect's signals (e.g. \ref QCPSelectionRect::accepted) in order to process the user interaction. + }; + +/*! + Defines the different ways a plottable can be selected. These images show the effect of the + different selection types, when the indicated selection rect was dragged: + +
+ + + + + + + + +
\image html selectiontype-none.png stNone\image html selectiontype-whole.png stWhole\image html selectiontype-singledata.png stSingleData\image html selectiontype-datarange.png stDataRange\image html selectiontype-multipledataranges.png stMultipleDataRanges
+
+ + \see QCPAbstractPlottable::setSelectable, QCPDataSelection::enforceType +*/ +enum SelectionType { stNone ///< The plottable is not selectable + ,stWhole ///< Selection behaves like \ref stMultipleDataRanges, but if there are any data points selected, the entire plottable is drawn as selected. + ,stSingleData ///< One individual data point can be selected at a time + ,stDataRange ///< Multiple contiguous data points (a data range) can be selected + ,stMultipleDataRanges ///< Any combination of data points/ranges can be selected + }; + +/*! \internal + + Returns whether the specified \a value is considered an invalid data value for plottables (i.e. + is \e nan or \e +/-inf). This function is used to check data validity upon replots, when the + compiler flag \c QCUSTOMPLOT_CHECK_DATA is set. +*/ +inline bool isInvalidData(double value) +{ + return qIsNaN(value) || qIsInf(value); +} + +/*! \internal + \overload + + Checks two arguments instead of one. +*/ +inline bool isInvalidData(double value1, double value2) +{ + return isInvalidData(value1) || isInvalidData(value2); +} + +/*! \internal + + Sets the specified \a side of \a margins to \a value + + \see getMarginValue +*/ +inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value) +{ + switch (side) + { + case QCP::msLeft: margins.setLeft(value); break; + case QCP::msRight: margins.setRight(value); break; + case QCP::msTop: margins.setTop(value); break; + case QCP::msBottom: margins.setBottom(value); break; + case QCP::msAll: margins = QMargins(value, value, value, value); break; + default: break; + } +} + +/*! \internal + + Returns the value of the specified \a side of \a margins. If \a side is \ref QCP::msNone or + \ref QCP::msAll, returns 0. + + \see setMarginValue +*/ +inline int getMarginValue(const QMargins &margins, QCP::MarginSide side) +{ + switch (side) + { + case QCP::msLeft: return margins.left(); + case QCP::msRight: return margins.right(); + case QCP::msTop: return margins.top(); + case QCP::msBottom: return margins.bottom(); + default: break; + } + return 0; +} + + +extern const QMetaObject staticMetaObject; // in moc-run we create a static meta object for QCP "fake" object. This line is the link to it via QCP::staticMetaObject in normal operation as namespace + +} // end of namespace QCP +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions) +Q_DECLARE_METATYPE(QCP::ExportPen) +Q_DECLARE_METATYPE(QCP::ResolutionUnit) +Q_DECLARE_METATYPE(QCP::SignDomain) +Q_DECLARE_METATYPE(QCP::MarginSide) +Q_DECLARE_METATYPE(QCP::AntialiasedElement) +Q_DECLARE_METATYPE(QCP::PlottingHint) +Q_DECLARE_METATYPE(QCP::Interaction) +Q_DECLARE_METATYPE(QCP::SelectionRectMode) +Q_DECLARE_METATYPE(QCP::SelectionType) + +/* end of 'src/global.h' */ + + +/* including file 'src/vector2d.h', size 4928 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPVector2D +{ +public: + QCPVector2D(); + QCPVector2D(double x, double y); + QCPVector2D(const QPoint &point); + QCPVector2D(const QPointF &point); + + // getters: + double x() const { return mX; } + double y() const { return mY; } + double &rx() { return mX; } + double &ry() { return mY; } + + // setters: + void setX(double x) { mX = x; } + void setY(double y) { mY = y; } + + // non-virtual methods: + double length() const { return qSqrt(mX*mX+mY*mY); } + double lengthSquared() const { return mX*mX+mY*mY; } + QPoint toPoint() const { return QPoint(mX, mY); } + QPointF toPointF() const { return QPointF(mX, mY); } + + bool isNull() const { return qIsNull(mX) && qIsNull(mY); } + void normalize(); + QCPVector2D normalized() const; + QCPVector2D perpendicular() const { return QCPVector2D(-mY, mX); } + double dot(const QCPVector2D &vec) const { return mX*vec.mX+mY*vec.mY; } + double distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const; + double distanceSquaredToLine(const QLineF &line) const; + double distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const; + + QCPVector2D &operator*=(double factor); + QCPVector2D &operator/=(double divisor); + QCPVector2D &operator+=(const QCPVector2D &vector); + QCPVector2D &operator-=(const QCPVector2D &vector); + +private: + // property members: + double mX, mY; + + friend inline const QCPVector2D operator*(double factor, const QCPVector2D &vec); + friend inline const QCPVector2D operator*(const QCPVector2D &vec, double factor); + friend inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor); + friend inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2); + friend inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2); + friend inline const QCPVector2D operator-(const QCPVector2D &vec); +}; +Q_DECLARE_TYPEINFO(QCPVector2D, Q_MOVABLE_TYPE); + +inline const QCPVector2D operator*(double factor, const QCPVector2D &vec) { return QCPVector2D(vec.mX*factor, vec.mY*factor); } +inline const QCPVector2D operator*(const QCPVector2D &vec, double factor) { return QCPVector2D(vec.mX*factor, vec.mY*factor); } +inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor) { return QCPVector2D(vec.mX/divisor, vec.mY/divisor); } +inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX+vec2.mX, vec1.mY+vec2.mY); } +inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX-vec2.mX, vec1.mY-vec2.mY); } +inline const QCPVector2D operator-(const QCPVector2D &vec) { return QCPVector2D(-vec.mX, -vec.mY); } + +/*! \relates QCPVector2D + + Prints \a vec in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPVector2D &vec) +{ + d.nospace() << "QCPVector2D(" << vec.x() << ", " << vec.y() << ")"; + return d.space(); +} + +/* end of 'src/vector2d.h' */ + + +/* including file 'src/painter.h', size 4035 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPPainter : public QPainter +{ + Q_GADGET +public: + /*! + Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds, + depending on whether they are wanted on the respective output device. + */ + enum PainterMode { pmDefault = 0x00 ///< 0x00 Default mode for painting on screen devices + ,pmVectorized = 0x01 ///< 0x01 Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes. + ,pmNoCaching = 0x02 ///< 0x02 Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels + ,pmNonCosmetic = 0x04 ///< 0x04 Turns pen widths 0 to 1, i.e. disables cosmetic pens. (A cosmetic pen is always drawn with width 1 pixel in the vector image/pdf viewer, independent of zoom.) + }; + Q_ENUMS(PainterMode) + Q_FLAGS(PainterModes) + Q_DECLARE_FLAGS(PainterModes, PainterMode) + + QCPPainter(); + explicit QCPPainter(QPaintDevice *device); + + // getters: + bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); } + PainterModes modes() const { return mModes; } + + // setters: + void setAntialiasing(bool enabled); + void setMode(PainterMode mode, bool enabled=true); + void setModes(PainterModes modes); + + // methods hiding non-virtual base class functions (QPainter bug workarounds): + bool begin(QPaintDevice *device); + void setPen(const QPen &pen); + void setPen(const QColor &color); + void setPen(Qt::PenStyle penStyle); + void drawLine(const QLineF &line); + void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));} + void save(); + void restore(); + + // non-virtual methods: + void makeNonCosmetic(); + +protected: + // property members: + PainterModes mModes; + bool mIsAntialiasing; + + // non-property members: + QStack mAntialiasingStack; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes) +Q_DECLARE_METATYPE(QCPPainter::PainterMode) + +/* end of 'src/painter.h' */ + + +/* including file 'src/paintbuffer.h', size 4958 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPAbstractPaintBuffer +{ +public: + explicit QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio); + virtual ~QCPAbstractPaintBuffer(); + + // getters: + QSize size() const { return mSize; } + bool invalidated() const { return mInvalidated; } + double devicePixelRatio() const { return mDevicePixelRatio; } + + // setters: + void setSize(const QSize &size); + void setInvalidated(bool invalidated=true); + void setDevicePixelRatio(double ratio); + + // introduced virtual methods: + virtual QCPPainter *startPainting() = 0; + virtual void donePainting() {} + virtual void draw(QCPPainter *painter) const = 0; + virtual void clear(const QColor &color) = 0; + +protected: + // property members: + QSize mSize; + double mDevicePixelRatio; + + // non-property members: + bool mInvalidated; + + // introduced virtual methods: + virtual void reallocateBuffer() = 0; +}; + + +class QCP_LIB_DECL QCPPaintBufferPixmap : public QCPAbstractPaintBuffer +{ +public: + explicit QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio); + virtual ~QCPPaintBufferPixmap(); + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QPixmap mBuffer; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; + + +#ifdef QCP_OPENGL_PBUFFER +class QCP_LIB_DECL QCPPaintBufferGlPbuffer : public QCPAbstractPaintBuffer +{ +public: + explicit QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples); + virtual ~QCPPaintBufferGlPbuffer(); + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QGLPixelBuffer *mGlPBuffer; + int mMultisamples; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; +#endif // QCP_OPENGL_PBUFFER + + +#ifdef QCP_OPENGL_FBO +class QCP_LIB_DECL QCPPaintBufferGlFbo : public QCPAbstractPaintBuffer, protected QOpenGLFunctions +{ +public: + explicit QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer glContext, QWeakPointer glPaintDevice); + virtual ~QCPPaintBufferGlFbo(); + + // reimplemented virtual methods: + virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; + virtual void donePainting() Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; + void clear(const QColor &color) Q_DECL_OVERRIDE; + +protected: + // non-property members: + QWeakPointer mGlContext; + QWeakPointer mGlPaintDevice; + QOpenGLFramebufferObject *mGlFrameBuffer; + + // reimplemented virtual methods: + virtual void reallocateBuffer() Q_DECL_OVERRIDE; +}; +#endif // QCP_OPENGL_FBO + +/* end of 'src/paintbuffer.h' */ + + +/* including file 'src/layer.h', size 6885 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPLayer : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) + Q_PROPERTY(QString name READ name) + Q_PROPERTY(int index READ index) + Q_PROPERTY(QList children READ children) + Q_PROPERTY(bool visible READ visible WRITE setVisible) + Q_PROPERTY(LayerMode mode READ mode WRITE setMode) + /// \endcond +public: + + /*! + Defines the different rendering modes of a layer. Depending on the mode, certain layers can be + replotted individually, without the need to replot (possibly complex) layerables on other + layers. + + \see setMode + */ + enum LayerMode { lmLogical ///< Layer is used only for rendering order, and shares paint buffer with all other adjacent logical layers. + ,lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref replot). + }; + Q_ENUMS(LayerMode) + + QCPLayer(QCustomPlot* parentPlot, const QString &layerName); + virtual ~QCPLayer(); + + // getters: + QCustomPlot *parentPlot() const { return mParentPlot; } + QString name() const { return mName; } + int index() const { return mIndex; } + QList children() const { return mChildren; } + bool visible() const { return mVisible; } + LayerMode mode() const { return mMode; } + + // setters: + void setVisible(bool visible); + void setMode(LayerMode mode); + + // non-virtual methods: + void replot(); + +protected: + // property members: + QCustomPlot *mParentPlot; + QString mName; + int mIndex; + QList mChildren; + bool mVisible; + LayerMode mMode; + + // non-property members: + QWeakPointer mPaintBuffer; + + // non-virtual methods: + void draw(QCPPainter *painter); + void drawToPaintBuffer(); + void addChild(QCPLayerable *layerable, bool prepend); + void removeChild(QCPLayerable *layerable); + +private: + Q_DISABLE_COPY(QCPLayer) + + friend class QCustomPlot; + friend class QCPLayerable; +}; +Q_DECLARE_METATYPE(QCPLayer::LayerMode) + +class QCP_LIB_DECL QCPLayerable : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool visible READ visible WRITE setVisible) + Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) + Q_PROPERTY(QCPLayerable* parentLayerable READ parentLayerable) + Q_PROPERTY(QCPLayer* layer READ layer WRITE setLayer NOTIFY layerChanged) + Q_PROPERTY(bool antialiased READ antialiased WRITE setAntialiased) + /// \endcond +public: + QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=0); + virtual ~QCPLayerable(); + + // getters: + bool visible() const { return mVisible; } + QCustomPlot *parentPlot() const { return mParentPlot; } + QCPLayerable *parentLayerable() const { return mParentLayerable.data(); } + QCPLayer *layer() const { return mLayer; } + bool antialiased() const { return mAntialiased; } + + // setters: + void setVisible(bool on); + Q_SLOT bool setLayer(QCPLayer *layer); + bool setLayer(const QString &layerName); + void setAntialiased(bool enabled); + + // introduced virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // non-property methods: + bool realVisibility() const; + +signals: + void layerChanged(QCPLayer *newLayer); + +protected: + // property members: + bool mVisible; + QCustomPlot *mParentPlot; + QPointer mParentLayerable; + QCPLayer *mLayer; + bool mAntialiased; + + // introduced virtual methods: + virtual void parentPlotInitialized(QCustomPlot *parentPlot); + virtual QCP::Interaction selectionCategory() const; + virtual QRect clipRect() const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const = 0; + virtual void draw(QCPPainter *painter) = 0; + // selection events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + // low-level mouse events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); + virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details); + virtual void wheelEvent(QWheelEvent *event); + + // non-property methods: + void initializeParentPlot(QCustomPlot *parentPlot); + void setParentLayerable(QCPLayerable* parentLayerable); + bool moveToLayer(QCPLayer *layer, bool prepend); + void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const; + +private: + Q_DISABLE_COPY(QCPLayerable) + + friend class QCustomPlot; + friend class QCPLayer; + friend class QCPAxisRect; +}; + +/* end of 'src/layer.h' */ + + +/* including file 'src/axis/range.h', size 5280 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPRange +{ +public: + double lower, upper; + + QCPRange(); + QCPRange(double lower, double upper); + + bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; } + bool operator!=(const QCPRange& other) const { return !(*this == other); } + + QCPRange &operator+=(const double& value) { lower+=value; upper+=value; return *this; } + QCPRange &operator-=(const double& value) { lower-=value; upper-=value; return *this; } + QCPRange &operator*=(const double& value) { lower*=value; upper*=value; return *this; } + QCPRange &operator/=(const double& value) { lower/=value; upper/=value; return *this; } + friend inline const QCPRange operator+(const QCPRange&, double); + friend inline const QCPRange operator+(double, const QCPRange&); + friend inline const QCPRange operator-(const QCPRange& range, double value); + friend inline const QCPRange operator*(const QCPRange& range, double value); + friend inline const QCPRange operator*(double value, const QCPRange& range); + friend inline const QCPRange operator/(const QCPRange& range, double value); + + double size() const { return upper-lower; } + double center() const { return (upper+lower)*0.5; } + void normalize() { if (lower > upper) qSwap(lower, upper); } + void expand(const QCPRange &otherRange); + void expand(double includeCoord); + QCPRange expanded(const QCPRange &otherRange) const; + QCPRange expanded(double includeCoord) const; + QCPRange bounded(double lowerBound, double upperBound) const; + QCPRange sanitizedForLogScale() const; + QCPRange sanitizedForLinScale() const; + bool contains(double value) const { return value >= lower && value <= upper; } + + static bool validRange(double lower, double upper); + static bool validRange(const QCPRange &range); + static const double minRange; + static const double maxRange; + +}; +Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE); + +/*! \relates QCPRange + + Prints \a range in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPRange &range) +{ + d.nospace() << "QCPRange(" << range.lower << ", " << range.upper << ")"; + return d.space(); +} + +/*! + Adds \a value to both boundaries of the range. +*/ +inline const QCPRange operator+(const QCPRange& range, double value) +{ + QCPRange result(range); + result += value; + return result; +} + +/*! + Adds \a value to both boundaries of the range. +*/ +inline const QCPRange operator+(double value, const QCPRange& range) +{ + QCPRange result(range); + result += value; + return result; +} + +/*! + Subtracts \a value from both boundaries of the range. +*/ +inline const QCPRange operator-(const QCPRange& range, double value) +{ + QCPRange result(range); + result -= value; + return result; +} + +/*! + Multiplies both boundaries of the range by \a value. +*/ +inline const QCPRange operator*(const QCPRange& range, double value) +{ + QCPRange result(range); + result *= value; + return result; +} + +/*! + Multiplies both boundaries of the range by \a value. +*/ +inline const QCPRange operator*(double value, const QCPRange& range) +{ + QCPRange result(range); + result *= value; + return result; +} + +/*! + Divides both boundaries of the range by \a value. +*/ +inline const QCPRange operator/(const QCPRange& range, double value) +{ + QCPRange result(range); + result /= value; + return result; +} + +/* end of 'src/axis/range.h' */ + + +/* including file 'src/selection.h', size 8579 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPDataRange +{ +public: + QCPDataRange(); + QCPDataRange(int begin, int end); + + bool operator==(const QCPDataRange& other) const { return mBegin == other.mBegin && mEnd == other.mEnd; } + bool operator!=(const QCPDataRange& other) const { return !(*this == other); } + + // getters: + int begin() const { return mBegin; } + int end() const { return mEnd; } + int size() const { return mEnd-mBegin; } + int length() const { return size(); } + + // setters: + void setBegin(int begin) { mBegin = begin; } + void setEnd(int end) { mEnd = end; } + + // non-property methods: + bool isValid() const { return (mEnd >= mBegin) && (mBegin >= 0); } + bool isEmpty() const { return length() == 0; } + QCPDataRange bounded(const QCPDataRange &other) const; + QCPDataRange expanded(const QCPDataRange &other) const; + QCPDataRange intersection(const QCPDataRange &other) const; + QCPDataRange adjusted(int changeBegin, int changeEnd) const { return QCPDataRange(mBegin+changeBegin, mEnd+changeEnd); } + bool intersects(const QCPDataRange &other) const; + bool contains(const QCPDataRange &other) const; + +private: + // property members: + int mBegin, mEnd; + +}; +Q_DECLARE_TYPEINFO(QCPDataRange, Q_MOVABLE_TYPE); + + +class QCP_LIB_DECL QCPDataSelection +{ +public: + explicit QCPDataSelection(); + explicit QCPDataSelection(const QCPDataRange &range); + + bool operator==(const QCPDataSelection& other) const; + bool operator!=(const QCPDataSelection& other) const { return !(*this == other); } + QCPDataSelection &operator+=(const QCPDataSelection& other); + QCPDataSelection &operator+=(const QCPDataRange& other); + QCPDataSelection &operator-=(const QCPDataSelection& other); + QCPDataSelection &operator-=(const QCPDataRange& other); + friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b); + friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b); + friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b); + + // getters: + int dataRangeCount() const { return mDataRanges.size(); } + int dataPointCount() const; + QCPDataRange dataRange(int index=0) const; + QList dataRanges() const { return mDataRanges; } + QCPDataRange span() const; + + // non-property methods: + void addDataRange(const QCPDataRange &dataRange, bool simplify=true); + void clear(); + bool isEmpty() const { return mDataRanges.isEmpty(); } + void simplify(); + void enforceType(QCP::SelectionType type); + bool contains(const QCPDataSelection &other) const; + QCPDataSelection intersection(const QCPDataRange &other) const; + QCPDataSelection intersection(const QCPDataSelection &other) const; + QCPDataSelection inverse(const QCPDataRange &outerRange) const; + +private: + // property members: + QList mDataRanges; + + inline static bool lessThanDataRangeBegin(const QCPDataRange &a, const QCPDataRange &b) { return a.begin() < b.begin(); } +}; +Q_DECLARE_METATYPE(QCPDataSelection) + + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. + The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). +*/ +inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result += b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! + Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. +*/ +inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b) +{ + QCPDataSelection result(a); + result -= b; + return result; +} + +/*! \relates QCPDataRange + + Prints \a dataRange in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPDataRange &dataRange) +{ + d.nospace() << "[" << dataRange.begin() << ".." << dataRange.end()-1 << "]"; + return d.space(); +} + +/*! \relates QCPDataSelection + + Prints \a selection in a human readable format to the qDebug output. +*/ +inline QDebug operator<< (QDebug d, const QCPDataSelection &selection) +{ + d.nospace() << "QCPDataSelection("; + for (int i=0; i elements(QCP::MarginSide side) const { return mChildren.value(side); } + bool isEmpty() const; + void clear(); + +protected: + // non-property members: + QCustomPlot *mParentPlot; + QHash > mChildren; + + // introduced virtual methods: + virtual int commonMargin(QCP::MarginSide side) const; + + // non-virtual methods: + void addChild(QCP::MarginSide side, QCPLayoutElement *element); + void removeChild(QCP::MarginSide side, QCPLayoutElement *element); + +private: + Q_DISABLE_COPY(QCPMarginGroup) + + friend class QCPLayoutElement; +}; + + +class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPLayout* layout READ layout) + Q_PROPERTY(QRect rect READ rect) + Q_PROPERTY(QRect outerRect READ outerRect WRITE setOuterRect) + Q_PROPERTY(QMargins margins READ margins WRITE setMargins) + Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins) + Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize) + Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize) + /// \endcond +public: + /*! + Defines the phases of the update process, that happens just before a replot. At each phase, + \ref update is called with the according UpdatePhase value. + */ + enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout + ,upMargins ///< Phase in which the margins are calculated and set + ,upLayout ///< Final phase in which the layout system places the rects of the elements + }; + Q_ENUMS(UpdatePhase) + + explicit QCPLayoutElement(QCustomPlot *parentPlot=0); + virtual ~QCPLayoutElement(); + + // getters: + QCPLayout *layout() const { return mParentLayout; } + QRect rect() const { return mRect; } + QRect outerRect() const { return mOuterRect; } + QMargins margins() const { return mMargins; } + QMargins minimumMargins() const { return mMinimumMargins; } + QCP::MarginSides autoMargins() const { return mAutoMargins; } + QSize minimumSize() const { return mMinimumSize; } + QSize maximumSize() const { return mMaximumSize; } + QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, (QCPMarginGroup*)0); } + QHash marginGroups() const { return mMarginGroups; } + + // setters: + void setOuterRect(const QRect &rect); + void setMargins(const QMargins &margins); + void setMinimumMargins(const QMargins &margins); + void setAutoMargins(QCP::MarginSides sides); + void setMinimumSize(const QSize &size); + void setMinimumSize(int width, int height); + void setMaximumSize(const QSize &size); + void setMaximumSize(int width, int height); + void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group); + + // introduced virtual methods: + virtual void update(UpdatePhase phase); + virtual QSize minimumSizeHint() const; + virtual QSize maximumSizeHint() const; + virtual QList elements(bool recursive) const; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + +protected: + // property members: + QCPLayout *mParentLayout; + QSize mMinimumSize, mMaximumSize; + QRect mRect, mOuterRect; + QMargins mMargins, mMinimumMargins; + QCP::MarginSides mAutoMargins; + QHash mMarginGroups; + + // introduced virtual methods: + virtual int calculateAutoMargin(QCP::MarginSide side); + virtual void layoutChanged(); + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE { Q_UNUSED(painter) } + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE { Q_UNUSED(painter) } + virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPLayoutElement) + + friend class QCustomPlot; + friend class QCPLayout; + friend class QCPMarginGroup; +}; +Q_DECLARE_METATYPE(QCPLayoutElement::UpdatePhase) + + +class QCP_LIB_DECL QCPLayout : public QCPLayoutElement +{ + Q_OBJECT +public: + explicit QCPLayout(); + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual int elementCount() const = 0; + virtual QCPLayoutElement* elementAt(int index) const = 0; + virtual QCPLayoutElement* takeAt(int index) = 0; + virtual bool take(QCPLayoutElement* element) = 0; + virtual void simplify(); + + // non-virtual methods: + bool removeAt(int index); + bool remove(QCPLayoutElement* element); + void clear(); + +protected: + // introduced virtual methods: + virtual void updateLayout(); + + // non-virtual methods: + void sizeConstraintsChanged() const; + void adoptElement(QCPLayoutElement *el); + void releaseElement(QCPLayoutElement *el); + QVector getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const; + +private: + Q_DISABLE_COPY(QCPLayout) + friend class QCPLayoutElement; +}; + + +class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(int rowCount READ rowCount) + Q_PROPERTY(int columnCount READ columnCount) + Q_PROPERTY(QList columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors) + Q_PROPERTY(QList rowStretchFactors READ rowStretchFactors WRITE setRowStretchFactors) + Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing) + Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing) + Q_PROPERTY(FillOrder fillOrder READ fillOrder WRITE setFillOrder) + Q_PROPERTY(int wrap READ wrap WRITE setWrap) + /// \endcond +public: + + /*! + Defines in which direction the grid is filled when using \ref addElement(QCPLayoutElement*). + The column/row at which wrapping into the next row/column occurs can be specified with \ref + setWrap. + + \see setFillOrder + */ + enum FillOrder { foRowsFirst ///< Rows are filled first, and a new element is wrapped to the next column if the row count would exceed \ref setWrap. + ,foColumnsFirst ///< Columns are filled first, and a new element is wrapped to the next row if the column count would exceed \ref setWrap. + }; + Q_ENUMS(FillOrder) + + explicit QCPLayoutGrid(); + virtual ~QCPLayoutGrid(); + + // getters: + int rowCount() const { return mElements.size(); } + int columnCount() const { return mElements.size() > 0 ? mElements.first().size() : 0; } + QList columnStretchFactors() const { return mColumnStretchFactors; } + QList rowStretchFactors() const { return mRowStretchFactors; } + int columnSpacing() const { return mColumnSpacing; } + int rowSpacing() const { return mRowSpacing; } + int wrap() const { return mWrap; } + FillOrder fillOrder() const { return mFillOrder; } + + // setters: + void setColumnStretchFactor(int column, double factor); + void setColumnStretchFactors(const QList &factors); + void setRowStretchFactor(int row, double factor); + void setRowStretchFactors(const QList &factors); + void setColumnSpacing(int pixels); + void setRowSpacing(int pixels); + void setWrap(int count); + void setFillOrder(FillOrder order, bool rearrange=true); + + // reimplemented virtual methods: + virtual void updateLayout() Q_DECL_OVERRIDE; + virtual int elementCount() const Q_DECL_OVERRIDE { return rowCount()*columnCount(); } + virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE; + virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + virtual void simplify() Q_DECL_OVERRIDE; + virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; + virtual QSize maximumSizeHint() const Q_DECL_OVERRIDE; + + // non-virtual methods: + QCPLayoutElement *element(int row, int column) const; + bool addElement(int row, int column, QCPLayoutElement *element); + bool addElement(QCPLayoutElement *element); + bool hasElement(int row, int column); + void expandTo(int newRowCount, int newColumnCount); + void insertRow(int newIndex); + void insertColumn(int newIndex); + int rowColToIndex(int row, int column) const; + void indexToRowCol(int index, int &row, int &column) const; + +protected: + // property members: + QList > mElements; + QList mColumnStretchFactors; + QList mRowStretchFactors; + int mColumnSpacing, mRowSpacing; + int mWrap; + FillOrder mFillOrder; + + // non-virtual methods: + void getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const; + void getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const; + +private: + Q_DISABLE_COPY(QCPLayoutGrid) +}; +Q_DECLARE_METATYPE(QCPLayoutGrid::FillOrder) + + +class QCP_LIB_DECL QCPLayoutInset : public QCPLayout +{ + Q_OBJECT +public: + /*! + Defines how the placement and sizing is handled for a certain element in a QCPLayoutInset. + */ + enum InsetPlacement { ipFree ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect + ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment + }; + Q_ENUMS(InsetPlacement) + + explicit QCPLayoutInset(); + virtual ~QCPLayoutInset(); + + // getters: + InsetPlacement insetPlacement(int index) const; + Qt::Alignment insetAlignment(int index) const; + QRectF insetRect(int index) const; + + // setters: + void setInsetPlacement(int index, InsetPlacement placement); + void setInsetAlignment(int index, Qt::Alignment alignment); + void setInsetRect(int index, const QRectF &rect); + + // reimplemented virtual methods: + virtual void updateLayout() Q_DECL_OVERRIDE; + virtual int elementCount() const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE; + virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE; + virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE; + virtual void simplify() Q_DECL_OVERRIDE {} + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void addElement(QCPLayoutElement *element, Qt::Alignment alignment); + void addElement(QCPLayoutElement *element, const QRectF &rect); + +protected: + // property members: + QList mElements; + QList mInsetPlacement; + QList mInsetAlignment; + QList mInsetRect; + +private: + Q_DISABLE_COPY(QCPLayoutInset) +}; +Q_DECLARE_METATYPE(QCPLayoutInset::InsetPlacement) + +/* end of 'src/layout.h' */ + + +/* including file 'src/lineending.h', size 4426 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPLineEnding +{ + Q_GADGET +public: + /*! + Defines the type of ending decoration for line-like items, e.g. an arrow. + + \image html QCPLineEnding.png + + The width and length of these decorations can be controlled with the functions \ref setWidth + and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only + support a width, the length property is ignored. + + \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding + */ + enum EndingStyle { esNone ///< No ending decoration + ,esFlatArrow ///< A filled arrow head with a straight/flat back (a triangle) + ,esSpikeArrow ///< A filled arrow head with an indented back + ,esLineArrow ///< A non-filled arrow head with open back + ,esDisc ///< A filled circle + ,esSquare ///< A filled square + ,esDiamond ///< A filled diamond (45 degrees rotated square) + ,esBar ///< A bar perpendicular to the line + ,esHalfBar ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted) + ,esSkewedBar ///< A bar that is skewed (skew controllable via \ref setLength) + }; + Q_ENUMS(EndingStyle) + + QCPLineEnding(); + QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false); + + // getters: + EndingStyle style() const { return mStyle; } + double width() const { return mWidth; } + double length() const { return mLength; } + bool inverted() const { return mInverted; } + + // setters: + void setStyle(EndingStyle style); + void setWidth(double width); + void setLength(double length); + void setInverted(bool inverted); + + // non-property methods: + double boundingDistance() const; + double realLength() const; + void draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const; + void draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const; + +protected: + // property members: + EndingStyle mStyle; + double mWidth, mLength; + bool mInverted; +}; +Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE); +Q_DECLARE_METATYPE(QCPLineEnding::EndingStyle) + +/* end of 'src/lineending.h' */ + + +/* including file 'src/axis/axisticker.h', size 4177 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines the strategies that the axis ticker may follow when choosing the size of the tick step. + + \see setTickStepStrategy + */ + enum TickStepStrategy + { + tssReadability ///< A nicely readable tick step is prioritized over matching the requested number of ticks (see \ref setTickCount) + ,tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count + }; + Q_ENUMS(TickStepStrategy) + + QCPAxisTicker(); + virtual ~QCPAxisTicker(); + + // getters: + TickStepStrategy tickStepStrategy() const { return mTickStepStrategy; } + int tickCount() const { return mTickCount; } + double tickOrigin() const { return mTickOrigin; } + + // setters: + void setTickStepStrategy(TickStepStrategy strategy); + void setTickCount(int count); + void setTickOrigin(double origin); + + // introduced virtual methods: + virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels); + +protected: + // property members: + TickStepStrategy mTickStepStrategy; + int mTickCount; + double mTickOrigin; + + // introduced virtual methods: + virtual double getTickStep(const QCPRange &range); + virtual int getSubTickCount(double tickStep); + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision); + virtual QVector createTickVector(double tickStep, const QCPRange &range); + virtual QVector createSubTickVector(int subTickCount, const QVector &ticks); + virtual QVector createLabelVector(const QVector &ticks, const QLocale &locale, QChar formatChar, int precision); + + // non-virtual methods: + void trimTicks(const QCPRange &range, QVector &ticks, bool keepOneOutlier) const; + double pickClosest(double target, const QVector &candidates) const; + double getMantissa(double input, double *magnitude=0) const; + double cleanMantissa(double input) const; +}; +Q_DECLARE_METATYPE(QCPAxisTicker::TickStepStrategy) +Q_DECLARE_METATYPE(QSharedPointer) + +/* end of 'src/axis/axisticker.h' */ + + +/* including file 'src/axis/axistickerdatetime.h', size 3289 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerDateTime : public QCPAxisTicker +{ +public: + QCPAxisTickerDateTime(); + + // getters: + QString dateTimeFormat() const { return mDateTimeFormat; } + Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; } + + // setters: + void setDateTimeFormat(const QString &format); + void setDateTimeSpec(Qt::TimeSpec spec); + void setTickOrigin(double origin); // hides base class method but calls baseclass implementation ("using" throws off IDEs and doxygen) + void setTickOrigin(const QDateTime &origin); + + // static methods: + static QDateTime keyToDateTime(double key); + static double dateTimeToKey(const QDateTime dateTime); + static double dateTimeToKey(const QDate date); + +protected: + // property members: + QString mDateTimeFormat; + Qt::TimeSpec mDateTimeSpec; + + // non-property members: + enum DateStrategy {dsNone, dsUniformTimeInDay, dsUniformDayInMonth} mDateStrategy; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; +}; + +/* end of 'src/axis/axistickerdatetime.h' */ + + +/* including file 'src/axis/axistickertime.h', size 3288 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines the logical units in which fractions of time spans can be expressed. + + \see setFieldWidth, setTimeFormat + */ + enum TimeUnit { tuMilliseconds + ,tuSeconds + ,tuMinutes + ,tuHours + ,tuDays + }; + Q_ENUMS(TimeUnit) + + QCPAxisTickerTime(); + + // getters: + QString timeFormat() const { return mTimeFormat; } + int fieldWidth(TimeUnit unit) const { return mFieldWidth.value(unit); } + + // setters: + void setTimeFormat(const QString &format); + void setFieldWidth(TimeUnit unit, int width); + +protected: + // property members: + QString mTimeFormat; + QHash mFieldWidth; + + // non-property members: + TimeUnit mSmallestUnit, mBiggestUnit; + QHash mFormatPattern; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + + // non-virtual methods: + void replaceUnit(QString &text, TimeUnit unit, int value) const; +}; +Q_DECLARE_METATYPE(QCPAxisTickerTime::TimeUnit) + +/* end of 'src/axis/axistickertime.h' */ + + +/* including file 'src/axis/axistickerfixed.h', size 3308 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerFixed : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines how the axis ticker may modify the specified tick step (\ref setTickStep) in order to + control the number of ticks in the axis range. + + \see setScaleStrategy + */ + enum ScaleStrategy { ssNone ///< Modifications are not allowed, the specified tick step is absolutely fixed. This might cause a high tick density and overlapping labels if the axis range is zoomed out. + ,ssMultiples ///< An integer multiple of the specified tick step is allowed. The used factor follows the base class properties of \ref setTickStepStrategy and \ref setTickCount. + ,ssPowers ///< An integer power of the specified tick step is allowed. + }; + Q_ENUMS(ScaleStrategy) + + QCPAxisTickerFixed(); + + // getters: + double tickStep() const { return mTickStep; } + ScaleStrategy scaleStrategy() const { return mScaleStrategy; } + + // setters: + void setTickStep(double step); + void setScaleStrategy(ScaleStrategy strategy); + +protected: + // property members: + double mTickStep; + ScaleStrategy mScaleStrategy; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; +}; +Q_DECLARE_METATYPE(QCPAxisTickerFixed::ScaleStrategy) + +/* end of 'src/axis/axistickerfixed.h' */ + + +/* including file 'src/axis/axistickertext.h', size 3085 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerText : public QCPAxisTicker +{ +public: + QCPAxisTickerText(); + + // getters: + QMap &ticks() { return mTicks; } + int subTickCount() const { return mSubTickCount; } + + // setters: + void setTicks(const QMap &ticks); + void setTicks(const QVector &positions, const QVector labels); + void setSubTickCount(int subTicks); + + // non-virtual methods: + void clear(); + void addTick(double position, QString label); + void addTicks(const QMap &ticks); + void addTicks(const QVector &positions, const QVector &labels); + +protected: + // property members: + QMap mTicks; + int mSubTickCount; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; + +}; + +/* end of 'src/axis/axistickertext.h' */ + + +/* including file 'src/axis/axistickerpi.h', size 3911 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerPi : public QCPAxisTicker +{ + Q_GADGET +public: + /*! + Defines how fractions should be displayed in tick labels. + + \see setFractionStyle + */ + enum FractionStyle { fsFloatingPoint ///< Fractions are displayed as regular decimal floating point numbers, e.g. "0.25" or "0.125". + ,fsAsciiFractions ///< Fractions are written as rationals using ASCII characters only, e.g. "1/4" or "1/8" + ,fsUnicodeFractions ///< Fractions are written using sub- and superscript UTF-8 digits and the fraction symbol. + }; + Q_ENUMS(FractionStyle) + + QCPAxisTickerPi(); + + // getters: + QString piSymbol() const { return mPiSymbol; } + double piValue() const { return mPiValue; } + bool periodicity() const { return mPeriodicity; } + FractionStyle fractionStyle() const { return mFractionStyle; } + + // setters: + void setPiSymbol(QString symbol); + void setPiValue(double pi); + void setPeriodicity(int multiplesOfPi); + void setFractionStyle(FractionStyle style); + +protected: + // property members: + QString mPiSymbol; + double mPiValue; + int mPeriodicity; + FractionStyle mFractionStyle; + + // non-property members: + double mPiTickStep; // size of one tick step in units of mPiValue + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE; + + // non-virtual methods: + void simplifyFraction(int &numerator, int &denominator) const; + QString fractionToString(int numerator, int denominator) const; + QString unicodeFraction(int numerator, int denominator) const; + QString unicodeSuperscript(int number) const; + QString unicodeSubscript(int number) const; +}; +Q_DECLARE_METATYPE(QCPAxisTickerPi::FractionStyle) + +/* end of 'src/axis/axistickerpi.h' */ + + +/* including file 'src/axis/axistickerlog.h', size 2663 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPAxisTickerLog : public QCPAxisTicker +{ +public: + QCPAxisTickerLog(); + + // getters: + double logBase() const { return mLogBase; } + int subTickCount() const { return mSubTickCount; } + + // setters: + void setLogBase(double base); + void setSubTickCount(int subTicks); + +protected: + // property members: + double mLogBase; + int mSubTickCount; + + // non-property members: + double mLogBaseLnInv; + + // reimplemented virtual methods: + virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; + virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; + virtual QVector createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE; +}; + +/* end of 'src/axis/axistickerlog.h' */ + + +/* including file 'src/axis/axis.h', size 20230 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPGrid :public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool subGridVisible READ subGridVisible WRITE setSubGridVisible) + Q_PROPERTY(bool antialiasedSubGrid READ antialiasedSubGrid WRITE setAntialiasedSubGrid) + Q_PROPERTY(bool antialiasedZeroLine READ antialiasedZeroLine WRITE setAntialiasedZeroLine) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen subGridPen READ subGridPen WRITE setSubGridPen) + Q_PROPERTY(QPen zeroLinePen READ zeroLinePen WRITE setZeroLinePen) + /// \endcond +public: + explicit QCPGrid(QCPAxis *parentAxis); + + // getters: + bool subGridVisible() const { return mSubGridVisible; } + bool antialiasedSubGrid() const { return mAntialiasedSubGrid; } + bool antialiasedZeroLine() const { return mAntialiasedZeroLine; } + QPen pen() const { return mPen; } + QPen subGridPen() const { return mSubGridPen; } + QPen zeroLinePen() const { return mZeroLinePen; } + + // setters: + void setSubGridVisible(bool visible); + void setAntialiasedSubGrid(bool enabled); + void setAntialiasedZeroLine(bool enabled); + void setPen(const QPen &pen); + void setSubGridPen(const QPen &pen); + void setZeroLinePen(const QPen &pen); + +protected: + // property members: + bool mSubGridVisible; + bool mAntialiasedSubGrid, mAntialiasedZeroLine; + QPen mPen, mSubGridPen, mZeroLinePen; + + // non-property members: + QCPAxis *mParentAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + void drawGridLines(QCPPainter *painter) const; + void drawSubGridLines(QCPPainter *painter) const; + + friend class QCPAxis; +}; + + +class QCP_LIB_DECL QCPAxis : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(AxisType axisType READ axisType) + Q_PROPERTY(QCPAxisRect* axisRect READ axisRect) + Q_PROPERTY(ScaleType scaleType READ scaleType WRITE setScaleType NOTIFY scaleTypeChanged) + Q_PROPERTY(QCPRange range READ range WRITE setRange NOTIFY rangeChanged) + Q_PROPERTY(bool rangeReversed READ rangeReversed WRITE setRangeReversed) + Q_PROPERTY(QSharedPointer ticker READ ticker WRITE setTicker) + Q_PROPERTY(bool ticks READ ticks WRITE setTicks) + Q_PROPERTY(bool tickLabels READ tickLabels WRITE setTickLabels) + Q_PROPERTY(int tickLabelPadding READ tickLabelPadding WRITE setTickLabelPadding) + Q_PROPERTY(QFont tickLabelFont READ tickLabelFont WRITE setTickLabelFont) + Q_PROPERTY(QColor tickLabelColor READ tickLabelColor WRITE setTickLabelColor) + Q_PROPERTY(double tickLabelRotation READ tickLabelRotation WRITE setTickLabelRotation) + Q_PROPERTY(LabelSide tickLabelSide READ tickLabelSide WRITE setTickLabelSide) + Q_PROPERTY(QString numberFormat READ numberFormat WRITE setNumberFormat) + Q_PROPERTY(int numberPrecision READ numberPrecision WRITE setNumberPrecision) + Q_PROPERTY(QVector tickVector READ tickVector) + Q_PROPERTY(QVector tickVectorLabels READ tickVectorLabels) + Q_PROPERTY(int tickLengthIn READ tickLengthIn WRITE setTickLengthIn) + Q_PROPERTY(int tickLengthOut READ tickLengthOut WRITE setTickLengthOut) + Q_PROPERTY(bool subTicks READ subTicks WRITE setSubTicks) + Q_PROPERTY(int subTickLengthIn READ subTickLengthIn WRITE setSubTickLengthIn) + Q_PROPERTY(int subTickLengthOut READ subTickLengthOut WRITE setSubTickLengthOut) + Q_PROPERTY(QPen basePen READ basePen WRITE setBasePen) + Q_PROPERTY(QPen tickPen READ tickPen WRITE setTickPen) + Q_PROPERTY(QPen subTickPen READ subTickPen WRITE setSubTickPen) + Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont) + Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int labelPadding READ labelPadding WRITE setLabelPadding) + Q_PROPERTY(int padding READ padding WRITE setPadding) + Q_PROPERTY(int offset READ offset WRITE setOffset) + Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged) + Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged) + Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont) + Q_PROPERTY(QFont selectedLabelFont READ selectedLabelFont WRITE setSelectedLabelFont) + Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor) + Q_PROPERTY(QColor selectedLabelColor READ selectedLabelColor WRITE setSelectedLabelColor) + Q_PROPERTY(QPen selectedBasePen READ selectedBasePen WRITE setSelectedBasePen) + Q_PROPERTY(QPen selectedTickPen READ selectedTickPen WRITE setSelectedTickPen) + Q_PROPERTY(QPen selectedSubTickPen READ selectedSubTickPen WRITE setSelectedSubTickPen) + Q_PROPERTY(QCPLineEnding lowerEnding READ lowerEnding WRITE setLowerEnding) + Q_PROPERTY(QCPLineEnding upperEnding READ upperEnding WRITE setUpperEnding) + Q_PROPERTY(QCPGrid* grid READ grid) + /// \endcond +public: + /*! + Defines at which side of the axis rect the axis will appear. This also affects how the tick + marks are drawn, on which side the labels are placed etc. + */ + enum AxisType { atLeft = 0x01 ///< 0x01 Axis is vertical and on the left side of the axis rect + ,atRight = 0x02 ///< 0x02 Axis is vertical and on the right side of the axis rect + ,atTop = 0x04 ///< 0x04 Axis is horizontal and on the top side of the axis rect + ,atBottom = 0x08 ///< 0x08 Axis is horizontal and on the bottom side of the axis rect + }; + Q_ENUMS(AxisType) + Q_FLAGS(AxisTypes) + Q_DECLARE_FLAGS(AxisTypes, AxisType) + /*! + Defines on which side of the axis the tick labels (numbers) shall appear. + + \see setTickLabelSide + */ + enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect + ,lsOutside ///< Tick labels will be displayed outside the axis rect + }; + Q_ENUMS(LabelSide) + /*! + Defines the scale of an axis. + \see setScaleType + */ + enum ScaleType { stLinear ///< Linear scaling + ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance). + }; + Q_ENUMS(ScaleType) + /*! + Defines the selectable parts of an axis. + \see setSelectableParts, setSelectedParts + */ + enum SelectablePart { spNone = 0 ///< None of the selectable parts + ,spAxis = 0x001 ///< The axis backbone and tick marks + ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually) + ,spAxisLabel = 0x004 ///< The axis label + }; + Q_ENUMS(SelectablePart) + Q_FLAGS(SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPAxis(QCPAxisRect *parent, AxisType type); + virtual ~QCPAxis(); + + // getters: + AxisType axisType() const { return mAxisType; } + QCPAxisRect *axisRect() const { return mAxisRect; } + ScaleType scaleType() const { return mScaleType; } + const QCPRange range() const { return mRange; } + bool rangeReversed() const { return mRangeReversed; } + QSharedPointer ticker() const { return mTicker; } + bool ticks() const { return mTicks; } + bool tickLabels() const { return mTickLabels; } + int tickLabelPadding() const; + QFont tickLabelFont() const { return mTickLabelFont; } + QColor tickLabelColor() const { return mTickLabelColor; } + double tickLabelRotation() const; + LabelSide tickLabelSide() const; + QString numberFormat() const; + int numberPrecision() const { return mNumberPrecision; } + QVector tickVector() const { return mTickVector; } + QVector tickVectorLabels() const { return mTickVectorLabels; } + int tickLengthIn() const; + int tickLengthOut() const; + bool subTicks() const { return mSubTicks; } + int subTickLengthIn() const; + int subTickLengthOut() const; + QPen basePen() const { return mBasePen; } + QPen tickPen() const { return mTickPen; } + QPen subTickPen() const { return mSubTickPen; } + QFont labelFont() const { return mLabelFont; } + QColor labelColor() const { return mLabelColor; } + QString label() const { return mLabel; } + int labelPadding() const; + int padding() const { return mPadding; } + int offset() const; + SelectableParts selectedParts() const { return mSelectedParts; } + SelectableParts selectableParts() const { return mSelectableParts; } + QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; } + QFont selectedLabelFont() const { return mSelectedLabelFont; } + QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; } + QColor selectedLabelColor() const { return mSelectedLabelColor; } + QPen selectedBasePen() const { return mSelectedBasePen; } + QPen selectedTickPen() const { return mSelectedTickPen; } + QPen selectedSubTickPen() const { return mSelectedSubTickPen; } + QCPLineEnding lowerEnding() const; + QCPLineEnding upperEnding() const; + QCPGrid *grid() const { return mGrid; } + + // setters: + Q_SLOT void setScaleType(QCPAxis::ScaleType type); + Q_SLOT void setRange(const QCPRange &range); + void setRange(double lower, double upper); + void setRange(double position, double size, Qt::AlignmentFlag alignment); + void setRangeLower(double lower); + void setRangeUpper(double upper); + void setRangeReversed(bool reversed); + void setTicker(QSharedPointer ticker); + void setTicks(bool show); + void setTickLabels(bool show); + void setTickLabelPadding(int padding); + void setTickLabelFont(const QFont &font); + void setTickLabelColor(const QColor &color); + void setTickLabelRotation(double degrees); + void setTickLabelSide(LabelSide side); + void setNumberFormat(const QString &formatCode); + void setNumberPrecision(int precision); + void setTickLength(int inside, int outside=0); + void setTickLengthIn(int inside); + void setTickLengthOut(int outside); + void setSubTicks(bool show); + void setSubTickLength(int inside, int outside=0); + void setSubTickLengthIn(int inside); + void setSubTickLengthOut(int outside); + void setBasePen(const QPen &pen); + void setTickPen(const QPen &pen); + void setSubTickPen(const QPen &pen); + void setLabelFont(const QFont &font); + void setLabelColor(const QColor &color); + void setLabel(const QString &str); + void setLabelPadding(int padding); + void setPadding(int padding); + void setOffset(int offset); + void setSelectedTickLabelFont(const QFont &font); + void setSelectedLabelFont(const QFont &font); + void setSelectedTickLabelColor(const QColor &color); + void setSelectedLabelColor(const QColor &color); + void setSelectedBasePen(const QPen &pen); + void setSelectedTickPen(const QPen &pen); + void setSelectedSubTickPen(const QPen &pen); + Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts); + void setLowerEnding(const QCPLineEnding &ending); + void setUpperEnding(const QCPLineEnding &ending); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-property methods: + Qt::Orientation orientation() const { return mOrientation; } + int pixelOrientation() const { return rangeReversed() != (orientation()==Qt::Vertical) ? -1 : 1; } + void moveRange(double diff); + void scaleRange(double factor); + void scaleRange(double factor, double center); + void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0); + void rescale(bool onlyVisiblePlottables=false); + double pixelToCoord(double value) const; + double coordToPixel(double value) const; + SelectablePart getPartAt(const QPointF &pos) const; + QList plottables() const; + QList graphs() const; + QList items() const; + + static AxisType marginSideToAxisType(QCP::MarginSide side); + static Qt::Orientation orientation(AxisType type) { return type==atBottom||type==atTop ? Qt::Horizontal : Qt::Vertical; } + static AxisType opposite(AxisType type); + +signals: + void rangeChanged(const QCPRange &newRange); + void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); + void scaleTypeChanged(QCPAxis::ScaleType scaleType); + void selectionChanged(const QCPAxis::SelectableParts &parts); + void selectableChanged(const QCPAxis::SelectableParts &parts); + +protected: + // property members: + // axis base: + AxisType mAxisType; + QCPAxisRect *mAxisRect; + //int mOffset; // in QCPAxisPainter + int mPadding; + Qt::Orientation mOrientation; + SelectableParts mSelectableParts, mSelectedParts; + QPen mBasePen, mSelectedBasePen; + //QCPLineEnding mLowerEnding, mUpperEnding; // in QCPAxisPainter + // axis label: + //int mLabelPadding; // in QCPAxisPainter + QString mLabel; + QFont mLabelFont, mSelectedLabelFont; + QColor mLabelColor, mSelectedLabelColor; + // tick labels: + //int mTickLabelPadding; // in QCPAxisPainter + bool mTickLabels; + //double mTickLabelRotation; // in QCPAxisPainter + QFont mTickLabelFont, mSelectedTickLabelFont; + QColor mTickLabelColor, mSelectedTickLabelColor; + int mNumberPrecision; + QLatin1Char mNumberFormatChar; + bool mNumberBeautifulPowers; + //bool mNumberMultiplyCross; // QCPAxisPainter + // ticks and subticks: + bool mTicks; + bool mSubTicks; + //int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; // QCPAxisPainter + QPen mTickPen, mSelectedTickPen; + QPen mSubTickPen, mSelectedSubTickPen; + // scale and range: + QCPRange mRange; + bool mRangeReversed; + ScaleType mScaleType; + + // non-property members: + QCPGrid *mGrid; + QCPAxisPainterPrivate *mAxisPainter; + QSharedPointer mTicker; + QVector mTickVector; + QVector mTickVectorLabels; + QVector mSubTickVector; + bool mCachedMarginValid; + int mCachedMargin; + + // introduced virtual methods: + virtual int calculateMargin(); + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // non-virtual methods: + void setupTickVectors(); + QPen getBasePen() const; + QPen getTickPen() const; + QPen getSubTickPen() const; + QFont getTickLabelFont() const; + QFont getLabelFont() const; + QColor getTickLabelColor() const; + QColor getLabelColor() const; + +private: + Q_DISABLE_COPY(QCPAxis) + + friend class QCustomPlot; + friend class QCPGrid; + friend class QCPAxisRect; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::SelectableParts) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::AxisTypes) +Q_DECLARE_METATYPE(QCPAxis::AxisType) +Q_DECLARE_METATYPE(QCPAxis::LabelSide) +Q_DECLARE_METATYPE(QCPAxis::ScaleType) +Q_DECLARE_METATYPE(QCPAxis::SelectablePart) + + +class QCPAxisPainterPrivate +{ +public: + explicit QCPAxisPainterPrivate(QCustomPlot *parentPlot); + virtual ~QCPAxisPainterPrivate(); + + virtual void draw(QCPPainter *painter); + virtual int size() const; + void clearCache(); + + QRect axisSelectionBox() const { return mAxisSelectionBox; } + QRect tickLabelsSelectionBox() const { return mTickLabelsSelectionBox; } + QRect labelSelectionBox() const { return mLabelSelectionBox; } + + // public property members: + QCPAxis::AxisType type; + QPen basePen; + QCPLineEnding lowerEnding, upperEnding; // directly accessed by QCPAxis setters/getters + int labelPadding; // directly accessed by QCPAxis setters/getters + QFont labelFont; + QColor labelColor; + QString label; + int tickLabelPadding; // directly accessed by QCPAxis setters/getters + double tickLabelRotation; // directly accessed by QCPAxis setters/getters + QCPAxis::LabelSide tickLabelSide; // directly accessed by QCPAxis setters/getters + bool substituteExponent; + bool numberMultiplyCross; // directly accessed by QCPAxis setters/getters + int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters + QPen tickPen, subTickPen; + QFont tickLabelFont; + QColor tickLabelColor; + QRect axisRect, viewportRect; + double offset; // directly accessed by QCPAxis setters/getters + bool abbreviateDecimalPowers; + bool reversedEndings; + + QVector subTickPositions; + QVector tickPositions; + QVector tickLabels; + +protected: + struct CachedLabel + { + QPointF offset; + QPixmap pixmap; + }; + struct TickLabelData + { + QString basePart, expPart, suffixPart; + QRect baseBounds, expBounds, suffixBounds, totalBounds, rotatedTotalBounds; + QFont baseFont, expFont; + }; + QCustomPlot *mParentPlot; + QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters + QCache mLabelCache; + QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox; + + virtual QByteArray generateLabelParameterHash() const; + + virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize); + virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const; + virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const; + virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const; + virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const; +}; + +/* end of 'src/axis/axis.h' */ + + +/* including file 'src/scatterstyle.h', size 7275 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPScatterStyle +{ + Q_GADGET +public: + /*! + Represents the various properties of a scatter style instance. For example, this enum is used + to specify which properties of \ref QCPSelectionDecorator::setScatterStyle will be used when + highlighting selected data points. + + Specific scatter properties can be transferred between \ref QCPScatterStyle instances via \ref + setFromOther. + */ + enum ScatterProperty { spNone = 0x00 ///< 0x00 None + ,spPen = 0x01 ///< 0x01 The pen property, see \ref setPen + ,spBrush = 0x02 ///< 0x02 The brush property, see \ref setBrush + ,spSize = 0x04 ///< 0x04 The size property, see \ref setSize + ,spShape = 0x08 ///< 0x08 The shape property, see \ref setShape + ,spAll = 0xFF ///< 0xFF All properties + }; + Q_ENUMS(ScatterProperty) + Q_FLAGS(ScatterProperties) + Q_DECLARE_FLAGS(ScatterProperties, ScatterProperty) + + /*! + Defines the shape used for scatter points. + + On plottables/items that draw scatters, the sizes of these visualizations (with exception of + \ref ssDot and \ref ssPixmap) can be controlled with the \ref setSize function. Scatters are + drawn with the pen and brush specified with \ref setPen and \ref setBrush. + */ + enum ScatterShape { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines) + ,ssDot ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius) + ,ssCross ///< \enumimage{ssCross.png} a cross + ,ssPlus ///< \enumimage{ssPlus.png} a plus + ,ssCircle ///< \enumimage{ssCircle.png} a circle + ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle) + ,ssSquare ///< \enumimage{ssSquare.png} a square + ,ssDiamond ///< \enumimage{ssDiamond.png} a diamond + ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus + ,ssTriangle ///< \enumimage{ssTriangle.png} an equilateral triangle, standing on baseline + ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner + ,ssCrossSquare ///< \enumimage{ssCrossSquare.png} a square with a cross inside + ,ssPlusSquare ///< \enumimage{ssPlusSquare.png} a square with a plus inside + ,ssCrossCircle ///< \enumimage{ssCrossCircle.png} a circle with a cross inside + ,ssPlusCircle ///< \enumimage{ssPlusCircle.png} a circle with a plus inside + ,ssPeace ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines + ,ssPixmap ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates + ,ssCustom ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath) + }; + Q_ENUMS(ScatterShape) + + QCPScatterStyle(); + QCPScatterStyle(ScatterShape shape, double size=6); + QCPScatterStyle(ScatterShape shape, const QColor &color, double size); + QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size); + QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size); + QCPScatterStyle(const QPixmap &pixmap); + QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6); + + // getters: + double size() const { return mSize; } + ScatterShape shape() const { return mShape; } + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QPixmap pixmap() const { return mPixmap; } + QPainterPath customPath() const { return mCustomPath; } + + // setters: + void setFromOther(const QCPScatterStyle &other, ScatterProperties properties); + void setSize(double size); + void setShape(ScatterShape shape); + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setPixmap(const QPixmap &pixmap); + void setCustomPath(const QPainterPath &customPath); + + // non-property methods: + bool isNone() const { return mShape == ssNone; } + bool isPenDefined() const { return mPenDefined; } + void undefinePen(); + void applyTo(QCPPainter *painter, const QPen &defaultPen) const; + void drawShape(QCPPainter *painter, const QPointF &pos) const; + void drawShape(QCPPainter *painter, double x, double y) const; + +protected: + // property members: + double mSize; + ScatterShape mShape; + QPen mPen; + QBrush mBrush; + QPixmap mPixmap; + QPainterPath mCustomPath; + + // non-property members: + bool mPenDefined; +}; +Q_DECLARE_TYPEINFO(QCPScatterStyle, Q_MOVABLE_TYPE); +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPScatterStyle::ScatterProperties) +Q_DECLARE_METATYPE(QCPScatterStyle::ScatterProperty) +Q_DECLARE_METATYPE(QCPScatterStyle::ScatterShape) + +/* end of 'src/scatterstyle.h' */ + + +/* including file 'src/datacontainer.h', size 4535 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +/*! \relates QCPDataContainer + Returns whether the sort key of \a a is less than the sort key of \a b. + + \see QCPDataContainer::sort +*/ +template +inline bool qcpLessThanSortKey(const DataType &a, const DataType &b) { return a.sortKey() < b.sortKey(); } + +template +class QCP_LIB_DECL QCPDataContainer +{ +public: + typedef typename QVector::const_iterator const_iterator; + typedef typename QVector::iterator iterator; + + QCPDataContainer(); + + // getters: + int size() const { return mData.size()-mPreallocSize; } + bool isEmpty() const { return size() == 0; } + bool autoSqueeze() const { return mAutoSqueeze; } + + // setters: + void setAutoSqueeze(bool enabled); + + // non-virtual methods: + void set(const QCPDataContainer &data); + void set(const QVector &data, bool alreadySorted=false); + void add(const QCPDataContainer &data); + void add(const QVector &data, bool alreadySorted=false); + void add(const DataType &data); + void removeBefore(double sortKey); + void removeAfter(double sortKey); + void remove(double sortKeyFrom, double sortKeyTo); + void remove(double sortKey); + void clear(); + void sort(); + void squeeze(bool preAllocation=true, bool postAllocation=true); + + const_iterator constBegin() const { return mData.constBegin()+mPreallocSize; } + const_iterator constEnd() const { return mData.constEnd(); } + iterator begin() { return mData.begin()+mPreallocSize; } + iterator end() { return mData.end(); } + const_iterator findBegin(double sortKey, bool expandedRange=true) const; + const_iterator findEnd(double sortKey, bool expandedRange=true) const; + const_iterator at(int index) const { return constBegin()+qBound(0, index, size()); } + QCPRange keyRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth); + QCPRange valueRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()); + QCPDataRange dataRange() const { return QCPDataRange(0, size()); } + void limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const; + +protected: + // property members: + bool mAutoSqueeze; + + // non-property memebers: + QVector mData; + int mPreallocSize; + int mPreallocIteration; + + // non-virtual methods: + void preallocateGrow(int minimumPreallocSize); + void performAutoSqueeze(); +}; + +// include implementation in header since it is a class template: + +/* including file 'src/datacontainer.cpp', size 31224 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPDataContainer +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPDataContainer + \brief The generic data container for one-dimensional plottables + + This class template provides a fast container for data storage of one-dimensional data. The data + type is specified as template parameter (called \a DataType in the following) and must provide + some methods as described in the \ref qcpdatacontainer-datatype "next section". + + The data is stored in a sorted fashion, which allows very quick lookups by the sorted key as well + as retrieval of ranges (see \ref findBegin, \ref findEnd, \ref keyRange) using binary search. The + container uses a preallocation and a postallocation scheme, such that appending and prepending + data (with respect to the sort key) is very fast and minimizes reallocations. If data is added + which needs to be inserted between existing keys, the merge usually can be done quickly too, + using the fact that existing data is always sorted. The user can further improve performance by + specifying that added data is already itself sorted by key, if he can guarantee that this is the + case (see for example \ref add(const QVector &data, bool alreadySorted)). + + The data can be accessed with the provided const iterators (\ref constBegin, \ref constEnd). If + it is necessary to alter existing data in-place, the non-const iterators can be used (\ref begin, + \ref end). Changing data members that are not the sort key (for most data types called \a key) is + safe from the container's perspective. + + Great care must be taken however if the sort key is modified through the non-const iterators. For + performance reasons, the iterators don't automatically cause a re-sorting upon their + manipulation. It is thus the responsibility of the user to leave the container in a sorted state + when finished with the data manipulation, before calling any other methods on the container. A + complete re-sort (e.g. after finishing all sort key manipulation) can be done by calling \ref + sort. Failing to do so can not be detected by the container efficiently and will cause both + rendering artifacts and potential data loss. + + Implementing one-dimensional plottables that make use of a \ref QCPDataContainer is usually + done by subclassing from \ref QCPAbstractPlottable1D "QCPAbstractPlottable1D", which + introduces an according \a mDataContainer member and some convenience methods. + + \section qcpdatacontainer-datatype Requirements for the DataType template parameter + + The template parameter DataType is the type of the stored data points. It must be + trivially copyable and have the following public methods, preferably inline: + + \li double sortKey() const\n Returns the member variable of this data point that is the + sort key, defining the ordering in the container. Often this variable is simply called \a key. + + \li static DataType fromSortKey(double sortKey)\n Returns a new instance of the data + type initialized with its sort key set to \a sortKey. + + \li static bool sortKeyIsMainKey()\n Returns true if the sort key is equal to the main + key (see method \c mainKey below). For most plottables this is the case. It is not the case for + example for \ref QCPCurve, which uses \a t as sort key and \a key as main key. This is the reason + why QCPCurve unlike QCPGraph can display parametric curves with loops. + + \li double mainKey() const\n Returns the variable of this data point considered the main + key. This is commonly the variable that is used as the coordinate of this data point on the key + axis of the plottable. This method is used for example when determining the automatic axis + rescaling of key axes (\ref QCPAxis::rescale). + + \li double mainValue() const\n Returns the variable of this data point considered the + main value. This is commonly the variable that is used as the coordinate of this data point on + the value axis of the plottable. + + \li QCPRange valueRange() const\n Returns the range this data point spans in the value + axis coordinate. If the data is single-valued (e.g. QCPGraphData), this is simply a range with + both lower and upper set to the main data point value. However if the data points can represent + multiple values at once (e.g QCPFinancialData with its \a high, \a low, \a open and \a close + values at each \a key) this method should return the range those values span. This method is used + for example when determining the automatic axis rescaling of value axes (\ref + QCPAxis::rescale). +*/ + +/* start documentation of inline functions */ + +/*! \fn int QCPDataContainer::size() const + + Returns the number of data points in the container. +*/ + +/*! \fn bool QCPDataContainer::isEmpty() const + + Returns whether this container holds no data points. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::constBegin() const + + Returns a const iterator to the first data point in this container. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::constEnd() const + + Returns a const iterator to the element past the last data point in this container. +*/ + +/*! \fn QCPDataContainer::iterator QCPDataContainer::begin() const + + Returns a non-const iterator to the first data point in this container. + + You can manipulate the data points in-place through the non-const iterators, but great care must + be taken when manipulating the sort key of a data point, see \ref sort, or the detailed + description of this class. +*/ + +/*! \fn QCPDataContainer::iterator QCPDataContainer::end() const + + Returns a non-const iterator to the element past the last data point in this container. + + You can manipulate the data points in-place through the non-const iterators, but great care must + be taken when manipulating the sort key of a data point, see \ref sort, or the detailed + description of this class. +*/ + +/*! \fn QCPDataContainer::const_iterator QCPDataContainer::at(int index) const + + Returns a const iterator to the element with the specified \a index. If \a index points beyond + the available elements in this container, returns \ref constEnd, i.e. an iterator past the last + valid element. + + You can use this method to easily obtain iterators from a \ref QCPDataRange, see the \ref + dataselection-accessing "data selection page" for an example. +*/ + +/*! \fn QCPDataRange QCPDataContainer::dataRange() const + + Returns a \ref QCPDataRange encompassing the entire data set of this container. This means the + begin index of the returned range is 0, and the end index is \ref size. +*/ + +/* end documentation of inline functions */ + +/*! + Constructs a QCPDataContainer used for plottable classes that represent a series of key-sorted + data +*/ +template +QCPDataContainer::QCPDataContainer() : + mAutoSqueeze(true), + mPreallocSize(0), + mPreallocIteration(0) +{ +} + +/*! + Sets whether the container automatically decides when to release memory from its post- and + preallocation pools when data points are removed. By default this is enabled and for typical + applications shouldn't be changed. + + If auto squeeze is disabled, you can manually decide when to release pre-/postallocation with + \ref squeeze. +*/ +template +void QCPDataContainer::setAutoSqueeze(bool enabled) +{ + if (mAutoSqueeze != enabled) + { + mAutoSqueeze = enabled; + if (mAutoSqueeze) + performAutoSqueeze(); + } +} + +/*! \overload + + Replaces the current data in this container with the provided \a data. + + \see add, remove +*/ +template +void QCPDataContainer::set(const QCPDataContainer &data) +{ + clear(); + add(data); +} + +/*! \overload + + Replaces the current data in this container with the provided \a data + + If you can guarantee that the data points in \a data have ascending order with respect to the + DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. + + \see add, remove +*/ +template +void QCPDataContainer::set(const QVector &data, bool alreadySorted) +{ + mData = data; + mPreallocSize = 0; + mPreallocIteration = 0; + if (!alreadySorted) + sort(); +} + +/*! \overload + + Adds the provided \a data to the current data in this container. + + \see set, remove +*/ +template +void QCPDataContainer::add(const QCPDataContainer &data) +{ + if (data.isEmpty()) + return; + + const int n = data.size(); + const int oldSize = size(); + + if (oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data keys are all smaller than or equal to existing ones + { + if (mPreallocSize < n) + preallocateGrow(n); + mPreallocSize -= n; + std::copy(data.constBegin(), data.constEnd(), begin()); + } else // don't need to prepend, so append and merge if necessary + { + mData.resize(mData.size()+n); + std::copy(data.constBegin(), data.constEnd(), end()-n); + if (oldSize > 0 && !qcpLessThanSortKey(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions + std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey); + } +} + +/*! + Adds the provided data points in \a data to the current data. + + If you can guarantee that the data points in \a data have ascending order with respect to the + DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. + + \see set, remove +*/ +template +void QCPDataContainer::add(const QVector &data, bool alreadySorted) +{ + if (data.isEmpty()) + return; + if (isEmpty()) + { + set(data, alreadySorted); + return; + } + + const int n = data.size(); + const int oldSize = size(); + + if (alreadySorted && oldSize > 0 && !qcpLessThanSortKey(*constBegin(), *(data.constEnd()-1))) // prepend if new data is sorted and keys are all smaller than or equal to existing ones + { + if (mPreallocSize < n) + preallocateGrow(n); + mPreallocSize -= n; + std::copy(data.constBegin(), data.constEnd(), begin()); + } else // don't need to prepend, so append and then sort and merge if necessary + { + mData.resize(mData.size()+n); + std::copy(data.constBegin(), data.constEnd(), end()-n); + if (!alreadySorted) // sort appended subrange if it wasn't already sorted + std::sort(end()-n, end(), qcpLessThanSortKey); + if (oldSize > 0 && !qcpLessThanSortKey(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions + std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey); + } +} + +/*! \overload + + Adds the provided single data point to the current data. + + \see remove +*/ +template +void QCPDataContainer::add(const DataType &data) +{ + if (isEmpty() || !qcpLessThanSortKey(data, *(constEnd()-1))) // quickly handle appends if new data key is greater or equal to existing ones + { + mData.append(data); + } else if (qcpLessThanSortKey(data, *constBegin())) // quickly handle prepends using preallocated space + { + if (mPreallocSize < 1) + preallocateGrow(1); + --mPreallocSize; + *begin() = data; + } else // handle inserts, maintaining sorted keys + { + QCPDataContainer::iterator insertionPoint = std::lower_bound(begin(), end(), data, qcpLessThanSortKey); + mData.insert(insertionPoint, data); + } +} + +/*! + Removes all data points with (sort-)keys smaller than or equal to \a sortKey. + + \see removeAfter, remove, clear +*/ +template +void QCPDataContainer::removeBefore(double sortKey) +{ + QCPDataContainer::iterator it = begin(); + QCPDataContainer::iterator itEnd = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + mPreallocSize += itEnd-it; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it) + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points with (sort-)keys greater than or equal to \a sortKey. + + \see removeBefore, remove, clear +*/ +template +void QCPDataContainer::removeAfter(double sortKey) +{ + QCPDataContainer::iterator it = std::upper_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + QCPDataContainer::iterator itEnd = end(); + mData.erase(it, itEnd); // typically adds it to the postallocated block + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points with (sort-)keys between \a sortKeyFrom and \a sortKeyTo. if \a + sortKeyFrom is greater or equal to \a sortKeyTo, the function does nothing. To remove a single + data point with known (sort-)key, use \ref remove(double sortKey). + + \see removeBefore, removeAfter, clear +*/ +template +void QCPDataContainer::remove(double sortKeyFrom, double sortKeyTo) +{ + if (sortKeyFrom >= sortKeyTo || isEmpty()) + return; + + QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKeyFrom), qcpLessThanSortKey); + QCPDataContainer::iterator itEnd = std::upper_bound(it, end(), DataType::fromSortKey(sortKeyTo), qcpLessThanSortKey); + mData.erase(it, itEnd); + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! \overload + + Removes a single data point at \a sortKey. If the position is not known with absolute (binary) + precision, consider using \ref remove(double sortKeyFrom, double sortKeyTo) with a small + fuzziness interval around the suspected position, depeding on the precision with which the + (sort-)key is known. + + \see removeBefore, removeAfter, clear +*/ +template +void QCPDataContainer::remove(double sortKey) +{ + QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (it != end() && it->sortKey() == sortKey) + { + if (it == begin()) + ++mPreallocSize; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it) + else + mData.erase(it); + } + if (mAutoSqueeze) + performAutoSqueeze(); +} + +/*! + Removes all data points. + + \see remove, removeAfter, removeBefore +*/ +template +void QCPDataContainer::clear() +{ + mData.clear(); + mPreallocIteration = 0; + mPreallocSize = 0; +} + +/*! + Re-sorts all data points in the container by their sort key. + + When setting, adding or removing points using the QCPDataContainer interface (\ref set, \ref add, + \ref remove, etc.), the container makes sure to always stay in a sorted state such that a full + resort is never necessary. However, if you choose to directly manipulate the sort key on data + points by accessing and modifying it through the non-const iterators (\ref begin, \ref end), it + is your responsibility to bring the container back into a sorted state before any other methods + are called on it. This can be achieved by calling this method immediately after finishing the + sort key manipulation. +*/ +template +void QCPDataContainer::sort() +{ + std::sort(begin(), end(), qcpLessThanSortKey); +} + +/*! + Frees all unused memory that is currently in the preallocation and postallocation pools. + + Note that QCPDataContainer automatically decides whether squeezing is necessary, if \ref + setAutoSqueeze is left enabled. It should thus not be necessary to use this method for typical + applications. + + The parameters \a preAllocation and \a postAllocation control whether pre- and/or post allocation + should be freed, respectively. +*/ +template +void QCPDataContainer::squeeze(bool preAllocation, bool postAllocation) +{ + if (preAllocation) + { + if (mPreallocSize > 0) + { + std::copy(begin(), end(), mData.begin()); + mData.resize(size()); + mPreallocSize = 0; + } + mPreallocIteration = 0; + } + if (postAllocation) + mData.squeeze(); +} + +/*! + Returns an iterator to the data point with a (sort-)key that is equal to, just below, or just + above \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be + considered, otherwise the one just above. + + This can be used in conjunction with \ref findEnd to iterate over data points within a given key + range, including or excluding the bounding data points that are just beyond the specified range. + + If \a expandedRange is true but there are no data points below \a sortKey, \ref constBegin is + returned. + + If the container is empty, returns \ref constEnd. + + \see findEnd, QCPPlottableInterface1D::findBegin +*/ +template +typename QCPDataContainer::const_iterator QCPDataContainer::findBegin(double sortKey, bool expandedRange) const +{ + if (isEmpty()) + return constEnd(); + + QCPDataContainer::const_iterator it = std::lower_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (expandedRange && it != constBegin()) // also covers it == constEnd case, and we know --constEnd is valid because mData isn't empty + --it; + return it; +} + +/*! + Returns an iterator to the element after the data point with a (sort-)key that is equal to, just + above or just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey + will be considered, otherwise the one just below. + + This can be used in conjunction with \ref findBegin to iterate over data points within a given + key range, including the bounding data points that are just below and above the specified range. + + If \a expandedRange is true but there are no data points above \a sortKey, \ref constEnd is + returned. + + If the container is empty, \ref constEnd is returned. + + \see findBegin, QCPPlottableInterface1D::findEnd +*/ +template +typename QCPDataContainer::const_iterator QCPDataContainer::findEnd(double sortKey, bool expandedRange) const +{ + if (isEmpty()) + return constEnd(); + + QCPDataContainer::const_iterator it = std::upper_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey); + if (expandedRange && it != constEnd()) + ++it; + return it; +} + +/*! + Returns the range encompassed by the (main-)key coordinate of all data points. The output + parameter \a foundRange indicates whether a sensible range was found. If this is false, you + should not use the returned QCPRange (e.g. the data container is empty or all points have the + same key). + + Use \a signDomain to control which sign of the key coordinates should be considered. This is + relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a + time. + + If the DataType reports that its main key is equal to the sort key (\a sortKeyIsMainKey), as is + the case for most plottables, this method uses this fact and finds the range very quickly. + + \see valueRange +*/ +template +QCPRange QCPDataContainer::keyRange(bool &foundRange, QCP::SignDomain signDomain) +{ + if (isEmpty()) + { + foundRange = false; + return QCPRange(); + } + QCPRange range; + bool haveLower = false; + bool haveUpper = false; + double current; + + QCPDataContainer::const_iterator it = constBegin(); + QCPDataContainer::const_iterator itEnd = constEnd(); + if (signDomain == QCP::sdBoth) // range may be anywhere + { + if (DataType::sortKeyIsMainKey()) // if DataType is sorted by main key (e.g. QCPGraph, but not QCPCurve), use faster algorithm by finding just first and last key with non-NaN value + { + while (it != itEnd) // find first non-nan going up from left + { + if (!qIsNaN(it->mainValue())) + { + range.lower = it->mainKey(); + haveLower = true; + break; + } + ++it; + } + it = itEnd; + while (it != constBegin()) // find first non-nan going down from right + { + --it; + if (!qIsNaN(it->mainValue())) + { + range.upper = it->mainKey(); + haveUpper = true; + break; + } + } + } else // DataType is not sorted by main key, go through all data points and accordingly expand range + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if (current < range.lower || !haveLower) + { + range.lower = current; + haveLower = true; + } + if (current > range.upper || !haveUpper) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } + } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if ((current < range.lower || !haveLower) && current < 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current < 0) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain + { + while (it != itEnd) + { + if (!qIsNaN(it->mainValue())) + { + current = it->mainKey(); + if ((current < range.lower || !haveLower) && current > 0) + { + range.lower = current; + haveLower = true; + } + if ((current > range.upper || !haveUpper) && current > 0) + { + range.upper = current; + haveUpper = true; + } + } + ++it; + } + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! + Returns the range encompassed by the value coordinates of the data points in the specified key + range (\a inKeyRange), using the full \a DataType::valueRange reported by the data points. The + output parameter \a foundRange indicates whether a sensible range was found. If this is false, + you should not use the returned QCPRange (e.g. the data container is empty or all points have the + same value). + + If \a inKeyRange has both lower and upper bound set to zero (is equal to QCPRange()), + all data points are considered, without any restriction on the keys. + + Use \a signDomain to control which sign of the value coordinates should be considered. This is + relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a + time. + + \see keyRange +*/ +template +QCPRange QCPDataContainer::valueRange(bool &foundRange, QCP::SignDomain signDomain, const QCPRange &inKeyRange) +{ + if (isEmpty()) + { + foundRange = false; + return QCPRange(); + } + QCPRange range; + const bool restrictKeyRange = inKeyRange != QCPRange(); + bool haveLower = false; + bool haveUpper = false; + QCPRange current; + QCPDataContainer::const_iterator itBegin = constBegin(); + QCPDataContainer::const_iterator itEnd = constEnd(); + if (DataType::sortKeyIsMainKey() && restrictKeyRange) + { + itBegin = findBegin(inKeyRange.lower); + itEnd = findEnd(inKeyRange.upper); + } + if (signDomain == QCP::sdBoth) // range may be anywhere + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && current.lower < 0 && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && current.upper < 0 && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain + { + for (QCPDataContainer::const_iterator it = itBegin; it != itEnd; ++it) + { + if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) + continue; + current = it->valueRange(); + if ((current.lower < range.lower || !haveLower) && current.lower > 0 && !qIsNaN(current.lower)) + { + range.lower = current.lower; + haveLower = true; + } + if ((current.upper > range.upper || !haveUpper) && current.upper > 0 && !qIsNaN(current.upper)) + { + range.upper = current.upper; + haveUpper = true; + } + } + } + + foundRange = haveLower && haveUpper; + return range; +} + +/*! + Makes sure \a begin and \a end mark a data range that is both within the bounds of this data + container's data, as well as within the specified \a dataRange. + + This function doesn't require for \a dataRange to be within the bounds of this data container's + valid range. +*/ +template +void QCPDataContainer::limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const +{ + QCPDataRange iteratorRange(begin-constBegin(), end-constBegin()); + iteratorRange = iteratorRange.bounded(dataRange.bounded(this->dataRange())); + begin = constBegin()+iteratorRange.begin(); + end = constBegin()+iteratorRange.end(); +} + +/*! \internal + + Increases the preallocation pool to have a size of at least \a minimumPreallocSize. Depending on + the preallocation history, the container will grow by more than requested, to speed up future + consecutive size increases. + + if \a minimumPreallocSize is smaller than or equal to the current preallocation pool size, this + method does nothing. +*/ +template +void QCPDataContainer::preallocateGrow(int minimumPreallocSize) +{ + if (minimumPreallocSize <= mPreallocSize) + return; + + int newPreallocSize = minimumPreallocSize; + newPreallocSize += (1u< +void QCPDataContainer::performAutoSqueeze() +{ + const int totalAlloc = mData.capacity(); + const int postAllocSize = totalAlloc-mData.size(); + const int usedSize = size(); + bool shrinkPostAllocation = false; + bool shrinkPreAllocation = false; + if (totalAlloc > 650000) // if allocation is larger, shrink earlier with respect to total used size + { + shrinkPostAllocation = postAllocSize > usedSize*1.5; // QVector grow strategy is 2^n for static data. Watch out not to oscillate! + shrinkPreAllocation = mPreallocSize*10 > usedSize; + } else if (totalAlloc > 1000) // below 10 MiB raw data be generous with preallocated memory, below 1k points don't even bother + { + shrinkPostAllocation = postAllocSize > usedSize*5; + shrinkPreAllocation = mPreallocSize > usedSize*1.5; // preallocation can grow into postallocation, so can be smaller + } + + if (shrinkPreAllocation || shrinkPostAllocation) + squeeze(shrinkPreAllocation, shrinkPostAllocation); +} +/* end of 'src/datacontainer.cpp' */ + + +/* end of 'src/datacontainer.h' */ + + +/* including file 'src/plottable.h', size 8312 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPSelectionDecorator +{ + Q_GADGET +public: + QCPSelectionDecorator(); + virtual ~QCPSelectionDecorator(); + + // getters: + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + QCPScatterStyle::ScatterProperties usedScatterProperties() const { return mUsedScatterProperties; } + + // setters: + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen); + void setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties); + + // non-virtual methods: + void applyPen(QCPPainter *painter) const; + void applyBrush(QCPPainter *painter) const; + QCPScatterStyle getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const; + + // introduced virtual methods: + virtual void copyFrom(const QCPSelectionDecorator *other); + virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection); + +protected: + // property members: + QPen mPen; + QBrush mBrush; + QCPScatterStyle mScatterStyle; + QCPScatterStyle::ScatterProperties mUsedScatterProperties; + // non-property members: + QCPAbstractPlottable *mPlottable; + + // introduced virtual methods: + virtual bool registerWithPlottable(QCPAbstractPlottable *plottable); + +private: + Q_DISABLE_COPY(QCPSelectionDecorator) + friend class QCPAbstractPlottable; +}; +Q_DECLARE_METATYPE(QCPSelectionDecorator*) + + +class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(bool antialiasedFill READ antialiasedFill WRITE setAntialiasedFill) + Q_PROPERTY(bool antialiasedScatters READ antialiasedScatters WRITE setAntialiasedScatters) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QCPAxis* keyAxis READ keyAxis WRITE setKeyAxis) + Q_PROPERTY(QCPAxis* valueAxis READ valueAxis WRITE setValueAxis) + Q_PROPERTY(QCP::SelectionType selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(QCPDataSelection selection READ selection WRITE setSelection NOTIFY selectionChanged) + Q_PROPERTY(QCPSelectionDecorator* selectionDecorator READ selectionDecorator WRITE setSelectionDecorator) + /// \endcond +public: + QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPAbstractPlottable(); + + // getters: + QString name() const { return mName; } + bool antialiasedFill() const { return mAntialiasedFill; } + bool antialiasedScatters() const { return mAntialiasedScatters; } + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QCPAxis *keyAxis() const { return mKeyAxis.data(); } + QCPAxis *valueAxis() const { return mValueAxis.data(); } + QCP::SelectionType selectable() const { return mSelectable; } + bool selected() const { return !mSelection.isEmpty(); } + QCPDataSelection selection() const { return mSelection; } + QCPSelectionDecorator *selectionDecorator() const { return mSelectionDecorator; } + + // setters: + void setName(const QString &name); + void setAntialiasedFill(bool enabled); + void setAntialiasedScatters(bool enabled); + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setKeyAxis(QCPAxis *axis); + void setValueAxis(QCPAxis *axis); + Q_SLOT void setSelectable(QCP::SelectionType selectable); + Q_SLOT void setSelection(QCPDataSelection selection); + void setSelectionDecorator(QCPSelectionDecorator *decorator); + + // introduced virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const = 0; + virtual QCPPlottableInterface1D *interface1D() { return 0; } + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const = 0; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const = 0; + + // non-property methods: + void coordsToPixels(double key, double value, double &x, double &y) const; + const QPointF coordsToPixels(double key, double value) const; + void pixelsToCoords(double x, double y, double &key, double &value) const; + void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const; + void rescaleAxes(bool onlyEnlarge=false) const; + void rescaleKeyAxis(bool onlyEnlarge=false) const; + void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const; + bool addToLegend(QCPLegend *legend); + bool addToLegend(); + bool removeFromLegend(QCPLegend *legend) const; + bool removeFromLegend() const; + +signals: + void selectionChanged(bool selected); + void selectionChanged(const QCPDataSelection &selection); + void selectableChanged(QCP::SelectionType selectable); + +protected: + // property members: + QString mName; + bool mAntialiasedFill, mAntialiasedScatters; + QPen mPen; + QBrush mBrush; + QPointer mKeyAxis, mValueAxis; + QCP::SelectionType mSelectable; + QCPDataSelection mSelection; + QCPSelectionDecorator *mSelectionDecorator; + + // reimplemented virtual methods: + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0; + + // non-virtual methods: + void applyFillAntialiasingHint(QCPPainter *painter) const; + void applyScattersAntialiasingHint(QCPPainter *painter) const; + +private: + Q_DISABLE_COPY(QCPAbstractPlottable) + + friend class QCustomPlot; + friend class QCPAxis; + friend class QCPPlottableLegendItem; +}; + + +/* end of 'src/plottable.h' */ + + +/* including file 'src/item.h', size 9368 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPItemAnchor +{ + Q_GADGET +public: + QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1); + virtual ~QCPItemAnchor(); + + // getters: + QString name() const { return mName; } + virtual QPointF pixelPosition() const; + +protected: + // property members: + QString mName; + + // non-property members: + QCustomPlot *mParentPlot; + QCPAbstractItem *mParentItem; + int mAnchorId; + QSet mChildrenX, mChildrenY; + + // introduced virtual methods: + virtual QCPItemPosition *toQCPItemPosition() { return 0; } + + // non-virtual methods: + void addChildX(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + void addChildY(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + +private: + Q_DISABLE_COPY(QCPItemAnchor) + + friend class QCPItemPosition; +}; + + + +class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor +{ + Q_GADGET +public: + /*! + Defines the ways an item position can be specified. Thus it defines what the numbers passed to + \ref setCoords actually mean. + + \see setType + */ + enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget. + ,ptViewportRatio ///< Static positioning given by a fraction of the viewport size. For example, if you call setCoords(0, 0), the position will be at the top + ///< left corner of the viewport/widget. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and + ///< vertically at the top of the viewport/widget, etc. + ,ptAxisRectRatio ///< Static positioning given by a fraction of the axis rect size (see \ref setAxisRect). For example, if you call setCoords(0, 0), the position will be at the top + ///< left corner of the axis rect. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and + ///< vertically at the top of the axis rect, etc. You can also go beyond the axis rect by providing negative coordinates or coordinates larger than 1. + ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes). + }; + Q_ENUMS(PositionType) + + QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name); + virtual ~QCPItemPosition(); + + // getters: + PositionType type() const { return typeX(); } + PositionType typeX() const { return mPositionTypeX; } + PositionType typeY() const { return mPositionTypeY; } + QCPItemAnchor *parentAnchor() const { return parentAnchorX(); } + QCPItemAnchor *parentAnchorX() const { return mParentAnchorX; } + QCPItemAnchor *parentAnchorY() const { return mParentAnchorY; } + double key() const { return mKey; } + double value() const { return mValue; } + QPointF coords() const { return QPointF(mKey, mValue); } + QCPAxis *keyAxis() const { return mKeyAxis.data(); } + QCPAxis *valueAxis() const { return mValueAxis.data(); } + QCPAxisRect *axisRect() const; + virtual QPointF pixelPosition() const; + + // setters: + void setType(PositionType type); + void setTypeX(PositionType type); + void setTypeY(PositionType type); + bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + void setCoords(double key, double value); + void setCoords(const QPointF &coords); + void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis); + void setAxisRect(QCPAxisRect *axisRect); + void setPixelPosition(const QPointF &pixelPosition); + +protected: + // property members: + PositionType mPositionTypeX, mPositionTypeY; + QPointer mKeyAxis, mValueAxis; + QPointer mAxisRect; + double mKey, mValue; + QCPItemAnchor *mParentAnchorX, *mParentAnchorY; + + // reimplemented virtual methods: + virtual QCPItemPosition *toQCPItemPosition() Q_DECL_OVERRIDE { return this; } + +private: + Q_DISABLE_COPY(QCPItemPosition) + +}; +Q_DECLARE_METATYPE(QCPItemPosition::PositionType) + + +class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool clipToAxisRect READ clipToAxisRect WRITE setClipToAxisRect) + Q_PROPERTY(QCPAxisRect* clipAxisRect READ clipAxisRect WRITE setClipAxisRect) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + explicit QCPAbstractItem(QCustomPlot *parentPlot); + virtual ~QCPAbstractItem(); + + // getters: + bool clipToAxisRect() const { return mClipToAxisRect; } + QCPAxisRect *clipAxisRect() const; + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setClipToAxisRect(bool clip); + void setClipAxisRect(QCPAxisRect *rect); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE = 0; + + // non-virtual methods: + QList positions() const { return mPositions; } + QList anchors() const { return mAnchors; } + QCPItemPosition *position(const QString &name) const; + QCPItemAnchor *anchor(const QString &name) const; + bool hasAnchor(const QString &name) const; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + bool mClipToAxisRect; + QPointer mClipAxisRect; + QList mPositions; + QList mAnchors; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual QPointF anchorPixelPosition(int anchorId) const; + + // non-virtual methods: + double rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const; + QCPItemPosition *createPosition(const QString &name); + QCPItemAnchor *createAnchor(const QString &name, int anchorId); + +private: + Q_DISABLE_COPY(QCPAbstractItem) + + friend class QCustomPlot; + friend class QCPItemAnchor; +}; + +/* end of 'src/item.h' */ + + +/* including file 'src/core.h', size 14797 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCustomPlot : public QWidget +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QRect viewport READ viewport WRITE setViewport) + Q_PROPERTY(QPixmap background READ background WRITE setBackground) + Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) + Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) + Q_PROPERTY(QCPLayoutGrid* plotLayout READ plotLayout) + Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend) + Q_PROPERTY(int selectionTolerance READ selectionTolerance WRITE setSelectionTolerance) + Q_PROPERTY(bool noAntialiasingOnDrag READ noAntialiasingOnDrag WRITE setNoAntialiasingOnDrag) + Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier) + Q_PROPERTY(bool openGl READ openGl WRITE setOpenGl) + /// \endcond +public: + /*! + Defines how a layer should be inserted relative to an other layer. + + \see addLayer, moveLayer + */ + enum LayerInsertMode { limBelow ///< Layer is inserted below other layer + ,limAbove ///< Layer is inserted above other layer + }; + Q_ENUMS(LayerInsertMode) + + /*! + Defines with what timing the QCustomPlot surface is refreshed after a replot. + + \see replot + */ + enum RefreshPriority { rpImmediateRefresh ///< Replots immediately and repaints the widget immediately by calling QWidget::repaint() after the replot + ,rpQueuedRefresh ///< Replots immediately, but queues the widget repaint, by calling QWidget::update() after the replot. This way multiple redundant widget repaints can be avoided. + ,rpRefreshHint ///< Whether to use immediate or queued refresh depends on whether the plotting hint \ref QCP::phImmediateRefresh is set, see \ref setPlottingHints. + ,rpQueuedReplot ///< Queues the entire replot for the next event loop iteration. This way multiple redundant replots can be avoided. The actual replot is then done with \ref rpRefreshHint priority. + }; + Q_ENUMS(RefreshPriority) + + explicit QCustomPlot(QWidget *parent = 0); + virtual ~QCustomPlot(); + + // getters: + QRect viewport() const { return mViewport; } + double bufferDevicePixelRatio() const { return mBufferDevicePixelRatio; } + QPixmap background() const { return mBackgroundPixmap; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + QCPLayoutGrid *plotLayout() const { return mPlotLayout; } + QCP::AntialiasedElements antialiasedElements() const { return mAntialiasedElements; } + QCP::AntialiasedElements notAntialiasedElements() const { return mNotAntialiasedElements; } + bool autoAddPlottableToLegend() const { return mAutoAddPlottableToLegend; } + const QCP::Interactions interactions() const { return mInteractions; } + int selectionTolerance() const { return mSelectionTolerance; } + bool noAntialiasingOnDrag() const { return mNoAntialiasingOnDrag; } + QCP::PlottingHints plottingHints() const { return mPlottingHints; } + Qt::KeyboardModifier multiSelectModifier() const { return mMultiSelectModifier; } + QCP::SelectionRectMode selectionRectMode() const { return mSelectionRectMode; } + QCPSelectionRect *selectionRect() const { return mSelectionRect; } + bool openGl() const { return mOpenGl; } + + // setters: + void setViewport(const QRect &rect); + void setBufferDevicePixelRatio(double ratio); + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements); + void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true); + void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements); + void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true); + void setAutoAddPlottableToLegend(bool on); + void setInteractions(const QCP::Interactions &interactions); + void setInteraction(const QCP::Interaction &interaction, bool enabled=true); + void setSelectionTolerance(int pixels); + void setNoAntialiasingOnDrag(bool enabled); + void setPlottingHints(const QCP::PlottingHints &hints); + void setPlottingHint(QCP::PlottingHint hint, bool enabled=true); + void setMultiSelectModifier(Qt::KeyboardModifier modifier); + void setSelectionRectMode(QCP::SelectionRectMode mode); + void setSelectionRect(QCPSelectionRect *selectionRect); + void setOpenGl(bool enabled, int multisampling=16); + + // non-property methods: + // plottable interface: + QCPAbstractPlottable *plottable(int index); + QCPAbstractPlottable *plottable(); + bool removePlottable(QCPAbstractPlottable *plottable); + bool removePlottable(int index); + int clearPlottables(); + int plottableCount() const; + QList selectedPlottables() const; + QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false) const; + bool hasPlottable(QCPAbstractPlottable *plottable) const; + + // specialized interface for QCPGraph: + QCPGraph *graph(int index) const; + QCPGraph *graph() const; + QCPGraph *addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0); + bool removeGraph(QCPGraph *graph); + bool removeGraph(int index); + int clearGraphs(); + int graphCount() const; + QList selectedGraphs() const; + + // item interface: + QCPAbstractItem *item(int index) const; + QCPAbstractItem *item() const; + bool removeItem(QCPAbstractItem *item); + bool removeItem(int index); + int clearItems(); + int itemCount() const; + QList selectedItems() const; + QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const; + bool hasItem(QCPAbstractItem *item) const; + + // layer interface: + QCPLayer *layer(const QString &name) const; + QCPLayer *layer(int index) const; + QCPLayer *currentLayer() const; + bool setCurrentLayer(const QString &name); + bool setCurrentLayer(QCPLayer *layer); + int layerCount() const; + bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove); + bool removeLayer(QCPLayer *layer); + bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove); + + // axis rect/layout interface: + int axisRectCount() const; + QCPAxisRect* axisRect(int index=0) const; + QList axisRects() const; + QCPLayoutElement* layoutElementAt(const QPointF &pos) const; + QCPAxisRect* axisRectAt(const QPointF &pos) const; + Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false); + + QList selectedAxes() const; + QList selectedLegends() const; + Q_SLOT void deselectAll(); + + bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString()); + bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); + QPixmap toPixmap(int width=0, int height=0, double scale=1.0); + void toPainter(QCPPainter *painter, int width=0, int height=0); + Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint); + + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; + QCPLegend *legend; + +signals: + void mouseDoubleClick(QMouseEvent *event); + void mousePress(QMouseEvent *event); + void mouseMove(QMouseEvent *event); + void mouseRelease(QMouseEvent *event); + void mouseWheel(QWheelEvent *event); + + void plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); + void plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); + void itemClick(QCPAbstractItem *item, QMouseEvent *event); + void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event); + void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + + void selectionChangedByUser(); + void beforeReplot(); + void afterReplot(); + +protected: + // property members: + QRect mViewport; + double mBufferDevicePixelRatio; + QCPLayoutGrid *mPlotLayout; + bool mAutoAddPlottableToLegend; + QList mPlottables; + QList mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph + QList mItems; + QList mLayers; + QCP::AntialiasedElements mAntialiasedElements, mNotAntialiasedElements; + QCP::Interactions mInteractions; + int mSelectionTolerance; + bool mNoAntialiasingOnDrag; + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayer *mCurrentLayer; + QCP::PlottingHints mPlottingHints; + Qt::KeyboardModifier mMultiSelectModifier; + QCP::SelectionRectMode mSelectionRectMode; + QCPSelectionRect *mSelectionRect; + bool mOpenGl; + + // non-property members: + QList > mPaintBuffers; + QPoint mMousePressPos; + bool mMouseHasMoved; + QPointer mMouseEventLayerable; + QVariant mMouseEventLayerableDetails; + bool mReplotting; + bool mReplotQueued; + int mOpenGlMultisamples; + QCP::AntialiasedElements mOpenGlAntialiasedElementsBackup; + bool mOpenGlCacheLabelsBackup; +#ifdef QCP_OPENGL_FBO + QSharedPointer mGlContext; + QSharedPointer mGlSurface; + QSharedPointer mGlPaintDevice; +#endif + + // reimplemented virtual methods: + virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; + virtual QSize sizeHint() const Q_DECL_OVERRIDE; + virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; + virtual void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void draw(QCPPainter *painter); + virtual void updateLayout(); + virtual void axisRemoved(QCPAxis *axis); + virtual void legendRemoved(QCPLegend *legend); + Q_SLOT virtual void processRectSelection(QRect rect, QMouseEvent *event); + Q_SLOT virtual void processRectZoom(QRect rect, QMouseEvent *event); + Q_SLOT virtual void processPointSelection(QMouseEvent *event); + + // non-virtual methods: + bool registerPlottable(QCPAbstractPlottable *plottable); + bool registerGraph(QCPGraph *graph); + bool registerItem(QCPAbstractItem* item); + void updateLayerIndices() const; + QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=0) const; + QList layerableListAt(const QPointF &pos, bool onlySelectable, QList *selectionDetails=0) const; + void drawBackground(QCPPainter *painter); + void setupPaintBuffers(); + QCPAbstractPaintBuffer *createPaintBuffer(); + bool hasInvalidatedPaintBuffers(); + bool setupOpenGl(); + void freeOpenGl(); + + friend class QCPLegend; + friend class QCPAxis; + friend class QCPLayer; + friend class QCPAxisRect; + friend class QCPAbstractPlottable; + friend class QCPGraph; + friend class QCPAbstractItem; +}; +Q_DECLARE_METATYPE(QCustomPlot::LayerInsertMode) +Q_DECLARE_METATYPE(QCustomPlot::RefreshPriority) + +/* end of 'src/core.h' */ + + +/* including file 'src/plottable1d.h', size 4250 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPPlottableInterface1D +{ +public: + // introduced pure virtual methods: + virtual int dataCount() const = 0; + virtual double dataMainKey(int index) const = 0; + virtual double dataSortKey(int index) const = 0; + virtual double dataMainValue(int index) const = 0; + virtual QCPRange dataValueRange(int index) const = 0; + virtual QPointF dataPixelPosition(int index) const = 0; + virtual bool sortKeyIsMainKey() const = 0; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; + virtual int findBegin(double sortKey, bool expandedRange=true) const = 0; + virtual int findEnd(double sortKey, bool expandedRange=true) const = 0; +}; + +template +class QCP_LIB_DECL QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D +{ + // No Q_OBJECT macro due to template class + +public: + QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPAbstractPlottable1D(); + + // virtual methods of 1d plottable interface: + virtual int dataCount() const; + virtual double dataMainKey(int index) const; + virtual double dataSortKey(int index) const; + virtual double dataMainValue(int index) const; + virtual QCPRange dataValueRange(int index) const; + virtual QPointF dataPixelPosition(int index) const; + virtual bool sortKeyIsMainKey() const; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const; + virtual int findBegin(double sortKey, bool expandedRange=true) const; + virtual int findEnd(double sortKey, bool expandedRange=true) const; + + // virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + virtual QCPPlottableInterface1D *interface1D() { return this; } + +protected: + // property members: + QSharedPointer > mDataContainer; + + // helpers for subclasses: + void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; + void drawPolyline(QCPPainter *painter, const QVector &lineData) const; + +private: + Q_DISABLE_COPY(QCPAbstractPlottable1D) + +}; + +// include implementation in header since it is a class template: + +/* including file 'src/plottable1d.cpp', size 22240 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPPlottableInterface1D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPPlottableInterface1D + \brief Defines an abstract interface for one-dimensional plottables + + This class contains only pure virtual methods which define a common interface to the data + of one-dimensional plottables. + + For example, it is implemented by the template class \ref QCPAbstractPlottable1D (the preferred + base class for one-dimensional plottables). So if you use that template class as base class of + your one-dimensional plottable, you won't have to care about implementing the 1d interface + yourself. + + If your plottable doesn't derive from \ref QCPAbstractPlottable1D but still wants to provide a 1d + interface (e.g. like \ref QCPErrorBars does), you should inherit from both \ref + QCPAbstractPlottable and \ref QCPPlottableInterface1D and accordingly reimplement the pure + virtual methods of the 1d interface, matching your data container. Also, reimplement \ref + QCPAbstractPlottable::interface1D to return the \c this pointer. + + If you have a \ref QCPAbstractPlottable pointer, you can check whether it implements this + interface by calling \ref QCPAbstractPlottable::interface1D and testing it for a non-zero return + value. If it indeed implements this interface, you may use it to access the plottable's data + without needing to know the exact type of the plottable or its data point type. +*/ + +/* start documentation of pure virtual functions */ + +/*! \fn virtual int QCPPlottableInterface1D::dataCount() const = 0; + + Returns the number of data points of the plottable. +*/ + +/*! \fn virtual QCPDataSelection QCPPlottableInterface1D::selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; + + Returns a data selection containing all the data points of this plottable which are contained (or + hit by) \a rect. This is used mainly in the selection rect interaction for data selection (\ref + dataselection "data selection mechanism"). + + If \a onlySelectable is true, an empty QCPDataSelection is returned if this plottable is not + selectable (i.e. if \ref QCPAbstractPlottable::setSelectable is \ref QCP::stNone). + + \note \a rect must be a normalized rect (positive or zero width and height). This is especially + important when using the rect of \ref QCPSelectionRect::accepted, which is not necessarily + normalized. Use QRect::normalized() when passing a rect which might not be normalized. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataMainKey(int index) const = 0 + + Returns the main key of the data point at the given \a index. + + What the main key is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataSortKey(int index) const = 0 + + Returns the sort key of the data point at the given \a index. + + What the sort key is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual double QCPPlottableInterface1D::dataMainValue(int index) const = 0 + + Returns the main value of the data point at the given \a index. + + What the main value is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual QCPRange QCPPlottableInterface1D::dataValueRange(int index) const = 0 + + Returns the value range of the data point at the given \a index. + + What the value range is, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual QPointF QCPPlottableInterface1D::dataPixelPosition(int index) const = 0 + + Returns the pixel position on the widget surface at which the data point at the given \a index + appears. + + Usually this corresponds to the point of \ref dataMainKey/\ref dataMainValue, in pixel + coordinates. However, depending on the plottable, this might be a different apparent position + than just a coord-to-pixel transform of those values. For example, \ref QCPBars apparent data + values can be shifted depending on their stacking, bar grouping or configured base value. +*/ + +/*! \fn virtual bool QCPPlottableInterface1D::sortKeyIsMainKey() const = 0 + + Returns whether the sort key (\ref dataSortKey) is identical to the main key (\ref dataMainKey). + + What the sort and main keys are, is defined by the plottable's data type. See the \ref + qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming + convention. +*/ + +/*! \fn virtual int QCPPlottableInterface1D::findBegin(double sortKey, bool expandedRange) const = 0 + + Returns the index of the data point with a (sort-)key that is equal to, just below, or just above + \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be considered, + otherwise the one just above. + + This can be used in conjunction with \ref findEnd to iterate over data points within a given key + range, including or excluding the bounding data points that are just beyond the specified range. + + If \a expandedRange is true but there are no data points below \a sortKey, 0 is returned. + + If the container is empty, returns 0 (in that case, \ref findEnd will also return 0, so a loop + using these methods will not iterate over the index 0). + + \see findEnd, QCPDataContainer::findBegin +*/ + +/*! \fn virtual int QCPPlottableInterface1D::findEnd(double sortKey, bool expandedRange) const = 0 + + Returns the index one after the data point with a (sort-)key that is equal to, just above, or + just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey will be + considered, otherwise the one just below. + + This can be used in conjunction with \ref findBegin to iterate over data points within a given + key range, including the bounding data points that are just below and above the specified range. + + If \a expandedRange is true but there are no data points above \a sortKey, the index just above the + highest data point is returned. + + If the container is empty, returns 0. + + \see findBegin, QCPDataContainer::findEnd +*/ + +/* end documentation of pure virtual functions */ + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// QCPAbstractPlottable1D +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/*! \class QCPAbstractPlottable1D + \brief A template base class for plottables with one-dimensional data + + This template class derives from \ref QCPAbstractPlottable and from the abstract interface \ref + QCPPlottableInterface1D. It serves as a base class for all one-dimensional data (i.e. data with + one key dimension), such as \ref QCPGraph and QCPCurve. + + The template parameter \a DataType is the type of the data points of this plottable (e.g. \ref + QCPGraphData or \ref QCPCurveData). The main purpose of this base class is to provide the member + \a mDataContainer (a shared pointer to a \ref QCPDataContainer "QCPDataContainer") and + implement the according virtual methods of the \ref QCPPlottableInterface1D, such that most + subclassed plottables don't need to worry about this anymore. + + Further, it provides a convenience method for retrieving selected/unselected data segments via + \ref getDataSegments. This is useful when subclasses implement their \ref draw method and need to + draw selected segments with a different pen/brush than unselected segments (also see \ref + QCPSelectionDecorator). + + This class implements basic functionality of \ref QCPAbstractPlottable::selectTest and \ref + QCPPlottableInterface1D::selectTestRect, assuming point-like data points, based on the 1D data + interface. In spite of that, most plottable subclasses will want to reimplement those methods + again, to provide a more accurate hit test based on their specific data visualization geometry. +*/ + +/* start documentation of inline functions */ + +/*! \fn QCPPlottableInterface1D *QCPAbstractPlottable1D::interface1D() + + Returns a \ref QCPPlottableInterface1D pointer to this plottable, providing access to its 1D + interface. + + \seebaseclassmethod +*/ + +/* end documentation of inline functions */ + +/*! + Forwards \a keyAxis and \a valueAxis to the \ref QCPAbstractPlottable::QCPAbstractPlottable + "QCPAbstractPlottable" constructor and allocates the \a mDataContainer. +*/ +template +QCPAbstractPlottable1D::QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis) : + QCPAbstractPlottable(keyAxis, valueAxis), + mDataContainer(new QCPDataContainer) +{ +} + +template +QCPAbstractPlottable1D::~QCPAbstractPlottable1D() +{ +} + +/*! + \copydoc QCPPlottableInterface1D::dataCount +*/ +template +int QCPAbstractPlottable1D::dataCount() const +{ + return mDataContainer->size(); +} + +/*! + \copydoc QCPPlottableInterface1D::dataMainKey +*/ +template +double QCPAbstractPlottable1D::dataMainKey(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->mainKey(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataSortKey +*/ +template +double QCPAbstractPlottable1D::dataSortKey(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->sortKey(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataMainValue +*/ +template +double QCPAbstractPlottable1D::dataMainValue(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->mainValue(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return 0; + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataValueRange +*/ +template +QCPRange QCPAbstractPlottable1D::dataValueRange(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + return (mDataContainer->constBegin()+index)->valueRange(); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return QCPRange(0, 0); + } +} + +/*! + \copydoc QCPPlottableInterface1D::dataPixelPosition +*/ +template +QPointF QCPAbstractPlottable1D::dataPixelPosition(int index) const +{ + if (index >= 0 && index < mDataContainer->size()) + { + const typename QCPDataContainer::const_iterator it = mDataContainer->constBegin()+index; + return coordsToPixels(it->mainKey(), it->mainValue()); + } else + { + qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; + return QPointF(); + } +} + +/*! + \copydoc QCPPlottableInterface1D::sortKeyIsMainKey +*/ +template +bool QCPAbstractPlottable1D::sortKeyIsMainKey() const +{ + return DataType::sortKeyIsMainKey(); +} + +/*! + Implements a rect-selection algorithm assuming the data (accessed via the 1D data interface) is + point-like. Most subclasses will want to reimplement this method again, to provide a more + accurate hit test based on the true data visualization geometry. + + \seebaseclassmethod +*/ +template +QCPDataSelection QCPAbstractPlottable1D::selectTestRect(const QRectF &rect, bool onlySelectable) const +{ + QCPDataSelection result; + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return result; + if (!mKeyAxis || !mValueAxis) + return result; + + // convert rect given in pixels to ranges given in plot coordinates: + double key1, value1, key2, value2; + pixelsToCoords(rect.topLeft(), key1, value1); + pixelsToCoords(rect.bottomRight(), key2, value2); + QCPRange keyRange(key1, key2); // QCPRange normalizes internally so we don't have to care about whether key1 < key2 + QCPRange valueRange(value1, value2); + typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); + typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); + if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: + { + begin = mDataContainer->findBegin(keyRange.lower, false); + end = mDataContainer->findEnd(keyRange.upper, false); + } + if (begin == end) + return result; + + int currentSegmentBegin = -1; // -1 means we're currently not in a segment that's contained in rect + for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) + { + if (currentSegmentBegin == -1) + { + if (valueRange.contains(it->mainValue()) && keyRange.contains(it->mainKey())) // start segment + currentSegmentBegin = it-mDataContainer->constBegin(); + } else if (!valueRange.contains(it->mainValue()) || !keyRange.contains(it->mainKey())) // segment just ended + { + result.addDataRange(QCPDataRange(currentSegmentBegin, it-mDataContainer->constBegin()), false); + currentSegmentBegin = -1; + } + } + // process potential last segment: + if (currentSegmentBegin != -1) + result.addDataRange(QCPDataRange(currentSegmentBegin, end-mDataContainer->constBegin()), false); + + result.simplify(); + return result; +} + +/*! + \copydoc QCPPlottableInterface1D::findBegin +*/ +template +int QCPAbstractPlottable1D::findBegin(double sortKey, bool expandedRange) const +{ + return mDataContainer->findBegin(sortKey, expandedRange)-mDataContainer->constBegin(); +} + +/*! + \copydoc QCPPlottableInterface1D::findEnd +*/ +template +int QCPAbstractPlottable1D::findEnd(double sortKey, bool expandedRange) const +{ + return mDataContainer->findEnd(sortKey, expandedRange)-mDataContainer->constBegin(); +} + +/*! + Implements a point-selection algorithm assuming the data (accessed via the 1D data interface) is + point-like. Most subclasses will want to reimplement this method again, to provide a more + accurate hit test based on the true data visualization geometry. + + \seebaseclassmethod +*/ +template +double QCPAbstractPlottable1D::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const +{ + if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) + return -1; + if (!mKeyAxis || !mValueAxis) + return -1; + + QCPDataSelection selectionResult; + double minDistSqr = std::numeric_limits::max(); + int minDistIndex = mDataContainer->size(); + + typename QCPDataContainer::const_iterator begin = mDataContainer->constBegin(); + typename QCPDataContainer::const_iterator end = mDataContainer->constEnd(); + if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval: + { + // determine which key range comes into question, taking selection tolerance around pos into account: + double posKeyMin, posKeyMax, dummy; + pixelsToCoords(pos-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy); + pixelsToCoords(pos+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy); + if (posKeyMin > posKeyMax) + qSwap(posKeyMin, posKeyMax); + begin = mDataContainer->findBegin(posKeyMin, true); + end = mDataContainer->findEnd(posKeyMax, true); + } + if (begin == end) + return -1; + QCPRange keyRange(mKeyAxis->range()); + QCPRange valueRange(mValueAxis->range()); + for (typename QCPDataContainer::const_iterator it=begin; it!=end; ++it) + { + const double mainKey = it->mainKey(); + const double mainValue = it->mainValue(); + if (keyRange.contains(mainKey) && valueRange.contains(mainValue)) // make sure data point is inside visible range, for speedup in cases where sort key isn't main key and we iterate over all points + { + const double currentDistSqr = QCPVector2D(coordsToPixels(mainKey, mainValue)-pos).lengthSquared(); + if (currentDistSqr < minDistSqr) + { + minDistSqr = currentDistSqr; + minDistIndex = it-mDataContainer->constBegin(); + } + } + } + if (minDistIndex != mDataContainer->size()) + selectionResult.addDataRange(QCPDataRange(minDistIndex, minDistIndex+1), false); + + selectionResult.simplify(); + if (details) + details->setValue(selectionResult); + return qSqrt(minDistSqr); +} + +/*! + Splits all data into selected and unselected segments and outputs them via \a selectedSegments + and \a unselectedSegments, respectively. + + This is useful when subclasses implement their \ref draw method and need to draw selected + segments with a different pen/brush than unselected segments (also see \ref + QCPSelectionDecorator). + + \see setSelection +*/ +template +void QCPAbstractPlottable1D::getDataSegments(QList &selectedSegments, QList &unselectedSegments) const +{ + selectedSegments.clear(); + unselectedSegments.clear(); + if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty + { + if (selected()) + selectedSegments << QCPDataRange(0, dataCount()); + else + unselectedSegments << QCPDataRange(0, dataCount()); + } else + { + QCPDataSelection sel(selection()); + sel.simplify(); + selectedSegments = sel.dataRanges(); + unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); + } +} + +/*! + A helper method which draws a line with the passed \a painter, according to the pixel data in \a + lineData. NaN points create gaps in the line, as expected from QCustomPlot's plottables (this is + the main difference to QPainter's regular drawPolyline, which handles NaNs by lagging or + crashing). + + Further it uses a faster line drawing technique based on \ref QCPPainter::drawLine rather than \c + QPainter::drawPolyline if the configured \ref QCustomPlot::setPlottingHints() and \a painter + style allows. +*/ +template +void QCPAbstractPlottable1D::drawPolyline(QCPPainter *painter, const QVector &lineData) const +{ + // if drawing solid line and not in PDF, use much faster line drawing instead of polyline: + if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) && + painter->pen().style() == Qt::SolidLine && + !painter->modes().testFlag(QCPPainter::pmVectorized) && + !painter->modes().testFlag(QCPPainter::pmNoCaching)) + { + int i = 0; + bool lastIsNan = false; + const int lineDataSize = lineData.size(); + while (i < lineDataSize && (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()))) // make sure first point is not NaN + ++i; + ++i; // because drawing works in 1 point retrospect + while (i < lineDataSize) + { + if (!qIsNaN(lineData.at(i).y()) && !qIsNaN(lineData.at(i).x())) // NaNs create a gap in the line + { + if (!lastIsNan) + painter->drawLine(lineData.at(i-1), lineData.at(i)); + else + lastIsNan = false; + } else + lastIsNan = true; + ++i; + } + } else + { + int segmentStart = 0; + int i = 0; + const int lineDataSize = lineData.size(); + while (i < lineDataSize) + { + if (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()) || qIsInf(lineData.at(i).y())) // NaNs create a gap in the line. Also filter Infs which make drawPolyline block + { + painter->drawPolyline(lineData.constData()+segmentStart, i-segmentStart); // i, because we don't want to include the current NaN point + segmentStart = i+1; + } + ++i; + } + // draw last segment: + painter->drawPolyline(lineData.constData()+segmentStart, lineDataSize-segmentStart); + } +} +/* end of 'src/plottable1d.cpp' */ + + +/* end of 'src/plottable1d.h' */ + + +/* including file 'src/colorgradient.h', size 6243 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPColorGradient +{ + Q_GADGET +public: + /*! + Defines the color spaces in which color interpolation between gradient stops can be performed. + + \see setColorInterpolation + */ + enum ColorInterpolation { ciRGB ///< Color channels red, green and blue are linearly interpolated + ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance) + }; + Q_ENUMS(ColorInterpolation) + + /*! + Defines the available presets that can be loaded with \ref loadPreset. See the documentation + there for an image of the presets. + */ + enum GradientPreset { gpGrayscale ///< Continuous lightness from black to white (suited for non-biased data representation) + ,gpHot ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation) + ,gpCold ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation) + ,gpNight ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation) + ,gpCandy ///< Blue over pink to white + ,gpGeography ///< Colors suitable to represent different elevations on geographical maps + ,gpIon ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates) + ,gpThermal ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white + ,gpPolar ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values + ,gpSpectrum ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates) + ,gpJet ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates) + ,gpHues ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic) + }; + Q_ENUMS(GradientPreset) + + QCPColorGradient(); + QCPColorGradient(GradientPreset preset); + bool operator==(const QCPColorGradient &other) const; + bool operator!=(const QCPColorGradient &other) const { return !(*this == other); } + + // getters: + int levelCount() const { return mLevelCount; } + QMap colorStops() const { return mColorStops; } + ColorInterpolation colorInterpolation() const { return mColorInterpolation; } + bool periodic() const { return mPeriodic; } + + // setters: + void setLevelCount(int n); + void setColorStops(const QMap &colorStops); + void setColorStopAt(double position, const QColor &color); + void setColorInterpolation(ColorInterpolation interpolation); + void setPeriodic(bool enabled); + + // non-property methods: + void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); + void colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); + QRgb color(double position, const QCPRange &range, bool logarithmic=false); + void loadPreset(GradientPreset preset); + void clearColorStops(); + QCPColorGradient inverted() const; + +protected: + // property members: + int mLevelCount; + QMap mColorStops; + ColorInterpolation mColorInterpolation; + bool mPeriodic; + + // non-property members: + QVector mColorBuffer; // have colors premultiplied with alpha (for usage with QImage::Format_ARGB32_Premultiplied) + bool mColorBufferInvalidated; + + // non-virtual methods: + bool stopsUseAlpha() const; + void updateColorBuffer(); +}; +Q_DECLARE_METATYPE(QCPColorGradient::ColorInterpolation) +Q_DECLARE_METATYPE(QCPColorGradient::GradientPreset) + +/* end of 'src/colorgradient.h' */ + + +/* including file 'src/selectiondecorator-bracket.h', size 4426 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator +{ + Q_GADGET +public: + + /*! + Defines which shape is drawn at the boundaries of selected data ranges. + + Some of the bracket styles further allow specifying a height and/or width, see \ref + setBracketHeight and \ref setBracketWidth. + */ + enum BracketStyle { bsSquareBracket ///< A square bracket is drawn. + ,bsHalfEllipse ///< A half ellipse is drawn. The size of the ellipse is given by the bracket width/height properties. + ,bsEllipse ///< An ellipse is drawn. The size of the ellipse is given by the bracket width/height properties. + ,bsPlus ///< A plus is drawn. + ,bsUserStyle ///< Start custom bracket styles at this index when subclassing and reimplementing \ref drawBracket. + }; + Q_ENUMS(BracketStyle) + + QCPSelectionDecoratorBracket(); + virtual ~QCPSelectionDecoratorBracket(); + + // getters: + QPen bracketPen() const { return mBracketPen; } + QBrush bracketBrush() const { return mBracketBrush; } + int bracketWidth() const { return mBracketWidth; } + int bracketHeight() const { return mBracketHeight; } + BracketStyle bracketStyle() const { return mBracketStyle; } + bool tangentToData() const { return mTangentToData; } + int tangentAverage() const { return mTangentAverage; } + + // setters: + void setBracketPen(const QPen &pen); + void setBracketBrush(const QBrush &brush); + void setBracketWidth(int width); + void setBracketHeight(int height); + void setBracketStyle(BracketStyle style); + void setTangentToData(bool enabled); + void setTangentAverage(int pointCount); + + // introduced virtual methods: + virtual void drawBracket(QCPPainter *painter, int direction) const; + + // virtual methods: + virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection); + +protected: + // property members: + QPen mBracketPen; + QBrush mBracketBrush; + int mBracketWidth; + int mBracketHeight; + BracketStyle mBracketStyle; + bool mTangentToData; + int mTangentAverage; + + // non-virtual methods: + double getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const; + QPointF getPixelCoordinates(const QCPPlottableInterface1D *interface1d, int dataIndex) const; + +}; +Q_DECLARE_METATYPE(QCPSelectionDecoratorBracket::BracketStyle) + +/* end of 'src/selectiondecorator-bracket.h' */ + + +/* including file 'src/layoutelements/layoutelement-axisrect.h', size 7528 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPixmap background READ background WRITE setBackground) + Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) + Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) + Q_PROPERTY(Qt::Orientations rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(Qt::Orientations rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + explicit QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true); + virtual ~QCPAxisRect(); + + // getters: + QPixmap background() const { return mBackgroundPixmap; } + QBrush backgroundBrush() const { return mBackgroundBrush; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + Qt::Orientations rangeDrag() const { return mRangeDrag; } + Qt::Orientations rangeZoom() const { return mRangeZoom; } + QCPAxis *rangeDragAxis(Qt::Orientation orientation); + QCPAxis *rangeZoomAxis(Qt::Orientation orientation); + QList rangeDragAxes(Qt::Orientation orientation); + QList rangeZoomAxes(Qt::Orientation orientation); + double rangeZoomFactor(Qt::Orientation orientation); + + // setters: + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setRangeDrag(Qt::Orientations orientations); + void setRangeZoom(Qt::Orientations orientations); + void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeDragAxes(QList axes); + void setRangeDragAxes(QList horizontal, QList vertical); + void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeZoomAxes(QList axes); + void setRangeZoomAxes(QList horizontal, QList vertical); + void setRangeZoomFactor(double horizontalFactor, double verticalFactor); + void setRangeZoomFactor(double factor); + + // non-property methods: + int axisCount(QCPAxis::AxisType type) const; + QCPAxis *axis(QCPAxis::AxisType type, int index=0) const; + QList axes(QCPAxis::AxisTypes types) const; + QList axes() const; + QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=0); + QList addAxes(QCPAxis::AxisTypes types); + bool removeAxis(QCPAxis *axis); + QCPLayoutInset *insetLayout() const { return mInsetLayout; } + + void zoom(const QRectF &pixelRect); + void zoom(const QRectF &pixelRect, const QList &affectedAxes); + void setupFullAxesBox(bool connectRanges=false); + QList plottables() const; + QList graphs() const; + QList items() const; + + // read-only interface imitating a QRect: + int left() const { return mRect.left(); } + int right() const { return mRect.right(); } + int top() const { return mRect.top(); } + int bottom() const { return mRect.bottom(); } + int width() const { return mRect.width(); } + int height() const { return mRect.height(); } + QSize size() const { return mRect.size(); } + QPoint topLeft() const { return mRect.topLeft(); } + QPoint topRight() const { return mRect.topRight(); } + QPoint bottomLeft() const { return mRect.bottomLeft(); } + QPoint bottomRight() const { return mRect.bottomRight(); } + QPoint center() const { return mRect.center(); } + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + virtual QList elements(bool recursive) const Q_DECL_OVERRIDE; + +protected: + // property members: + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayoutInset *mInsetLayout; + Qt::Orientations mRangeDrag, mRangeZoom; + QList > mRangeDragHorzAxis, mRangeDragVertAxis; + QList > mRangeZoomHorzAxis, mRangeZoomVertAxis; + double mRangeZoomFactorHorz, mRangeZoomFactorVert; + + // non-property members: + QList mDragStartHorzRange, mDragStartVertRange; + QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; + QPoint mDragStart; + bool mDragging; + QHash > mAxes; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual int calculateAutoMargin(QCP::MarginSide side) Q_DECL_OVERRIDE; + virtual void layoutChanged() Q_DECL_OVERRIDE; + // events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + + // non-property methods: + void drawBackground(QCPPainter *painter); + void updateAxesOffset(QCPAxis::AxisType type); + +private: + Q_DISABLE_COPY(QCPAxisRect) + + friend class QCustomPlot; +}; + + +/* end of 'src/layoutelements/layoutelement-axisrect.h' */ + + +/* including file 'src/layoutelements/layoutelement-legend.h', size 10392 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPLegend* parentLegend READ parentLegend) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectionChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectableChanged) + /// \endcond +public: + explicit QCPAbstractLegendItem(QCPLegend *parent); + + // getters: + QCPLegend *parentLegend() const { return mParentLegend; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + QCPLegend *mParentLegend; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual QRect clipRect() const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPAbstractLegendItem) + + friend class QCPLegend; +}; + + +class QCP_LIB_DECL QCPPlottableLegendItem : public QCPAbstractLegendItem +{ + Q_OBJECT +public: + QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable); + + // getters: + QCPAbstractPlottable *plottable() { return mPlottable; } + +protected: + // property members: + QCPAbstractPlottable *mPlottable; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen getIconBorderPen() const; + QColor getTextColor() const; + QFont getFont() const; +}; + + +class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen borderPen READ borderPen WRITE setBorderPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) + Q_PROPERTY(int iconTextPadding READ iconTextPadding WRITE setIconTextPadding) + Q_PROPERTY(QPen iconBorderPen READ iconBorderPen WRITE setIconBorderPen) + Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectionChanged) + Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectableChanged) + Q_PROPERTY(QPen selectedBorderPen READ selectedBorderPen WRITE setSelectedBorderPen) + Q_PROPERTY(QPen selectedIconBorderPen READ selectedIconBorderPen WRITE setSelectedIconBorderPen) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + /// \endcond +public: + /*! + Defines the selectable parts of a legend + + \see setSelectedParts, setSelectableParts + */ + enum SelectablePart { spNone = 0x000 ///< 0x000 None + ,spLegendBox = 0x001 ///< 0x001 The legend box (frame) + ,spItems = 0x002 ///< 0x002 Legend items individually (see \ref selectedItems) + }; + Q_ENUMS(SelectablePart) + Q_FLAGS(SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPLegend(); + virtual ~QCPLegend(); + + // getters: + QPen borderPen() const { return mBorderPen; } + QBrush brush() const { return mBrush; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QSize iconSize() const { return mIconSize; } + int iconTextPadding() const { return mIconTextPadding; } + QPen iconBorderPen() const { return mIconBorderPen; } + SelectableParts selectableParts() const { return mSelectableParts; } + SelectableParts selectedParts() const; + QPen selectedBorderPen() const { return mSelectedBorderPen; } + QPen selectedIconBorderPen() const { return mSelectedIconBorderPen; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + + // setters: + void setBorderPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setIconSize(const QSize &size); + void setIconSize(int width, int height); + void setIconTextPadding(int padding); + void setIconBorderPen(const QPen &pen); + Q_SLOT void setSelectableParts(const SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const SelectableParts &selectedParts); + void setSelectedBorderPen(const QPen &pen); + void setSelectedIconBorderPen(const QPen &pen); + void setSelectedBrush(const QBrush &brush); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QCPAbstractLegendItem *item(int index) const; + QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const; + int itemCount() const; + bool hasItem(QCPAbstractLegendItem *item) const; + bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const; + bool addItem(QCPAbstractLegendItem *item); + bool removeItem(int index); + bool removeItem(QCPAbstractLegendItem *item); + void clearItems(); + QList selectedItems() const; + +signals: + void selectionChanged(QCPLegend::SelectableParts parts); + void selectableChanged(QCPLegend::SelectableParts parts); + +protected: + // property members: + QPen mBorderPen, mIconBorderPen; + QBrush mBrush; + QFont mFont; + QColor mTextColor; + QSize mIconSize; + int mIconTextPadding; + SelectableParts mSelectedParts, mSelectableParts; + QPen mSelectedBorderPen, mSelectedIconBorderPen; + QBrush mSelectedBrush; + QFont mSelectedFont; + QColor mSelectedTextColor; + + // reimplemented virtual methods: + virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; + virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen getBorderPen() const; + QBrush getBrush() const; + +private: + Q_DISABLE_COPY(QCPLegend) + + friend class QCustomPlot; + friend class QCPAbstractLegendItem; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPLegend::SelectableParts) +Q_DECLARE_METATYPE(QCPLegend::SelectablePart) + +/* end of 'src/layoutelements/layoutelement-legend.h' */ + + +/* including file 'src/layoutelements/layoutelement-textelement.h', size 5343 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPTextElement : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + explicit QCPTextElement(QCustomPlot *parentPlot); + QCPTextElement(QCustomPlot *parentPlot, const QString &text); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize); + QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font); + + // getters: + QString text() const { return mText; } + int textFlags() const { return mTextFlags; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setText(const QString &text); + void setTextFlags(int flags); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + void clicked(QMouseEvent *event); + void doubleClicked(QMouseEvent *event); + +protected: + // property members: + QString mText; + int mTextFlags; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + QRect mTextBoundingRect; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; + virtual QSize maximumSizeHint() const Q_DECL_OVERRIDE; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE; + virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; + + // non-virtual methods: + QFont mainFont() const; + QColor mainTextColor() const; + +private: + Q_DISABLE_COPY(QCPTextElement) +}; + + + +/* end of 'src/layoutelements/layoutelement-textelement.h' */ + + +/* including file 'src/layoutelements/layoutelement-colorscale.h', size 5907 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + + +class QCPColorScaleAxisRectPrivate : public QCPAxisRect +{ + Q_OBJECT +public: + explicit QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale); +protected: + QCPColorScale *mParentColorScale; + QImage mGradientImage; + bool mGradientImageInvalidated; + // re-using some methods of QCPAxisRect to make them available to friend class QCPColorScale + using QCPAxisRect::calculateAutoMargin; + using QCPAxisRect::mousePressEvent; + using QCPAxisRect::mouseMoveEvent; + using QCPAxisRect::mouseReleaseEvent; + using QCPAxisRect::wheelEvent; + using QCPAxisRect::update; + virtual void draw(QCPPainter *painter); + void updateGradientImage(); + Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts); + Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts); + friend class QCPColorScale; +}; + + +class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPAxis::AxisType type READ type WRITE setType) + Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) + Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) + Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int barWidth READ barWidth WRITE setBarWidth) + Q_PROPERTY(bool rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(bool rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + explicit QCPColorScale(QCustomPlot *parentPlot); + virtual ~QCPColorScale(); + + // getters: + QCPAxis *axis() const { return mColorAxis.data(); } + QCPAxis::AxisType type() const { return mType; } + QCPRange dataRange() const { return mDataRange; } + QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } + QCPColorGradient gradient() const { return mGradient; } + QString label() const; + int barWidth () const { return mBarWidth; } + bool rangeDrag() const; + bool rangeZoom() const; + + // setters: + void setType(QCPAxis::AxisType type); + Q_SLOT void setDataRange(const QCPRange &dataRange); + Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); + Q_SLOT void setGradient(const QCPColorGradient &gradient); + void setLabel(const QString &str); + void setBarWidth(int width); + void setRangeDrag(bool enabled); + void setRangeZoom(bool enabled); + + // non-property methods: + QList colorMaps() const; + void rescaleDataRange(bool onlyVisibleMaps); + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; + +signals: + void dataRangeChanged(const QCPRange &newRange); + void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + void gradientChanged(const QCPColorGradient &newGradient); + +protected: + // property members: + QCPAxis::AxisType mType; + QCPRange mDataRange; + QCPAxis::ScaleType mDataScaleType; + QCPColorGradient mGradient; + int mBarWidth; + + // non-property members: + QPointer mAxisRect; + QPointer mColorAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; + // events: + virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; + virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; + virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QCPColorScale) + + friend class QCPColorScaleAxisRectPrivate; +}; + + +/* end of 'src/layoutelements/layoutelement-colorscale.h' */ + + +/* including file 'src/plottables/plottable-graph.h', size 8826 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPGraphData +{ +public: + QCPGraphData(); + QCPGraphData(double key, double value); + + inline double sortKey() const { return key; } + inline static QCPGraphData fromSortKey(double sortKey) { return QCPGraphData(sortKey, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } + + double key, value; +}; +Q_DECLARE_TYPEINFO(QCPGraphData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPGraphDataContainer + + Container for storing \ref QCPGraphData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPGraph holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPGraphData, QCPGraph::setData +*/ +typedef QCPDataContainer QCPGraphDataContainer; + +class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) + Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) + Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) + Q_PROPERTY(QCPGraph* channelFillGraph READ channelFillGraph WRITE setChannelFillGraph) + Q_PROPERTY(bool adaptiveSampling READ adaptiveSampling WRITE setAdaptiveSampling) + /// \endcond +public: + /*! + Defines how the graph's line is represented visually in the plot. The line is drawn with the + current pen of the graph (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< data points are not connected with any lines (e.g. data only represented + ///< with symbols according to the scatter style, see \ref setScatterStyle) + ,lsLine ///< data points are connected by a straight line + ,lsStepLeft ///< line is drawn as steps where the step height is the value of the left data point + ,lsStepRight ///< line is drawn as steps where the step height is the value of the right data point + ,lsStepCenter ///< line is drawn as steps where the step is in between two data points + ,lsImpulse ///< each data point is represented by a line parallel to the value axis, which reaches from the data point to the zero-value-line + }; + Q_ENUMS(LineStyle) + + explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPGraph(); + + // getters: + QSharedPointer data() const { return mDataContainer; } + LineStyle lineStyle() const { return mLineStyle; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + int scatterSkip() const { return mScatterSkip; } + QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); } + bool adaptiveSampling() const { return mAdaptiveSampling; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void setLineStyle(LineStyle ls); + void setScatterStyle(const QCPScatterStyle &style); + void setScatterSkip(int skip); + void setChannelFillGraph(QCPGraph *targetGraph); + void setAdaptiveSampling(bool enabled); + + // non-property methods: + void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void addData(double key, double value); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + LineStyle mLineStyle; + QCPScatterStyle mScatterStyle; + int mScatterSkip; + QPointer mChannelFillGraph; + bool mAdaptiveSampling; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawFill(QCPPainter *painter, QVector *lines) const; + virtual void drawScatterPlot(QCPPainter *painter, const QVector &scatters, const QCPScatterStyle &style) const; + virtual void drawLinePlot(QCPPainter *painter, const QVector &lines) const; + virtual void drawImpulsePlot(QCPPainter *painter, const QVector &lines) const; + + virtual void getOptimizedLineData(QVector *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const; + virtual void getOptimizedScatterData(QVector *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const; + + // non-virtual methods: + void getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; + void getLines(QVector *lines, const QCPDataRange &dataRange) const; + void getScatters(QVector *scatters, const QCPDataRange &dataRange) const; + QVector dataToLines(const QVector &data) const; + QVector dataToStepLeftLines(const QVector &data) const; + QVector dataToStepRightLines(const QVector &data) const; + QVector dataToStepCenterLines(const QVector &data) const; + QVector dataToImpulseLines(const QVector &data) const; + void addFillBasePoints(QVector *lines) const; + void removeFillBasePoints(QVector *lines) const; + QPointF lowerFillBasePoint(double lowerKey) const; + QPointF upperFillBasePoint(double upperKey) const; + const QPolygonF getChannelFillPolygon(const QVector *lines) const; + int findIndexBelowX(const QVector *data, double x) const; + int findIndexAboveX(const QVector *data, double x) const; + int findIndexBelowY(const QVector *data, double y) const; + int findIndexAboveY(const QVector *data, double y) const; + double pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPGraph::LineStyle) + +/* end of 'src/plottables/plottable-graph.h' */ + + +/* including file 'src/plottables/plottable-curve.h', size 7409 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPCurveData +{ +public: + QCPCurveData(); + QCPCurveData(double t, double key, double value); + + inline double sortKey() const { return t; } + inline static QCPCurveData fromSortKey(double sortKey) { return QCPCurveData(sortKey, 0, 0); } + inline static bool sortKeyIsMainKey() { return false; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } + + double t, key, value; +}; +Q_DECLARE_TYPEINFO(QCPCurveData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPCurveDataContainer + + Container for storing \ref QCPCurveData points. The data is stored sorted by \a t, so the \a + sortKey() (returning \a t) is different from \a mainKey() (returning \a key). + + This template instantiation is the container in which QCPCurve holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPCurveData, QCPCurve::setData +*/ +typedef QCPDataContainer QCPCurveDataContainer; + +class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) + Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) + Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) + /// \endcond +public: + /*! + Defines how the curve's line is represented visually in the plot. The line is drawn with the + current pen of the curve (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< No line is drawn between data points (e.g. only scatters) + ,lsLine ///< Data points are connected with a straight line + }; + Q_ENUMS(LineStyle) + + explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPCurve(); + + // getters: + QSharedPointer data() const { return mDataContainer; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + int scatterSkip() const { return mScatterSkip; } + LineStyle lineStyle() const { return mLineStyle; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); + void setData(const QVector &keys, const QVector &values); + void setScatterStyle(const QCPScatterStyle &style); + void setScatterSkip(int skip); + void setLineStyle(LineStyle style); + + // non-property methods: + void addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); + void addData(const QVector &keys, const QVector &values); + void addData(double t, double key, double value); + void addData(double key, double value); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + QCPScatterStyle mScatterStyle; + int mScatterSkip; + LineStyle mLineStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawCurveLine(QCPPainter *painter, const QVector &lines) const; + virtual void drawScatterPlot(QCPPainter *painter, const QVector &points, const QCPScatterStyle &style) const; + + // non-virtual methods: + void getCurveLines(QVector *lines, const QCPDataRange &dataRange, double penWidth) const; + void getScatters(QVector *scatters, const QCPDataRange &dataRange, double scatterWidth) const; + int getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + QVector getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const; + bool mayTraverse(int prevRegion, int currentRegion) const; + bool getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const; + void getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector &beforeTraverse, QVector &afterTraverse) const; + double pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPCurve::LineStyle) + +/* end of 'src/plottables/plottable-curve.h' */ + + +/* including file 'src/plottables/plottable-bars.h', size 8924 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPBarsGroup : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(SpacingType spacingType READ spacingType WRITE setSpacingType) + Q_PROPERTY(double spacing READ spacing WRITE setSpacing) + /// \endcond +public: + /*! + Defines the ways the spacing between bars in the group can be specified. Thus it defines what + the number passed to \ref setSpacing actually means. + + \see setSpacingType, setSpacing + */ + enum SpacingType { stAbsolute ///< Bar spacing is in absolute pixels + ,stAxisRectRatio ///< Bar spacing is given by a fraction of the axis rect size + ,stPlotCoords ///< Bar spacing is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(SpacingType) + + QCPBarsGroup(QCustomPlot *parentPlot); + virtual ~QCPBarsGroup(); + + // getters: + SpacingType spacingType() const { return mSpacingType; } + double spacing() const { return mSpacing; } + + // setters: + void setSpacingType(SpacingType spacingType); + void setSpacing(double spacing); + + // non-virtual methods: + QList bars() const { return mBars; } + QCPBars* bars(int index) const; + int size() const { return mBars.size(); } + bool isEmpty() const { return mBars.isEmpty(); } + void clear(); + bool contains(QCPBars *bars) const { return mBars.contains(bars); } + void append(QCPBars *bars); + void insert(int i, QCPBars *bars); + void remove(QCPBars *bars); + +protected: + // non-property members: + QCustomPlot *mParentPlot; + SpacingType mSpacingType; + double mSpacing; + QList mBars; + + // non-virtual methods: + void registerBars(QCPBars *bars); + void unregisterBars(QCPBars *bars); + + // virtual methods: + double keyPixelOffset(const QCPBars *bars, double keyCoord); + double getPixelSpacing(const QCPBars *bars, double keyCoord); + +private: + Q_DISABLE_COPY(QCPBarsGroup) + + friend class QCPBars; +}; +Q_DECLARE_METATYPE(QCPBarsGroup::SpacingType) + + +class QCP_LIB_DECL QCPBarsData +{ +public: + QCPBarsData(); + QCPBarsData(double key, double value); + + inline double sortKey() const { return key; } + inline static QCPBarsData fromSortKey(double sortKey) { return QCPBarsData(sortKey, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return value; } + + inline QCPRange valueRange() const { return QCPRange(value, value); } // note that bar base value isn't held in each QCPBarsData and thus can't/shouldn't be returned here + + double key, value; +}; +Q_DECLARE_TYPEINFO(QCPBarsData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPBarsDataContainer + + Container for storing \ref QCPBarsData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPBars holds its data. For details about + the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPBarsData, QCPBars::setData +*/ +typedef QCPDataContainer QCPBarsDataContainer; + +class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) + Q_PROPERTY(QCPBarsGroup* barsGroup READ barsGroup WRITE setBarsGroup) + Q_PROPERTY(double baseValue READ baseValue WRITE setBaseValue) + Q_PROPERTY(double stackingGap READ stackingGap WRITE setStackingGap) + Q_PROPERTY(QCPBars* barBelow READ barBelow) + Q_PROPERTY(QCPBars* barAbove READ barAbove) + /// \endcond +public: + /*! + Defines the ways the width of the bar can be specified. Thus it defines what the number passed + to \ref setWidth actually means. + + \see setWidthType, setWidth + */ + enum WidthType { wtAbsolute ///< Bar width is in absolute pixels + ,wtAxisRectRatio ///< Bar width is given by a fraction of the axis rect size + ,wtPlotCoords ///< Bar width is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(WidthType) + + explicit QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPBars(); + + // getters: + double width() const { return mWidth; } + WidthType widthType() const { return mWidthType; } + QCPBarsGroup *barsGroup() const { return mBarsGroup; } + double baseValue() const { return mBaseValue; } + double stackingGap() const { return mStackingGap; } + QCPBars *barBelow() const { return mBarBelow.data(); } + QCPBars *barAbove() const { return mBarAbove.data(); } + QSharedPointer data() const { return mDataContainer; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void setWidth(double width); + void setWidthType(WidthType widthType); + void setBarsGroup(QCPBarsGroup *barsGroup); + void setBaseValue(double baseValue); + void setStackingGap(double pixels); + + // non-property methods: + void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); + void addData(double key, double value); + void moveBelow(QCPBars *bars); + void moveAbove(QCPBars *bars); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; + +protected: + // property members: + double mWidth; + WidthType mWidthType; + QCPBarsGroup *mBarsGroup; + double mBaseValue; + double mStackingGap; + QPointer mBarBelow, mBarAbove; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const; + QRectF getBarRect(double key, double value) const; + void getPixelWidth(double key, double &lower, double &upper) const; + double getStackedBaseValue(double key, bool positive) const; + static void connectBars(QCPBars* lower, QCPBars* upper); + + friend class QCustomPlot; + friend class QCPLegend; + friend class QCPBarsGroup; +}; +Q_DECLARE_METATYPE(QCPBars::WidthType) + +/* end of 'src/plottables/plottable-bars.h' */ + + +/* including file 'src/plottables/plottable-statisticalbox.h', size 7516 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPStatisticalBoxData +{ +public: + QCPStatisticalBoxData(); + QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector& outliers=QVector()); + + inline double sortKey() const { return key; } + inline static QCPStatisticalBoxData fromSortKey(double sortKey) { return QCPStatisticalBoxData(sortKey, 0, 0, 0, 0, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return median; } + + inline QCPRange valueRange() const + { + QCPRange result(minimum, maximum); + for (QVector::const_iterator it = outliers.constBegin(); it != outliers.constEnd(); ++it) + result.expand(*it); + return result; + } + + double key, minimum, lowerQuartile, median, upperQuartile, maximum; + QVector outliers; +}; +Q_DECLARE_TYPEINFO(QCPStatisticalBoxData, Q_MOVABLE_TYPE); + + +/*! \typedef QCPStatisticalBoxDataContainer + + Container for storing \ref QCPStatisticalBoxData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPStatisticalBox holds its data. For + details about the generic container, see the documentation of the class template \ref + QCPDataContainer. + + \see QCPStatisticalBoxData, QCPStatisticalBox::setData +*/ +typedef QCPDataContainer QCPStatisticalBoxDataContainer; + +class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) + Q_PROPERTY(QPen whiskerPen READ whiskerPen WRITE setWhiskerPen) + Q_PROPERTY(QPen whiskerBarPen READ whiskerBarPen WRITE setWhiskerBarPen) + Q_PROPERTY(bool whiskerAntialiased READ whiskerAntialiased WRITE setWhiskerAntialiased) + Q_PROPERTY(QPen medianPen READ medianPen WRITE setMedianPen) + Q_PROPERTY(QCPScatterStyle outlierStyle READ outlierStyle WRITE setOutlierStyle) + /// \endcond +public: + explicit QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis); + + // getters: + QSharedPointer data() const { return mDataContainer; } + double width() const { return mWidth; } + double whiskerWidth() const { return mWhiskerWidth; } + QPen whiskerPen() const { return mWhiskerPen; } + QPen whiskerBarPen() const { return mWhiskerBarPen; } + bool whiskerAntialiased() const { return mWhiskerAntialiased; } + QPen medianPen() const { return mMedianPen; } + QCPScatterStyle outlierStyle() const { return mOutlierStyle; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); + void setWidth(double width); + void setWhiskerWidth(double width); + void setWhiskerPen(const QPen &pen); + void setWhiskerBarPen(const QPen &pen); + void setWhiskerAntialiased(bool enabled); + void setMedianPen(const QPen &pen); + void setOutlierStyle(const QCPScatterStyle &style); + + // non-property methods: + void addData(const QVector &keys, const QVector &minimum, const QVector &lowerQuartile, const QVector &median, const QVector &upperQuartile, const QVector &maximum, bool alreadySorted=false); + void addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector &outliers=QVector()); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +protected: + // property members: + double mWidth; + double mWhiskerWidth; + QPen mWhiskerPen, mWhiskerBarPen; + bool mWhiskerAntialiased; + QPen mMedianPen; + QCPScatterStyle mOutlierStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // introduced virtual methods: + virtual void drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const; + + // non-virtual methods: + void getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const; + QRectF getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const; + QVector getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const; + QVector getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-statisticalbox.h' */ + + +/* including file 'src/plottables/plottable-colormap.h', size 7070 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPColorMapData +{ +public: + QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange); + ~QCPColorMapData(); + QCPColorMapData(const QCPColorMapData &other); + QCPColorMapData &operator=(const QCPColorMapData &other); + + // getters: + int keySize() const { return mKeySize; } + int valueSize() const { return mValueSize; } + QCPRange keyRange() const { return mKeyRange; } + QCPRange valueRange() const { return mValueRange; } + QCPRange dataBounds() const { return mDataBounds; } + double data(double key, double value); + double cell(int keyIndex, int valueIndex); + unsigned char alpha(int keyIndex, int valueIndex); + + // setters: + void setSize(int keySize, int valueSize); + void setKeySize(int keySize); + void setValueSize(int valueSize); + void setRange(const QCPRange &keyRange, const QCPRange &valueRange); + void setKeyRange(const QCPRange &keyRange); + void setValueRange(const QCPRange &valueRange); + void setData(double key, double value, double z); + void setCell(int keyIndex, int valueIndex, double z); + void setAlpha(int keyIndex, int valueIndex, unsigned char alpha); + + // non-property methods: + void recalculateDataBounds(); + void clear(); + void clearAlpha(); + void fill(double z); + void fillAlpha(unsigned char alpha); + bool isEmpty() const { return mIsEmpty; } + void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const; + void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const; + +protected: + // property members: + int mKeySize, mValueSize; + QCPRange mKeyRange, mValueRange; + bool mIsEmpty; + + // non-property members: + double *mData; + unsigned char *mAlpha; + QCPRange mDataBounds; + bool mDataModified; + + bool createAlpha(bool initializeOpaque=true); + + friend class QCPColorMap; +}; + + +class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) + Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) + Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) + Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate) + Q_PROPERTY(bool tightBoundary READ tightBoundary WRITE setTightBoundary) + Q_PROPERTY(QCPColorScale* colorScale READ colorScale WRITE setColorScale) + /// \endcond +public: + explicit QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPColorMap(); + + // getters: + QCPColorMapData *data() const { return mMapData; } + QCPRange dataRange() const { return mDataRange; } + QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } + bool interpolate() const { return mInterpolate; } + bool tightBoundary() const { return mTightBoundary; } + QCPColorGradient gradient() const { return mGradient; } + QCPColorScale *colorScale() const { return mColorScale.data(); } + + // setters: + void setData(QCPColorMapData *data, bool copy=false); + Q_SLOT void setDataRange(const QCPRange &dataRange); + Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); + Q_SLOT void setGradient(const QCPColorGradient &gradient); + void setInterpolate(bool enabled); + void setTightBoundary(bool enabled); + void setColorScale(QCPColorScale *colorScale); + + // non-property methods: + void rescaleDataRange(bool recalculateDataBounds=false); + Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18)); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + +signals: + void dataRangeChanged(const QCPRange &newRange); + void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + void gradientChanged(const QCPColorGradient &newGradient); + +protected: + // property members: + QCPRange mDataRange; + QCPAxis::ScaleType mDataScaleType; + QCPColorMapData *mMapData; + QCPColorGradient mGradient; + bool mInterpolate; + bool mTightBoundary; + QPointer mColorScale; + + // non-property members: + QImage mMapImage, mUndersampledMapImage; + QPixmap mLegendIcon; + bool mMapImageInvalidated; + + // introduced virtual methods: + virtual void updateMapImage(); + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-colormap.h' */ + + +/* including file 'src/plottables/plottable-financial.h', size 8622 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPFinancialData +{ +public: + QCPFinancialData(); + QCPFinancialData(double key, double open, double high, double low, double close); + + inline double sortKey() const { return key; } + inline static QCPFinancialData fromSortKey(double sortKey) { return QCPFinancialData(sortKey, 0, 0, 0, 0); } + inline static bool sortKeyIsMainKey() { return true; } + + inline double mainKey() const { return key; } + inline double mainValue() const { return open; } + + inline QCPRange valueRange() const { return QCPRange(low, high); } // open and close must lie between low and high, so we don't need to check them + + double key, open, high, low, close; +}; +Q_DECLARE_TYPEINFO(QCPFinancialData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPFinancialDataContainer + + Container for storing \ref QCPFinancialData points. The data is stored sorted by \a key. + + This template instantiation is the container in which QCPFinancial holds its data. For details + about the generic container, see the documentation of the class template \ref QCPDataContainer. + + \see QCPFinancialData, QCPFinancial::setData +*/ +typedef QCPDataContainer QCPFinancialDataContainer; + +class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(ChartStyle chartStyle READ chartStyle WRITE setChartStyle) + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) + Q_PROPERTY(bool twoColored READ twoColored WRITE setTwoColored) + Q_PROPERTY(QBrush brushPositive READ brushPositive WRITE setBrushPositive) + Q_PROPERTY(QBrush brushNegative READ brushNegative WRITE setBrushNegative) + Q_PROPERTY(QPen penPositive READ penPositive WRITE setPenPositive) + Q_PROPERTY(QPen penNegative READ penNegative WRITE setPenNegative) + /// \endcond +public: + /*! + Defines the ways the width of the financial bar can be specified. Thus it defines what the + number passed to \ref setWidth actually means. + + \see setWidthType, setWidth + */ + enum WidthType { wtAbsolute ///< width is in absolute pixels + ,wtAxisRectRatio ///< width is given by a fraction of the axis rect size + ,wtPlotCoords ///< width is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(WidthType) + + /*! + Defines the possible representations of OHLC data in the plot. + + \see setChartStyle + */ + enum ChartStyle { csOhlc ///< Open-High-Low-Close bar representation + ,csCandlestick ///< Candlestick representation + }; + Q_ENUMS(ChartStyle) + + explicit QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPFinancial(); + + // getters: + QSharedPointer data() const { return mDataContainer; } + ChartStyle chartStyle() const { return mChartStyle; } + double width() const { return mWidth; } + WidthType widthType() const { return mWidthType; } + bool twoColored() const { return mTwoColored; } + QBrush brushPositive() const { return mBrushPositive; } + QBrush brushNegative() const { return mBrushNegative; } + QPen penPositive() const { return mPenPositive; } + QPen penNegative() const { return mPenNegative; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); + void setChartStyle(ChartStyle style); + void setWidth(double width); + void setWidthType(WidthType widthType); + void setTwoColored(bool twoColored); + void setBrushPositive(const QBrush &brush); + void setBrushNegative(const QBrush &brush); + void setPenPositive(const QPen &pen); + void setPenNegative(const QPen &pen); + + // non-property methods: + void addData(const QVector &keys, const QVector &open, const QVector &high, const QVector &low, const QVector &close, bool alreadySorted=false); + void addData(double key, double open, double high, double low, double close); + + // reimplemented virtual methods: + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + + // static methods: + static QCPFinancialDataContainer timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset = 0); + +protected: + // property members: + ChartStyle mChartStyle; + double mWidth; + WidthType mWidthType; + bool mTwoColored; + QBrush mBrushPositive, mBrushNegative; + QPen mPenPositive, mPenNegative; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected); + void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected); + double getPixelWidth(double key, double keyPixel) const; + double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const; + double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const; + void getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const; + QRectF selectionHitBox(QCPFinancialDataContainer::const_iterator it) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; +Q_DECLARE_METATYPE(QCPFinancial::ChartStyle) + +/* end of 'src/plottables/plottable-financial.h' */ + + +/* including file 'src/plottables/plottable-errorbar.h', size 7567 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPErrorBarsData +{ +public: + QCPErrorBarsData(); + explicit QCPErrorBarsData(double error); + QCPErrorBarsData(double errorMinus, double errorPlus); + + double errorMinus, errorPlus; +}; +Q_DECLARE_TYPEINFO(QCPErrorBarsData, Q_PRIMITIVE_TYPE); + + +/*! \typedef QCPErrorBarsDataContainer + + Container for storing \ref QCPErrorBarsData points. It is a typedef for QVector<\ref + QCPErrorBarsData>. + + This is the container in which \ref QCPErrorBars holds its data. Unlike most other data + containers for plottables, it is not based on \ref QCPDataContainer. This is because the error + bars plottable is special in that it doesn't store its own key and value coordinate per error + bar. It adopts the key and value from the plottable to which the error bars shall be applied + (\ref QCPErrorBars::setDataPlottable). So the stored \ref QCPErrorBarsData doesn't need a + sortable key, but merely an index (as \c QVector provides), which maps one-to-one to the indices + of the other plottable's data. + + \see QCPErrorBarsData, QCPErrorBars::setData +*/ +typedef QVector QCPErrorBarsDataContainer; + +class QCP_LIB_DECL QCPErrorBars : public QCPAbstractPlottable, public QCPPlottableInterface1D +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QSharedPointer data READ data WRITE setData) + Q_PROPERTY(QCPAbstractPlottable* dataPlottable READ dataPlottable WRITE setDataPlottable) + Q_PROPERTY(ErrorType errorType READ errorType WRITE setErrorType) + Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) + Q_PROPERTY(double symbolGap READ symbolGap WRITE setSymbolGap) + /// \endcond +public: + + /*! + Defines in which orientation the error bars shall appear. If your data needs both error + dimensions, create two \ref QCPErrorBars with different \ref ErrorType. + + \see setErrorType + */ + enum ErrorType { etKeyError ///< The errors are for the key dimension (bars appear parallel to the key axis) + ,etValueError ///< The errors are for the value dimension (bars appear parallel to the value axis) + }; + Q_ENUMS(ErrorType) + + explicit QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPErrorBars(); + // getters: + QSharedPointer data() const { return mDataContainer; } + QCPAbstractPlottable *dataPlottable() const { return mDataPlottable.data(); } + ErrorType errorType() const { return mErrorType; } + double whiskerWidth() const { return mWhiskerWidth; } + double symbolGap() const { return mSymbolGap; } + + // setters: + void setData(QSharedPointer data); + void setData(const QVector &error); + void setData(const QVector &errorMinus, const QVector &errorPlus); + void setDataPlottable(QCPAbstractPlottable* plottable); + void setErrorType(ErrorType type); + void setWhiskerWidth(double pixels); + void setSymbolGap(double pixels); + + // non-property methods: + void addData(const QVector &error); + void addData(const QVector &errorMinus, const QVector &errorPlus); + void addData(double error); + void addData(double errorMinus, double errorPlus); + + // virtual methods of 1d plottable interface: + virtual int dataCount() const; + virtual double dataMainKey(int index) const; + virtual double dataSortKey(int index) const; + virtual double dataMainValue(int index) const; + virtual QCPRange dataValueRange(int index) const; + virtual QPointF dataPixelPosition(int index) const; + virtual bool sortKeyIsMainKey() const; + virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const; + virtual int findBegin(double sortKey, bool expandedRange=true) const; + virtual int findEnd(double sortKey, bool expandedRange=true) const; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } + +protected: + // property members: + QSharedPointer mDataContainer; + QPointer mDataPlottable; + ErrorType mErrorType; + double mWhiskerWidth; + double mSymbolGap; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; + virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE; + virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector &backbones, QVector &whiskers) const; + void getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const; + double pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const; + // helpers: + void getDataSegments(QList &selectedSegments, QList &unselectedSegments) const; + bool errorBarVisible(int index) const; + bool rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + +/* end of 'src/plottables/plottable-errorbar.h' */ + + +/* including file 'src/items/item-straightline.h', size 3117 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPItemStraightLine : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + /// \endcond +public: + explicit QCPItemStraightLine(QCustomPlot *parentPlot); + virtual ~QCPItemStraightLine(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const point1; + QCPItemPosition * const point2; + +protected: + // property members: + QPen mPen, mSelectedPen; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QLineF getRectClippedStraightLine(const QCPVector2D &point1, const QCPVector2D &vec, const QRect &rect) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-straightline.h' */ + + +/* including file 'src/items/item-line.h', size 3407 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPItemLine : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) + Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) + /// \endcond +public: + explicit QCPItemLine(QCustomPlot *parentPlot); + virtual ~QCPItemLine(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const start; + QCPItemPosition * const end; + +protected: + // property members: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QLineF getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-line.h' */ + + +/* including file 'src/items/item-curve.h', size 3379 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPItemCurve : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) + Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) + /// \endcond +public: + explicit QCPItemCurve(QCustomPlot *parentPlot); + virtual ~QCPItemCurve(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const start; + QCPItemPosition * const startDir; + QCPItemPosition * const endDir; + QCPItemPosition * const end; + +protected: + // property members: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; +}; + +/* end of 'src/items/item-curve.h' */ + + +/* including file 'src/items/item-rect.h', size 3688 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + /// \endcond +public: + explicit QCPItemRect(QCustomPlot *parentPlot); + virtual ~QCPItemRect(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-rect.h' */ + + +/* including file 'src/items/item-text.h', size 5554 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPItemText : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QColor color READ color WRITE setColor) + Q_PROPERTY(QColor selectedColor READ selectedColor WRITE setSelectedColor) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(Qt::Alignment positionAlignment READ positionAlignment WRITE setPositionAlignment) + Q_PROPERTY(Qt::Alignment textAlignment READ textAlignment WRITE setTextAlignment) + Q_PROPERTY(double rotation READ rotation WRITE setRotation) + Q_PROPERTY(QMargins padding READ padding WRITE setPadding) + /// \endcond +public: + explicit QCPItemText(QCustomPlot *parentPlot); + virtual ~QCPItemText(); + + // getters: + QColor color() const { return mColor; } + QColor selectedColor() const { return mSelectedColor; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont font() const { return mFont; } + QFont selectedFont() const { return mSelectedFont; } + QString text() const { return mText; } + Qt::Alignment positionAlignment() const { return mPositionAlignment; } + Qt::Alignment textAlignment() const { return mTextAlignment; } + double rotation() const { return mRotation; } + QMargins padding() const { return mPadding; } + + // setters; + void setColor(const QColor &color); + void setSelectedColor(const QColor &color); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setFont(const QFont &font); + void setSelectedFont(const QFont &font); + void setText(const QString &text); + void setPositionAlignment(Qt::Alignment alignment); + void setTextAlignment(Qt::Alignment alignment); + void setRotation(double degrees); + void setPadding(const QMargins &padding); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const position; + QCPItemAnchor * const topLeft; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRight; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTopLeft, aiTop, aiTopRight, aiRight, aiBottomRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QColor mColor, mSelectedColor; + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + QFont mFont, mSelectedFont; + QString mText; + Qt::Alignment mPositionAlignment; + Qt::Alignment mTextAlignment; + double mRotation; + QMargins mPadding; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const; + QFont mainFont() const; + QColor mainColor() const; + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-text.h' */ + + +/* including file 'src/items/item-ellipse.h', size 3868 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + /// \endcond +public: + explicit QCPItemEllipse(QCustomPlot *parentPlot); + virtual ~QCPItemEllipse(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const topLeftRim; + QCPItemAnchor * const top; + QCPItemAnchor * const topRightRim; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRightRim; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeftRim; + QCPItemAnchor * const left; + QCPItemAnchor * const center; + +protected: + enum AnchorIndex {aiTopLeftRim, aiTop, aiTopRightRim, aiRight, aiBottomRightRim, aiBottom, aiBottomLeftRim, aiLeft, aiCenter}; + + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + +/* end of 'src/items/item-ellipse.h' */ + + +/* including file 'src/items/item-pixmap.h', size 4373 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) + Q_PROPERTY(bool scaled READ scaled WRITE setScaled) + Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode) + Q_PROPERTY(Qt::TransformationMode transformationMode READ transformationMode) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + /// \endcond +public: + explicit QCPItemPixmap(QCustomPlot *parentPlot); + virtual ~QCPItemPixmap(); + + // getters: + QPixmap pixmap() const { return mPixmap; } + bool scaled() const { return mScaled; } + Qt::AspectRatioMode aspectRatioMode() const { return mAspectRatioMode; } + Qt::TransformationMode transformationMode() const { return mTransformationMode; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPixmap(const QPixmap &pixmap); + void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QPixmap mPixmap; + QPixmap mScaledPixmap; + bool mScaled; + bool mScaledPixmapInvalidated; + Qt::AspectRatioMode mAspectRatioMode; + Qt::TransformationMode mTransformationMode; + QPen mPen, mSelectedPen; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false); + QRect getFinalRect(bool *flippedHorz=0, bool *flippedVert=0) const; + QPen mainPen() const; +}; + +/* end of 'src/items/item-pixmap.h' */ + + +/* including file 'src/items/item-tracer.h', size 4762 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(double size READ size WRITE setSize) + Q_PROPERTY(TracerStyle style READ style WRITE setStyle) + Q_PROPERTY(QCPGraph* graph READ graph WRITE setGraph) + Q_PROPERTY(double graphKey READ graphKey WRITE setGraphKey) + Q_PROPERTY(bool interpolating READ interpolating WRITE setInterpolating) + /// \endcond +public: + /*! + The different visual appearances a tracer item can have. Some styles size may be controlled with \ref setSize. + + \see setStyle + */ + enum TracerStyle { tsNone ///< The tracer is not visible + ,tsPlus ///< A plus shaped crosshair with limited size + ,tsCrosshair ///< A plus shaped crosshair which spans the complete axis rect + ,tsCircle ///< A circle + ,tsSquare ///< A square + }; + Q_ENUMS(TracerStyle) + + explicit QCPItemTracer(QCustomPlot *parentPlot); + virtual ~QCPItemTracer(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + double size() const { return mSize; } + TracerStyle style() const { return mStyle; } + QCPGraph *graph() const { return mGraph; } + double graphKey() const { return mGraphKey; } + bool interpolating() const { return mInterpolating; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setSize(double size); + void setStyle(TracerStyle style); + void setGraph(QCPGraph *graph); + void setGraphKey(double key); + void setInterpolating(bool enabled); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + // non-virtual methods: + void updatePosition(); + + QCPItemPosition * const position; + +protected: + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + double mSize; + TracerStyle mStyle; + QCPGraph *mGraph; + double mGraphKey; + bool mInterpolating; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; +Q_DECLARE_METATYPE(QCPItemTracer::TracerStyle) + +/* end of 'src/items/item-tracer.h' */ + + +/* including file 'src/items/item-bracket.h', size 3969 */ +/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ + +class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(double length READ length WRITE setLength) + Q_PROPERTY(BracketStyle style READ style WRITE setStyle) + /// \endcond +public: + /*! + Defines the various visual shapes of the bracket item. The appearance can be further modified + by \ref setLength and \ref setPen. + + \see setStyle + */ + enum BracketStyle { bsSquare ///< A brace with angled edges + ,bsRound ///< A brace with round edges + ,bsCurly ///< A curly brace + ,bsCalligraphic ///< A curly brace with varying stroke width giving a calligraphic impression + }; + Q_ENUMS(BracketStyle) + + explicit QCPItemBracket(QCustomPlot *parentPlot); + virtual ~QCPItemBracket(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + double length() const { return mLength; } + BracketStyle style() const { return mStyle; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setLength(double length); + void setStyle(BracketStyle style); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE; + + QCPItemPosition * const left; + QCPItemPosition * const right; + QCPItemAnchor * const center; + +protected: + // property members: + enum AnchorIndex {aiCenter}; + QPen mPen, mSelectedPen; + double mLength; + BracketStyle mStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; + virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; + + // non-virtual methods: + QPen mainPen() const; +}; +Q_DECLARE_METATYPE(QCPItemBracket::BracketStyle) + +/* end of 'src/items/item-bracket.h' */ + + +#endif // QCUSTOMPLOT_H + diff --git a/Desktop_Interface/ui_elements/qcp2/qcustomplot.h.REMOVED.git-id b/Desktop_Interface/ui_elements/qcp2/qcustomplot.h.REMOVED.git-id deleted file mode 100644 index 86a27d11..00000000 --- a/Desktop_Interface/ui_elements/qcp2/qcustomplot.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -25316bf815bacddefdad3c2956961a1300dc39e2 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/siPrint.cpp b/Desktop_Interface/ui_elements/siPrint.cpp new file mode 100644 index 00000000..287ef3c9 --- /dev/null +++ b/Desktop_Interface/ui_elements/siPrint.cpp @@ -0,0 +1,65 @@ +#include "siprint.h" + +siprint::siprint(char *unitsInit, double valInit) +{ + strncpy(units, unitsInit, 6); + value = valInit; +} + +char* siprint::printVal(){ + double tempValue = value; + bool negative = false; + + if (tempValue == 0){ + sprintf(printString, "0%s", units); + return printString; + } + if (value < 0){ + negative = true; + tempValue *= -1; + } + if (tempValue >= 1000000000000000000){ + sprintf(printString, "Inf %s", units); + return printString; + } + + + if (tempValue >= 1000000){ + sprintf(printString, "%c%.2fM%s", (negative ? '-':' '), tempValue/1000000, units); + return printString; + } + + if (tempValue >= 1000){ + sprintf(printString, "%c%.2fk%s", (negative ? '-':' '), tempValue/1000, units); + return printString; + } + + if (tempValue >= 1){ + sprintf(printString, "%c%.2f%s", (negative ? '-':' '), tempValue, units); + return printString; + } + + if (tempValue >= 0.001){ + sprintf(printString, "%c%.2fm%s", (negative ? '-' : ' '), tempValue*1000, units); + return printString; + } + + if (tempValue >= 0.000001){ + sprintf(printString, "%c%.2fu%s", (negative ? '-':' '), tempValue*1000000, units); + return printString; + } + + if (tempValue >= 0.000000001){ + sprintf(printString, "%c%.2fn%s", (negative ? '-':' '), tempValue*1000000000, units); + return printString; + } + + if (tempValue >= 0.000000000001){ + sprintf(printString, "%c%.2fp%s", (negative ? '-':' '), tempValue*1000000000000, units); + return printString; + } + + + sprintf(printString, "0%s", units); + return printString; +} diff --git a/Desktop_Interface/ui_elements/siPrint.cpp.REMOVED.git-id b/Desktop_Interface/ui_elements/siPrint.cpp.REMOVED.git-id deleted file mode 100644 index cbd96918..00000000 --- a/Desktop_Interface/ui_elements/siPrint.cpp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -287ef3c90bb28fd2d6740afa696f02e548e6ee35 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/siprint.h b/Desktop_Interface/ui_elements/siprint.h new file mode 100644 index 00000000..bcee87ac --- /dev/null +++ b/Desktop_Interface/ui_elements/siprint.h @@ -0,0 +1,21 @@ +#ifndef SIPRINT_H +#define SIPRINT_H + +#include +#include + +//siprint just prints values with their SI prefix. +//For example, it would print the number 1000 and unit V as "1kV". +class siprint +{ +public: + siprint(char *unitsInit, double valInit); + char* printVal(); + char units[6]; + double value; +private: + char printString[160]; + +}; + +#endif // SIPRINT_H diff --git a/Desktop_Interface/ui_elements/siprint.h.REMOVED.git-id b/Desktop_Interface/ui_elements/siprint.h.REMOVED.git-id deleted file mode 100644 index 08a420b6..00000000 --- a/Desktop_Interface/ui_elements/siprint.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bcee87acfb197ccf4923320f0db8d376f4dd6267 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/swipeystack.cpp b/Desktop_Interface/ui_elements/swipeystack.cpp new file mode 100644 index 00000000..e02b48a9 --- /dev/null +++ b/Desktop_Interface/ui_elements/swipeystack.cpp @@ -0,0 +1,60 @@ +#include "swipeystack.h" + +swipeyStack::swipeyStack(QWidget *parent) : QStackedWidget(parent) +{ +} + +void swipeyStack::mousePressEvent(QMouseEvent *event){ + initial_x = event->globalX(); + initial_y = event->globalY(); + initial_epochTime = QDateTime::currentMSecsSinceEpoch(); + return; +} + +void swipeyStack::mouseReleaseEvent(QMouseEvent *event){ + qint64 msecsPassed = QDateTime::currentMSecsSinceEpoch() - initial_epochTime; + int x = event->globalX(); + int y = event->globalY(); + + int deltaX = x - initial_x; + int deltaY = y - initial_y; + + qDebug("TouchPoint moved [%d, %d] in %lldms", deltaX, deltaY, msecsPassed); + + if((msecsPassed < SWIPEYSTACK_MAX_DRAG_TIME) && (qAbs(deltaX) > SWIPEYSTACK_MIN_DELTAX)){ + if((qreal)deltaX/(qreal)msecsPassed > 1){ + qDebug() << "SWIPE RIGHT"; + cycleStack(-1); + } + if((qreal)deltaX/(qreal)msecsPassed < -1){ + qDebug() << "SWIPE LEFT"; + cycleStack(1); + } + } + return; + } + +void swipeyStack::cycleStack(int delta){ + int idx = currentIndex(); + int cnt = count(); + if(!wrapEnabled){ + if((delta > 0) && ((idx + delta) > (cnt-1))){ + setCurrentIndex(cnt-1); + return; + } + if((delta < 0) && ((idx + delta) < 0)){ + setCurrentIndex(0); + return; + } + } + if(idx == 0){ + idx = cnt; + } + setCurrentIndex((idx + delta) % cnt); + return; +} + +void swipeyStack::enableWrapping(bool enabled){ + wrapEnabled = enabled; +} + diff --git a/Desktop_Interface/ui_elements/swipeystack.cpp.REMOVED.git-id b/Desktop_Interface/ui_elements/swipeystack.cpp.REMOVED.git-id deleted file mode 100644 index 4fba34c5..00000000 --- a/Desktop_Interface/ui_elements/swipeystack.cpp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e02b48a9cf2845cea6b204caa1125025e677600e \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/swipeystack.h b/Desktop_Interface/ui_elements/swipeystack.h new file mode 100644 index 00000000..7090ccc6 --- /dev/null +++ b/Desktop_Interface/ui_elements/swipeystack.h @@ -0,0 +1,32 @@ +#ifndef SWIPEYSTACK_H +#define SWIPEYSTACK_H + +#include +#include +#include +#include + +#define SWIPEYSTACK_MIN_DELTAX 20 +#define SWIPEYSTACK_MAX_DRAG_TIME 500 + + +class swipeyStack : public QStackedWidget +{ + Q_OBJECT +public: + explicit swipeyStack(QWidget *parent = 0); +private: + int initial_x; + int initial_y; + qint64 initial_epochTime; + bool wrapEnabled = true; +signals: + +public slots: + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void enableWrapping(bool enabled); + void cycleStack(int delta); +}; + +#endif // SWIPEYSTACK_H diff --git a/Desktop_Interface/ui_elements/swipeystack.h.REMOVED.git-id b/Desktop_Interface/ui_elements/swipeystack.h.REMOVED.git-id deleted file mode 100644 index c975c21e..00000000 --- a/Desktop_Interface/ui_elements/swipeystack.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7090ccc6cca6cf3078fe207242e0ee39e4946a1a \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/timedtickbox.cpp b/Desktop_Interface/ui_elements/timedtickbox.cpp new file mode 100644 index 00000000..76ad242f --- /dev/null +++ b/Desktop_Interface/ui_elements/timedtickbox.cpp @@ -0,0 +1,24 @@ +#include "timedtickbox.h" + +timedTickBox::timedTickBox(QWidget *parent) : QCheckBox(parent) +{ + timer = new QTimer(); + timer->setTimerType(Qt::PreciseTimer); + timer->start(timerLength); + connect(timer, SIGNAL(timeout()), this, SLOT(timerTick())); + +} + +void timedTickBox::resetTimer(){ + timer->stop(); + if(timerEnabled) timer->start(timerLength); +} + +void timedTickBox::timerTick(){ + this->setChecked(true); + timer->stop(); +} + +void timedTickBox::enableTimer(bool enabled){ + timerEnabled = enabled; +} diff --git a/Desktop_Interface/ui_elements/timedtickbox.cpp.REMOVED.git-id b/Desktop_Interface/ui_elements/timedtickbox.cpp.REMOVED.git-id deleted file mode 100644 index 5d9c555b..00000000 --- a/Desktop_Interface/ui_elements/timedtickbox.cpp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -76ad242fdbd6b748872d2d55bc9b46d068f6198c \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/timedtickbox.h b/Desktop_Interface/ui_elements/timedtickbox.h new file mode 100644 index 00000000..9242e744 --- /dev/null +++ b/Desktop_Interface/ui_elements/timedtickbox.h @@ -0,0 +1,28 @@ +#ifndef TIMEDTICKBOX_H +#define TIMEDTICKBOX_H + +#include +#include +#include + +//timedTickBox is used to re-lock the power supply after a few seconds. +//It's just a tickbox with a timer on it. + +class timedTickBox : public QCheckBox +{ + Q_OBJECT +public: + explicit timedTickBox(QWidget *parent = 0); + bool timerEnabled = true; + int timerLength = 7500; + QTimer *timer = NULL; + +signals: + +public slots: + void resetTimer(); + void timerTick(); + void enableTimer(bool enabled); +}; + +#endif // TIMEDTICKBOX_H diff --git a/Desktop_Interface/ui_elements/timedtickbox.h.REMOVED.git-id b/Desktop_Interface/ui_elements/timedtickbox.h.REMOVED.git-id deleted file mode 100644 index 59e3b247..00000000 --- a/Desktop_Interface/ui_elements/timedtickbox.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9242e74453eb0d5dc54d40d75967bcfffc6f8097 \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/voltagespinbox.cpp b/Desktop_Interface/ui_elements/voltagespinbox.cpp new file mode 100644 index 00000000..f7e94ae7 --- /dev/null +++ b/Desktop_Interface/ui_elements/voltagespinbox.cpp @@ -0,0 +1,14 @@ +#include "voltagespinbox.h" + +voltageSpinBox::voltageSpinBox(QWidget *parent) : QDoubleSpinBox(parent) +{ + +} + +void voltageSpinBox::setMax(double newMax){ + this->setMaximum(newMax); +} + +void voltageSpinBox::setMin(double newMin){ + this->setMinimum(newMin); +} diff --git a/Desktop_Interface/ui_elements/voltagespinbox.cpp.REMOVED.git-id b/Desktop_Interface/ui_elements/voltagespinbox.cpp.REMOVED.git-id deleted file mode 100644 index 5f31d473..00000000 --- a/Desktop_Interface/ui_elements/voltagespinbox.cpp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f7e94ae7ca22bb1a40edc5efcf8af8fb8972b53e \ No newline at end of file diff --git a/Desktop_Interface/ui_elements/voltagespinbox.h b/Desktop_Interface/ui_elements/voltagespinbox.h new file mode 100644 index 00000000..36d37887 --- /dev/null +++ b/Desktop_Interface/ui_elements/voltagespinbox.h @@ -0,0 +1,23 @@ +#ifndef VOLTAGESPINBOX_H +#define VOLTAGESPINBOX_H + +#include +#include + +//Wrapper for the spinboxes on the "Enter Scope Range" dialog (Oscilloscope->Range->Enter Manually; shortcut is "M"). +//It needs to exist in order to map the setMaximum() and setMinimum() functions for QDOubleSpinbox to slots. + +class voltageSpinBox : public QDoubleSpinBox +{ + Q_OBJECT +public: + explicit voltageSpinBox(QWidget *parent = 0); + bool min = false; +signals: + +public slots: + void setMax(double newMax); + void setMin(double newMin); +}; + +#endif // VOLTAGESPINBOX_H diff --git a/Desktop_Interface/ui_elements/voltagespinbox.h.REMOVED.git-id b/Desktop_Interface/ui_elements/voltagespinbox.h.REMOVED.git-id deleted file mode 100644 index 26498b67..00000000 --- a/Desktop_Interface/ui_elements/voltagespinbox.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -36d3788783580207561aa1bde4487b0c7a62cf10 \ No newline at end of file diff --git a/Desktop_Interface/ui_files_desktop/mainwindow.ui b/Desktop_Interface/ui_files_desktop/mainwindow.ui new file mode 100644 index 00000000..8623a839 --- /dev/null +++ b/Desktop_Interface/ui_files_desktop/mainwindow.ui @@ -0,0 +1,4034 @@ + + + MainWindow + + + true + + + + 0 + 0 + 1440 + 900 + + + + + 1024 + 768 + + + + EspoTek Labrador + + + + + + + QLayout::SetMinAndMaxSize + + + + + + 0 + 0 + + + + + 500 + 400 + + + + Qt::LeftToRight + + + + + + + + 16777215 + 48 + + + + cursorStatsLabel + + + Qt::AlignCenter + + + + + + + SALUTON MI ESTAS FUNCTION GENERATOR CONTROLLER + + + + + + + + + + -60 + + + 10 + + + 10 + + + -20 + + + -20 + + + true + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 10 + + + + + + + true + + + + 0 + 0 + + + + + 16777215 + 48 + + + + true + + + + + + + + 16777215 + 48 + + + + true + + + + + + + + + + + Device Not Connected! + + + Qt::AlignCenter + + + + + + + + + + + Oscilloscope CH1 + + + false + + + true + + + true + + + + + + Paused + + + + + + + AC Coupled + + + + + + + Filter + + + + + + + Double Sample Rate + + + + + + + 0 + + + + + Max + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + Min + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + Mean + + + + + + + RMS + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + acCoupledLabel_CH1 + filterLabel_CH1 + pausedLabeL_CH1 + doubleSampleLabel + + + + + + true + + + Cursor + + + false + + + false + + + + + + Horizontal + + + + + + + Vertical + + + + + + + CURSOR ENABLER + + + + + + + + + + + + + + true + + + Oscilloscope CH2 + + + false + + + true + + + false + + + + + + Paused + + + + + + + AC Coupled + + + + + + + Filter + + + + + + + X-Y Display + + + + + + + 0 + + + + + Max + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + Min + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + Mean + + + + + + + RMS + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + + + + + + true + + + Trigger + + + true + + + false + + + + + + + CH1 (Rising) + + + + + CH1 (Falling) + + + + + CH2 (Rising) + + + + + CH2 (Falling) + + + + + + + + -20.000000000000000 + + + 20.000000000000000 + + + 0.100000000000000 + + + + + + + Single Shot + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + false + + + Multimeter++ + + + true + + + false + + + + + + + V + + + + + I + + + + + R + + + + + C + + + + + + + + 0 + + + 0 + + + + + Max + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + 4 + + + + + + + Min + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + 4 + + + + + + + Mean + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + 4 + + + + + + + RMS + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + 4 + + + + + + + + + Paused + + + + + + + Series Resistance + + + + + + + Mode + + + + + + + Ω + + + 0 + + + 1000000.000000000000000 + + + + + + + + Signal Gen CH2 + + + + + Power Supply + + + + + + + + Source + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + true + + + Signal Gen CH1 + + + false + + + false + + + + + + Waveform + + + + + + + + + + Frequency + + + + + + + Hz + + + 2 + + + 0.000000000000000 + + + 1000000.000000000000000 + + + 100.000000000000000 + + + 1000.000000000000000 + + + + + + + Amplitude (Peak-Peak) + + + + + + + V + + + 9.600000000000000 + + + 0.100000000000000 + + + + + + + Offset + + + + + + + V + + + 9.600000000000000 + + + 0.100000000000000 + + + + + + + + + + true + + + Signal Gen CH2 + + + false + + + false + + + + + + true + + + Waveform + + + + + + + true + + + + + + + true + + + Frequency + + + + + + + true + + + Hz + + + 2 + + + 1000000.000000000000000 + + + 100.000000000000000 + + + 1000.000000000000000 + + + + + + + true + + + Amplitude (Peak-Peak) + + + + + + + true + + + V + + + 10.000000000000000 + + + 0.100000000000000 + + + + + + + true + + + Offset + + + + + + + true + + + V + + + 10.000000000000000 + + + 0.100000000000000 + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + SALUTON MI ESTAS ISO DRIVER + + + + + + + + + + + false + + + PSU + + + + + + false + + + 90 + + + 240 + + + 1 + + + Qt::Vertical + + + QSlider::TicksBelow + + + 20 + + + + + + + Lock PSU + + + true + + + + + + + + 108 + 36 + + + + + 108 + 36 + + + + true + + + 4 + + + 5.000000000000000 + + + 5 + + + + + + + + + + + + Logic Analyzer CH1 + + + true + + + false + + + + + + true + + + Pause + + + + + + + Serial Decoding + + + true + + + true + + + false + + + + 0 + + + 0 + + + 6 + + + 0 + + + 0 + + + + + + UART + + + + + SPI + + + + + I2C + + + + + + + + + + + + + + false + + + Logic Analyzer CH2 + + + true + + + false + + + + + + Serial Decoding + + + true + + + true + + + false + + + + 0 + + + 0 + + + 6 + + + 0 + + + 0 + + + + + + UART + + + + + SPI + + + + + I2C + + + + + + + + + + + + + + Digital Output + + + + + + Pin 3 + + + + + + + Pin 2 + + + + + + + Pin 1 + + + + + + + Pin 4 + + + + + digitalOutCheckbox_CH2 + digitalOutCheckbox_CH1 + digitalOutCheckbox_CH3 + digitalOutCheckbox_CH4 + + + + + + Debug! + + + + + + + ReinitUsb() + + + + + + + Jump to Bootloader + + + + + + + + 96 + 36 + + + + + 96 + 36 + + + + BUFFER IMAGE HERE + + + Qt::AlignCenter + + + + + + + + + + + + + 0 + 0 + 1440 + 21 + + + + + File + + + + + + + Oscilloscope + + + + Gain + + + + + + + + + + + + + + CH1 Stats + + + + + + + + + CH2 Stats + + + + + + + + + Frame rate + + + + + + + + + + + Range + + + + + + + + + + + + + + + + + + + + + Multimeter + + + + + 0 + 0 + 135 + 116 + + + + Range (V) + + + + + + + + Range (I) + + + + + + + + Range (R) + + + + + + + + Range (C) + + + + + + + + + + + + + + Logic Analyzer + + + + UART 1 + + + + Baud Rate + + + + + + + + + + + + + + + + + Parity Bit + + + + + + Data Bits + + + + + + + + + + UART 2 + + + + Baud Rate + + + + + + + + + + + + + + + + + Data Bits + + + + + + Parity Bit + + + + + + + + + + + + + Power Supply + + + + + + Connection Type + + + + + + + + + + + + + + + true + + + Auto + + + + + true + + + 0.5 + + + + + true + + + 1 + + + + + true + + + 2 + + + + + true + + + 4 + + + + + true + + + 8 + + + + + true + + + 16 + + + + + true + + + 32 + + + + + true + + + 64 + + + QAction::TextHeuristicRole + + + + + Calibrate + + + + + true + + + true + + + Cursor Stats + + + + + true + + + Max + + + + + true + + + Min + + + + + true + + + Mean + + + + + true + + + RMS + + + + + true + + + Max + + + + + true + + + Min + + + + + true + + + Mean + + + + + true + + + RMS + + + + + true + + + false + + + mV + + + + + true + + + false + + + V + + + + + true + + + true + + + Auto + + + + + true + + + true + + + Auto + + + + + true + + + false + + + mA + + + + + true + + + A + + + + + true + + + 300 + + + + + true + + + 600 + + + + + true + + + 1200 + + + + + true + + + 2400 + + + + + true + + + 4800 + + + + + true + + + 9600 + + + + + true + + + 14400 + + + + + true + + + 19200 + + + + + true + + + 28800 + + + + + true + + + 38400 + + + + + true + + + 57600 (Glitchy) + + + + + true + + + 115200 (Glitchy) + + + + + true + + + 8 + + + + + true + + + None + + + + + true + + + 300 + + + + + true + + + 600 + + + + + true + + + 1200 + + + + + true + + + 2400 + + + + + true + + + 4800 + + + + + true + + + 9600 + + + + + true + + + 14400 + + + + + true + + + 19200 + + + + + true + + + 28800 + + + + + true + + + 38400 + + + + + true + + + 57600 (Glitchy) + + + + + true + + + 115200 (Glitchy) + + + + + true + + + 8 + + + + + true + + + None + + + + + true + + + Record + + + + + true + + + Force Square Display (Not Officially Supported) + + + + + true + + + true + + + Enable Cursors on Click + + + + + true + + + true + + + 60FPS + + + + + true + + + 30FPS + + + + + true + + + 20FPS + + + + + true + + + 15FPS + + + + + true + + + 10FPS + + + + + true + + + 5FPS + + + + + true + + + true + + + Auto Lock + + + + + Snap to Cursors + + + + + Enter Manually + + + + + Take Snapshot + + + + + true + + + true + + + Auto + + + + + true + + + Ω + + + + + true + + + + + + + + true + + + true + + + Auto + + + + + true + + + nF + + + + + true + + + μF + + + + + true + + + true + + + lo-bw + + + + + true + + + single-ep-msync + + + + + true + + + single-ep-async + + + + + + + QCustomPlot + QWidget +
qcustomplot.h
+ 1 + + mouseWheel(QWheelEvent*) + mouseRelease(QMouseEvent*) + mousePress(QMouseEvent*) + mouseMove(QMouseEvent*) + +
+ + bufferControl + QLabel +
buffercontrol.h
+ + scopeOut_CH1(bool) + scopeOut_CH2(bool) + scopeUncheck(bool) + signalGenOut(bool) + busSnifferOut_CH1(bool) + busSnifferOut_CH2(bool) + busSnifferUncheck(bool) + multimeterOut(bool) + scopeDsrOut(bool) + scopeDsrUncheck(bool) + updateDig(int) + modeChange(int) + setDSR(bool) + scopeIn_CH1(bool) + scopeIn_CH2(bool) + signalGenIn(bool) + busSnifferIn_CH1(bool) + busSnifferIn_CH2(bool) + multimeterIn(bool) + scopeDsrIn(bool) + digIn_CH1(bool) + digIn_CH2(bool) + digIn_CH3(bool) + digIn_CH4(bool) + +
+ + espoSlider + QSlider +
esposlider.h
+ + lcdOut(QString) + voltageChanged(double) + selfMoved(int) + +
+ + espoSpinBox + QDoubleSpinBox +
espospinbox.h
+ + maximumChanged(double) + setMax(double) + setMin(double) + changeStepping(double) + +
+ + espoComboBox + QComboBox +
espocombobox.h
+
+ + functionGenControl + QLabel +
functiongencontrol.h
+ + functionGenToUpdate(int,functionGenControl*) + setMaxFreq_CH1(double) + setMinFreq_CH1(double) + setMaxFreq_CH2(double) + setMinFreq_CH2(double) + waveformName_CH1(QString) + waveformName_CH2(QString) + freqUpdate_CH1(double) + amplitudeUpdate_CH1(double) + offsetUpdate_CH1(double) + freqUpdate_CH2(double) + amplitudeUpdate_CH2(double) + offsetUpdate_CH2(double) + +
+ + isoDriver + QLabel +
isodriver.h
+ + setGain(double) + disableWindow(bool) + setCursorStatsVisible(bool) + sendCursorStatsText(QString) + singleShotTriggered(bool) + multimeterMax(double) + multimeterMin(double) + multimeterMean(double) + sendMultimeterLabel1(QString) + sendMultimeterLabel2(QString) + sendMultimeterLabel3(QString) + changeTimeAxis(bool) + sendTriggerValue(double) + sendVmax_CH1(double) + sendVmin_CH1(double) + sendVmean_CH1(double) + sendVmax_CH2(double) + sendVmin_CH2(double) + sendVmean_CH2(double) + multimeterREnabled(int) + multimeterRMS(double) + sendMultimeterLabel4(QString) + setWindow(int) + setVoltageRange(QWheelEvent*) + pauseEnable_CH1(bool) + pauseEnable_CH2(bool) + startTimer() + clearBuffers(bool,bool,bool) + setVisible_CH2(bool) + gainBuffers(double) + setAutoGain(bool) + graphMousePress(QMouseEvent*) + graphMouseRelease(QMouseEvent*) + cursorEnableHori(bool) + cursorEnableVert(bool) + graphMouseMove(QMouseEvent*) + setTriggerEnabled(bool) + setTriggerLevel(double) + setSingleShotEnabled(bool) + setTriggerMode(int) + setAC_CH1(bool) + setAC_CH2(bool) + setMultimeterType(int) + setSeriesResistance(double) + enableMM() + setSerialDecodeEnabled_CH1(bool) + setSerialDecodeEnabled_CH2(bool) + setXYmode(bool) + triggerGroupStateChange(bool) + pauseEnable_multimeter(bool) + timerTick() + rSourceChanged(int) + +
+ + noCloseMenu + QMenu +
noclosemenu.h
+
+ + cursorEnabler + QLabel +
cursorenabler.h
+ + tickHori(bool) + tickVert(bool) + passOnSignal(QMouseEvent*) + clickDetected(QMouseEvent*) + setTurnedOn(bool) + +
+ + deviceConnectedDisplay + QLabel +
deviceconnecteddisplay.h
+ + connectedStatusChanged(bool) + +
+ + timedTickBox + QCheckBox +
timedtickbox.h
+ + resetTimer() + +
+
+ + + + scopeGroup_CH1 + toggled(bool) + bufferDisplay + scopeIn_CH1(bool) + + + 1160 + 168 + + + 1394 + 888 + + + + + scopeGroup_CH2 + toggled(bool) + bufferDisplay + scopeIn_CH2(bool) + + + 1287 + 158 + + + 1394 + 888 + + + + + signalGenGroup_CH2 + toggled(bool) + bufferDisplay + signalGenIn(bool) + + + 1288 + 839 + + + 1394 + 888 + + + + + bufferDisplay + busSnifferOut_CH2(bool) + busSnifferGroup_CH2 + setEnabled(bool) + + + 1394 + 888 + + + 1428 + 680 + + + + + bufferDisplay + signalGenOut(bool) + signalGenGroup_CH2 + setEnabled(bool) + + + 1394 + 888 + + + 1288 + 839 + + + + + bufferDisplay + scopeOut_CH1(bool) + scopeGroup_CH1 + setEnabled(bool) + + + 1394 + 888 + + + 1160 + 259 + + + + + bufferDisplay + scopeOut_CH2(bool) + scopeGroup_CH2 + setEnabled(bool) + + + 1394 + 888 + + + 1287 + 249 + + + + + bufferDisplay + busSnifferUncheck(bool) + busSnifferGroup_CH2 + setChecked(bool) + + + 1394 + 888 + + + 1428 + 680 + + + + + bufferDisplay + scopeUncheck(bool) + scopeGroup_CH2 + setChecked(bool) + + + 1394 + 888 + + + 1287 + 249 + + + + + doubleSampleLabel + toggled(bool) + bufferDisplay + scopeDsrIn(bool) + + + 1150 + 160 + + + 1394 + 888 + + + + + bufferDisplay + scopeDsrUncheck(bool) + doubleSampleLabel + setChecked(bool) + + + 1394 + 888 + + + 1150 + 160 + + + + + bufferDisplay + scopeDsrOut(bool) + doubleSampleLabel + setEnabled(bool) + + + 1394 + 888 + + + 1150 + 160 + + + + + psuSlider + valueChanged(int) + psuSlider + selfMoved(int) + + + 1331 + 376 + + + 1331 + 376 + + + + + psuSlider + lcdOut(QString) + psuDisplay + display(QString) + + + 1331 + 376 + + + 1415 + 490 + + + + + amplitudeValue_CH1 + valueChanged(double) + dcOffsetValue_CH1 + maximumChanged(double) + + + 1141 + 784 + + + 1141 + 829 + + + + + amplitudeValue_CH2 + valueChanged(double) + dcOffsetValue_CH2 + maximumChanged(double) + + + 1278 + 784 + + + 1278 + 829 + + + + + dcOffsetValue_CH1 + valueChanged(double) + amplitudeValue_CH1 + maximumChanged(double) + + + 1141 + 829 + + + 1141 + 784 + + + + + dcOffsetValue_CH2 + valueChanged(double) + amplitudeValue_CH2 + maximumChanged(double) + + + 1278 + 829 + + + 1278 + 784 + + + + + waveformSelect_CH1 + currentTextChanged(QString) + controller_fg + waveformName_CH1(QString) + + + 1141 + 694 + + + 970 + 468 + + + + + waveformSelect_CH2 + currentTextChanged(QString) + controller_fg + waveformName_CH2(QString) + + + 1278 + 694 + + + 970 + 468 + + + + + amplitudeValue_CH1 + valueChanged(double) + controller_fg + amplitudeUpdate_CH1(double) + + + 1141 + 784 + + + 970 + 468 + + + + + dcOffsetValue_CH1 + valueChanged(double) + controller_fg + offsetUpdate_CH1(double) + + + 1141 + 829 + + + 970 + 468 + + + + + bufferDisplay + busSnifferOut_CH1(bool) + busSifferGroup_CH1 + setEnabled(bool) + + + 1394 + 888 + + + 1428 + 602 + + + + + bufferDisplay + busSnifferOut_CH2(bool) + busSnifferGroup_CH2 + setEnabled(bool) + + + 1394 + 888 + + + 1428 + 680 + + + + + busSifferGroup_CH1 + toggled(bool) + bufferDisplay + busSnifferIn_CH1(bool) + + + 1428 + 602 + + + 1394 + 888 + + + + + busSnifferGroup_CH2 + toggled(bool) + bufferDisplay + busSnifferIn_CH2(bool) + + + 1428 + 680 + + + 1394 + 888 + + + + + digitalOutCheckbox_CH1 + toggled(bool) + bufferDisplay + digIn_CH1(bool) + + + 1360 + 726 + + + 1394 + 888 + + + + + digitalOutCheckbox_CH2 + toggled(bool) + bufferDisplay + digIn_CH2(bool) + + + 1418 + 726 + + + 1394 + 888 + + + + + digitalOutCheckbox_CH3 + toggled(bool) + bufferDisplay + digIn_CH3(bool) + + + 1360 + 749 + + + 1394 + 888 + + + + + digitalOutCheckbox_CH4 + toggled(bool) + bufferDisplay + digIn_CH4(bool) + + + 1418 + 749 + + + 1394 + 888 + + + + + amplitudeValue_CH2 + valueChanged(double) + controller_fg + amplitudeUpdate_CH2(double) + + + 1278 + 784 + + + 970 + 468 + + + + + dcOffsetValue_CH2 + valueChanged(double) + controller_fg + offsetUpdate_CH2(double) + + + 1278 + 829 + + + 970 + 468 + + + + + timeBaseSlider + valueChanged(int) + controller_iso + setWindow(int) + + + 434 + 781 + + + 1289 + 889 + + + + + scopeAxes + mouseWheel(QWheelEvent*) + controller_iso + setVoltageRange(QWheelEvent*) + + + 492 + 430 + + + 1289 + 889 + + + + + pausedLabeL_CH1 + toggled(bool) + controller_iso + pauseEnable_CH1(bool) + + + 1150 + 91 + + + 1289 + 889 + + + + + pausedLabel_CH2 + toggled(bool) + controller_iso + pauseEnable_CH2(bool) + + + 1277 + 91 + + + 1289 + 889 + + + + + pausedLabeL_CH1 + toggled(bool) + pausedLabel_CH2 + setChecked(bool) + + + 1150 + 91 + + + 1277 + 91 + + + + + pausedLabel_CH2 + toggled(bool) + pausedLabeL_CH1 + setChecked(bool) + + + 1277 + 91 + + + 1150 + 91 + + + + + controller_iso + disableWindow(bool) + MainWindow + setEnabled(bool) + + + 1289 + 889 + + + 1023 + 226 + + + + + scopeAxes + mouseRelease(QMouseEvent*) + controller_iso + graphMouseRelease(QMouseEvent*) + + + 364 + 430 + + + 1289 + 889 + + + + + cursorHoriCheck + toggled(bool) + controller_iso + cursorEnableHori(bool) + + + 1150 + 320 + + + 1289 + 889 + + + + + cursorVertCheck + toggled(bool) + controller_iso + cursorEnableVert(bool) + + + 1150 + 343 + + + 1289 + 889 + + + + + scopeAxes + mouseMove(QMouseEvent*) + controller_iso + graphMouseMove(QMouseEvent*) + + + 451 + 430 + + + 1289 + 889 + + + + + controller_iso + setCursorStatsVisible(bool) + cursorStatsLabel + setVisible(bool) + + + 1289 + 889 + + + 970 + 449 + + + + + lockPsuCheckBox + toggled(bool) + psuSlider + setDisabled(bool) + + + 1419 + 448 + + + 1331 + 376 + + + + + triggerGroup + toggled(bool) + controller_iso + setTriggerEnabled(bool) + + + 1287 + 382 + + + 1289 + 889 + + + + + triggerLevelValue + valueChanged(double) + controller_iso + setTriggerLevel(double) + + + 1277 + 349 + + + 1289 + 889 + + + + + controller_iso + singleShotTriggered(bool) + pausedLabeL_CH1 + setChecked(bool) + + + 1289 + 889 + + + 1150 + 91 + + + + + singleShotCheckBox + toggled(bool) + controller_iso + setSingleShotEnabled(bool) + + + 1277 + 372 + + + 1289 + 889 + + + + + triggerChannelSelect + currentIndexChanged(int) + controller_iso + setTriggerMode(int) + + + 1277 + 323 + + + 1289 + 889 + + + + + acCoupledLabel_CH1 + toggled(bool) + controller_iso + setAC_CH1(bool) + + + 1150 + 114 + + + 1289 + 889 + + + + + acCoupledLabel_CH2 + toggled(bool) + controller_iso + setAC_CH2(bool) + + + 1277 + 114 + + + 1289 + 889 + + + + + multimeterGroup + toggled(bool) + bufferDisplay + multimeterIn(bool) + + + 1289 + 603 + + + 1394 + 888 + + + + + bufferDisplay + multimeterOut(bool) + multimeterGroup + setEnabled(bool) + + + 1394 + 888 + + + 1289 + 603 + + + + + multimeterModeSelect + currentIndexChanged(int) + controller_iso + setMultimeterType(int) + + + 1151 + 474 + + + 1289 + 889 + + + + + controller_iso + multimeterMax(double) + multimeterMaxDisplay + display(double) + + + 1289 + 889 + + + 1278 + 460 + + + + + controller_iso + multimeterMin(double) + multimeterMinDisplay + display(double) + + + 1289 + 889 + + + 1278 + 484 + + + + + controller_iso + multimeterMean(double) + multimeterMeanDisplay + display(double) + + + 1289 + 889 + + + 1278 + 508 + + + + + multimeterResistanceSelect + valueChanged(double) + controller_iso + setSeriesResistance(double) + + + 1151 + 564 + + + 1289 + 889 + + + + + controller_iso + sendMultimeterLabel1(QString) + multimeterMaxLabel + setText(QString) + + + 1289 + 889 + + + 1181 + 458 + + + + + controller_iso + sendMultimeterLabel2(QString) + multimeterMinLabel + setText(QString) + + + 1289 + 889 + + + 1177 + 482 + + + + + controller_iso + sendMultimeterLabel3(QString) + multimeterMeanLabel + setText(QString) + + + 1289 + 889 + + + 1187 + 506 + + + + + serialDecodingCheck_CH1 + toggled(bool) + controller_iso + setSerialDecodeEnabled_CH1(bool) + + + 1418 + 592 + + + 1289 + 889 + + + + + serialDecodingCheck_CH2 + toggled(bool) + controller_iso + setSerialDecodeEnabled_CH2(bool) + + + 1418 + 670 + + + 1289 + 889 + + + + + serialDecodingCheck_CH1 + toggled(bool) + console1 + setVisible(bool) + + + 1418 + 592 + + + 394 + 835 + + + + + serialDecodingCheck_CH2 + toggled(bool) + console2 + setVisible(bool) + + + 1418 + 670 + + + 498 + 889 + + + + + controller_iso + changeTimeAxis(bool) + MainWindow + timeBaseNeedsChanging(bool) + + + 1289 + 889 + + + 800 + 696 + + + + + xyDisplayLabel + toggled(bool) + controller_iso + setXYmode(bool) + + + 1277 + 160 + + + 1289 + 889 + + + + + busSnifferGroup_CH2 + toggled(bool) + signalGenGroup_CH2 + setDisabled(bool) + + + 1428 + 680 + + + 1288 + 839 + + + + + scopeAxes + mousePress(QMouseEvent*) + makeCursorsNicer + clickDetected(QMouseEvent*) + + + 590 + 401 + + + 1150 + 372 + + + + + makeCursorsNicer + tickHori(bool) + cursorHoriCheck + setChecked(bool) + + + 1150 + 372 + + + 1150 + 320 + + + + + makeCursorsNicer + tickVert(bool) + cursorVertCheck + setChecked(bool) + + + 1150 + 372 + + + 1150 + 343 + + + + + makeCursorsNicer + passOnSignal(QMouseEvent*) + controller_iso + graphMousePress(QMouseEvent*) + + + 1150 + 372 + + + 1289 + 889 + + + + + controller_iso + sendTriggerValue(double) + triggerLevelValue + setValue(double) + + + 1289 + 889 + + + 1277 + 349 + + + + + triggerGroup + toggled(bool) + controller_iso + triggerGroupStateChange(bool) + + + 1287 + 382 + + + 1289 + 889 + + + + + controller_iso + disableWindow(bool) + deviceConnected + connectedStatusChanged(bool) + + + 1289 + 889 + + + 1289 + 43 + + + + + multimeterPauseCheckBox + toggled(bool) + controller_iso + pauseEnable_multimeter(bool) + + + 1151 + 593 + + + 1289 + 889 + + + + + controller_iso + sendVmax_CH1(double) + voltageInfoMaxDisplay_CH1 + display(double) + + + 1289 + 889 + + + 1149 + 191 + + + + + controller_iso + sendVmin_CH1(double) + voltageInfoMinDisplay_CH1 + display(double) + + + 1289 + 889 + + + 1149 + 215 + + + + + controller_iso + sendVmean_CH1(double) + voltageInfoMeanDisplay_CH1 + display(double) + + + 1289 + 889 + + + 1149 + 239 + + + + + controller_iso + sendVmax_CH2(double) + voltageInfoMaxDisplay_CH2 + display(double) + + + 1289 + 889 + + + 1276 + 191 + + + + + controller_iso + sendVmin_CH2(double) + voltageInfoMinDisplay_CH2 + display(double) + + + 1289 + 889 + + + 1276 + 215 + + + + + controller_iso + sendVmean_CH2(double) + voltageInfoMeanDisplay_CH2 + display(double) + + + 1289 + 889 + + + 1276 + 239 + + + + + lockPsuCheckBox + toggled(bool) + lockPsuCheckBox + resetTimer(bool) + + + 1419 + 448 + + + 1419 + 448 + + + + + lockPsuCheckBox + toggled(bool) + lockPsuCheckBox + resetTimer() + + + 1419 + 448 + + + 1419 + 448 + + + + + psuSlider + sliderMoved(int) + lockPsuCheckBox + resetTimer() + + + 1331 + 221 + + + 1419 + 448 + + + + + pause_LA + toggled(bool) + pausedLabeL_CH1 + setChecked(bool) + + + 1418 + 547 + + + 1150 + 91 + + + + + pausedLabeL_CH1 + toggled(bool) + pause_LA + setChecked(bool) + + + 1150 + 91 + + + 1418 + 547 + + + + + controller_fg + setMaxFreq_CH2(double) + frequencyValue_CH2 + setMax(double) + + + 970 + 468 + + + 1278 + 739 + + + + + controller_fg + setMinFreq_CH2(double) + frequencyValue_CH2 + setMin(double) + + + 970 + 468 + + + 1278 + 739 + + + + + frequencyValue_CH2 + valueChanged(double) + controller_fg + freqUpdate_CH2(double) + + + 1278 + 739 + + + 970 + 468 + + + + + frequencyValue_CH1 + valueChanged(double) + controller_fg + freqUpdate_CH1(double) + + + 1141 + 739 + + + 970 + 468 + + + + + controller_fg + setMaxFreq_CH1(double) + frequencyValue_CH1 + setMax(double) + + + 970 + 468 + + + 1141 + 739 + + + + + controller_fg + setMinFreq_CH1(double) + frequencyValue_CH1 + setMin(double) + + + 970 + 468 + + + 1141 + 739 + + + + + frequencyValue_CH1 + valueChanged(double) + frequencyValue_CH1 + changeStepping(double) + + + 1141 + 739 + + + 1141 + 739 + + + + + frequencyValue_CH2 + valueChanged(double) + frequencyValue_CH2 + changeStepping(double) + + + 1278 + 739 + + + 1278 + 739 + + + + + debugButton2 + clicked() + MainWindow + reinitUsb() + + + 1428 + 817 + + + 682 + 738 + + + + + multimeterRComboBox + currentIndexChanged(int) + MainWindow + rSourceIndexChanged(int) + + + 1073 + 514 + + + 1025 + 616 + + + + + controller_iso + multimeterREnabled(int) + MainWindow + rSourceIndexChanged(int) + + + 1040 + 881 + + + 1095 + 621 + + + + + controller_iso + multimeterRMS(double) + multimeterRmsDisplay + display(double) + + + 1189 + 877 + + + 1225 + 523 + + + + + controller_iso + sendMultimeterLabel4(QString) + multimeterRmsLabel + setText(QString) + + + 1117 + 882 + + + 1167 + 523 + + + + + multimeterRComboBox + currentIndexChanged(int) + controller_iso + rSourceChanged(int) + + + 1085 + 510 + + + 1095 + 879 + + + + + multimeterGroup + toggled(bool) + MainWindow + multimeterStateChange(bool) + + + 1032 + 418 + + + 1034 + 388 + + + + + + timeBaseNeedsChanging(bool) + reinitUsb() + rSourceIndexChanged(int) + multimeterStateChange(bool) + +
diff --git a/Desktop_Interface/ui_files_desktop/mainwindow.ui.REMOVED.git-id b/Desktop_Interface/ui_files_desktop/mainwindow.ui.REMOVED.git-id deleted file mode 100644 index 50e544d1..00000000 --- a/Desktop_Interface/ui_files_desktop/mainwindow.ui.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8623a8393cac623537d8fec0e564671f376ed9d6 \ No newline at end of file diff --git a/Desktop_Interface/ui_files_desktop/scoperangeenterdialog.ui b/Desktop_Interface/ui_files_desktop/scoperangeenterdialog.ui new file mode 100644 index 00000000..c04a52ee --- /dev/null +++ b/Desktop_Interface/ui_files_desktop/scoperangeenterdialog.ui @@ -0,0 +1,222 @@ + + + scopeRangeEnterDialog + + + + 0 + 0 + 187 + 147 + + + + Enter Scope Range + + + + + + + + + + 20.000000000000000 + + + 20.000000000000000 + + + + + + + Vmax + + + + + + + -20.000000000000000 + + + -20.000000000000000 + + + + + + + Vmin + + + + + + + 6 + + + 0.000001000000000 + + + 10.000000000000000 + + + + + + + Time Window + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + + + voltageSpinBox + QDoubleSpinBox +
voltagespinbox.h
+ + setMin(double) + setMax(double) + +
+
+ + + + buttonBox + accepted() + scopeRangeEnterDialog + accept() + + + 176 + 136 + + + 157 + 274 + + + + + buttonBox + rejected() + scopeRangeEnterDialog + reject() + + + 176 + 136 + + + 286 + 274 + + + + + vMaxBox + valueChanged(double) + scopeRangeEnterDialog + toUpdateYTop(double) + + + 63 + 30 + + + 56 + 21 + + + + + vMinBox + valueChanged(double) + scopeRangeEnterDialog + toUpdateYBot(double) + + + 67 + 56 + + + 254 + 90 + + + + + vMaxBox + valueChanged(double) + vMinBox + setMax(double) + + + 63 + 30 + + + 67 + 56 + + + + + vMinBox + valueChanged(double) + vMaxBox + setMin(double) + + + 67 + 56 + + + 63 + 30 + + + + + timeWindowBox + valueChanged(double) + scopeRangeEnterDialog + toUpdateWindow(double) + + + 37 + 74 + + + 15 + 99 + + + + + + toUpdateYTop(double) + toUpdateYBot(double) + toUpdateWindow(double) + +
diff --git a/Desktop_Interface/ui_files_desktop/scoperangeenterdialog.ui.REMOVED.git-id b/Desktop_Interface/ui_files_desktop/scoperangeenterdialog.ui.REMOVED.git-id deleted file mode 100644 index 7d8795f9..00000000 --- a/Desktop_Interface/ui_files_desktop/scoperangeenterdialog.ui.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c04a52eeb6524c09241b8f645860c5e93adc536c \ No newline at end of file diff --git a/Desktop_Interface/ui_files_mobile/mainwindow.ui b/Desktop_Interface/ui_files_mobile/mainwindow.ui new file mode 100644 index 00000000..ded44ca6 --- /dev/null +++ b/Desktop_Interface/ui_files_mobile/mainwindow.ui @@ -0,0 +1,4368 @@ + + + MainWindow + + + true + + + + 0 + 0 + 720 + 1280 + + + + + 480 + 720 + + + + EspoTek Labrador + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Device Not Connected! + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 720 + 400 + + + + Qt::LeftToRight + + + + + + + + 0 + 0 + + + + + 16777215 + 400 + + + + + 8 + + + + 1 + + + + + 8 + + + + + 0 + + + 0 + + + 2 + + + 0 + + + 0 + + + + + + + + + 2 + + + + + Oscilloscope CH1 + + + false + + + true + + + true + + + + 2 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + AC Coupled + + + + + + + Filter + + + + + + + Double Sample Rate + + + + + + + 0 + + + + + Max + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + Min + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + Mean + + + + + + + RMS + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + + + + + + true + + + Cursor/Scaling + + + false + + + false + + + + + + Horizontal + + + + + + + CURSOR ENABLER + + + + + + + Vertical + + + + + + + H-Scale + + + + + + + V-Scale + + + true + + + + + + + + + + + + 2 + + + + + true + + + Oscilloscope CH2 + + + false + + + true + + + false + + + + 2 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + AC Coupled + + + + + + + Filter + + + + + + + X-Y Display + + + + + + + 0 + + + + + Max + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + Min + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + Mean + + + + + + + RMS + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + + 0 + 24 + + + + QFrame::NoFrame + + + + + + + + + + + + true + + + Trigger + + + true + + + false + + + + 2 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + CH1 (Rising) + + + + + CH1 (Falling) + + + + + CH2 (Rising) + + + + + CH2 (Falling) + + + + + + + + -20.000000000000000 + + + 20.000000000000000 + + + 0.100000000000000 + + + + + + + Single Shot + + + + + + + + + + + + + + Paused + + + + + + + Paused + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + Signal Gen CH1 + + + false + + + false + + + + + + Waveform + + + + + + + + + + Frequency + + + + + + + Hz + + + 2 + + + 0.000000000000000 + + + 1000000.000000000000000 + + + 100.000000000000000 + + + 1000.000000000000000 + + + + + + + Amplitude (Peak-Peak) + + + + + + + V + + + 9.600000000000000 + + + 0.100000000000000 + + + + + + + Offset + + + + + + + V + + + 9.600000000000000 + + + 0.100000000000000 + + + + + + + + + + true + + + Signal Gen CH2 + + + false + + + false + + + + + + true + + + Waveform + + + + + + + true + + + + + + + true + + + Frequency + + + + + + + true + + + Hz + + + 2 + + + 1000000.000000000000000 + + + 100.000000000000000 + + + 1000.000000000000000 + + + + + + + true + + + Amplitude (Peak-Peak) + + + + + + + true + + + V + + + 10.000000000000000 + + + 0.100000000000000 + + + + + + + true + + + Offset + + + + + + + true + + + V + + + 10.000000000000000 + + + 0.100000000000000 + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + false + + + Multimeter++ + + + true + + + false + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + + 180 + 16777215 + + + + Mode + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + + 0 + 0 + + + + + 180 + 16777215 + + + + + V + + + + + I + + + + + R + + + + + C + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + + 180 + 16777215 + + + + Series Resistance + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + + 0 + 0 + + + + + 180 + 16777215 + + + + Ω + + + 0 + + + 1000000.000000000000000 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + 96 + + + + Max + + + + + + + + 0 + 0 + + + + + 0 + 96 + + + + QFrame::NoFrame + + + 4 + + + + + + + + 0 + 0 + + + + + 0 + 96 + + + + Min + + + + + + + + 0 + 0 + + + + + 0 + 96 + + + + QFrame::NoFrame + + + 4 + + + + + + + Qt::Vertical + + + QSizePolicy::Preferred + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + + 0 + 96 + + + + Mean + + + + + + + + 0 + 0 + + + + + 0 + 96 + + + + QFrame::NoFrame + + + 4 + + + + + + + Qt::Vertical + + + QSizePolicy::Preferred + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + + 0 + 96 + + + + RMS + + + + + + + + 0 + 0 + + + + + 0 + 96 + + + + QFrame::NoFrame + + + 4 + + + + + + + Qt::Vertical + + + QSizePolicy::Preferred + + + + 20 + 40 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 0 + 0 + + + + + 180 + 16777215 + + + + + false + + + + Paused + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + false + + + PSU + + + + + + false + + + 90 + + + 300 + + + 1 + + + Qt::Vertical + + + QSlider::TicksBelow + + + 20 + + + + + + + Lock PSU + + + true + + + + + + + + 108 + 36 + + + + + 108 + 36 + + + + true + + + 4 + + + 5.000000000000000 + + + 5 + + + + + + + + + + + + SALUTON MI ESTAS FUNCTION GENERATOR CONTROLLER + + + + + + + + 96 + 36 + + + + + 96 + 36 + + + + BUFFER IMAGE HERE + + + Qt::AlignCenter + + + + + + + + 16777215 + 48 + + + + cursorStatsLabel + + + Qt::AlignCenter + + + + + + + Jump to Bootloader + + + + + + + Debug! + + + + + + + -60 + + + 10 + + + 10 + + + -20 + + + -20 + + + true + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 10 + + + + + + + ReinitUsb() + + + + + + + + + + SALUTON MI ESTAS ISO DRIVER + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + 0 + 48 + + + + + 16777215 + 96 + + + + true + + + + + + + + 0 + 48 + + + + + 16777215 + 96 + + + + true + + + + + + + + + Digital Output + + + + + + Pin 3 + + + + + + + Pin 2 + + + + + + + Pin 1 + + + + + + + Pin 4 + + + + + digitalOutCheckbox_CH2 + digitalOutCheckbox_CH1 + digitalOutCheckbox_CH3 + digitalOutCheckbox_CH4 + + + + + + Logic Analyzer CH1 + + + true + + + false + + + + + + Serial Decoding + + + true + + + true + + + false + + + + 0 + + + 0 + + + 6 + + + 0 + + + 0 + + + + + + UART + + + + + SPI + + + + + I2C + + + + + + + + + + + + + + false + + + Logic Analyzer CH2 + + + true + + + false + + + + + + Serial Decoding + + + true + + + true + + + false + + + + 0 + + + 0 + + + 6 + + + 0 + + + 0 + + + + + + UART + + + + + SPI + + + + + I2C + + + + + + + + + + + + + + + + true + + + Paused + + + + + + + + + scopeAxes + deviceConnected + stackedWidget + + + + + 0 + 0 + 720 + 21 + + + + + Oscilloscope + + + + Gain + + + + + + + + + + + + + + CH1 Stats + + + + + + + + + CH2 Stats + + + + + + + + + Frame rate + + + + + + + + + + + Range + + + + + + + + + + + + + + + + + + + + + Multimeter + + + + Range (V) + + + + + + + + Range (I) + + + + + + + + Range (R) + + + + + + + + Range (C) + + + + + + + + + + + + + + Logic Analyzer + + + + UART 1 + + + + Baud Rate + + + + + + + + + + + + + + + + + Type Here + + + + + Parity Bit + + + + + + Data Bits + + + + + + + + + + + UART 2 + + + + Baud Rate + + + + + + + + + + + + + + + + + Data Bits + + + + + + Parity Bit + + + + + + + + + + + + + Android Special + + + + + + Connection Type + + + + + + + + + + + + + + true + + + Auto + + + + + true + + + 0.5 + + + + + true + + + 1 + + + + + true + + + 2 + + + + + true + + + 4 + + + + + true + + + 8 + + + + + true + + + 16 + + + + + true + + + 32 + + + + + true + + + 64 + + + QAction::TextHeuristicRole + + + + + Calibrate + + + + + true + + + true + + + Cursor Stats + + + + + true + + + Max + + + + + true + + + Min + + + + + true + + + Mean + + + + + true + + + RMS + + + + + true + + + Max + + + + + true + + + Min + + + + + true + + + Mean + + + + + true + + + RMS + + + + + true + + + false + + + mV + + + + + true + + + false + + + V + + + + + true + + + true + + + Auto + + + + + true + + + true + + + Auto + + + + + true + + + false + + + mA + + + + + true + + + A + + + + + true + + + 300 + + + + + true + + + 600 + + + + + true + + + 1200 + + + + + true + + + 2400 + + + + + true + + + 4800 + + + + + true + + + 9600 + + + + + true + + + 14400 + + + + + true + + + 19200 + + + + + true + + + 28800 + + + + + true + + + 38400 + + + + + true + + + 57600 (Glitchy) + + + + + true + + + 115200 (Glitchy) + + + + + true + + + 8 + + + + + true + + + None + + + + + true + + + 300 + + + + + true + + + 600 + + + + + true + + + 1200 + + + + + true + + + 2400 + + + + + true + + + 4800 + + + + + true + + + 9600 + + + + + true + + + 14400 + + + + + true + + + 19200 + + + + + true + + + 28800 + + + + + true + + + 38400 + + + + + true + + + 57600 (Glitchy) + + + + + true + + + 115200 (Glitchy) + + + + + true + + + 8 + + + + + true + + + None + + + + + true + + + Record + + + + + true + + + Force Square Display (Not Officially Supported) + + + + + true + + + true + + + Enable Cursors on Click + + + + + true + + + true + + + 60FPS + + + + + true + + + 30FPS + + + + + true + + + 20FPS + + + + + true + + + 15FPS + + + + + true + + + 10FPS + + + + + true + + + 5FPS + + + + + true + + + true + + + Auto Lock + + + + + Snap to Cursors + + + + + Enter Manually + + + + + Take Snapshot + + + + + true + + + Old Person Mode + + + + + true + + + true + + + Auto + + + + + true + + + Ω + + + + + true + + + + + + + + true + + + true + + + Auto + + + + + true + + + nF + + + + + true + + + μF + + + + + true + + + true + + + lo-bw + + + + + true + + + single-ep-msync + + + + + true + + + single-ep-async + + + + + + + QCustomPlot + QWidget +
qcustomplot.h
+ 1 + + mouseWheel(QWheelEvent*) + mouseRelease(QMouseEvent*) + mousePress(QMouseEvent*) + mouseMove(QMouseEvent*) + +
+ + bufferControl + QLabel +
buffercontrol.h
+ + scopeOut_CH1(bool) + scopeOut_CH2(bool) + scopeUncheck(bool) + signalGenOut(bool) + busSnifferOut_CH1(bool) + busSnifferOut_CH2(bool) + busSnifferUncheck(bool) + multimeterOut(bool) + scopeDsrOut(bool) + scopeDsrUncheck(bool) + updateDig(int) + modeChange(int) + setDSR(bool) + scopeIn_CH1(bool) + scopeIn_CH2(bool) + signalGenIn(bool) + busSnifferIn_CH1(bool) + busSnifferIn_CH2(bool) + multimeterIn(bool) + scopeDsrIn(bool) + digIn_CH1(bool) + digIn_CH2(bool) + digIn_CH3(bool) + digIn_CH4(bool) + +
+ + espoSlider + QSlider +
esposlider.h
+ + lcdOut(QString) + voltageChanged(double) + selfMoved(int) + +
+ + espoSpinBox + QDoubleSpinBox +
espospinbox.h
+ + maximumChanged(double) + setMax(double) + setMin(double) + changeStepping(double) + +
+ + espoComboBox + QComboBox +
espocombobox.h
+
+ + functionGenControl + QLabel +
functiongencontrol.h
+ + functionGenToUpdate(int,functionGenControl*) + setMaxFreq_CH1(double) + setMinFreq_CH1(double) + setMaxFreq_CH2(double) + setMinFreq_CH2(double) + waveformName_CH1(QString) + waveformName_CH2(QString) + freqUpdate_CH1(double) + amplitudeUpdate_CH1(double) + offsetUpdate_CH1(double) + freqUpdate_CH2(double) + amplitudeUpdate_CH2(double) + offsetUpdate_CH2(double) + +
+ + isoDriver + QLabel +
isodriver.h
+ + setGain(double) + disableWindow(bool) + setCursorStatsVisible(bool) + sendCursorStatsText(QString) + singleShotTriggered(bool) + multimeterMax(double) + multimeterMin(double) + multimeterMean(double) + sendMultimeterLabel1(QString) + sendMultimeterLabel2(QString) + sendMultimeterLabel3(QString) + changeTimeAxis(bool) + sendTriggerValue(double) + sendVmax_CH1(double) + sendVmin_CH1(double) + sendVmean_CH1(double) + sendVmax_CH2(double) + sendVmin_CH2(double) + sendVmean_CH2(double) + multimeterREnabled(int) + multimeterRMS(double) + sendMultimeterLabel4(QString) + setWindow(int) + setVoltageRange(QWheelEvent*) + pauseEnable_CH1(bool) + pauseEnable_CH2(bool) + startTimer() + clearBuffers(bool,bool,bool) + setVisible_CH2(bool) + gainBuffers(double) + setAutoGain(bool) + graphMousePress(QMouseEvent*) + graphMouseRelease(QMouseEvent*) + cursorEnableHori(bool) + cursorEnableVert(bool) + graphMouseMove(QMouseEvent*) + setTriggerEnabled(bool) + setTriggerLevel(double) + setSingleShotEnabled(bool) + setTriggerMode(int) + setAC_CH1(bool) + setAC_CH2(bool) + setMultimeterType(int) + setSeriesResistance(double) + enableMM() + setSerialDecodeEnabled_CH1(bool) + setSerialDecodeEnabled_CH2(bool) + setXYmode(bool) + triggerGroupStateChange(bool) + pauseEnable_multimeter(bool) + timerTick() + rSourceChanged(int) + +
+ + noCloseMenu + QMenu +
noclosemenu.h
+
+ + cursorEnabler + QLabel +
cursorenabler.h
+ + tickHori(bool) + tickVert(bool) + passOnSignal(QMouseEvent*) + clickDetected(QMouseEvent*) + setTurnedOn(bool) + +
+ + deviceConnectedDisplay + QLabel +
deviceconnecteddisplay.h
+ + connectedStatusChanged(bool) + +
+ + timedTickBox + QCheckBox +
timedtickbox.h
+ + resetTimer() + +
+ + swipeyStack + QStackedWidget +
swipeystack.h
+ 1 +
+
+ + + + scopeGroup_CH1 + toggled(bool) + bufferDisplay + scopeIn_CH1(bool) + + + 843 + 116 + + + 1065 + 756 + + + + + scopeGroup_CH2 + toggled(bool) + bufferDisplay + scopeIn_CH2(bool) + + + 983 + 106 + + + 1065 + 756 + + + + + signalGenGroup_CH2 + toggled(bool) + bufferDisplay + signalGenIn(bool) + + + 984 + 723 + + + 1065 + 756 + + + + + bufferDisplay + busSnifferOut_CH2(bool) + busSnifferGroup_CH2 + setEnabled(bool) + + + 1065 + 756 + + + 1124 + 577 + + + + + bufferDisplay + signalGenOut(bool) + signalGenGroup_CH2 + setEnabled(bool) + + + 1065 + 756 + + + 984 + 723 + + + + + bufferDisplay + scopeOut_CH1(bool) + scopeGroup_CH1 + setEnabled(bool) + + + 1065 + 756 + + + 818 + 207 + + + + + bufferDisplay + scopeOut_CH2(bool) + scopeGroup_CH2 + setEnabled(bool) + + + 1065 + 756 + + + 958 + 197 + + + + + bufferDisplay + busSnifferUncheck(bool) + busSnifferGroup_CH2 + setChecked(bool) + + + 1065 + 756 + + + 1124 + 577 + + + + + bufferDisplay + scopeUncheck(bool) + scopeGroup_CH2 + setChecked(bool) + + + 1065 + 756 + + + 958 + 197 + + + + + doubleSampleLabel + toggled(bool) + bufferDisplay + scopeDsrIn(bool) + + + 808 + 160 + + + 1065 + 756 + + + + + bufferDisplay + scopeDsrUncheck(bool) + doubleSampleLabel + setChecked(bool) + + + 1065 + 756 + + + 808 + 160 + + + + + bufferDisplay + scopeDsrOut(bool) + doubleSampleLabel + setEnabled(bool) + + + 1065 + 756 + + + 808 + 160 + + + + + psuSlider + valueChanged(int) + psuSlider + selfMoved(int) + + + 1027 + 322 + + + 1027 + 322 + + + + + psuSlider + lcdOut(QString) + psuDisplay + display(QString) + + + 1027 + 322 + + + 1086 + 368 + + + + + amplitudeValue_CH1 + valueChanged(double) + dcOffsetValue_CH1 + maximumChanged(double) + + + 806 + 668 + + + 806 + 713 + + + + + amplitudeValue_CH2 + valueChanged(double) + dcOffsetValue_CH2 + maximumChanged(double) + + + 949 + 668 + + + 949 + 713 + + + + + dcOffsetValue_CH1 + valueChanged(double) + amplitudeValue_CH1 + maximumChanged(double) + + + 806 + 713 + + + 806 + 668 + + + + + dcOffsetValue_CH2 + valueChanged(double) + amplitudeValue_CH2 + maximumChanged(double) + + + 949 + 713 + + + 949 + 668 + + + + + waveformSelect_CH1 + currentTextChanged(QString) + controller_fg + waveformName_CH1(QString) + + + 806 + 578 + + + 960 + 509 + + + + + waveformSelect_CH2 + currentTextChanged(QString) + controller_fg + waveformName_CH2(QString) + + + 949 + 578 + + + 960 + 509 + + + + + amplitudeValue_CH1 + valueChanged(double) + controller_fg + amplitudeUpdate_CH1(double) + + + 806 + 668 + + + 960 + 509 + + + + + dcOffsetValue_CH1 + valueChanged(double) + controller_fg + offsetUpdate_CH1(double) + + + 806 + 713 + + + 960 + 509 + + + + + bufferDisplay + busSnifferOut_CH1(bool) + busSifferGroup_CH1 + setEnabled(bool) + + + 1065 + 756 + + + 1124 + 499 + + + + + bufferDisplay + busSnifferOut_CH2(bool) + busSnifferGroup_CH2 + setEnabled(bool) + + + 1065 + 756 + + + 1124 + 577 + + + + + busSifferGroup_CH1 + toggled(bool) + bufferDisplay + busSnifferIn_CH1(bool) + + + 1124 + 499 + + + 1065 + 756 + + + + + busSnifferGroup_CH2 + toggled(bool) + bufferDisplay + busSnifferIn_CH2(bool) + + + 1124 + 577 + + + 1065 + 756 + + + + + digitalOutCheckbox_CH1 + toggled(bool) + bufferDisplay + digIn_CH1(bool) + + + 1044 + 623 + + + 1065 + 756 + + + + + digitalOutCheckbox_CH2 + toggled(bool) + bufferDisplay + digIn_CH2(bool) + + + 1114 + 623 + + + 1065 + 756 + + + + + digitalOutCheckbox_CH3 + toggled(bool) + bufferDisplay + digIn_CH3(bool) + + + 1044 + 646 + + + 1065 + 756 + + + + + digitalOutCheckbox_CH4 + toggled(bool) + bufferDisplay + digIn_CH4(bool) + + + 1114 + 646 + + + 1065 + 756 + + + + + amplitudeValue_CH2 + valueChanged(double) + controller_fg + amplitudeUpdate_CH2(double) + + + 949 + 668 + + + 960 + 509 + + + + + dcOffsetValue_CH2 + valueChanged(double) + controller_fg + offsetUpdate_CH2(double) + + + 949 + 713 + + + 960 + 509 + + + + + timeBaseSlider + valueChanged(int) + controller_iso + setWindow(int) + + + 424 + 647 + + + 960 + 757 + + + + + scopeAxes + mouseWheel(QWheelEvent*) + controller_iso + setVoltageRange(QWheelEvent*) + + + 482 + 567 + + + 960 + 757 + + + + + pausedLabeL_CH1 + toggled(bool) + controller_iso + pauseEnable_CH1(bool) + + + 833 + 91 + + + 960 + 757 + + + + + pausedLabel_CH2 + toggled(bool) + controller_iso + pauseEnable_CH2(bool) + + + 973 + 91 + + + 960 + 757 + + + + + pausedLabeL_CH1 + toggled(bool) + pausedLabel_CH2 + setChecked(bool) + + + 833 + 91 + + + 973 + 91 + + + + + pausedLabel_CH2 + toggled(bool) + pausedLabeL_CH1 + setChecked(bool) + + + 973 + 91 + + + 833 + 91 + + + + + controller_iso + disableWindow(bool) + MainWindow + setEnabled(bool) + + + 960 + 757 + + + 1023 + 226 + + + + + scopeAxes + mouseRelease(QMouseEvent*) + controller_iso + graphMouseRelease(QMouseEvent*) + + + 354 + 510 + + + 960 + 757 + + + + + cursorHoriCheck + toggled(bool) + controller_iso + cursorEnableHori(bool) + + + 808 + 253 + + + 960 + 757 + + + + + cursorVertCheck + toggled(bool) + controller_iso + cursorEnableVert(bool) + + + 808 + 276 + + + 960 + 757 + + + + + scopeAxes + mouseMove(QMouseEvent*) + controller_iso + graphMouseMove(QMouseEvent*) + + + 441 + 474 + + + 960 + 757 + + + + + controller_iso + setCursorStatsVisible(bool) + cursorStatsLabel + setVisible(bool) + + + 960 + 757 + + + 960 + 332 + + + + + lockPsuCheckBox + toggled(bool) + psuSlider + setDisabled(bool) + + + 1115 + 345 + + + 1027 + 322 + + + + + triggerGroup + toggled(bool) + controller_iso + setTriggerEnabled(bool) + + + 983 + 305 + + + 960 + 757 + + + + + triggerLevelValue + valueChanged(double) + controller_iso + setTriggerLevel(double) + + + 948 + 272 + + + 960 + 757 + + + + + controller_iso + singleShotTriggered(bool) + pausedLabeL_CH1 + setChecked(bool) + + + 960 + 757 + + + 833 + 91 + + + + + singleShotCheckBox + toggled(bool) + controller_iso + setSingleShotEnabled(bool) + + + 948 + 295 + + + 960 + 757 + + + + + triggerChannelSelect + currentIndexChanged(int) + controller_iso + setTriggerMode(int) + + + 948 + 246 + + + 960 + 757 + + + + + acCoupledLabel_CH1 + toggled(bool) + controller_iso + setAC_CH1(bool) + + + 808 + 114 + + + 960 + 757 + + + + + acCoupledLabel_CH2 + toggled(bool) + controller_iso + setAC_CH2(bool) + + + 948 + 114 + + + 960 + 757 + + + + + multimeterGroup + toggled(bool) + bufferDisplay + multimeterIn(bool) + + + 960 + 484 + + + 1065 + 756 + + + + + bufferDisplay + multimeterOut(bool) + multimeterGroup + setEnabled(bool) + + + 1065 + 756 + + + 960 + 484 + + + + + multimeterModeSelect + currentIndexChanged(int) + controller_iso + setMultimeterType(int) + + + 816 + 400 + + + 960 + 757 + + + + + controller_iso + multimeterMax(double) + multimeterMaxDisplay + display(double) + + + 960 + 757 + + + 949 + 386 + + + + + controller_iso + multimeterMin(double) + multimeterMinDisplay + display(double) + + + 960 + 757 + + + 949 + 410 + + + + + controller_iso + multimeterMean(double) + multimeterMeanDisplay + display(double) + + + 960 + 757 + + + 949 + 434 + + + + + multimeterResistanceSelect + valueChanged(double) + controller_iso + setSeriesResistance(double) + + + 816 + 445 + + + 960 + 757 + + + + + controller_iso + sendMultimeterLabel1(QString) + multimeterMaxLabel + setText(QString) + + + 960 + 757 + + + 871 + 384 + + + + + controller_iso + sendMultimeterLabel2(QString) + multimeterMinLabel + setText(QString) + + + 960 + 757 + + + 867 + 408 + + + + + controller_iso + sendMultimeterLabel3(QString) + multimeterMeanLabel + setText(QString) + + + 960 + 757 + + + 852 + 432 + + + + + serialDecodingCheck_CH1 + toggled(bool) + controller_iso + setSerialDecodeEnabled_CH1(bool) + + + 1114 + 489 + + + 960 + 757 + + + + + serialDecodingCheck_CH2 + toggled(bool) + controller_iso + setSerialDecodeEnabled_CH2(bool) + + + 1114 + 567 + + + 960 + 757 + + + + + controller_iso + changeTimeAxis(bool) + MainWindow + timeBaseNeedsChanging(bool) + + + 960 + 757 + + + 800 + 696 + + + + + xyDisplayLabel + toggled(bool) + controller_iso + setXYmode(bool) + + + 863 + 149 + + + 960 + 757 + + + + + busSnifferGroup_CH2 + toggled(bool) + signalGenGroup_CH2 + setDisabled(bool) + + + 1124 + 577 + + + 959 + 723 + + + + + scopeAxes + mousePress(QMouseEvent*) + makeCursorsNicer + clickDetected(QMouseEvent*) + + + 590 + 401 + + + 808 + 295 + + + + + makeCursorsNicer + tickHori(bool) + cursorHoriCheck + setChecked(bool) + + + 808 + 295 + + + 808 + 253 + + + + + makeCursorsNicer + tickVert(bool) + cursorVertCheck + setChecked(bool) + + + 808 + 295 + + + 808 + 276 + + + + + makeCursorsNicer + passOnSignal(QMouseEvent*) + controller_iso + graphMousePress(QMouseEvent*) + + + 808 + 295 + + + 960 + 757 + + + + + controller_iso + sendTriggerValue(double) + triggerLevelValue + setValue(double) + + + 960 + 757 + + + 948 + 272 + + + + + triggerGroup + toggled(bool) + controller_iso + triggerGroupStateChange(bool) + + + 905 + 230 + + + 960 + 757 + + + + + controller_iso + disableWindow(bool) + deviceConnected + connectedStatusChanged(bool) + + + 960 + 757 + + + 828 + 35 + + + + + multimeterPauseCheckBox + toggled(bool) + controller_iso + pauseEnable_multimeter(bool) + + + 816 + 474 + + + 960 + 757 + + + + + controller_iso + sendVmax_CH1(double) + voltageInfoMaxDisplay_CH1 + display(double) + + + 960 + 757 + + + 790 + 175 + + + + + controller_iso + sendVmin_CH1(double) + voltageInfoMinDisplay_CH1 + display(double) + + + 960 + 757 + + + 800 + 193 + + + + + controller_iso + sendVmean_CH1(double) + voltageInfoMeanDisplay_CH1 + display(double) + + + 960 + 757 + + + 807 + 206 + + + + + controller_iso + sendVmax_CH2(double) + voltageInfoMaxDisplay_CH2 + display(double) + + + 960 + 757 + + + 929 + 172 + + + + + controller_iso + sendVmin_CH2(double) + voltageInfoMinDisplay_CH2 + display(double) + + + 960 + 757 + + + 943 + 184 + + + + + controller_iso + sendVmean_CH2(double) + voltageInfoMeanDisplay_CH2 + display(double) + + + 960 + 757 + + + 940 + 196 + + + + + lockPsuCheckBox + toggled(bool) + lockPsuCheckBox + resetTimer(bool) + + + 1115 + 345 + + + 1115 + 345 + + + + + lockPsuCheckBox + toggled(bool) + lockPsuCheckBox + resetTimer() + + + 1115 + 345 + + + 1115 + 345 + + + + + psuSlider + sliderMoved(int) + lockPsuCheckBox + resetTimer() + + + 1027 + 167 + + + 1115 + 345 + + + + + pause_LA + toggled(bool) + pausedLabeL_CH1 + setChecked(bool) + + + 1114 + 444 + + + 722 + 87 + + + + + pausedLabeL_CH1 + toggled(bool) + pause_LA + setChecked(bool) + + + 762 + 80 + + + 1114 + 444 + + + + + controller_fg + setMaxFreq_CH2(double) + frequencyValue_CH2 + setMax(double) + + + 960 + 509 + + + 949 + 623 + + + + + controller_fg + setMinFreq_CH2(double) + frequencyValue_CH2 + setMin(double) + + + 960 + 509 + + + 949 + 623 + + + + + frequencyValue_CH2 + valueChanged(double) + controller_fg + freqUpdate_CH2(double) + + + 949 + 623 + + + 960 + 509 + + + + + frequencyValue_CH1 + valueChanged(double) + controller_fg + freqUpdate_CH1(double) + + + 806 + 623 + + + 960 + 509 + + + + + controller_fg + setMaxFreq_CH1(double) + frequencyValue_CH1 + setMax(double) + + + 960 + 509 + + + 806 + 623 + + + + + controller_fg + setMinFreq_CH1(double) + frequencyValue_CH1 + setMin(double) + + + 960 + 509 + + + 806 + 623 + + + + + frequencyValue_CH1 + valueChanged(double) + frequencyValue_CH1 + changeStepping(double) + + + 740 + 611 + + + 831 + 623 + + + + + frequencyValue_CH2 + valueChanged(double) + frequencyValue_CH2 + changeStepping(double) + + + 881 + 608 + + + 904 + 613 + + + + + debugButton2 + clicked() + MainWindow + reinitUsb() + + + 1038 + 700 + + + 682 + 738 + + + + + + timeBaseNeedsChanging(bool) + reinitUsb() + +
diff --git a/Desktop_Interface/ui_files_mobile/mainwindow.ui.REMOVED.git-id b/Desktop_Interface/ui_files_mobile/mainwindow.ui.REMOVED.git-id deleted file mode 100644 index 4ac1314a..00000000 --- a/Desktop_Interface/ui_files_mobile/mainwindow.ui.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ded44ca64a235531b5e1e73406a78aa5892d00a8 \ No newline at end of file diff --git a/Desktop_Interface/ui_files_mobile/scoperangeenterdialog.ui b/Desktop_Interface/ui_files_mobile/scoperangeenterdialog.ui new file mode 100644 index 00000000..c04a52ee --- /dev/null +++ b/Desktop_Interface/ui_files_mobile/scoperangeenterdialog.ui @@ -0,0 +1,222 @@ + + + scopeRangeEnterDialog + + + + 0 + 0 + 187 + 147 + + + + Enter Scope Range + + + + + + + + + + 20.000000000000000 + + + 20.000000000000000 + + + + + + + Vmax + + + + + + + -20.000000000000000 + + + -20.000000000000000 + + + + + + + Vmin + + + + + + + 6 + + + 0.000001000000000 + + + 10.000000000000000 + + + + + + + Time Window + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + + + voltageSpinBox + QDoubleSpinBox +
voltagespinbox.h
+ + setMin(double) + setMax(double) + +
+
+ + + + buttonBox + accepted() + scopeRangeEnterDialog + accept() + + + 176 + 136 + + + 157 + 274 + + + + + buttonBox + rejected() + scopeRangeEnterDialog + reject() + + + 176 + 136 + + + 286 + 274 + + + + + vMaxBox + valueChanged(double) + scopeRangeEnterDialog + toUpdateYTop(double) + + + 63 + 30 + + + 56 + 21 + + + + + vMinBox + valueChanged(double) + scopeRangeEnterDialog + toUpdateYBot(double) + + + 67 + 56 + + + 254 + 90 + + + + + vMaxBox + valueChanged(double) + vMinBox + setMax(double) + + + 63 + 30 + + + 67 + 56 + + + + + vMinBox + valueChanged(double) + vMaxBox + setMin(double) + + + 67 + 56 + + + 63 + 30 + + + + + timeWindowBox + valueChanged(double) + scopeRangeEnterDialog + toUpdateWindow(double) + + + 37 + 74 + + + 15 + 99 + + + + + + toUpdateYTop(double) + toUpdateYBot(double) + toUpdateWindow(double) + +
diff --git a/Desktop_Interface/ui_files_mobile/scoperangeenterdialog.ui.REMOVED.git-id b/Desktop_Interface/ui_files_mobile/scoperangeenterdialog.ui.REMOVED.git-id deleted file mode 100644 index 7d8795f9..00000000 --- a/Desktop_Interface/ui_files_mobile/scoperangeenterdialog.ui.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c04a52eeb6524c09241b8f645860c5e93adc536c \ No newline at end of file diff --git a/Desktop_Interface/uic_wrapper.sh.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/uic_wrapper.sh.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 1a36e656..00000000 --- a/Desktop_Interface/uic_wrapper.sh.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c876058a80f1a6d60dce62bfb00b10d0d1e5b22d \ No newline at end of file diff --git a/Desktop_Interface/unified_debug_structure.h b/Desktop_Interface/unified_debug_structure.h new file mode 100644 index 00000000..a773a824 --- /dev/null +++ b/Desktop_Interface/unified_debug_structure.h @@ -0,0 +1,38 @@ +/* + * unified_debug_structure.h + * + * Created: 1/02/2017 9:38:31 AM + * Author: Esposch + */ + + +#ifndef UNIFIED_DEBUG_STRUCTURE_H_ +#define UNIFIED_DEBUG_STRUCTURE_H_ + +#include + +//EVERYTHING MUST BE SENT ONE BYTE AT A TIME, HIGH AND LOW BYTES SEPARATE, IN ORDER TO AVOID ISSUES WITH ENDIANNESS. +typedef struct uds{ + volatile char header[9]; + volatile uint8_t trfcntL0; + volatile uint8_t trfcntH0; + volatile uint8_t trfcntL1; + volatile uint8_t trfcntH1; + volatile uint8_t medianTrfcntL; + volatile uint8_t medianTrfcntH; + volatile uint8_t calValNeg; + volatile uint8_t calValPos; + volatile uint8_t CALA; + volatile uint8_t CALB; + volatile uint8_t outOfRangeL; + volatile uint8_t outOfRangeH; + volatile uint8_t counterL; + volatile uint8_t counterH; + volatile uint8_t dma_ch0_cntL; + volatile uint8_t dma_ch0_cntH; + volatile uint8_t dma_ch1_cntL; + volatile uint8_t dma_ch1_cntH; + +} unified_debug; + +#endif /* UNIFIED_DEBUG_STRUCTURE_H_ */ diff --git a/Desktop_Interface/unified_debug_structure.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/unified_debug_structure.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 7fad9689..00000000 --- a/Desktop_Interface/unified_debug_structure.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0062a6774bc459095a1f10b9bbcd763c8a92debb \ No newline at end of file diff --git a/Desktop_Interface/unixusbdriver.cpp b/Desktop_Interface/unixusbdriver.cpp new file mode 100644 index 00000000..f9b72afe --- /dev/null +++ b/Desktop_Interface/unixusbdriver.cpp @@ -0,0 +1,375 @@ +#include "unixusbdriver.h" +#include "platformspecific.h" + +unixUsbDriver::unixUsbDriver(QWidget *parent) : genericUsbDriver(parent) +{ + qDebug() << "unixUsbDriver created!"; + tv.tv_sec = 0; + tv.tv_usec = 100000; + for (unsigned char k=0; kterminate(); + delete(isoHandler); + delete(workerThread); + qDebug() << "THREAD Gone!"; + + for (int i=0; ictx = ctx; + isoHandler->moveToThread(workerThread); + connect(workerThread, SIGNAL(started()), isoHandler, SLOT(handle())); + + workerThread->start(); + + qDebug() << "MAIN THREAD ID" << QThread::currentThreadId(); + //QThread::sleep(1); + qDebug() << "Iso Stack initialised!"; + return 1; +} + +void unixUsbDriver::isoTimerTick(void){ + timerCount++; + + char subString[3] = "th"; + if(timerCount%10 == 1) strcpy(subString, "st"); + if(timerCount%10 == 2) strcpy(subString, "nd"); + if(timerCount%10 == 3) strcpy(subString, "rd"); + if((timerCount<20) && (timerCount > 10)) strcpy(subString, "th"); + + //qDebug("\n\nThis is the %d%s Tick!", timerCount, subString); + + int n, error, earliest = MAX_OVERLAP; + qint64 minFrame = 9223372036854775807; //max value for 64 bit signed + + unsigned int i, packetLength = 0; + unsigned char* packetPointer; + + tcBlockMutex.lock(); + for (n=0; nnum_iso_packets;i++){ + for(unsigned char k=0; kiso_packet_desc[i].actual_length); + } + packetLength += ISO_PACKET_SIZE; + } + + packetLength = 0; //I don't really know why I use the same variable twice but hey + //Read out from mid-buffer to out-buffer + unsigned char *srcPtr; + qint64 current_offset; + for(i=0;inum_iso_packets;i++){ + for(unsigned char k=0; k= 0){ + srcPtr = &midBuffer_current[k][ISO_PACKET_SIZE * current_offset]; + }else{ + srcPtr = &midBuffer_prev[k][ISO_PACKET_SIZE * (ISO_PACKETS_PER_CTX + current_offset)]; + } + memcpy(&(outBuffers[currentWriteBuffer][packetLength]), srcPtr, ISO_PACKET_SIZE); + packetLength += ISO_PACKET_SIZE; + } + } + + //qDebug() << "Data copy complete!"; + + //Control data for isoDriver + bufferLengths[currentWriteBuffer] = packetLength; + currentWriteBuffer = !currentWriteBuffer; + + //Setup next transfer + for(unsigned char k=0; kstopTime = true; +} + +int unixUsbDriver::flashFirmware(void){ +#ifndef PLATFORM_ANDROID + char fname[128]; + qDebug() << "\n\n\n\n\n\n\n\nFIRMWARE MISMATCH!!!! FLASHING....\n\n\n\n\n\n\n"; + sprintf(fname, "/firmware/labrafirm_%04x_%02x.hex", EXPECTED_FIRMWARE_VERSION, DEFINED_EXPECTED_VARIANT); + qDebug() << "FLASHING " << fname; + + bootloaderJump(); + qDebug() << "BA94 closed"; + + QThread::msleep(2000); + + QString dirString = QCoreApplication::applicationDirPath(); + dirString.append(fname); + QByteArray array = dirString.toLocal8Bit(); + char* buffer = array.data(); + //qDebug() << buffer; + + + //Set up interface to dfuprog + int exit_code = 1; + char command1[256]; + sprintf(command1, "dfu-programmer atxmega32a4u erase --force"); + char command2[256]; + sprintf(command2, "dfu-programmer atxmega32a4u flash %s", buffer); + char command3[256]; + sprintf(command3, "dfu-programmer atxmega32a4u launch"); + char command4[256]; + sprintf(command4, "dfu-programmer atxmega32a4u launch"); + + //Run stage 1 + while(exit_code){ + QThread::msleep(250); + exit_code = dfuprog_virtual_cmd(command1); + } + + //Run stage 2 + exit_code = dfuprog_virtual_cmd(command2); + if(exit_code){ + return exit_code+200; + } + + //Run stage 3 + exit_code = dfuprog_virtual_cmd(command3); + if(exit_code){ + return exit_code+300; + } + + QThread::msleep(2000); + + //Run stage 4 - double launch to clear the eeprom flag from bootloaderJump. + exit_code = 1; + while(exit_code){ + QThread::msleep(250); + exit_code = dfuprog_virtual_cmd(command4); + } + + libusb_release_interface(handle, 0); + qDebug() << "Interface released"; + libusb_close(handle); + qDebug() << "Device Closed"; + libusb_exit(ctx); + qDebug() << "Libusb exited"; + connected = false; + handle = NULL; + ctx = NULL; + + return 0; +#endif +} diff --git a/Desktop_Interface/unixusbdriver.cpp.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/unixusbdriver.cpp.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index a6a7127d..00000000 --- a/Desktop_Interface/unixusbdriver.cpp.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a46ce28f7d4585ad2e37254c977f8d7ff07717ca \ No newline at end of file diff --git a/Desktop_Interface/unixusbdriver.h b/Desktop_Interface/unixusbdriver.h new file mode 100644 index 00000000..2b70baa0 --- /dev/null +++ b/Desktop_Interface/unixusbdriver.h @@ -0,0 +1,116 @@ +#ifndef unixUsbDriver_H +#define unixUsbDriver_H + +#include +#include +#include +#include + +#include "genericusbdriver.h" +#include "libusb.h" +extern "C" +{ + #include "libdfuprog.h" +} + +#define MAX_ALLOWABLE_CUMULATIVE_FRAME_ERROR 50 + +//tcBlock is fed to the callback in the libusb user data section. +typedef struct tcBlock{ + int number; + bool completed; + qint64 timeReceived; +} tcBlock; + +//Oddly, libusb requires you to make a blocking libusb_handle_events() call in order to execute the callbacks for an asynchronous transfer. +//Since the call is blocking, this worker must exist in a separate, low priority thread! +class worker : public QObject +{ + Q_OBJECT + +public: + worker(){}; + ~worker(){}; + libusb_context *ctx; + bool stopTime = false; + unsigned char cleanupRemaining = 2; +public slots: + void handle(){ + qDebug() << "SUB THREAD ID" << QThread::currentThreadId(); + while(1){ + //qDebug() << cleanupRemaining; + if(libusb_event_handling_ok(ctx)){ + libusb_handle_events_timeout(ctx, &tv); + //qDebug() << "HANDLED"; + } + if(stopTime){ + if(cleanupRemaining){ + cleanupRemaining--; + }else while(1){ + QThread::msleep(100); + //qDebug() << "Cleanup complete"; //THIS THREAD STILL EXISTS + } + } + } + } +}; + +//This is the actual unixUsbDriver +//It handles the Mac/Linux specific parts of USB communication, through libusb. +//See genericUsbDriver for the non-platform-specific parts. +class unixUsbDriver : public genericUsbDriver +{ + Q_OBJECT +public: + explicit unixUsbDriver(QWidget *parent = 0); + ~unixUsbDriver(); + void usbSendControl(uint8_t RequestType, uint8_t Request, uint16_t Value, uint16_t Index, uint16_t Length, unsigned char *LDATA); + char *isoRead(unsigned int *newLength); +protected: + //USB Vars + libusb_context *ctx = NULL; + libusb_device_handle *handle = NULL; + //USBIso Vars + unsigned char *midBuffer_current[NUM_ISO_ENDPOINTS]; + unsigned char *midBuffer_prev[NUM_ISO_ENDPOINTS]; + qint64 midBufferOffsets[NUM_ISO_ENDPOINTS]; + libusb_transfer *isoCtx[NUM_ISO_ENDPOINTS][NUM_FUTURE_CTX]; + tcBlock transferCompleted[NUM_ISO_ENDPOINTS][NUM_FUTURE_CTX]; + unsigned char dataBuffer[NUM_ISO_ENDPOINTS][NUM_FUTURE_CTX][ISO_PACKET_SIZE*ISO_PACKETS_PER_CTX]; + worker *isoHandler; + QThread *workerThread; + int cumulativeFramePhaseErrors = 0; + //Generic Functions + virtual unsigned char usbInit(unsigned long VIDin, unsigned long PIDin); + unsigned char usbIsoInit(void); + virtual int flashFirmware(void); + bool allEndpointsComplete(int n); + bool shutdownMode = false; + int numCancelled = 0; +signals: +public slots: + void isoTimerTick(void); + void recoveryTick(void); + void shutdownProcedure(void); + void backupCleanup(void); +}; + +//Callback on iso transfer complete. +static void LIBUSB_CALL isoCallback(struct libusb_transfer * transfer){ + tcBlockMutex.lock(); + //int number = ((tcBlock *)transfer->user_data)->number; + //bool completed = ((tcBlock *)transfer->user_data)->completed; + + //qDebug() << "CALLBACK" << number; + //qDebug() << completed; + + if(transfer->status!=LIBUSB_TRANSFER_CANCELLED){ + ((tcBlock *)transfer->user_data)->completed = true; + ((tcBlock *)transfer->user_data)->timeReceived = QDateTime::currentMSecsSinceEpoch(); + } + //qDebug() << ((tcBlock *)transfer->user_data)->timeReceived; + tcBlockMutex.unlock(); + return; +} + +#endif // unixUsbDriver_H diff --git a/Desktop_Interface/unixusbdriver.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/unixusbdriver.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 358ed5a9..00000000 --- a/Desktop_Interface/unixusbdriver.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c765d99764890c6342fcd09273e6f8d3198e8dfd \ No newline at end of file diff --git a/Desktop_Interface/unixusbdriver.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/unixusbdriver.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 85688cca..00000000 --- a/Desktop_Interface/unixusbdriver.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -61715bbc7731eb3a453b226ce71522a682c62368 \ No newline at end of file diff --git a/Desktop_Interface/unixusbdriver.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/unixusbdriver.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 49cbfb22..00000000 --- a/Desktop_Interface/unixusbdriver.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -74bdce34c73c85ecacf47fb71a9f5e447548b6b9 \ No newline at end of file diff --git a/Desktop_Interface/usbdriver.h b/Desktop_Interface/usbdriver.h new file mode 100644 index 00000000..b1c250ac --- /dev/null +++ b/Desktop_Interface/usbdriver.h @@ -0,0 +1,18 @@ +#ifndef USBDRIVER_H +#define USBDRIVER_H + +#include +#include + +class usbDriver : public QLabel +{ + Q_OBJECT +public: + explicit usbDriver(QLabel *parent = 0); + +signals: + +public slots: +}; + +#endif // USBDRIVER_H diff --git a/Desktop_Interface/usbdriver.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/usbdriver.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 9d25aacb..00000000 --- a/Desktop_Interface/usbdriver.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -932979f722aedcd05849472fa10fbfe29cec2bb7 \ No newline at end of file diff --git a/Desktop_Interface/voltagespinbox.o.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/voltagespinbox.o.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 9de6b803..00000000 --- a/Desktop_Interface/voltagespinbox.o.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7f25c9b3a2cb2ea41178e3c3a0e07f02a7e34e49 \ No newline at end of file diff --git a/Desktop_Interface/voltagespinbox.obj.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/voltagespinbox.obj.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 145f9d17..00000000 --- a/Desktop_Interface/voltagespinbox.obj.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a7365fb1bd637f7a39ab83567330981749b9cd55 \ No newline at end of file diff --git a/Desktop_Interface/waveforms/DC.tlw.REMOVED.git-id b/Desktop_Interface/waveforms/DC.tlw.REMOVED.git-id deleted file mode 100644 index 4db09170..00000000 --- a/Desktop_Interface/waveforms/DC.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ffa750a416f427836537ed2ea8f7cc844d0b2835 \ No newline at end of file diff --git a/Desktop_Interface/waveforms/Sawtooth.tlw.REMOVED.git-id b/Desktop_Interface/waveforms/Sawtooth.tlw.REMOVED.git-id deleted file mode 100644 index 87e86502..00000000 --- a/Desktop_Interface/waveforms/Sawtooth.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e989a81be4fb7a2d79495ce7e96db776b0366a94 \ No newline at end of file diff --git a/Desktop_Interface/waveforms/Sin.tlw.REMOVED.git-id b/Desktop_Interface/waveforms/Sin.tlw.REMOVED.git-id deleted file mode 100644 index ceeb1ad1..00000000 --- a/Desktop_Interface/waveforms/Sin.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e376c35388394ccfa4a86cb5bc6f9961e00fef20 \ No newline at end of file diff --git a/Desktop_Interface/waveforms/Square.tlw.REMOVED.git-id b/Desktop_Interface/waveforms/Square.tlw.REMOVED.git-id deleted file mode 100644 index 25d85bc6..00000000 --- a/Desktop_Interface/waveforms/Square.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7bdd30bee84b15cc3fe88dd02751316a2016060c \ No newline at end of file diff --git a/Desktop_Interface/waveforms/Triangle.tlw.REMOVED.git-id b/Desktop_Interface/waveforms/Triangle.tlw.REMOVED.git-id deleted file mode 100644 index 768d2ac7..00000000 --- a/Desktop_Interface/waveforms/Triangle.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -420ac92c2c292688434b3987874cc98a9180e336 \ No newline at end of file diff --git a/Desktop_Interface/waveforms/_list.wfl.REMOVED.git-id b/Desktop_Interface/waveforms/_list.wfl.REMOVED.git-id deleted file mode 100644 index 2b3bbd46..00000000 --- a/Desktop_Interface/waveforms/_list.wfl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d9c5ca2b7e1352538debad0a17885fc4355864fc \ No newline at end of file diff --git a/Desktop_Interface/waveforms_OLD/Sawtooth.tlw.REMOVED.git-id b/Desktop_Interface/waveforms_OLD/Sawtooth.tlw.REMOVED.git-id deleted file mode 100644 index 87e86502..00000000 --- a/Desktop_Interface/waveforms_OLD/Sawtooth.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e989a81be4fb7a2d79495ce7e96db776b0366a94 \ No newline at end of file diff --git a/Desktop_Interface/waveforms_OLD/Sin.tlw.REMOVED.git-id b/Desktop_Interface/waveforms_OLD/Sin.tlw.REMOVED.git-id deleted file mode 100644 index 03dea263..00000000 --- a/Desktop_Interface/waveforms_OLD/Sin.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a971bdad9c2461cecbb008a7ebf7dccdecfd352f \ No newline at end of file diff --git a/Desktop_Interface/waveforms_OLD/Square.tlw.REMOVED.git-id b/Desktop_Interface/waveforms_OLD/Square.tlw.REMOVED.git-id deleted file mode 100644 index 25d85bc6..00000000 --- a/Desktop_Interface/waveforms_OLD/Square.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7bdd30bee84b15cc3fe88dd02751316a2016060c \ No newline at end of file diff --git a/Desktop_Interface/waveforms_OLD/Triangle.tlw.REMOVED.git-id b/Desktop_Interface/waveforms_OLD/Triangle.tlw.REMOVED.git-id deleted file mode 100644 index 768d2ac7..00000000 --- a/Desktop_Interface/waveforms_OLD/Triangle.tlw.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -420ac92c2c292688434b3987874cc98a9180e336 \ No newline at end of file diff --git a/Desktop_Interface/waveforms_OLD/_list.wfl.REMOVED.git-id b/Desktop_Interface/waveforms_OLD/_list.wfl.REMOVED.git-id deleted file mode 100644 index 91e06b43..00000000 --- a/Desktop_Interface/waveforms_OLD/_list.wfl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -488a0133badf9d48927f82bcc9fcf039e36d2065 \ No newline at end of file diff --git a/Desktop_Interface/winusbdriver.cpp b/Desktop_Interface/winusbdriver.cpp new file mode 100644 index 00000000..52567114 --- /dev/null +++ b/Desktop_Interface/winusbdriver.cpp @@ -0,0 +1,392 @@ +#include "winusbdriver.h" +#include + +#define SLEEP_DIVIDER 16 + +winUsbDriver::winUsbDriver(QWidget *parent) : genericUsbDriver(parent) +{ +} + +winUsbDriver::~winUsbDriver(void){ + + //Like any decent destructor, this just frees resources + + qDebug() << "\n\nwinUsbDriver destructor ran!"; + for (unsigned char k=0; k 10)) strcpy(subString, "th"); + + //qDebug("\n\nThis is the %d%s Tick!", timerCount, subString); + + bool success; + DWORD errorCode = ERROR_SUCCESS; + int n, earliest = MAX_OVERLAP; + unsigned int minFrame = 4294967295; + unsigned int dataBufferOffset; + unsigned int packetLength = 0; + + //Getting earliest transfer number. + for (n=0; nStartFrame < minFrame){ + minFrame = isoCtx[0][n]->StartFrame; + earliest = n; + } + } + } + + //qDebug() << n << "is the earliest!"; + + if (earliest == MAX_OVERLAP){ + return; + } + + //Copy the tranfer data into buffer + for(int i=0;iNumberOfPackets;i++){ + for(unsigned char k=0; kIsoPackets[i].Offset; + memcpy(&(outBuffers[currentWriteBuffer][packetLength]), &dataBuffer[k][earliest][dataBufferOffset], isoCtx[k][earliest]->IsoPackets[i].Length); + packetLength += isoCtx[k][earliest]->IsoPackets[i].Length; + } + } + + //Get the data for isoRead() ready and swap buffers + bufferLengths[currentWriteBuffer] = packetLength; + currentWriteBuffer = !currentWriteBuffer; + + + //Check for incorrect setup and kill if that were the case. + UINT ep0frame = isoCtx[0][earliest]->StartFrame; + UINT epkframe = isoCtx[NUM_ISO_ENDPOINTS-1][earliest]->StartFrame; + UINT framePhaseError = epkframe - ep0frame; + if(framePhaseError){ + qDebug("Frame phase error of %d", framePhaseError); + killMe(); + } + + + UINT oldStart; + //Setup transfer for resubmission + for(unsigned char k=0; kStartFrame; + success = IsoK_ReUse(isoCtx[k][earliest]); + if(!success){ + errorCode = GetLastError(); + qDebug() << "IsoK_Init failed with error code" << errorCode; + qDebug() << "n =" << n; + return; + } + isoCtx[k][earliest]->StartFrame = 0; + + success = OvlK_ReUse(ovlkHandle[k][earliest]); + if(!success){ + errorCode = GetLastError(); + qDebug() << "OvlK_ReUse failed with error code" << errorCode; + qDebug() << "n =" << n; + return; + }*/ + //Resubmit the transfer + success = UsbK_IsoReadPipe(handle, pipeID[k], dataBuffer[k][earliest], sizeof(dataBuffer[k][earliest]), (LPOVERLAPPED) ovlkHandle[k][earliest], isoCtx[k][earliest]); + } + //qDebug() << "Resubmitted Ctx #"<< earliest; + //Signal to isoDriver that it can draw a new frame. + upTick(); + return; +} + +char *winUsbDriver::isoRead(unsigned int *newLength){ + //This will be called almost immediately after the upTick() signal is sent. Make sure bufferLengths[] abd outBuffers[] are ready! + *(newLength) = bufferLengths[!currentWriteBuffer]; + return (char*) outBuffers[(unsigned char) !currentWriteBuffer]; +} + +bool winUsbDriver::allEndpointsComplete(int n){ + //Just tells you if transfers have completed on _all_ iso endpoints for a given value of n. + for (unsigned char k=0;k +#include +#include +#include +#include "libusbk.h" + +#include "genericusbdriver.h" + +//winUsbDriver handles the Windows-specific parts of USB communication, through libusbK. +//See genericUsbDriver for the non-platform-specific parts. +class winUsbDriver : public genericUsbDriver +{ + Q_OBJECT +public: + //Generic Functions + explicit winUsbDriver(QWidget *parent = 0); + ~winUsbDriver(); + void usbSendControl(uint8_t RequestType, uint8_t Request, uint16_t Value, uint16_t Index, uint16_t Length, unsigned char *LDATA); + char *isoRead(unsigned int *newLength); +private: + //USB Vars + KUSB_HANDLE handle = NULL; + //USBIso Vars + PKISO_CONTEXT isoCtx[NUM_ISO_ENDPOINTS][NUM_FUTURE_CTX]; + KOVL_HANDLE ovlkHandle[NUM_ISO_ENDPOINTS][NUM_FUTURE_CTX]; + KOVL_POOL_HANDLE ovlPool; + unsigned char dataBuffer[NUM_ISO_ENDPOINTS][NUM_FUTURE_CTX][ISO_PACKET_SIZE*ISO_PACKETS_PER_CTX]; + //Generic Functions + unsigned char usbInit(unsigned long VIDin, unsigned long PIDin); + unsigned char usbIsoInit(void); + int flashFirmware(void); + bool allEndpointsComplete(int n); +signals: +public slots: + void isoTimerTick(void); + void recoveryTick(); + void shutdownProcedure(void); +}; + +#endif // WINUSBDRIVER_H diff --git a/Desktop_Interface/winusbdriver.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/winusbdriver.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index cf09c839..00000000 --- a/Desktop_Interface/winusbdriver.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d72519fc6dc95ed6f5b116a2a2e48680d57ff020 \ No newline at end of file diff --git a/Desktop_Interface/xmega.h b/Desktop_Interface/xmega.h new file mode 100644 index 00000000..3fe8ae51 --- /dev/null +++ b/Desktop_Interface/xmega.h @@ -0,0 +1,29 @@ +#ifndef XMEGA_H +#define XMEGA_H + +//Just a whole lot of variables related to the hardware itself. + +#define FGEN_OFFSET 5 +#define FGEN_LIMIT (double) 3.2 +#define CLOCK_FREQ 48000000 +#define DAC_SPS 1000000 +#define ADC_SPS 750000 +#define ADC_SPF (ADC_SPS/1000) + +#define vcc (double)3.3 +#define vref ((double)(vcc/2)) +#define R4 (double)75000 +#define R3 (double)1000000 +#define R2 (double)1000 +#define R1 (double)1000 + +#define INIT_DEVICE_MODE 0 + +#define PSU_STEP 5 +#define PSU_PERIOD 100 +#define PSU_ADC_TOP 128 + +#define INVERT_TRIPLE +#define INVERT_MM + +#endif // XMEGA_H diff --git a/Desktop_Interface/xmega.h.REMOVED.git-id.REMOVED.git-id b/Desktop_Interface/xmega.h.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index 6a8a5ffb..00000000 --- a/Desktop_Interface/xmega.h.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cc1779d787c1ad6ade34cc72c25f9ec72bc418c2 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/entries.REMOVED.git-id b/Old Matlab Interface/.svn/entries.REMOVED.git-id deleted file mode 100644 index fd042729..00000000 --- a/Old Matlab Interface/.svn/entries.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -48082f72f087ce7e6fa75b9c41d7387daecd447b \ No newline at end of file diff --git a/Old Matlab Interface/.svn/format.REMOVED.git-id b/Old Matlab Interface/.svn/format.REMOVED.git-id deleted file mode 100644 index fd042729..00000000 --- a/Old Matlab Interface/.svn/format.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -48082f72f087ce7e6fa75b9c41d7387daecd447b \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/00/000cd9de688114eca60ab3ed8f47af0cbec6bcbe.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/00/000cd9de688114eca60ab3ed8f47af0cbec6bcbe.svn-base.REMOVED.git-id deleted file mode 100644 index fc20db98..00000000 --- a/Old Matlab Interface/.svn/pristine/00/000cd9de688114eca60ab3ed8f47af0cbec6bcbe.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9108f9cbc8ebae2ea71c264932c4745df9135df2 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/01/018e814e444b6e657ced7f4e357f4b61e626deb6.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/01/018e814e444b6e657ced7f4e357f4b61e626deb6.svn-base.REMOVED.git-id deleted file mode 100644 index b301c879..00000000 --- a/Old Matlab Interface/.svn/pristine/01/018e814e444b6e657ced7f4e357f4b61e626deb6.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1be234aba825c981dc9f9e607e82846cd927a349 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/02/02959e28e6695fe91c27b1bdd0ca6444d7e30afa.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/02/02959e28e6695fe91c27b1bdd0ca6444d7e30afa.svn-base.REMOVED.git-id deleted file mode 100644 index 43331493..00000000 --- a/Old Matlab Interface/.svn/pristine/02/02959e28e6695fe91c27b1bdd0ca6444d7e30afa.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8b4645c79f291896498d477a57d1773507e9eecb \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/03/034b6e7436daea3b23ae2bc025a1fc7e30abbde2.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/03/034b6e7436daea3b23ae2bc025a1fc7e30abbde2.svn-base.REMOVED.git-id deleted file mode 100644 index b68b34db..00000000 --- a/Old Matlab Interface/.svn/pristine/03/034b6e7436daea3b23ae2bc025a1fc7e30abbde2.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1479c989413bdf6aabc54e3ef32f65a2a942c1fc \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/04/0450c9a25a7b428bd340570efb1a7ffc4095bb68.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/04/0450c9a25a7b428bd340570efb1a7ffc4095bb68.svn-base.REMOVED.git-id deleted file mode 100644 index 1c6213ee..00000000 --- a/Old Matlab Interface/.svn/pristine/04/0450c9a25a7b428bd340570efb1a7ffc4095bb68.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -69d31ae51d3772c668ea7bddb67c161f7211b7a7 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/04/04e63fc7fbe69172abc51b394d95cb2a5d9db039.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/04/04e63fc7fbe69172abc51b394d95cb2a5d9db039.svn-base.REMOVED.git-id deleted file mode 100644 index 456efbe9..00000000 --- a/Old Matlab Interface/.svn/pristine/04/04e63fc7fbe69172abc51b394d95cb2a5d9db039.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b5a2f51b3919bbb54461972d6e28d8bea03c90f5 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/05/05787edbc2f1e75f2606006c2c2263929603df87.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/05/05787edbc2f1e75f2606006c2c2263929603df87.svn-base.REMOVED.git-id deleted file mode 100644 index b4a174dc..00000000 --- a/Old Matlab Interface/.svn/pristine/05/05787edbc2f1e75f2606006c2c2263929603df87.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7759e7333ec615288acf5a75e0e3d74b00ed1f9e \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/06/06807992cb300543c1acac3d136e5fad0b012b98.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/06/06807992cb300543c1acac3d136e5fad0b012b98.svn-base.REMOVED.git-id deleted file mode 100644 index ef36a4a5..00000000 --- a/Old Matlab Interface/.svn/pristine/06/06807992cb300543c1acac3d136e5fad0b012b98.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8efc6b0be55c844dc36fa8d3feb252538f10f02e \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/08/08980606867d71236732281e564c26aa234d0492.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/08/08980606867d71236732281e564c26aa234d0492.svn-base.REMOVED.git-id deleted file mode 100644 index dc233b71..00000000 --- a/Old Matlab Interface/.svn/pristine/08/08980606867d71236732281e564c26aa234d0492.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2a9d895af1c59c3ab68f2f994d6ff7a48fe30bc7 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/08/08d40aedf477a62efb9c0ab6835396973e703d44.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/08/08d40aedf477a62efb9c0ab6835396973e703d44.svn-base.REMOVED.git-id deleted file mode 100644 index 71fdf9d0..00000000 --- a/Old Matlab Interface/.svn/pristine/08/08d40aedf477a62efb9c0ab6835396973e703d44.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7eeeaa55680e26d316c94f6d028ff338d2fca3c9 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/09/09558fa38390ff5b9e448f4e133ecec897d3a6ed.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/09/09558fa38390ff5b9e448f4e133ecec897d3a6ed.svn-base.REMOVED.git-id deleted file mode 100644 index bd1d1fcb..00000000 --- a/Old Matlab Interface/.svn/pristine/09/09558fa38390ff5b9e448f4e133ecec897d3a6ed.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d2faa355f43e26c192ded6e3e59c0e8c7eb96d02 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/0a/0abcb49af2b00438c78205c594f66918aaed46be.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/0a/0abcb49af2b00438c78205c594f66918aaed46be.svn-base.REMOVED.git-id deleted file mode 100644 index 3e794884..00000000 --- a/Old Matlab Interface/.svn/pristine/0a/0abcb49af2b00438c78205c594f66918aaed46be.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ddc00a05e2e65dc3560e0686d92739749a1cff34 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/0b/0bbebb77dacc40a9055f623a3fc40734d684599c.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/0b/0bbebb77dacc40a9055f623a3fc40734d684599c.svn-base.REMOVED.git-id deleted file mode 100644 index 117cb37e..00000000 --- a/Old Matlab Interface/.svn/pristine/0b/0bbebb77dacc40a9055f623a3fc40734d684599c.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c9287752b8f1b2faa95f2b0fca2a1fb9ba5548f1 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/0b/0bea3176a50a8b215a4230940af3da4df02e76e5.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/0b/0bea3176a50a8b215a4230940af3da4df02e76e5.svn-base.REMOVED.git-id deleted file mode 100644 index b44cc427..00000000 --- a/Old Matlab Interface/.svn/pristine/0b/0bea3176a50a8b215a4230940af3da4df02e76e5.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b2be80470c157c93a0accd10759cc94203eebc16 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/0c/0c9396420176d71310c25719e16eab65ad651680.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/0c/0c9396420176d71310c25719e16eab65ad651680.svn-base.REMOVED.git-id deleted file mode 100644 index 78b172e1..00000000 --- a/Old Matlab Interface/.svn/pristine/0c/0c9396420176d71310c25719e16eab65ad651680.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9dfcb4d414e37e4562db1fe9ec4f64d1ed55c1ca \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/0e/0ed0593721eb6952fb9d053197d6bf9b002875fd.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/0e/0ed0593721eb6952fb9d053197d6bf9b002875fd.svn-base.REMOVED.git-id deleted file mode 100644 index 1ca0234d..00000000 --- a/Old Matlab Interface/.svn/pristine/0e/0ed0593721eb6952fb9d053197d6bf9b002875fd.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7c5aff1aa1111193c79a257d4cc7c8bde9079f75 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/0f/0f12a5f7cb26c94273fd8b33b99a2faba6d5722d.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/0f/0f12a5f7cb26c94273fd8b33b99a2faba6d5722d.svn-base.REMOVED.git-id deleted file mode 100644 index c0e0903f..00000000 --- a/Old Matlab Interface/.svn/pristine/0f/0f12a5f7cb26c94273fd8b33b99a2faba6d5722d.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -47980eea95a0cf714d064a9acff67ff933a72f2c \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/0f/0ffe81cc039ff9bb68c4a763e940a3fd1ff33679.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/0f/0ffe81cc039ff9bb68c4a763e940a3fd1ff33679.svn-base.REMOVED.git-id deleted file mode 100644 index baae6660..00000000 --- a/Old Matlab Interface/.svn/pristine/0f/0ffe81cc039ff9bb68c4a763e940a3fd1ff33679.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -335ce7f6492f67ab88a877e15707744c0cbcb1f3 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/10/10de157f63173d022f4d6a0ed452a3c74574d9ca.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/10/10de157f63173d022f4d6a0ed452a3c74574d9ca.svn-base.REMOVED.git-id deleted file mode 100644 index 2644f33f..00000000 --- a/Old Matlab Interface/.svn/pristine/10/10de157f63173d022f4d6a0ed452a3c74574d9ca.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fd54ba80e7651ca7f3d077705c84982775bac90a \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/11/11873190b9aa35cf3c7da49845992102338d0d01.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/11/11873190b9aa35cf3c7da49845992102338d0d01.svn-base.REMOVED.git-id deleted file mode 100644 index 619d0f53..00000000 --- a/Old Matlab Interface/.svn/pristine/11/11873190b9aa35cf3c7da49845992102338d0d01.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e236095849bbbff3d13c8a544e7c2fbf11e4c6e1 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/12/12b094e22d62f48741be7b2ca0100de171ded2a6.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/12/12b094e22d62f48741be7b2ca0100de171ded2a6.svn-base.REMOVED.git-id deleted file mode 100644 index 35f60002..00000000 --- a/Old Matlab Interface/.svn/pristine/12/12b094e22d62f48741be7b2ca0100de171ded2a6.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fff68b837797c41d8f82a911a866efc8fac3b93e \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/14/1475a16f806ec250fcccd22d8e49fcf18ef6c240.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/14/1475a16f806ec250fcccd22d8e49fcf18ef6c240.svn-base.REMOVED.git-id deleted file mode 100644 index 1fa8e8a2..00000000 --- a/Old Matlab Interface/.svn/pristine/14/1475a16f806ec250fcccd22d8e49fcf18ef6c240.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2f390040f2c3f79b8dafb442c993ac36e2f6dc26 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/14/148866eba70db42d9fcbfb226f8c185367a019c7.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/14/148866eba70db42d9fcbfb226f8c185367a019c7.svn-base.REMOVED.git-id deleted file mode 100644 index badb554d..00000000 --- a/Old Matlab Interface/.svn/pristine/14/148866eba70db42d9fcbfb226f8c185367a019c7.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6ce771ae00b6f1655f1b2c8cad47ad29c926d0ef \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/15/153f1151c37be3e4bfa431d9db08559ad4629bf0.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/15/153f1151c37be3e4bfa431d9db08559ad4629bf0.svn-base.REMOVED.git-id deleted file mode 100644 index 0e49926f..00000000 --- a/Old Matlab Interface/.svn/pristine/15/153f1151c37be3e4bfa431d9db08559ad4629bf0.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0de7cfbb24d00dbb34706b3086b5f73211d645b9 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/15/1547850f20be0023538e6f0c41009aa5f53fd630.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/15/1547850f20be0023538e6f0c41009aa5f53fd630.svn-base.REMOVED.git-id deleted file mode 100644 index e83a7468..00000000 --- a/Old Matlab Interface/.svn/pristine/15/1547850f20be0023538e6f0c41009aa5f53fd630.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -53654e97afad0c4edce0bc20d1a93e8009a2c6f1 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/16/16bc34a84f9aaded710f7d05ce5c5d9eafe673d7.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/16/16bc34a84f9aaded710f7d05ce5c5d9eafe673d7.svn-base.REMOVED.git-id deleted file mode 100644 index 61a89922..00000000 --- a/Old Matlab Interface/.svn/pristine/16/16bc34a84f9aaded710f7d05ce5c5d9eafe673d7.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -906db7fc0cf3a88f14846b248acfaec44e3c0aac \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/18/1878abed33b62f38495f26e323231de6640f0b3b.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/18/1878abed33b62f38495f26e323231de6640f0b3b.svn-base.REMOVED.git-id deleted file mode 100644 index 04137c51..00000000 --- a/Old Matlab Interface/.svn/pristine/18/1878abed33b62f38495f26e323231de6640f0b3b.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -30bd56e2d159385a7bdcaae5c7a12d72056e2079 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/1b/1bc1bc5b7cd5d326b0581de8e57be48ed902a1bf.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/1b/1bc1bc5b7cd5d326b0581de8e57be48ed902a1bf.svn-base.REMOVED.git-id deleted file mode 100644 index 51be98fb..00000000 --- a/Old Matlab Interface/.svn/pristine/1b/1bc1bc5b7cd5d326b0581de8e57be48ed902a1bf.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cf20bd7936a72bd15f3e9c85c2deefab7adbae51 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/1c/1c4358dca057b00006ed90c0ffca5a5971e2adcd.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/1c/1c4358dca057b00006ed90c0ffca5a5971e2adcd.svn-base.REMOVED.git-id deleted file mode 100644 index bf826dea..00000000 --- a/Old Matlab Interface/.svn/pristine/1c/1c4358dca057b00006ed90c0ffca5a5971e2adcd.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f5b0ea0cf061c25b145fecdf0d6d728b2856525b \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/1d/1d1e0e7eb037bb37f68f7f6d3f68d1137f1fe193.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/1d/1d1e0e7eb037bb37f68f7f6d3f68d1137f1fe193.svn-base.REMOVED.git-id deleted file mode 100644 index d2ac96c2..00000000 --- a/Old Matlab Interface/.svn/pristine/1d/1d1e0e7eb037bb37f68f7f6d3f68d1137f1fe193.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7d562888e6020241f56717b426932990b316904f \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/21/210ff8921909a8810c7ea800fbf3a98550ceb291.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/21/210ff8921909a8810c7ea800fbf3a98550ceb291.svn-base.REMOVED.git-id deleted file mode 100644 index ceae8d92..00000000 --- a/Old Matlab Interface/.svn/pristine/21/210ff8921909a8810c7ea800fbf3a98550ceb291.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2ccdc10d8d7167dd18636a886b090cb96b4101ea \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/23/2336279f1af60694c0294df1651788c6e0a3f67d.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/23/2336279f1af60694c0294df1651788c6e0a3f67d.svn-base.REMOVED.git-id deleted file mode 100644 index ce6ee138..00000000 --- a/Old Matlab Interface/.svn/pristine/23/2336279f1af60694c0294df1651788c6e0a3f67d.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -163041d65fe80b7477e13116c7afd95b8d0c6c44 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/23/2378d9995f80894725f18d2c905e64aa16464d35.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/23/2378d9995f80894725f18d2c905e64aa16464d35.svn-base.REMOVED.git-id deleted file mode 100644 index 64ab9151..00000000 --- a/Old Matlab Interface/.svn/pristine/23/2378d9995f80894725f18d2c905e64aa16464d35.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -61c9d45d470fb34ee1e35d272d293d2b2d00bdd5 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/23/23880a000a15dd9a71984f677ace3f759b3d176c.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/23/23880a000a15dd9a71984f677ace3f759b3d176c.svn-base.REMOVED.git-id deleted file mode 100644 index c8e49235..00000000 --- a/Old Matlab Interface/.svn/pristine/23/23880a000a15dd9a71984f677ace3f759b3d176c.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -52da3e383aff9bc0eae181de8b717617afa605c9 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/24/24252c4f32cacda1c505e6fc27fbc7ba69f5aa71.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/24/24252c4f32cacda1c505e6fc27fbc7ba69f5aa71.svn-base.REMOVED.git-id deleted file mode 100644 index 38a24d29..00000000 --- a/Old Matlab Interface/.svn/pristine/24/24252c4f32cacda1c505e6fc27fbc7ba69f5aa71.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f959ea5ec149b661197d3ede2b7bf24be0268ab4 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/28/2829ca960562d879bb9bc425ae0f4d356f78aaf9.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/28/2829ca960562d879bb9bc425ae0f4d356f78aaf9.svn-base.REMOVED.git-id deleted file mode 100644 index 5ac1b6a6..00000000 --- a/Old Matlab Interface/.svn/pristine/28/2829ca960562d879bb9bc425ae0f4d356f78aaf9.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9cd8f040129b2d5a9470c3fd8453d582dbd595bc \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/28/28a638cd51e648387350a4716cb2c2182b540d87.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/28/28a638cd51e648387350a4716cb2c2182b540d87.svn-base.REMOVED.git-id deleted file mode 100644 index c40c1c40..00000000 --- a/Old Matlab Interface/.svn/pristine/28/28a638cd51e648387350a4716cb2c2182b540d87.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bf017c322fd491338d913a0e16d1b9f9b3072927 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/29/290c7bf876399b9cac7f5c4ed4285c05b25cd206.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/29/290c7bf876399b9cac7f5c4ed4285c05b25cd206.svn-base.REMOVED.git-id deleted file mode 100644 index 9491d87f..00000000 --- a/Old Matlab Interface/.svn/pristine/29/290c7bf876399b9cac7f5c4ed4285c05b25cd206.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -541af56ee228f1e5df3d2a1a9b52e0d6d70f8d1c \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/29/29c64fec6e69ca22f81ebf30fba87a8a76bf64b6.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/29/29c64fec6e69ca22f81ebf30fba87a8a76bf64b6.svn-base.REMOVED.git-id deleted file mode 100644 index 2ba2ba3f..00000000 --- a/Old Matlab Interface/.svn/pristine/29/29c64fec6e69ca22f81ebf30fba87a8a76bf64b6.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f6623d605e2f3c67a8ccbb65ad45a11e4f98db04 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/2b/2b3e861ba0c928f44218c33b357ee225b210861d.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/2b/2b3e861ba0c928f44218c33b357ee225b210861d.svn-base.REMOVED.git-id deleted file mode 100644 index a94bc484..00000000 --- a/Old Matlab Interface/.svn/pristine/2b/2b3e861ba0c928f44218c33b357ee225b210861d.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b1a4e14a00715f44b58d14cba4b482809adb0527 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/2c/2c2cac302b7f1cdf9fa687082d023d2095c94195.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/2c/2c2cac302b7f1cdf9fa687082d023d2095c94195.svn-base.REMOVED.git-id deleted file mode 100644 index 777b1fdc..00000000 --- a/Old Matlab Interface/.svn/pristine/2c/2c2cac302b7f1cdf9fa687082d023d2095c94195.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -84b1c5d3d8c969566dd7ba6ad706b90af055c762 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/2e/2edbf56631bf8c322ab56509a78f197f01786957.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/2e/2edbf56631bf8c322ab56509a78f197f01786957.svn-base.REMOVED.git-id deleted file mode 100644 index 7e4ab0c5..00000000 --- a/Old Matlab Interface/.svn/pristine/2e/2edbf56631bf8c322ab56509a78f197f01786957.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -400c2b7c163b76767f8d6ace4dbd7e7b74f44e3b \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/2f/2feca4ba5ed6b3d0dedf490a9063cb7ab9430790.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/2f/2feca4ba5ed6b3d0dedf490a9063cb7ab9430790.svn-base.REMOVED.git-id deleted file mode 100644 index 8958dd78..00000000 --- a/Old Matlab Interface/.svn/pristine/2f/2feca4ba5ed6b3d0dedf490a9063cb7ab9430790.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d81057dd7db630d6342743103cdcc436f2ddea7d \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/32/32ba5d36cb2ab8663296ce2e48e64fb66bb09f3a.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/32/32ba5d36cb2ab8663296ce2e48e64fb66bb09f3a.svn-base.REMOVED.git-id deleted file mode 100644 index 2b21ca51..00000000 --- a/Old Matlab Interface/.svn/pristine/32/32ba5d36cb2ab8663296ce2e48e64fb66bb09f3a.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6447face6c73fb25f73a5f1ea7e730bd545a57a3 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/33/338975c9c725c4146ae2eee3933f4a85f9c2f115.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/33/338975c9c725c4146ae2eee3933f4a85f9c2f115.svn-base.REMOVED.git-id deleted file mode 100644 index 66c0303d..00000000 --- a/Old Matlab Interface/.svn/pristine/33/338975c9c725c4146ae2eee3933f4a85f9c2f115.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1d49bc93c846047e5be411cfe6cdd620b3860a3c \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/36/361d39f794648a08cb9406c83d158220c347bb09.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/36/361d39f794648a08cb9406c83d158220c347bb09.svn-base.REMOVED.git-id deleted file mode 100644 index 6e60dd60..00000000 --- a/Old Matlab Interface/.svn/pristine/36/361d39f794648a08cb9406c83d158220c347bb09.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c03221f1d419619371ef4c0774bdc9a94f17e098 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/36/364d01a33894c1318342a60513444fea9f79f626.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/36/364d01a33894c1318342a60513444fea9f79f626.svn-base.REMOVED.git-id deleted file mode 100644 index f75de14b..00000000 --- a/Old Matlab Interface/.svn/pristine/36/364d01a33894c1318342a60513444fea9f79f626.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5178aa5251bfa9b880ede3f787001393d18a4b71 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/37/3760526ebf9920e390f38d721bd4effaecc3265c.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/37/3760526ebf9920e390f38d721bd4effaecc3265c.svn-base.REMOVED.git-id deleted file mode 100644 index c6689faf..00000000 --- a/Old Matlab Interface/.svn/pristine/37/3760526ebf9920e390f38d721bd4effaecc3265c.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cf30a774ebd540eb818fded441e996f8c489af91 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/3a/3a88715c2d02f41769b36f97cc570d5770a32ccc.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/3a/3a88715c2d02f41769b36f97cc570d5770a32ccc.svn-base.REMOVED.git-id deleted file mode 100644 index 81ba61f7..00000000 --- a/Old Matlab Interface/.svn/pristine/3a/3a88715c2d02f41769b36f97cc570d5770a32ccc.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8e4e5e9aaff4509870bb71a5d103c2f3c905df1b \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/3a/3aff65596faed59f9ea33ee9452d0e153ae9d3d5.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/3a/3aff65596faed59f9ea33ee9452d0e153ae9d3d5.svn-base.REMOVED.git-id deleted file mode 100644 index 77918502..00000000 --- a/Old Matlab Interface/.svn/pristine/3a/3aff65596faed59f9ea33ee9452d0e153ae9d3d5.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e4d69f15bc675917b7ce8d8ddce30de5dd56a3f8 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/3c/3cc215bf1d754958f357d474d049774db8f3b9e5.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/3c/3cc215bf1d754958f357d474d049774db8f3b9e5.svn-base.REMOVED.git-id deleted file mode 100644 index f3b6f802..00000000 --- a/Old Matlab Interface/.svn/pristine/3c/3cc215bf1d754958f357d474d049774db8f3b9e5.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b8bdd81676ebb6d619fc044141a7fa6b07465f60 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/3e/3e3d3ac6346a8cafb643956eb1e4e90c54adeff0.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/3e/3e3d3ac6346a8cafb643956eb1e4e90c54adeff0.svn-base.REMOVED.git-id deleted file mode 100644 index a6697b4a..00000000 --- a/Old Matlab Interface/.svn/pristine/3e/3e3d3ac6346a8cafb643956eb1e4e90c54adeff0.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1dd9f7ce4cde9c2d84a62a736fb28084f130dad2 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/3e/3eabd99f8e0f3fab49d501dac0f56cb63904bbcd.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/3e/3eabd99f8e0f3fab49d501dac0f56cb63904bbcd.svn-base.REMOVED.git-id deleted file mode 100644 index 599f026f..00000000 --- a/Old Matlab Interface/.svn/pristine/3e/3eabd99f8e0f3fab49d501dac0f56cb63904bbcd.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -462e7ecd870da210ff9cb712ea23a787e8931aa9 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/3f/3f2ffe70410dd117d147aa7c9feb072a8f3d1c80.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/3f/3f2ffe70410dd117d147aa7c9feb072a8f3d1c80.svn-base.REMOVED.git-id deleted file mode 100644 index 74525be8..00000000 --- a/Old Matlab Interface/.svn/pristine/3f/3f2ffe70410dd117d147aa7c9feb072a8f3d1c80.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9f980ed9ada78349c8ab22c8fa1f5089ead80a4e \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/3f/3fad4e091d61f24c210253e31673d3f211b79fe6.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/3f/3fad4e091d61f24c210253e31673d3f211b79fe6.svn-base.REMOVED.git-id deleted file mode 100644 index 2de3521c..00000000 --- a/Old Matlab Interface/.svn/pristine/3f/3fad4e091d61f24c210253e31673d3f211b79fe6.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cbcd7962e6f064c24eb22fc52527c2929c750065 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/40/405594dae0acbcf5943de3d37764a402bd7ab863.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/40/405594dae0acbcf5943de3d37764a402bd7ab863.svn-base.REMOVED.git-id deleted file mode 100644 index c939c4c9..00000000 --- a/Old Matlab Interface/.svn/pristine/40/405594dae0acbcf5943de3d37764a402bd7ab863.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2906160be2f21f8466d8a3a4d0da2c031307c30d \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/42/42d93a134c140d54d42b87e62b2bd7f4d1725dcb.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/42/42d93a134c140d54d42b87e62b2bd7f4d1725dcb.svn-base.REMOVED.git-id deleted file mode 100644 index b8ab0634..00000000 --- a/Old Matlab Interface/.svn/pristine/42/42d93a134c140d54d42b87e62b2bd7f4d1725dcb.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cdb959ec63bfffc20ef366b8795256851e53e38a \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/44/44bc75aeccf2b62e28cc9c5e8625165149f06afc.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/44/44bc75aeccf2b62e28cc9c5e8625165149f06afc.svn-base.REMOVED.git-id deleted file mode 100644 index 98144807..00000000 --- a/Old Matlab Interface/.svn/pristine/44/44bc75aeccf2b62e28cc9c5e8625165149f06afc.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -20ca2cfe5c773bd5f92009831c62f3fe62dbeae1 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/45/45b1a4617d02872cdb3cf169cda0dafbc514c065.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/45/45b1a4617d02872cdb3cf169cda0dafbc514c065.svn-base.REMOVED.git-id deleted file mode 100644 index 7964a513..00000000 --- a/Old Matlab Interface/.svn/pristine/45/45b1a4617d02872cdb3cf169cda0dafbc514c065.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -de609355dfb18613618f04e8c362739fe2c3fdc2 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/46/464dd4dd02051c93fe0a923037104d7466493cc4.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/46/464dd4dd02051c93fe0a923037104d7466493cc4.svn-base.REMOVED.git-id deleted file mode 100644 index e8580a54..00000000 --- a/Old Matlab Interface/.svn/pristine/46/464dd4dd02051c93fe0a923037104d7466493cc4.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -02a976c5defd3120bc01475570fd321dddf80194 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/46/46a1ec401c74e36b3e78d64c045fe1e8c73479ed.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/46/46a1ec401c74e36b3e78d64c045fe1e8c73479ed.svn-base.REMOVED.git-id deleted file mode 100644 index 387a78ae..00000000 --- a/Old Matlab Interface/.svn/pristine/46/46a1ec401c74e36b3e78d64c045fe1e8c73479ed.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1dbe9cea538458c43eded095874afe80717bd47d \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/47/47b15748ecc8e952c5935170090db7c269ce4b4f.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/47/47b15748ecc8e952c5935170090db7c269ce4b4f.svn-base.REMOVED.git-id deleted file mode 100644 index f3dbd193..00000000 --- a/Old Matlab Interface/.svn/pristine/47/47b15748ecc8e952c5935170090db7c269ce4b4f.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -af7dbebbacef595e3089c01c05671016c21a8304 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/48/48aaf1da9402bb0414597607011113f2852d4dc2.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/48/48aaf1da9402bb0414597607011113f2852d4dc2.svn-base.REMOVED.git-id deleted file mode 100644 index 43c32a95..00000000 --- a/Old Matlab Interface/.svn/pristine/48/48aaf1da9402bb0414597607011113f2852d4dc2.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -717244d59d3388a7d0c61611fe09dfcbc16506b8 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/4d/4d006a3643aedd8782c700ef93c1dd03fe8d4d6b.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/4d/4d006a3643aedd8782c700ef93c1dd03fe8d4d6b.svn-base.REMOVED.git-id deleted file mode 100644 index be9ab0f8..00000000 --- a/Old Matlab Interface/.svn/pristine/4d/4d006a3643aedd8782c700ef93c1dd03fe8d4d6b.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f75aa2cdcf03626691b18c5b8215b8b88a0b45fa \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/4f/4f3af4a617fd58cd7638129886ba749e38d74fd0.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/4f/4f3af4a617fd58cd7638129886ba749e38d74fd0.svn-base.REMOVED.git-id deleted file mode 100644 index c4e68d50..00000000 --- a/Old Matlab Interface/.svn/pristine/4f/4f3af4a617fd58cd7638129886ba749e38d74fd0.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aeb17d6a30c8033625eb150268cdcb84bfb0d010 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/4f/4fb1d6240092ae6c3b97164efd0529b27e935af1.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/4f/4fb1d6240092ae6c3b97164efd0529b27e935af1.svn-base.REMOVED.git-id deleted file mode 100644 index 5349f9fe..00000000 --- a/Old Matlab Interface/.svn/pristine/4f/4fb1d6240092ae6c3b97164efd0529b27e935af1.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -de01e97f1142e35fecf28aa28a12708580495a69 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/51/515fab57bd8558f7621bbd33ab04891cb2b8811a.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/51/515fab57bd8558f7621bbd33ab04891cb2b8811a.svn-base.REMOVED.git-id deleted file mode 100644 index e4f9cf46..00000000 --- a/Old Matlab Interface/.svn/pristine/51/515fab57bd8558f7621bbd33ab04891cb2b8811a.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -09b12375bd4a2cca513b724f1d90ae7ce8b7b814 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/52/52199dbf885e9ec1c33e31cde43d2a282dbd5a39.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/52/52199dbf885e9ec1c33e31cde43d2a282dbd5a39.svn-base.REMOVED.git-id deleted file mode 100644 index f41ca066..00000000 --- a/Old Matlab Interface/.svn/pristine/52/52199dbf885e9ec1c33e31cde43d2a282dbd5a39.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9a908ffa257a4f3d3d9e3ff4a6420db016f890d8 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/56/56fd215b6b3d0436eae86a247d4b0dc543e49390.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/56/56fd215b6b3d0436eae86a247d4b0dc543e49390.svn-base.REMOVED.git-id deleted file mode 100644 index 267cdb2c..00000000 --- a/Old Matlab Interface/.svn/pristine/56/56fd215b6b3d0436eae86a247d4b0dc543e49390.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e24371147c5c261ed171450b03a67fb3b34b9b84 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/57/571c8f6ab65e01badee44f72848f6375c4712600.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/57/571c8f6ab65e01badee44f72848f6375c4712600.svn-base.REMOVED.git-id deleted file mode 100644 index b38643cb..00000000 --- a/Old Matlab Interface/.svn/pristine/57/571c8f6ab65e01badee44f72848f6375c4712600.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9beca6a8bb5f64cb65d854d6344dff409ca274b5 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/57/572bf27dfedabdb5a9d3c7981b098e71dca49f0f.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/57/572bf27dfedabdb5a9d3c7981b098e71dca49f0f.svn-base.REMOVED.git-id deleted file mode 100644 index db187309..00000000 --- a/Old Matlab Interface/.svn/pristine/57/572bf27dfedabdb5a9d3c7981b098e71dca49f0f.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -276ddd0af705a850997ddc5908bf50e1f702f0eb \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/58/5813b6b7f9eb3d89e58a3a4b26364d7e1062255e.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/58/5813b6b7f9eb3d89e58a3a4b26364d7e1062255e.svn-base.REMOVED.git-id deleted file mode 100644 index 844bd158..00000000 --- a/Old Matlab Interface/.svn/pristine/58/5813b6b7f9eb3d89e58a3a4b26364d7e1062255e.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -910ca72bbf02d1103692ab58ed45b91d737a224f \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/58/58218339f1e12918006f36e0cfd826fc23983e57.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/58/58218339f1e12918006f36e0cfd826fc23983e57.svn-base.REMOVED.git-id deleted file mode 100644 index 4111a66a..00000000 --- a/Old Matlab Interface/.svn/pristine/58/58218339f1e12918006f36e0cfd826fc23983e57.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -00e349c88bbd7a3437d4929f6e68b0ad8808b5aa \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/59/595f27fe648f1942abb804c8fbb9342ecf345a4e.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/59/595f27fe648f1942abb804c8fbb9342ecf345a4e.svn-base.REMOVED.git-id deleted file mode 100644 index 3b2112df..00000000 --- a/Old Matlab Interface/.svn/pristine/59/595f27fe648f1942abb804c8fbb9342ecf345a4e.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a36eca487cbc874125758ad9d1a2f64ffcf28c8d \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/59/59a310c93c725583f6365f711ff3ba6f6d022b13.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/59/59a310c93c725583f6365f711ff3ba6f6d022b13.svn-base.REMOVED.git-id deleted file mode 100644 index edd5248a..00000000 --- a/Old Matlab Interface/.svn/pristine/59/59a310c93c725583f6365f711ff3ba6f6d022b13.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6dbbd773a7f3c4bb55b1de93bffa2e67dad26a0e \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/5a/5a04bd49ab8afaf758cd327491fedb96f3865d3e.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/5a/5a04bd49ab8afaf758cd327491fedb96f3865d3e.svn-base.REMOVED.git-id deleted file mode 100644 index 5cc87780..00000000 --- a/Old Matlab Interface/.svn/pristine/5a/5a04bd49ab8afaf758cd327491fedb96f3865d3e.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bde5de18a8eb236f39ab371696b4fdaedd8c281b \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/5d/5d281d1e5368816eaa425ac9a876e265bdeb0f1b.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/5d/5d281d1e5368816eaa425ac9a876e265bdeb0f1b.svn-base.REMOVED.git-id deleted file mode 100644 index a046b7f2..00000000 --- a/Old Matlab Interface/.svn/pristine/5d/5d281d1e5368816eaa425ac9a876e265bdeb0f1b.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6f1e8d3020e185bf1167ee105a3a949a94c93be3 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/5e/5e1d04de66ffcc5dfd813530ab6992e6daaae417.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/5e/5e1d04de66ffcc5dfd813530ab6992e6daaae417.svn-base.REMOVED.git-id deleted file mode 100644 index bb199510..00000000 --- a/Old Matlab Interface/.svn/pristine/5e/5e1d04de66ffcc5dfd813530ab6992e6daaae417.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -39645652af62950ebf3b28ec3a5400dcec30b1c4 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/5e/5e58d8a07a334d81a70b361ad73b5e8a5e447688.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/5e/5e58d8a07a334d81a70b361ad73b5e8a5e447688.svn-base.REMOVED.git-id deleted file mode 100644 index ff7195ed..00000000 --- a/Old Matlab Interface/.svn/pristine/5e/5e58d8a07a334d81a70b361ad73b5e8a5e447688.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ab0f6183cf42de1d1b1818b9e08a07d22dcac324 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/5f/5f04c8e98522ce9584f2216a606b11301e8e357a.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/5f/5f04c8e98522ce9584f2216a606b11301e8e357a.svn-base.REMOVED.git-id deleted file mode 100644 index c1430e78..00000000 --- a/Old Matlab Interface/.svn/pristine/5f/5f04c8e98522ce9584f2216a606b11301e8e357a.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8a3093e06133d6833e31cae53d41a5d1a4f4f1c6 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/5f/5f4e17dea5e6b15424f9d7af77a70beb8bcdf153.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/5f/5f4e17dea5e6b15424f9d7af77a70beb8bcdf153.svn-base.REMOVED.git-id deleted file mode 100644 index 6d42df11..00000000 --- a/Old Matlab Interface/.svn/pristine/5f/5f4e17dea5e6b15424f9d7af77a70beb8bcdf153.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -035f0468e6d7ff749407947a38b4bef13bbb10fe \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/62/625d155c06d982dcf6562f7b33f057c2000f7a35.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/62/625d155c06d982dcf6562f7b33f057c2000f7a35.svn-base.REMOVED.git-id deleted file mode 100644 index edaec86e..00000000 --- a/Old Matlab Interface/.svn/pristine/62/625d155c06d982dcf6562f7b33f057c2000f7a35.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -dca059f238e0259a5e072e34c3531e39b66c4f9c \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/66/668a6732f464095a0d6f139f3b99925ffb4003f2.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/66/668a6732f464095a0d6f139f3b99925ffb4003f2.svn-base.REMOVED.git-id deleted file mode 100644 index 09792fda..00000000 --- a/Old Matlab Interface/.svn/pristine/66/668a6732f464095a0d6f139f3b99925ffb4003f2.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4f3d52aaa5db74254adb8aa5cbc19a90160c4031 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/66/668cfaa1a816b8698bcfe18181d4964d1dc45605.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/66/668cfaa1a816b8698bcfe18181d4964d1dc45605.svn-base.REMOVED.git-id deleted file mode 100644 index 2ba1d9de..00000000 --- a/Old Matlab Interface/.svn/pristine/66/668cfaa1a816b8698bcfe18181d4964d1dc45605.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -10eb9f0ca7d60bf02548666cfcb7801f19a47f50 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/67/670da6e74eb825895d78773d5fb7e693456cbfaa.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/67/670da6e74eb825895d78773d5fb7e693456cbfaa.svn-base.REMOVED.git-id deleted file mode 100644 index 334744ad..00000000 --- a/Old Matlab Interface/.svn/pristine/67/670da6e74eb825895d78773d5fb7e693456cbfaa.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9adaca833a95960327158b756654851490c85fcf \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/68/68b6ca4c477007e9b1bc0d43b4a14c3bc1a3aad5.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/68/68b6ca4c477007e9b1bc0d43b4a14c3bc1a3aad5.svn-base.REMOVED.git-id deleted file mode 100644 index 84f7a367..00000000 --- a/Old Matlab Interface/.svn/pristine/68/68b6ca4c477007e9b1bc0d43b4a14c3bc1a3aad5.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c8358a402616820ce03836fde9ec66d91c8f0293 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/69/697b5fbc6357cededb5ebe4e63254276d07daea9.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/69/697b5fbc6357cededb5ebe4e63254276d07daea9.svn-base.REMOVED.git-id deleted file mode 100644 index 0efb631b..00000000 --- a/Old Matlab Interface/.svn/pristine/69/697b5fbc6357cededb5ebe4e63254276d07daea9.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3b414327d759fdb4927753daeab25ad6c3d00855 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/6b/6b54b54984147f1b32fe68dbaa766f3b2000c508.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/6b/6b54b54984147f1b32fe68dbaa766f3b2000c508.svn-base.REMOVED.git-id deleted file mode 100644 index c74f411d..00000000 --- a/Old Matlab Interface/.svn/pristine/6b/6b54b54984147f1b32fe68dbaa766f3b2000c508.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0c8f63ccdefb03bbd30929c0c4987cbce9fc9557 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/6b/6bcb7516b24c37fa7330dcd3d4d2ccb53905f22d.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/6b/6bcb7516b24c37fa7330dcd3d4d2ccb53905f22d.svn-base.REMOVED.git-id deleted file mode 100644 index 117c1b51..00000000 --- a/Old Matlab Interface/.svn/pristine/6b/6bcb7516b24c37fa7330dcd3d4d2ccb53905f22d.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7e23f28d943734718a670e2100bea3f72040f574 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/6c/6c378d3e96a933397f034cbb46862b36c3159642.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/6c/6c378d3e96a933397f034cbb46862b36c3159642.svn-base.REMOVED.git-id deleted file mode 100644 index 04386b95..00000000 --- a/Old Matlab Interface/.svn/pristine/6c/6c378d3e96a933397f034cbb46862b36c3159642.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fc136d6507cc9df8e9cce8546a4c7daf0cbd8aee \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/6c/6c6a73ab3cbe75c885f6d1dd673ae5fab0179fd4.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/6c/6c6a73ab3cbe75c885f6d1dd673ae5fab0179fd4.svn-base.REMOVED.git-id deleted file mode 100644 index 01df8cac..00000000 --- a/Old Matlab Interface/.svn/pristine/6c/6c6a73ab3cbe75c885f6d1dd673ae5fab0179fd4.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -77a9c0fe8639eb4e66f732c38266aef2075b7d55 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/6c/6c902550934daa388a7f4bd6b7d3a5e821ab7b79.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/6c/6c902550934daa388a7f4bd6b7d3a5e821ab7b79.svn-base.REMOVED.git-id deleted file mode 100644 index 88f42ce5..00000000 --- a/Old Matlab Interface/.svn/pristine/6c/6c902550934daa388a7f4bd6b7d3a5e821ab7b79.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -000f42e69ba16842f302232f95a83332aaff755d \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/6d/6d7787be02fc4a01b9a562c5c015699be31a2269.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/6d/6d7787be02fc4a01b9a562c5c015699be31a2269.svn-base.REMOVED.git-id deleted file mode 100644 index 57c931f8..00000000 --- a/Old Matlab Interface/.svn/pristine/6d/6d7787be02fc4a01b9a562c5c015699be31a2269.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5a34b87123d6edfe73309908e76dfddfd7ede633 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/6e/6e7927959ad433000d17dce5491f498151cf36a1.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/6e/6e7927959ad433000d17dce5491f498151cf36a1.svn-base.REMOVED.git-id deleted file mode 100644 index c92f05dc..00000000 --- a/Old Matlab Interface/.svn/pristine/6e/6e7927959ad433000d17dce5491f498151cf36a1.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -00ca0be24341f61210a233b653307b75dccd53f7 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/74/749166eff8c546e24e0c1bd4db17cf7b85af8cf2.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/74/749166eff8c546e24e0c1bd4db17cf7b85af8cf2.svn-base.REMOVED.git-id deleted file mode 100644 index 8a08a43e..00000000 --- a/Old Matlab Interface/.svn/pristine/74/749166eff8c546e24e0c1bd4db17cf7b85af8cf2.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b391df84b80addf52371dd440c583a826c216404 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/74/74ab792fd8b045e2ac5e42386036bd8a784d7a83.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/74/74ab792fd8b045e2ac5e42386036bd8a784d7a83.svn-base.REMOVED.git-id deleted file mode 100644 index d006fa54..00000000 --- a/Old Matlab Interface/.svn/pristine/74/74ab792fd8b045e2ac5e42386036bd8a784d7a83.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6008fdd5eb61ec865f948d5e3d69f1ef7eb38b1a \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/74/74bb6da9ab65e93b7e2925112c3d7c30b0fadfb3.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/74/74bb6da9ab65e93b7e2925112c3d7c30b0fadfb3.svn-base.REMOVED.git-id deleted file mode 100644 index eac35bf4..00000000 --- a/Old Matlab Interface/.svn/pristine/74/74bb6da9ab65e93b7e2925112c3d7c30b0fadfb3.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7c032cf37e0629c9e0a5bb00cf24a0e1adb7f406 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/74/74c451a6c26a806eb6fa35fe1be696d8e18b5a55.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/74/74c451a6c26a806eb6fa35fe1be696d8e18b5a55.svn-base.REMOVED.git-id deleted file mode 100644 index a730154b..00000000 --- a/Old Matlab Interface/.svn/pristine/74/74c451a6c26a806eb6fa35fe1be696d8e18b5a55.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5fd33a01bed1f1606fafcb6c52e1097e55183314 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/77/77efb475527df5be676d213528b5ced7955ce2ac.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/77/77efb475527df5be676d213528b5ced7955ce2ac.svn-base.REMOVED.git-id deleted file mode 100644 index c8cf847b..00000000 --- a/Old Matlab Interface/.svn/pristine/77/77efb475527df5be676d213528b5ced7955ce2ac.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7ac51320b9d104b06b06c75d84b5201fea80e0db \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/78/787752147806941a97858ca492d13c388b1e12b9.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/78/787752147806941a97858ca492d13c388b1e12b9.svn-base.REMOVED.git-id deleted file mode 100644 index 8b788905..00000000 --- a/Old Matlab Interface/.svn/pristine/78/787752147806941a97858ca492d13c388b1e12b9.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4d8d76183d95f76b2ceca3b720961aa6031fa40d \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/7a/7a574ec4e525727674ae7f5c8c1809f297404050.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/7a/7a574ec4e525727674ae7f5c8c1809f297404050.svn-base.REMOVED.git-id deleted file mode 100644 index 91db37fb..00000000 --- a/Old Matlab Interface/.svn/pristine/7a/7a574ec4e525727674ae7f5c8c1809f297404050.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b839721c72a5ba4a761293c7aa4056e86244f967 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/7d/7dd3b89f71ee9ee97d78aa0ce502fbf9ffd1591c.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/7d/7dd3b89f71ee9ee97d78aa0ce502fbf9ffd1591c.svn-base.REMOVED.git-id deleted file mode 100644 index 57e4888c..00000000 --- a/Old Matlab Interface/.svn/pristine/7d/7dd3b89f71ee9ee97d78aa0ce502fbf9ffd1591c.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -01955c69b2e644789b0c65e3a6a10db7f822b26c \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/7f/7f1789992aed7f13d9a17497c169cbbc3912b5c1.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/7f/7f1789992aed7f13d9a17497c169cbbc3912b5c1.svn-base.REMOVED.git-id deleted file mode 100644 index d3b954d9..00000000 --- a/Old Matlab Interface/.svn/pristine/7f/7f1789992aed7f13d9a17497c169cbbc3912b5c1.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ae1b91a9fa873ba38008da659839fe47ea8ab0c5 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/81/8155cab5fb6d2b6bf6bacf3ed8168a4020ffdd34.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/81/8155cab5fb6d2b6bf6bacf3ed8168a4020ffdd34.svn-base.REMOVED.git-id deleted file mode 100644 index 93cb6c26..00000000 --- a/Old Matlab Interface/.svn/pristine/81/8155cab5fb6d2b6bf6bacf3ed8168a4020ffdd34.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f98c51124d43a1c7d625db7fb56ff63588ef55e2 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/81/8161bdf39d77246e52a863a09a61cb13dd66d475.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/81/8161bdf39d77246e52a863a09a61cb13dd66d475.svn-base.REMOVED.git-id deleted file mode 100644 index e4538073..00000000 --- a/Old Matlab Interface/.svn/pristine/81/8161bdf39d77246e52a863a09a61cb13dd66d475.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9f1d532103d18813901e5a5ea6cf3fac1bbb4283 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/83/83fdb95bddd831f110af1c74760c826cebb32320.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/83/83fdb95bddd831f110af1c74760c826cebb32320.svn-base.REMOVED.git-id deleted file mode 100644 index dd5779fd..00000000 --- a/Old Matlab Interface/.svn/pristine/83/83fdb95bddd831f110af1c74760c826cebb32320.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -db99e100a4e00a3b302a990c3b58582f6b7f01bb \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/84/84effe1a1f62eb33ba16625a6129c21f32c80689.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/84/84effe1a1f62eb33ba16625a6129c21f32c80689.svn-base.REMOVED.git-id deleted file mode 100644 index cfe81dd0..00000000 --- a/Old Matlab Interface/.svn/pristine/84/84effe1a1f62eb33ba16625a6129c21f32c80689.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -252ebda40efe7f17c7f0a51a274088f1c0305a5c \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/85/854e53ad0c1c900867bb3e38b74b8aaf39b05517.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/85/854e53ad0c1c900867bb3e38b74b8aaf39b05517.svn-base.REMOVED.git-id deleted file mode 100644 index 2df36643..00000000 --- a/Old Matlab Interface/.svn/pristine/85/854e53ad0c1c900867bb3e38b74b8aaf39b05517.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -25fbf807e3a1f15bde118fc0a473afa9784ee5c2 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/86/86eb39f23878c96ac9ca0a3c0171051d4449cbd5.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/86/86eb39f23878c96ac9ca0a3c0171051d4449cbd5.svn-base.REMOVED.git-id deleted file mode 100644 index b4b75327..00000000 --- a/Old Matlab Interface/.svn/pristine/86/86eb39f23878c96ac9ca0a3c0171051d4449cbd5.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9705f823e15bcc30e45c0f42be26e3caefbad5a3 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/87/8772b8f072c56c428c182689f088a4190f73110d.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/87/8772b8f072c56c428c182689f088a4190f73110d.svn-base.REMOVED.git-id deleted file mode 100644 index 6876816c..00000000 --- a/Old Matlab Interface/.svn/pristine/87/8772b8f072c56c428c182689f088a4190f73110d.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c361e69d0f58c1880f3f4844dcfaaf9f4395519a \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/87/87c12e93d8d3b7b0509c2b191a294c488a14da87.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/87/87c12e93d8d3b7b0509c2b191a294c488a14da87.svn-base.REMOVED.git-id deleted file mode 100644 index 9df56b28..00000000 --- a/Old Matlab Interface/.svn/pristine/87/87c12e93d8d3b7b0509c2b191a294c488a14da87.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -18ba51183d354c385889d160dd9286d484489457 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/87/87e4a5b01caf2064c8cfbba9838e98683da95ed3.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/87/87e4a5b01caf2064c8cfbba9838e98683da95ed3.svn-base.REMOVED.git-id deleted file mode 100644 index f7ff8e6f..00000000 --- a/Old Matlab Interface/.svn/pristine/87/87e4a5b01caf2064c8cfbba9838e98683da95ed3.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -65b7fa05b6ce763001e1c09565bdafc8b9fe9360 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/89/89196469f0ff6239dde91a79ecea47656acdda7f.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/89/89196469f0ff6239dde91a79ecea47656acdda7f.svn-base.REMOVED.git-id deleted file mode 100644 index b459ccd5..00000000 --- a/Old Matlab Interface/.svn/pristine/89/89196469f0ff6239dde91a79ecea47656acdda7f.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7c3080c9e499d4d40510ddc868f11843e476fd11 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/89/891c79cc3525c8953dc38d3952360b1c6a6fc91f.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/89/891c79cc3525c8953dc38d3952360b1c6a6fc91f.svn-base.REMOVED.git-id deleted file mode 100644 index 2c585758..00000000 --- a/Old Matlab Interface/.svn/pristine/89/891c79cc3525c8953dc38d3952360b1c6a6fc91f.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f5ccfdfb550ef5608c7faac6769f63905ab5b927 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/89/891f6ae35ed50d8ee116d5081d309a2139cb1f55.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/89/891f6ae35ed50d8ee116d5081d309a2139cb1f55.svn-base.REMOVED.git-id deleted file mode 100644 index c3c28bcd..00000000 --- a/Old Matlab Interface/.svn/pristine/89/891f6ae35ed50d8ee116d5081d309a2139cb1f55.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ad31dc657c40d9aa8e0b86af759c0484642d54bc \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/8a/8a3d6b9a31578b2614976a87b55da6b1305c5407.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/8a/8a3d6b9a31578b2614976a87b55da6b1305c5407.svn-base.REMOVED.git-id deleted file mode 100644 index 24ce0fb8..00000000 --- a/Old Matlab Interface/.svn/pristine/8a/8a3d6b9a31578b2614976a87b55da6b1305c5407.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4c4d34fc7be35f1ef60cd2c0edb76a9f2ae76de4 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/8a/8add2b852c170d1d1ca460b388ad1b0ab28e6156.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/8a/8add2b852c170d1d1ca460b388ad1b0ab28e6156.svn-base.REMOVED.git-id deleted file mode 100644 index d989bfd4..00000000 --- a/Old Matlab Interface/.svn/pristine/8a/8add2b852c170d1d1ca460b388ad1b0ab28e6156.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -dfa7188b2ab39e552c6588ade4877d2303514ae9 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/8c/8cad3faa6a8b5a9b56a42297d8581b70c81bd4e1.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/8c/8cad3faa6a8b5a9b56a42297d8581b70c81bd4e1.svn-base.REMOVED.git-id deleted file mode 100644 index cb75fa8e..00000000 --- a/Old Matlab Interface/.svn/pristine/8c/8cad3faa6a8b5a9b56a42297d8581b70c81bd4e1.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -676f8f331d74eced25170b33370e32561a00f8f6 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/8c/8cd1937ea79bdfed87f7af58afb69e3246c362f3.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/8c/8cd1937ea79bdfed87f7af58afb69e3246c362f3.svn-base.REMOVED.git-id deleted file mode 100644 index c3748347..00000000 --- a/Old Matlab Interface/.svn/pristine/8c/8cd1937ea79bdfed87f7af58afb69e3246c362f3.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -49b1b90919ebeec8bf06125a05982c91283658bc \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/8d/8d91434d05e3b1d6e19cffdb2a684e984f2f5991.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/8d/8d91434d05e3b1d6e19cffdb2a684e984f2f5991.svn-base.REMOVED.git-id deleted file mode 100644 index 592e77dc..00000000 --- a/Old Matlab Interface/.svn/pristine/8d/8d91434d05e3b1d6e19cffdb2a684e984f2f5991.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4280bc3ce10a5bf77d49db8ab253694608ec217d \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/8d/8dff77fcaf116493419ad088b481af6a4fc10114.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/8d/8dff77fcaf116493419ad088b481af6a4fc10114.svn-base.REMOVED.git-id deleted file mode 100644 index d2d14f48..00000000 --- a/Old Matlab Interface/.svn/pristine/8d/8dff77fcaf116493419ad088b481af6a4fc10114.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5ee45658dbf9ab99c23d2ec56bea9e60e9a822a7 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/8f/8f1132ee0db0983091d41e2f856bf5bf0af3b2f5.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/8f/8f1132ee0db0983091d41e2f856bf5bf0af3b2f5.svn-base.REMOVED.git-id deleted file mode 100644 index dab78be8..00000000 --- a/Old Matlab Interface/.svn/pristine/8f/8f1132ee0db0983091d41e2f856bf5bf0af3b2f5.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6e1586a0d844a699ac499df128a0c60bbf9a018b \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/8f/8f3b546183f36253bc8c454c70e9b8fbefb922ff.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/8f/8f3b546183f36253bc8c454c70e9b8fbefb922ff.svn-base.REMOVED.git-id deleted file mode 100644 index cfbd5db0..00000000 --- a/Old Matlab Interface/.svn/pristine/8f/8f3b546183f36253bc8c454c70e9b8fbefb922ff.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -65ae715238230b3415611a1b278c7d4aa8f074ee \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/90/90d475a7054803e545ad8a4f6e6868f608f55f6d.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/90/90d475a7054803e545ad8a4f6e6868f608f55f6d.svn-base.REMOVED.git-id deleted file mode 100644 index 3b5e653e..00000000 --- a/Old Matlab Interface/.svn/pristine/90/90d475a7054803e545ad8a4f6e6868f608f55f6d.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -05ad2639022f19fc4363c6f16f32e0a512b5f551 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/91/912bf56237775ea922c9d891e7cc8f1cd019d308.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/91/912bf56237775ea922c9d891e7cc8f1cd019d308.svn-base.REMOVED.git-id deleted file mode 100644 index a9094385..00000000 --- a/Old Matlab Interface/.svn/pristine/91/912bf56237775ea922c9d891e7cc8f1cd019d308.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -acc8fef190b6ec148c9cb702a566cc0f64ad2718 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/94/94015317cc0c78f6e1899a1f7eba73bcec65b371.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/94/94015317cc0c78f6e1899a1f7eba73bcec65b371.svn-base.REMOVED.git-id deleted file mode 100644 index 53777957..00000000 --- a/Old Matlab Interface/.svn/pristine/94/94015317cc0c78f6e1899a1f7eba73bcec65b371.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -993ca4ad8725f5f3a04e7e9f9f259a0c12931a3d \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/94/94a348c0208e96952918834c70333658f876cde9.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/94/94a348c0208e96952918834c70333658f876cde9.svn-base.REMOVED.git-id deleted file mode 100644 index d4071789..00000000 --- a/Old Matlab Interface/.svn/pristine/94/94a348c0208e96952918834c70333658f876cde9.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2acea442f135e741d7bd6f91b0cc271a5119ab69 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/94/94f8cd2a1888db8f59f1d8f3030ba8b7f50bf3d2.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/94/94f8cd2a1888db8f59f1d8f3030ba8b7f50bf3d2.svn-base.REMOVED.git-id deleted file mode 100644 index 336eca70..00000000 --- a/Old Matlab Interface/.svn/pristine/94/94f8cd2a1888db8f59f1d8f3030ba8b7f50bf3d2.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -938ed8762a79bafa33bdfbe71b305cf5c88229e3 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/95/95632618c0f551232d080babe816c7e8228aaf53.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/95/95632618c0f551232d080babe816c7e8228aaf53.svn-base.REMOVED.git-id deleted file mode 100644 index 65d13538..00000000 --- a/Old Matlab Interface/.svn/pristine/95/95632618c0f551232d080babe816c7e8228aaf53.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0e819efa6d3d672f77740df5f229023ca12ab576 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/98/98a81befbeda1076bba948201f50294a85cc61e6.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/98/98a81befbeda1076bba948201f50294a85cc61e6.svn-base.REMOVED.git-id deleted file mode 100644 index 156dba89..00000000 --- a/Old Matlab Interface/.svn/pristine/98/98a81befbeda1076bba948201f50294a85cc61e6.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b0e2050bd4d9af92e7c5fbf2c64deacd64414ae8 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/99/99db985423ee055b8fb4316d524a91bc22870f17.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/99/99db985423ee055b8fb4316d524a91bc22870f17.svn-base.REMOVED.git-id deleted file mode 100644 index 6d0c4930..00000000 --- a/Old Matlab Interface/.svn/pristine/99/99db985423ee055b8fb4316d524a91bc22870f17.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0ba3803006dfa360dfab621e9a376f7aac13392b \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/9a/9a889ec32d482cfe17903fdcc469511a417950b0.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/9a/9a889ec32d482cfe17903fdcc469511a417950b0.svn-base.REMOVED.git-id deleted file mode 100644 index 4e1ff61c..00000000 --- a/Old Matlab Interface/.svn/pristine/9a/9a889ec32d482cfe17903fdcc469511a417950b0.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bbca8d486e83995ebeb813b9e55220bf0b63ec26 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/9b/9b08e8cee2d7f7bedff6fa2bfbe2c6df5b15e349.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/9b/9b08e8cee2d7f7bedff6fa2bfbe2c6df5b15e349.svn-base.REMOVED.git-id deleted file mode 100644 index 2efef1da..00000000 --- a/Old Matlab Interface/.svn/pristine/9b/9b08e8cee2d7f7bedff6fa2bfbe2c6df5b15e349.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fe23367405c6a8e907f71e8cf88799e541c7ed66 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/9c/9c530c9fdb85289e34d2176bcaa511a0bfdb9e3c.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/9c/9c530c9fdb85289e34d2176bcaa511a0bfdb9e3c.svn-base.REMOVED.git-id deleted file mode 100644 index 47484916..00000000 --- a/Old Matlab Interface/.svn/pristine/9c/9c530c9fdb85289e34d2176bcaa511a0bfdb9e3c.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fd0b334b5654f6507a73957ad715aa654707b954 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/9d/9d464fa3e71f5ee633a65b39defaff34912f8456.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/9d/9d464fa3e71f5ee633a65b39defaff34912f8456.svn-base.REMOVED.git-id deleted file mode 100644 index b1c69577..00000000 --- a/Old Matlab Interface/.svn/pristine/9d/9d464fa3e71f5ee633a65b39defaff34912f8456.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -15d0793c024263ac3470a83926811db644f959ec \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/9d/9db7f1983a4fa1edf6213bca2caa61ec4026cece.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/9d/9db7f1983a4fa1edf6213bca2caa61ec4026cece.svn-base.REMOVED.git-id deleted file mode 100644 index 1e868f5f..00000000 --- a/Old Matlab Interface/.svn/pristine/9d/9db7f1983a4fa1edf6213bca2caa61ec4026cece.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f632a987be420a3f5c049f3db3f65bfbb8938363 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/9e/9e3d03b7e7e60a616b3035af99b9ea43979ccf43.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/9e/9e3d03b7e7e60a616b3035af99b9ea43979ccf43.svn-base.REMOVED.git-id deleted file mode 100644 index 45d23606..00000000 --- a/Old Matlab Interface/.svn/pristine/9e/9e3d03b7e7e60a616b3035af99b9ea43979ccf43.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -448c3b1d09507a0159e394513cd71fba1a707413 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/a0/a020241393e5c9788f977eaf9de0b0d8d9c66ff5.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/a0/a020241393e5c9788f977eaf9de0b0d8d9c66ff5.svn-base.REMOVED.git-id deleted file mode 100644 index 7f24fbb5..00000000 --- a/Old Matlab Interface/.svn/pristine/a0/a020241393e5c9788f977eaf9de0b0d8d9c66ff5.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -db614fd8942bfc55c8c36a6eff2c56c01c00a654 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/a3/a3023fbcec1c59bde87572af9b5c3486e515080a.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/a3/a3023fbcec1c59bde87572af9b5c3486e515080a.svn-base.REMOVED.git-id deleted file mode 100644 index db15eb65..00000000 --- a/Old Matlab Interface/.svn/pristine/a3/a3023fbcec1c59bde87572af9b5c3486e515080a.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0a21e192b64941ab5da1ada602edff4823b166a6 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/a3/a3c8e67f1bd40c0642728d94c5415ee8a96e5eaa.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/a3/a3c8e67f1bd40c0642728d94c5415ee8a96e5eaa.svn-base.REMOVED.git-id deleted file mode 100644 index f132237c..00000000 --- a/Old Matlab Interface/.svn/pristine/a3/a3c8e67f1bd40c0642728d94c5415ee8a96e5eaa.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cc9f9b4cc539b86854ae5ab711ec0d0abb31eadd \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/a3/a3ede89335933964727b486c8f69eb99abc78601.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/a3/a3ede89335933964727b486c8f69eb99abc78601.svn-base.REMOVED.git-id deleted file mode 100644 index b97b5b67..00000000 --- a/Old Matlab Interface/.svn/pristine/a3/a3ede89335933964727b486c8f69eb99abc78601.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -083c5514f89a39ccb14f1d3c5537dff34ef08557 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/a4/a41cc954b085ad5a93e71bdfbdb675e99e173ecd.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/a4/a41cc954b085ad5a93e71bdfbdb675e99e173ecd.svn-base.REMOVED.git-id deleted file mode 100644 index 803612dc..00000000 --- a/Old Matlab Interface/.svn/pristine/a4/a41cc954b085ad5a93e71bdfbdb675e99e173ecd.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ddfa3fa9ee3b225f7f62f2f089d39b1fd0c3ca2c \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/a4/a4d7e09e485d3552853c661f4cd30ca35a42f08d.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/a4/a4d7e09e485d3552853c661f4cd30ca35a42f08d.svn-base.REMOVED.git-id deleted file mode 100644 index 09fe936e..00000000 --- a/Old Matlab Interface/.svn/pristine/a4/a4d7e09e485d3552853c661f4cd30ca35a42f08d.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9409e06c65ed66967a18c8e127a07ce1b7398ff0 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/a5/a519965b93dc0b1921febca0183228564d9eee72.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/a5/a519965b93dc0b1921febca0183228564d9eee72.svn-base.REMOVED.git-id deleted file mode 100644 index 66e74f21..00000000 --- a/Old Matlab Interface/.svn/pristine/a5/a519965b93dc0b1921febca0183228564d9eee72.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -80402b0e92eec5eba199b0a1ebe6964427218acc \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/a5/a58a71ed80434868fb8810b5a3027e0bf5223c40.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/a5/a58a71ed80434868fb8810b5a3027e0bf5223c40.svn-base.REMOVED.git-id deleted file mode 100644 index d3b7cfe4..00000000 --- a/Old Matlab Interface/.svn/pristine/a5/a58a71ed80434868fb8810b5a3027e0bf5223c40.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -339bc805e8ad8a5b1bc3cd13073c8467818ea013 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/a7/a74754103cbbd024e69f4caec56f8ce9481448f8.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/a7/a74754103cbbd024e69f4caec56f8ce9481448f8.svn-base.REMOVED.git-id deleted file mode 100644 index 317e9d13..00000000 --- a/Old Matlab Interface/.svn/pristine/a7/a74754103cbbd024e69f4caec56f8ce9481448f8.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2dbf01c59b8529688c9c6a7531f327cd669fc840 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/a7/a794081f3fb8dd91b746e26103b6a5d218317d28.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/a7/a794081f3fb8dd91b746e26103b6a5d218317d28.svn-base.REMOVED.git-id deleted file mode 100644 index 24886b33..00000000 --- a/Old Matlab Interface/.svn/pristine/a7/a794081f3fb8dd91b746e26103b6a5d218317d28.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f301b946e51e63389285f3106ea3c432cef265de \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/aa/aa82fa4703a4d43e494d8342c568fa83052c2a00.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/aa/aa82fa4703a4d43e494d8342c568fa83052c2a00.svn-base.REMOVED.git-id deleted file mode 100644 index f3fba8eb..00000000 --- a/Old Matlab Interface/.svn/pristine/aa/aa82fa4703a4d43e494d8342c568fa83052c2a00.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -00ca9bf2041189a9384eb101956baa01c6dd238a \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/ab/ab017b74c73e98cf9ee73581f26e8ede95d0b5aa.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/ab/ab017b74c73e98cf9ee73581f26e8ede95d0b5aa.svn-base.REMOVED.git-id deleted file mode 100644 index 0dcb3636..00000000 --- a/Old Matlab Interface/.svn/pristine/ab/ab017b74c73e98cf9ee73581f26e8ede95d0b5aa.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4526dd2c919e286e225c69be9b8ffb2f8f181fa7 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/ab/abaa245b99298141b3f1958ed5af6b2bcec74b77.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/ab/abaa245b99298141b3f1958ed5af6b2bcec74b77.svn-base.REMOVED.git-id deleted file mode 100644 index 6d4a4eeb..00000000 --- a/Old Matlab Interface/.svn/pristine/ab/abaa245b99298141b3f1958ed5af6b2bcec74b77.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -43c719c35b2e4f5ac7671101d8f7aba66d6d95de \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/ac/ac387008baf3577ae9168fd267cc8fc08dce9203.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/ac/ac387008baf3577ae9168fd267cc8fc08dce9203.svn-base.REMOVED.git-id deleted file mode 100644 index 2af42938..00000000 --- a/Old Matlab Interface/.svn/pristine/ac/ac387008baf3577ae9168fd267cc8fc08dce9203.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a93e068ed0cf56b3dc1737ff30f1726c2ae1e11a \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/ac/ac771183697485fc6e7d0811d57341e2477b6f32.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/ac/ac771183697485fc6e7d0811d57341e2477b6f32.svn-base.REMOVED.git-id deleted file mode 100644 index 0c3dd62d..00000000 --- a/Old Matlab Interface/.svn/pristine/ac/ac771183697485fc6e7d0811d57341e2477b6f32.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7e54ebd918c087ffb73de536166c5fc8831b2d2b \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/ae/ae0f25c36f3df7432704d2bf7e1dbe0d0273513e.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/ae/ae0f25c36f3df7432704d2bf7e1dbe0d0273513e.svn-base.REMOVED.git-id deleted file mode 100644 index 866e06ae..00000000 --- a/Old Matlab Interface/.svn/pristine/ae/ae0f25c36f3df7432704d2bf7e1dbe0d0273513e.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f9649c33cd2120c8fce19d375a5cd18f9723eca9 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/b1/b1a26ccf1a429fc72cfff9a3b4419a4c5886270d.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/b1/b1a26ccf1a429fc72cfff9a3b4419a4c5886270d.svn-base.REMOVED.git-id deleted file mode 100644 index ac387060..00000000 --- a/Old Matlab Interface/.svn/pristine/b1/b1a26ccf1a429fc72cfff9a3b4419a4c5886270d.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f4ee05df64d140f383132b741a01cea22f83fc33 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/b4/b44f8b25b8edf496c954c87abf9e73f992c0b26d.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/b4/b44f8b25b8edf496c954c87abf9e73f992c0b26d.svn-base.REMOVED.git-id deleted file mode 100644 index a974a754..00000000 --- a/Old Matlab Interface/.svn/pristine/b4/b44f8b25b8edf496c954c87abf9e73f992c0b26d.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -01b9ce836a6cc856b5a8fe97c2b08c9e9a2870b6 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/b5/b5d926b78c0ca46b2e63aa5ed1a2491f4225ecca.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/b5/b5d926b78c0ca46b2e63aa5ed1a2491f4225ecca.svn-base.REMOVED.git-id deleted file mode 100644 index d032c0b4..00000000 --- a/Old Matlab Interface/.svn/pristine/b5/b5d926b78c0ca46b2e63aa5ed1a2491f4225ecca.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f86821bd55a21ac4fdf01e5bb5983d70ba00c070 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/ba/bab093ba2af354496638140bb68de7d473dd215c.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/ba/bab093ba2af354496638140bb68de7d473dd215c.svn-base.REMOVED.git-id deleted file mode 100644 index 3e6c902a..00000000 --- a/Old Matlab Interface/.svn/pristine/ba/bab093ba2af354496638140bb68de7d473dd215c.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -50c1bb50770dc14c539ccc1ba1762deb153f8cf2 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/bd/bd7bf351de353254abead31a09f14e0d87a0633f.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/bd/bd7bf351de353254abead31a09f14e0d87a0633f.svn-base.REMOVED.git-id deleted file mode 100644 index e2669c15..00000000 --- a/Old Matlab Interface/.svn/pristine/bd/bd7bf351de353254abead31a09f14e0d87a0633f.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7dae927baab0d4bcb8a8aa628b8afa7132bc59e5 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/bd/bd9cd5c53b27c190f63541df132b4b29f54b9dd9.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/bd/bd9cd5c53b27c190f63541df132b4b29f54b9dd9.svn-base.REMOVED.git-id deleted file mode 100644 index 9819de3b..00000000 --- a/Old Matlab Interface/.svn/pristine/bd/bd9cd5c53b27c190f63541df132b4b29f54b9dd9.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -420e7d70ebfa8f93a41532268d3dab2eb4aa86f0 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/bd/bdf7a339b44a37e42b34c1561828dd031f37f95a.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/bd/bdf7a339b44a37e42b34c1561828dd031f37f95a.svn-base.REMOVED.git-id deleted file mode 100644 index 5742e4b6..00000000 --- a/Old Matlab Interface/.svn/pristine/bd/bdf7a339b44a37e42b34c1561828dd031f37f95a.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3b4d0f57b541c79a8a9aaceab64bc06c3805aadb \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/c0/c08e2e1c5ccfc0f4c6ed2ba1fb5cde835ebf53b7.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/c0/c08e2e1c5ccfc0f4c6ed2ba1fb5cde835ebf53b7.svn-base.REMOVED.git-id deleted file mode 100644 index 38cd5e0b..00000000 --- a/Old Matlab Interface/.svn/pristine/c0/c08e2e1c5ccfc0f4c6ed2ba1fb5cde835ebf53b7.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -50d5d46d9a1b198918e80946f15dc62784d16399 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/c1/c16c7b18552b3fc8b2a52f6d5c6f5634ba03bcda.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/c1/c16c7b18552b3fc8b2a52f6d5c6f5634ba03bcda.svn-base.REMOVED.git-id deleted file mode 100644 index 1ff8df85..00000000 --- a/Old Matlab Interface/.svn/pristine/c1/c16c7b18552b3fc8b2a52f6d5c6f5634ba03bcda.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ca0f7a9f5b243193e99c44b3d4cbf7b4278513fa \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/c5/c55b35eb191bca8e58fbab3b4e69302308bdd0c3.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/c5/c55b35eb191bca8e58fbab3b4e69302308bdd0c3.svn-base.REMOVED.git-id deleted file mode 100644 index e201f611..00000000 --- a/Old Matlab Interface/.svn/pristine/c5/c55b35eb191bca8e58fbab3b4e69302308bdd0c3.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9188b95dbcbd750c1a906eb6720172d93b313a68 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/c5/c59f20e7cc2d121a4c984a45dd615e2cc84be5a7.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/c5/c59f20e7cc2d121a4c984a45dd615e2cc84be5a7.svn-base.REMOVED.git-id deleted file mode 100644 index 05766448..00000000 --- a/Old Matlab Interface/.svn/pristine/c5/c59f20e7cc2d121a4c984a45dd615e2cc84be5a7.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -db006a3fb8aeae9a7bdcb632ba5b1f00a7b76713 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/c7/c73ee86a3151a5652537a0cdf85eb2544c2ac2fc.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/c7/c73ee86a3151a5652537a0cdf85eb2544c2ac2fc.svn-base.REMOVED.git-id deleted file mode 100644 index 830f50cd..00000000 --- a/Old Matlab Interface/.svn/pristine/c7/c73ee86a3151a5652537a0cdf85eb2544c2ac2fc.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e0e93271a5c0253e3782bdc22680be47d04f762f \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/c8/c8241f8aa6cded21d2f4c182db3240c8c80f5acd.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/c8/c8241f8aa6cded21d2f4c182db3240c8c80f5acd.svn-base.REMOVED.git-id deleted file mode 100644 index d3654023..00000000 --- a/Old Matlab Interface/.svn/pristine/c8/c8241f8aa6cded21d2f4c182db3240c8c80f5acd.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c230e609a0096946c0f4da86c1c47c0b2b0832c2 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/c9/c911569ea160a4acb105a087c4c99a8133cc6ad2.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/c9/c911569ea160a4acb105a087c4c99a8133cc6ad2.svn-base.REMOVED.git-id deleted file mode 100644 index c4450b04..00000000 --- a/Old Matlab Interface/.svn/pristine/c9/c911569ea160a4acb105a087c4c99a8133cc6ad2.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5cbcae5a6e91a38d14dce3f789ab3508dc7c06b2 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/c9/c9d65d7d2ae53bd4e2a501d2b9e8a465681d039d.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/c9/c9d65d7d2ae53bd4e2a501d2b9e8a465681d039d.svn-base.REMOVED.git-id deleted file mode 100644 index 9de84a3e..00000000 --- a/Old Matlab Interface/.svn/pristine/c9/c9d65d7d2ae53bd4e2a501d2b9e8a465681d039d.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5e9d6a49e950c31020f427e41fc6a42290705524 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/c9/c9fc3943bb5e40c85ade2f8bd88314f327f40ec7.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/c9/c9fc3943bb5e40c85ade2f8bd88314f327f40ec7.svn-base.REMOVED.git-id deleted file mode 100644 index ff645e9f..00000000 --- a/Old Matlab Interface/.svn/pristine/c9/c9fc3943bb5e40c85ade2f8bd88314f327f40ec7.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2a030327369a56844c210c88339964120b6c7466 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/ca/ca5efeb46a4701590fffc385c7cc9f0f693389fc.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/ca/ca5efeb46a4701590fffc385c7cc9f0f693389fc.svn-base.REMOVED.git-id deleted file mode 100644 index 8ba23b29..00000000 --- a/Old Matlab Interface/.svn/pristine/ca/ca5efeb46a4701590fffc385c7cc9f0f693389fc.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8b904fc570ae13dd357f83a11ffaa1e6bec3950b \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/cb/cbd188d48e4202497c0f72bd16bb87da5ef6f2d1.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/cb/cbd188d48e4202497c0f72bd16bb87da5ef6f2d1.svn-base.REMOVED.git-id deleted file mode 100644 index f0c64bdf..00000000 --- a/Old Matlab Interface/.svn/pristine/cb/cbd188d48e4202497c0f72bd16bb87da5ef6f2d1.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a266b8268927ec11066eb44f2ade205a926fad98 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/ce/ce10b80357bb5082e5834e41bfc9d842f114f45b.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/ce/ce10b80357bb5082e5834e41bfc9d842f114f45b.svn-base.REMOVED.git-id deleted file mode 100644 index 6d86a1e0..00000000 --- a/Old Matlab Interface/.svn/pristine/ce/ce10b80357bb5082e5834e41bfc9d842f114f45b.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4ca6bb25c7f422a0b9b614f7a4fdd402c48300da \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/cf/cfed60fdfa127afcb252a0507c939b2e6d710f4a.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/cf/cfed60fdfa127afcb252a0507c939b2e6d710f4a.svn-base.REMOVED.git-id deleted file mode 100644 index fbf5521e..00000000 --- a/Old Matlab Interface/.svn/pristine/cf/cfed60fdfa127afcb252a0507c939b2e6d710f4a.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e343618943e9694cd66f4a4da0ca16c8d4f5cdf4 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/d0/d050cf2300644013dd8cb6702d7131635f651fd2.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/d0/d050cf2300644013dd8cb6702d7131635f651fd2.svn-base.REMOVED.git-id deleted file mode 100644 index a76ba082..00000000 --- a/Old Matlab Interface/.svn/pristine/d0/d050cf2300644013dd8cb6702d7131635f651fd2.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f20f18dea31b67c2b55a1b21508882403a6be68a \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/d2/d25c3322121da7330cfaba960c9517632a0ff944.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/d2/d25c3322121da7330cfaba960c9517632a0ff944.svn-base.REMOVED.git-id deleted file mode 100644 index c59c0ed0..00000000 --- a/Old Matlab Interface/.svn/pristine/d2/d25c3322121da7330cfaba960c9517632a0ff944.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a3f6e4223c01ec4b6452b8d6a6a030bf5fd8ec0b \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/d3/d35431714a5bc9b48fad9121b319978f5f34bed8.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/d3/d35431714a5bc9b48fad9121b319978f5f34bed8.svn-base.REMOVED.git-id deleted file mode 100644 index 05cbaff3..00000000 --- a/Old Matlab Interface/.svn/pristine/d3/d35431714a5bc9b48fad9121b319978f5f34bed8.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ffc7c41c304366375d648c90f0223c934fdbcf46 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/d6/d6cabc27537ccaf079a2064ef3b96519b25f6c85.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/d6/d6cabc27537ccaf079a2064ef3b96519b25f6c85.svn-base.REMOVED.git-id deleted file mode 100644 index 55240e85..00000000 --- a/Old Matlab Interface/.svn/pristine/d6/d6cabc27537ccaf079a2064ef3b96519b25f6c85.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5ad957744824f07674ade1e1d32cee83ddf7d208 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/da/da39a3ee5e6b4b0d3255bfef95601890afd80709.svn-base b/Old Matlab Interface/.svn/pristine/da/da39a3ee5e6b4b0d3255bfef95601890afd80709.svn-base deleted file mode 100644 index e69de29b..00000000 diff --git a/Old Matlab Interface/.svn/pristine/da/da866910c208578c2c480996b8f954aa1ab590a1.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/da/da866910c208578c2c480996b8f954aa1ab590a1.svn-base.REMOVED.git-id deleted file mode 100644 index d959cfd9..00000000 --- a/Old Matlab Interface/.svn/pristine/da/da866910c208578c2c480996b8f954aa1ab590a1.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4d5d74c26ef18251ff9aed9baa601354392ba703 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/db/db182b0d3ea5e048b3e869ea5f3010741accba03.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/db/db182b0d3ea5e048b3e869ea5f3010741accba03.svn-base.REMOVED.git-id deleted file mode 100644 index 85b1760d..00000000 --- a/Old Matlab Interface/.svn/pristine/db/db182b0d3ea5e048b3e869ea5f3010741accba03.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aa2829ac2b10a544df1687874b1f8b1095a2acc3 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/dc/dc51964367858a68e8535d6469dd458b6ba901bd.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/dc/dc51964367858a68e8535d6469dd458b6ba901bd.svn-base.REMOVED.git-id deleted file mode 100644 index 27708882..00000000 --- a/Old Matlab Interface/.svn/pristine/dc/dc51964367858a68e8535d6469dd458b6ba901bd.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -78bbdccdc7dea009c909c60d6a6ea67467325716 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/dd/dd80704ba87713ec4a22e4bc45c69cb28591c907.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/dd/dd80704ba87713ec4a22e4bc45c69cb28591c907.svn-base.REMOVED.git-id deleted file mode 100644 index 0cad0114..00000000 --- a/Old Matlab Interface/.svn/pristine/dd/dd80704ba87713ec4a22e4bc45c69cb28591c907.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -391ba9500d359887c9619b2ef2fa516c3548e003 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/dd/dde630d9e7c16214e15471c54bfb5e6f6a438efd.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/dd/dde630d9e7c16214e15471c54bfb5e6f6a438efd.svn-base.REMOVED.git-id deleted file mode 100644 index 6437e2ab..00000000 --- a/Old Matlab Interface/.svn/pristine/dd/dde630d9e7c16214e15471c54bfb5e6f6a438efd.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fae4ac323869d20e55b64822018d1064479f0109 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/de/de51647d95849ef82e410e841ad7472895a45c08.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/de/de51647d95849ef82e410e841ad7472895a45c08.svn-base.REMOVED.git-id deleted file mode 100644 index b7bef8c8..00000000 --- a/Old Matlab Interface/.svn/pristine/de/de51647d95849ef82e410e841ad7472895a45c08.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -be39bb28b7ea71787d75c643bd8229c7a04d601c \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/de/dee616359ba67ec117dffff180ca1669936f867a.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/de/dee616359ba67ec117dffff180ca1669936f867a.svn-base.REMOVED.git-id deleted file mode 100644 index 8d4ac1ff..00000000 --- a/Old Matlab Interface/.svn/pristine/de/dee616359ba67ec117dffff180ca1669936f867a.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0a2ec0f4cd0ab99387ca97bcc097499e924c8d23 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/df/df65a8a27c87f1048f63bf5425146ada309e0042.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/df/df65a8a27c87f1048f63bf5425146ada309e0042.svn-base.REMOVED.git-id deleted file mode 100644 index 8f10f3dc..00000000 --- a/Old Matlab Interface/.svn/pristine/df/df65a8a27c87f1048f63bf5425146ada309e0042.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -85f25b07fef5c4cf77b75db34d33b6d0ba06031e \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/df/dfc3cbd62eadfc9c19e1481956d39d3f78bcb631.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/df/dfc3cbd62eadfc9c19e1481956d39d3f78bcb631.svn-base.REMOVED.git-id deleted file mode 100644 index 2ed1da38..00000000 --- a/Old Matlab Interface/.svn/pristine/df/dfc3cbd62eadfc9c19e1481956d39d3f78bcb631.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -66fa3d1e6c95c4ad28ef89b0d5e514a14464ae13 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/e0/e00bd01aaeb4abbbaa963b83ef9b8fc9ff93c944.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/e0/e00bd01aaeb4abbbaa963b83ef9b8fc9ff93c944.svn-base.REMOVED.git-id deleted file mode 100644 index 83acfda7..00000000 --- a/Old Matlab Interface/.svn/pristine/e0/e00bd01aaeb4abbbaa963b83ef9b8fc9ff93c944.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -605b0244398cb10260e4d88c129774c1fbbcbef4 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/e3/e31bc70650fefc87ee8e537155c125d24f11c484.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/e3/e31bc70650fefc87ee8e537155c125d24f11c484.svn-base.REMOVED.git-id deleted file mode 100644 index 0eb24a64..00000000 --- a/Old Matlab Interface/.svn/pristine/e3/e31bc70650fefc87ee8e537155c125d24f11c484.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a506a2bddfc7388c19f5415e57115f9d19c99e9a \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/e7/e78c57614ab2a63318d6d6b1fcdde440f5f47cf9.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/e7/e78c57614ab2a63318d6d6b1fcdde440f5f47cf9.svn-base.REMOVED.git-id deleted file mode 100644 index d6385c49..00000000 --- a/Old Matlab Interface/.svn/pristine/e7/e78c57614ab2a63318d6d6b1fcdde440f5f47cf9.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aafd8f21450477ae1db4b34a6404254e29aa79e1 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/e8/e8395bc3b71c1792e8a9fe2b5896f8a263b73e57.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/e8/e8395bc3b71c1792e8a9fe2b5896f8a263b73e57.svn-base.REMOVED.git-id deleted file mode 100644 index 2fba024e..00000000 --- a/Old Matlab Interface/.svn/pristine/e8/e8395bc3b71c1792e8a9fe2b5896f8a263b73e57.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3e1285c0f7a587dcb0fdf67abc74dbd3e5eb45be \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/e9/e9c483bf05438060fe1bcbf50fec15e3e5f96514.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/e9/e9c483bf05438060fe1bcbf50fec15e3e5f96514.svn-base.REMOVED.git-id deleted file mode 100644 index e0697d63..00000000 --- a/Old Matlab Interface/.svn/pristine/e9/e9c483bf05438060fe1bcbf50fec15e3e5f96514.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fd8f2ffddf248bfc2fba5384666b6672455e60b5 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/ea/ea3ef4fbc860418881fc8e3efaef12369b1c858c.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/ea/ea3ef4fbc860418881fc8e3efaef12369b1c858c.svn-base.REMOVED.git-id deleted file mode 100644 index 8a615667..00000000 --- a/Old Matlab Interface/.svn/pristine/ea/ea3ef4fbc860418881fc8e3efaef12369b1c858c.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -808d2beaae550f506446893c1771020f3e42e430 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/ea/eac5f5e9f6f8cab74dcb0452c5173d2a1944ce01.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/ea/eac5f5e9f6f8cab74dcb0452c5173d2a1944ce01.svn-base.REMOVED.git-id deleted file mode 100644 index e6e10b53..00000000 --- a/Old Matlab Interface/.svn/pristine/ea/eac5f5e9f6f8cab74dcb0452c5173d2a1944ce01.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -522fc2be141bb6cbdea183c443c1bbb63ec40c36 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/ed/edbf362730f0f3d815f3b0ae22207cb7d9615695.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/ed/edbf362730f0f3d815f3b0ae22207cb7d9615695.svn-base.REMOVED.git-id deleted file mode 100644 index 64eb8325..00000000 --- a/Old Matlab Interface/.svn/pristine/ed/edbf362730f0f3d815f3b0ae22207cb7d9615695.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bdd2f7706a477d800d64a6905c06fd10dc7b0f16 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/ee/ee3c211940aae62be90eccd5e6da149da079ba7c.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/ee/ee3c211940aae62be90eccd5e6da149da079ba7c.svn-base.REMOVED.git-id deleted file mode 100644 index 93ee545a..00000000 --- a/Old Matlab Interface/.svn/pristine/ee/ee3c211940aae62be90eccd5e6da149da079ba7c.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -dc6152c71c5f8050d5f64451ac5692023d33d1a2 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/ef/efe4e6fc3b4b3682712980af8b94ae14cb294d33.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/ef/efe4e6fc3b4b3682712980af8b94ae14cb294d33.svn-base.REMOVED.git-id deleted file mode 100644 index d43090b3..00000000 --- a/Old Matlab Interface/.svn/pristine/ef/efe4e6fc3b4b3682712980af8b94ae14cb294d33.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -48d26bc8282b07ca9a394dea66c53e756cc75dcc \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f0/f09b1f3552567c912a993da851d7016c8481685b.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f0/f09b1f3552567c912a993da851d7016c8481685b.svn-base.REMOVED.git-id deleted file mode 100644 index debf5f40..00000000 --- a/Old Matlab Interface/.svn/pristine/f0/f09b1f3552567c912a993da851d7016c8481685b.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fe0a07942496794dcabe55cc2bb41b8dc1fe8de9 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f0/f0dcf1670d184c7e3efd7864797fd7b745b6bafc.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f0/f0dcf1670d184c7e3efd7864797fd7b745b6bafc.svn-base.REMOVED.git-id deleted file mode 100644 index 1455df63..00000000 --- a/Old Matlab Interface/.svn/pristine/f0/f0dcf1670d184c7e3efd7864797fd7b745b6bafc.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bac5f81b4b7c7358636ed45329651ea7bd92d647 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f1/f172784ffef766d0efe968a17adaac35c87924ff.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f1/f172784ffef766d0efe968a17adaac35c87924ff.svn-base.REMOVED.git-id deleted file mode 100644 index 98c0fa57..00000000 --- a/Old Matlab Interface/.svn/pristine/f1/f172784ffef766d0efe968a17adaac35c87924ff.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3a7cf3e2e4df3f531374fa61f6472c102baa7308 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f1/f187db5d81d807f7a4be8e690e725d8dd82fdb65.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f1/f187db5d81d807f7a4be8e690e725d8dd82fdb65.svn-base.REMOVED.git-id deleted file mode 100644 index 1398cb4b..00000000 --- a/Old Matlab Interface/.svn/pristine/f1/f187db5d81d807f7a4be8e690e725d8dd82fdb65.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d8e62241fc4220be3e459a3ce8d68727b2173fdb \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f1/f1fb5c24b06f5285a19173c9c4f834ea90ec5363.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f1/f1fb5c24b06f5285a19173c9c4f834ea90ec5363.svn-base.REMOVED.git-id deleted file mode 100644 index ce751ee8..00000000 --- a/Old Matlab Interface/.svn/pristine/f1/f1fb5c24b06f5285a19173c9c4f834ea90ec5363.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -df20690a1c499895428626c88ee3ca5e74d1d08d \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f2/f20e3547e49aa4c0b0d16561bfd892e6033fd46d.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f2/f20e3547e49aa4c0b0d16561bfd892e6033fd46d.svn-base.REMOVED.git-id deleted file mode 100644 index dac96ee5..00000000 --- a/Old Matlab Interface/.svn/pristine/f2/f20e3547e49aa4c0b0d16561bfd892e6033fd46d.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c8e9715427a40f8f94e73f22c51a28d012e00e11 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f2/f28f71d8657521632dd5fb0a70026a6ce407e60d.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f2/f28f71d8657521632dd5fb0a70026a6ce407e60d.svn-base.REMOVED.git-id deleted file mode 100644 index e583ba23..00000000 --- a/Old Matlab Interface/.svn/pristine/f2/f28f71d8657521632dd5fb0a70026a6ce407e60d.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -542cfdb9dcb6b63241e000a81f00cb0b870fbc4b \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f3/f3685fb5bb5629016249592d02bc3d60a4b72e50.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f3/f3685fb5bb5629016249592d02bc3d60a4b72e50.svn-base.REMOVED.git-id deleted file mode 100644 index 611158c6..00000000 --- a/Old Matlab Interface/.svn/pristine/f3/f3685fb5bb5629016249592d02bc3d60a4b72e50.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ab2a692dd8803712e73c6080517c03f77742988c \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f4/f48d51886747a7bb88daf54ea7b7aa914607f5dd.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f4/f48d51886747a7bb88daf54ea7b7aa914607f5dd.svn-base.REMOVED.git-id deleted file mode 100644 index 5f27e626..00000000 --- a/Old Matlab Interface/.svn/pristine/f4/f48d51886747a7bb88daf54ea7b7aa914607f5dd.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -64876bbdfd6d08dc6f34450ef8e5886e64745649 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f4/f4dda42d5cff055dd900dc56988ee4a55c7431e2.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f4/f4dda42d5cff055dd900dc56988ee4a55c7431e2.svn-base.REMOVED.git-id deleted file mode 100644 index 124126ad..00000000 --- a/Old Matlab Interface/.svn/pristine/f4/f4dda42d5cff055dd900dc56988ee4a55c7431e2.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7f2cb1cf25a8c212ea0074dc181d414fb67b8263 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f5/f558604348185cbfa01f7a96be6c925909d79515.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f5/f558604348185cbfa01f7a96be6c925909d79515.svn-base.REMOVED.git-id deleted file mode 100644 index 355dae73..00000000 --- a/Old Matlab Interface/.svn/pristine/f5/f558604348185cbfa01f7a96be6c925909d79515.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -baf03dbe2d0df5195360bfdd533d0df510fda273 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f7/f701f327c83d2ffcf07fb071e5c135e223413720.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f7/f701f327c83d2ffcf07fb071e5c135e223413720.svn-base.REMOVED.git-id deleted file mode 100644 index a1cdd61f..00000000 --- a/Old Matlab Interface/.svn/pristine/f7/f701f327c83d2ffcf07fb071e5c135e223413720.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8b63a44819563923aa8e56e50567912043dc9e21 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f7/f721594f8b78f89886bccf09b4b52038dfe1b0db.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f7/f721594f8b78f89886bccf09b4b52038dfe1b0db.svn-base.REMOVED.git-id deleted file mode 100644 index 965f3ad6..00000000 --- a/Old Matlab Interface/.svn/pristine/f7/f721594f8b78f89886bccf09b4b52038dfe1b0db.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9862dab08cdbad46b889bce9278b33943543275b \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f8/f854b5c665bc7738d913c722a7dd3991befe68a2.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f8/f854b5c665bc7738d913c722a7dd3991befe68a2.svn-base.REMOVED.git-id deleted file mode 100644 index 90888e1b..00000000 --- a/Old Matlab Interface/.svn/pristine/f8/f854b5c665bc7738d913c722a7dd3991befe68a2.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -af3aec855fdf51e79d2503a70733facd72a25a22 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/f8/f89ac51bd77fc899b6f8fe81d7957e17659037cd.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/f8/f89ac51bd77fc899b6f8fe81d7957e17659037cd.svn-base.REMOVED.git-id deleted file mode 100644 index 9afbcccb..00000000 --- a/Old Matlab Interface/.svn/pristine/f8/f89ac51bd77fc899b6f8fe81d7957e17659037cd.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d471ccea6ee6628110ac88777d9ee63e013660fb \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/fa/fa8489441ac82d22567b5c3d5b494576df54f37d.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/fa/fa8489441ac82d22567b5c3d5b494576df54f37d.svn-base.REMOVED.git-id deleted file mode 100644 index 6bfd6c15..00000000 --- a/Old Matlab Interface/.svn/pristine/fa/fa8489441ac82d22567b5c3d5b494576df54f37d.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d8112b9e825d4ea9ab0ee96685aa18b02ab58e4f \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/fb/fb204cea8eb501738d9e4ec41eb60316a3896b12.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/fb/fb204cea8eb501738d9e4ec41eb60316a3896b12.svn-base.REMOVED.git-id deleted file mode 100644 index c9d0952f..00000000 --- a/Old Matlab Interface/.svn/pristine/fb/fb204cea8eb501738d9e4ec41eb60316a3896b12.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6b77b17dcb6e0c3a839fa567ef4883572fb13b96 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/fb/fb57921a14cfc57fcfdc9ae090915910e58b90e4.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/fb/fb57921a14cfc57fcfdc9ae090915910e58b90e4.svn-base.REMOVED.git-id deleted file mode 100644 index 85456ba7..00000000 --- a/Old Matlab Interface/.svn/pristine/fb/fb57921a14cfc57fcfdc9ae090915910e58b90e4.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -20150cf90cadb8e8454c157b0f9a86b1ca6f7ddc \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/fb/fb80c8c407241aa3266ea0297d0973b4109368c7.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/fb/fb80c8c407241aa3266ea0297d0973b4109368c7.svn-base.REMOVED.git-id deleted file mode 100644 index 49a39a71..00000000 --- a/Old Matlab Interface/.svn/pristine/fb/fb80c8c407241aa3266ea0297d0973b4109368c7.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f3f072247d640f83b52e6513c5ebabea45fbff41 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/fb/fbaab675ab97abde1c3353748e9f3d129bd92023.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/fb/fbaab675ab97abde1c3353748e9f3d129bd92023.svn-base.REMOVED.git-id deleted file mode 100644 index 1cadebcf..00000000 --- a/Old Matlab Interface/.svn/pristine/fb/fbaab675ab97abde1c3353748e9f3d129bd92023.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c5b23ee75d5f0d3e5d9de4d7e3f88261b533e1bc \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/fc/fc2350e45b0c7bdac7ac35f42b65f5fdfd622464.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/fc/fc2350e45b0c7bdac7ac35f42b65f5fdfd622464.svn-base.REMOVED.git-id deleted file mode 100644 index 14163cc7..00000000 --- a/Old Matlab Interface/.svn/pristine/fc/fc2350e45b0c7bdac7ac35f42b65f5fdfd622464.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0d41062911fabaa111324b1e7887ccee4f491000 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/fc/fc253270c36a209bcb1a8a7efc73b7bc27c5dec6.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/fc/fc253270c36a209bcb1a8a7efc73b7bc27c5dec6.svn-base.REMOVED.git-id deleted file mode 100644 index fef6af8d..00000000 --- a/Old Matlab Interface/.svn/pristine/fc/fc253270c36a209bcb1a8a7efc73b7bc27c5dec6.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b733556e4cec21e799033b503666737b87c67039 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/fe/fec3f9b96c660796ba167efb57158c7afe7d751e.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/fe/fec3f9b96c660796ba167efb57158c7afe7d751e.svn-base.REMOVED.git-id deleted file mode 100644 index 27a279a4..00000000 --- a/Old Matlab Interface/.svn/pristine/fe/fec3f9b96c660796ba167efb57158c7afe7d751e.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0e43a803c20310a795d9778dea7ab4827364daaa \ No newline at end of file diff --git a/Old Matlab Interface/.svn/pristine/fe/fed3c95fe8e06ff11d5eaaafdea8c28f8c7577ed.svn-base.REMOVED.git-id b/Old Matlab Interface/.svn/pristine/fe/fed3c95fe8e06ff11d5eaaafdea8c28f8c7577ed.svn-base.REMOVED.git-id deleted file mode 100644 index 5e0381e8..00000000 --- a/Old Matlab Interface/.svn/pristine/fe/fed3c95fe8e06ff11d5eaaafdea8c28f8c7577ed.svn-base.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4cabd8c0374aa1ca34f36c143f476a5882feb4a1 \ No newline at end of file diff --git a/Old Matlab Interface/.svn/wc.db.REMOVED.git-id b/Old Matlab Interface/.svn/wc.db.REMOVED.git-id deleted file mode 100644 index 8ef2c6d1..00000000 --- a/Old Matlab Interface/.svn/wc.db.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a2b294875d161ce501ac72d9150ea4ee988c7dc0 \ No newline at end of file diff --git a/Old Matlab Interface/GUIDE/figstate.m.REMOVED.git-id b/Old Matlab Interface/GUIDE/figstate.m.REMOVED.git-id deleted file mode 100644 index 43331493..00000000 --- a/Old Matlab Interface/GUIDE/figstate.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8b4645c79f291896498d477a57d1773507e9eecb \ No newline at end of file diff --git a/Old Matlab Interface/GUIDE/figstate.p.REMOVED.git-id b/Old Matlab Interface/GUIDE/figstate.p.REMOVED.git-id deleted file mode 100644 index fc20db98..00000000 --- a/Old Matlab Interface/GUIDE/figstate.p.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9108f9cbc8ebae2ea71c264932c4745df9135df2 \ No newline at end of file diff --git a/Old Matlab Interface/GUIDE/figstate_7a.p.REMOVED.git-id b/Old Matlab Interface/GUIDE/figstate_7a.p.REMOVED.git-id deleted file mode 100644 index c74f411d..00000000 --- a/Old Matlab Interface/GUIDE/figstate_7a.p.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0c8f63ccdefb03bbd30929c0c4987cbce9fc9557 \ No newline at end of file diff --git a/Old Matlab Interface/GUIDE/launchgui.m b/Old Matlab Interface/GUIDE/launchgui.m deleted file mode 100644 index e69de29b..00000000 diff --git a/Old Matlab Interface/GUIDE/maxfig.m.REMOVED.git-id b/Old Matlab Interface/GUIDE/maxfig.m.REMOVED.git-id deleted file mode 100644 index 1c6213ee..00000000 --- a/Old Matlab Interface/GUIDE/maxfig.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -69d31ae51d3772c668ea7bddb67c161f7211b7a7 \ No newline at end of file diff --git a/Old Matlab Interface/GUIDE/maxfig.p.REMOVED.git-id b/Old Matlab Interface/GUIDE/maxfig.p.REMOVED.git-id deleted file mode 100644 index 2ed1da38..00000000 --- a/Old Matlab Interface/GUIDE/maxfig.p.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -66fa3d1e6c95c4ad28ef89b0d5e514a14464ae13 \ No newline at end of file diff --git a/Old Matlab Interface/GUIDE/maxfig_7a.p.REMOVED.git-id b/Old Matlab Interface/GUIDE/maxfig_7a.p.REMOVED.git-id deleted file mode 100644 index 267cdb2c..00000000 --- a/Old Matlab Interface/GUIDE/maxfig_7a.p.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e24371147c5c261ed171450b03a67fb3b34b9b84 \ No newline at end of file diff --git a/Old Matlab Interface/GUIDE/minfig.m.REMOVED.git-id b/Old Matlab Interface/GUIDE/minfig.m.REMOVED.git-id deleted file mode 100644 index 35f60002..00000000 --- a/Old Matlab Interface/GUIDE/minfig.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fff68b837797c41d8f82a911a866efc8fac3b93e \ No newline at end of file diff --git a/Old Matlab Interface/GUIDE/minfig.p.REMOVED.git-id b/Old Matlab Interface/GUIDE/minfig.p.REMOVED.git-id deleted file mode 100644 index 619d0f53..00000000 --- a/Old Matlab Interface/GUIDE/minfig.p.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e236095849bbbff3d13c8a544e7c2fbf11e4c6e1 \ No newline at end of file diff --git a/Old Matlab Interface/GUIDE/untitled.fig.REMOVED.git-id b/Old Matlab Interface/GUIDE/untitled.fig.REMOVED.git-id deleted file mode 100644 index 05cbaff3..00000000 --- a/Old Matlab Interface/GUIDE/untitled.fig.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ffc7c41c304366375d648c90f0223c934fdbcf46 \ No newline at end of file diff --git a/Old Matlab Interface/GUIDE/untitled.m.REMOVED.git-id b/Old Matlab Interface/GUIDE/untitled.m.REMOVED.git-id deleted file mode 100644 index 965f3ad6..00000000 --- a/Old Matlab Interface/GUIDE/untitled.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9862dab08cdbad46b889bce9278b33943543275b \ No newline at end of file diff --git a/Old Matlab Interface/HelloWorld.exe.REMOVED.git-id b/Old Matlab Interface/HelloWorld.exe.REMOVED.git-id deleted file mode 100644 index c8cf847b..00000000 --- a/Old Matlab Interface/HelloWorld.exe.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7ac51320b9d104b06b06c75d84b5201fea80e0db \ No newline at end of file diff --git a/Old Matlab Interface/ISOLOOPTEST.m.REMOVED.git-id b/Old Matlab Interface/ISOLOOPTEST.m.REMOVED.git-id deleted file mode 100644 index 2af42938..00000000 --- a/Old Matlab Interface/ISOLOOPTEST.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a93e068ed0cf56b3dc1737ff30f1726c2ae1e11a \ No newline at end of file diff --git a/Old Matlab Interface/MYFIRSTWAVEFORM.txt.REMOVED.git-id b/Old Matlab Interface/MYFIRSTWAVEFORM.txt.REMOVED.git-id deleted file mode 100644 index a94bc484..00000000 --- a/Old Matlab Interface/MYFIRSTWAVEFORM.txt.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b1a4e14a00715f44b58d14cba4b482809adb0527 \ No newline at end of file diff --git a/Old Matlab Interface/MYFIRSTWAVEFORM_CLEANED.txt.REMOVED.git-id b/Old Matlab Interface/MYFIRSTWAVEFORM_CLEANED.txt.REMOVED.git-id deleted file mode 100644 index a974a754..00000000 --- a/Old Matlab Interface/MYFIRSTWAVEFORM_CLEANED.txt.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -01b9ce836a6cc856b5a8fe97c2b08c9e9a2870b6 \ No newline at end of file diff --git a/Old Matlab Interface/USB_CTRL_SEND.c.REMOVED.git-id b/Old Matlab Interface/USB_CTRL_SEND.c.REMOVED.git-id deleted file mode 100644 index 35c789a6..00000000 --- a/Old Matlab Interface/USB_CTRL_SEND.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -23b6868b2695a4a09da11d560fc985db7cd40b02 \ No newline at end of file diff --git a/Old Matlab Interface/USB_CTRL_SEND.mexw64.REMOVED.git-id b/Old Matlab Interface/USB_CTRL_SEND.mexw64.REMOVED.git-id deleted file mode 100644 index 3ec21d86..00000000 --- a/Old Matlab Interface/USB_CTRL_SEND.mexw64.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6e220f23e6c31084f0e19b359c82da98a43677c2 \ No newline at end of file diff --git a/Old Matlab Interface/USB_INIT.c.REMOVED.git-id b/Old Matlab Interface/USB_INIT.c.REMOVED.git-id deleted file mode 100644 index 5349f9fe..00000000 --- a/Old Matlab Interface/USB_INIT.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -de01e97f1142e35fecf28aa28a12708580495a69 \ No newline at end of file diff --git a/Old Matlab Interface/USB_INIT.mexw64.REMOVED.git-id b/Old Matlab Interface/USB_INIT.mexw64.REMOVED.git-id deleted file mode 100644 index eda0c526..00000000 --- a/Old Matlab Interface/USB_INIT.mexw64.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6bc5513127c9cba09384c151d6b164ce42c2e65d \ No newline at end of file diff --git a/Old Matlab Interface/USB_ISO_INIT.c.REMOVED.git-id b/Old Matlab Interface/USB_ISO_INIT.c.REMOVED.git-id deleted file mode 100644 index 4c53bfa6..00000000 --- a/Old Matlab Interface/USB_ISO_INIT.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -47bf668bda90088e41a9dd8831c08016f2ac2bd4 \ No newline at end of file diff --git a/Old Matlab Interface/USB_ISO_INIT.mexw64.REMOVED.git-id b/Old Matlab Interface/USB_ISO_INIT.mexw64.REMOVED.git-id deleted file mode 100644 index 07bc9077..00000000 --- a/Old Matlab Interface/USB_ISO_INIT.mexw64.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4646c4f382d5b11b2028f67f67878c9603a473c9 \ No newline at end of file diff --git a/Old Matlab Interface/USB_ISO_LOOP.c.REMOVED.git-id b/Old Matlab Interface/USB_ISO_LOOP.c.REMOVED.git-id deleted file mode 100644 index a1cdd61f..00000000 --- a/Old Matlab Interface/USB_ISO_LOOP.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8b63a44819563923aa8e56e50567912043dc9e21 \ No newline at end of file diff --git a/Old Matlab Interface/USB_ISO_LOOP.mexw64.REMOVED.git-id b/Old Matlab Interface/USB_ISO_LOOP.mexw64.REMOVED.git-id deleted file mode 100644 index 63930c46..00000000 --- a/Old Matlab Interface/USB_ISO_LOOP.mexw64.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1768fc8067eeeb48f53e2f2901408278ee6f1308 \ No newline at end of file diff --git a/Old Matlab Interface/USB_POOL_FREE.c.REMOVED.git-id b/Old Matlab Interface/USB_POOL_FREE.c.REMOVED.git-id deleted file mode 100644 index 57c931f8..00000000 --- a/Old Matlab Interface/USB_POOL_FREE.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5a34b87123d6edfe73309908e76dfddfd7ede633 \ No newline at end of file diff --git a/Old Matlab Interface/USB_POOL_FREE.mexw64.REMOVED.git-id b/Old Matlab Interface/USB_POOL_FREE.mexw64.REMOVED.git-id deleted file mode 100644 index 51568d3a..00000000 --- a/Old Matlab Interface/USB_POOL_FREE.mexw64.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -00a8590e157f59889c5042113d70643d065e86c6 \ No newline at end of file diff --git a/Old Matlab Interface/amp2bin.m.REMOVED.git-id b/Old Matlab Interface/amp2bin.m.REMOVED.git-id deleted file mode 100644 index 4b9051c0..00000000 --- a/Old Matlab Interface/amp2bin.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4fa40c653d963c37525f2125cc0e36ae8c60a097 \ No newline at end of file diff --git a/Old Matlab Interface/autogain.m.REMOVED.git-id b/Old Matlab Interface/autogain.m.REMOVED.git-id deleted file mode 100644 index 75b58992..00000000 --- a/Old Matlab Interface/autogain.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bea05bdcf95c05709e3a4e365c572720b6be3e3c \ No newline at end of file diff --git a/Old Matlab Interface/avrbreak.m.REMOVED.git-id b/Old Matlab Interface/avrbreak.m.REMOVED.git-id deleted file mode 100644 index 7e4ab0c5..00000000 --- a/Old Matlab Interface/avrbreak.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -400c2b7c163b76767f8d6ace4dbd7e7b74f44e3b \ No newline at end of file diff --git a/Old Matlab Interface/avrbreakcl.m.REMOVED.git-id b/Old Matlab Interface/avrbreakcl.m.REMOVED.git-id deleted file mode 100644 index c3748347..00000000 --- a/Old Matlab Interface/avrbreakcl.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -49b1b90919ebeec8bf06125a05982c91283658bc \ No newline at end of file diff --git a/Old Matlab Interface/axes1_ButtonDownFcn.m.REMOVED.git-id b/Old Matlab Interface/axes1_ButtonDownFcn.m.REMOVED.git-id deleted file mode 100644 index f2b9885c..00000000 --- a/Old Matlab Interface/axes1_ButtonDownFcn.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e6dc52545f5b33f65fe9ad12e5d69c8811c55366 \ No newline at end of file diff --git a/Old Matlab Interface/bin/dll/amd64/libusbK.dll.REMOVED.git-id b/Old Matlab Interface/bin/dll/amd64/libusbK.dll.REMOVED.git-id deleted file mode 100644 index 6bfd6c15..00000000 --- a/Old Matlab Interface/bin/dll/amd64/libusbK.dll.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d8112b9e825d4ea9ab0ee96685aa18b02ab58e4f \ No newline at end of file diff --git a/Old Matlab Interface/bin/dll/ia64/libusbK.dll.REMOVED.git-id b/Old Matlab Interface/bin/dll/ia64/libusbK.dll.REMOVED.git-id deleted file mode 100644 index 43c32a95..00000000 --- a/Old Matlab Interface/bin/dll/ia64/libusbK.dll.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -717244d59d3388a7d0c61611fe09dfcbc16506b8 \ No newline at end of file diff --git a/Old Matlab Interface/bin/dll/x86/libusbK.dll.REMOVED.git-id b/Old Matlab Interface/bin/dll/x86/libusbK.dll.REMOVED.git-id deleted file mode 100644 index 14163cc7..00000000 --- a/Old Matlab Interface/bin/dll/x86/libusbK.dll.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0d41062911fabaa111324b1e7887ccee4f491000 \ No newline at end of file diff --git a/Old Matlab Interface/bin/lib/amd64/libusbK.lib.REMOVED.git-id b/Old Matlab Interface/bin/lib/amd64/libusbK.lib.REMOVED.git-id deleted file mode 100644 index 84f7a367..00000000 --- a/Old Matlab Interface/bin/lib/amd64/libusbK.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c8358a402616820ce03836fde9ec66d91c8f0293 \ No newline at end of file diff --git a/Old Matlab Interface/bin/lib/ia64/libusbK.lib.REMOVED.git-id b/Old Matlab Interface/bin/lib/ia64/libusbK.lib.REMOVED.git-id deleted file mode 100644 index f3b6f802..00000000 --- a/Old Matlab Interface/bin/lib/ia64/libusbK.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b8bdd81676ebb6d619fc044141a7fa6b07465f60 \ No newline at end of file diff --git a/Old Matlab Interface/bin/lib/static/amd64/libusbK.lib.REMOVED.git-id b/Old Matlab Interface/bin/lib/static/amd64/libusbK.lib.REMOVED.git-id deleted file mode 100644 index a76ba082..00000000 --- a/Old Matlab Interface/bin/lib/static/amd64/libusbK.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f20f18dea31b67c2b55a1b21508882403a6be68a \ No newline at end of file diff --git a/Old Matlab Interface/bin/lib/static/ia64/libusbK.lib.REMOVED.git-id b/Old Matlab Interface/bin/lib/static/ia64/libusbK.lib.REMOVED.git-id deleted file mode 100644 index 27a279a4..00000000 --- a/Old Matlab Interface/bin/lib/static/ia64/libusbK.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0e43a803c20310a795d9778dea7ab4827364daaa \ No newline at end of file diff --git a/Old Matlab Interface/bin/lib/static/x86/libusbK.lib.REMOVED.git-id b/Old Matlab Interface/bin/lib/static/x86/libusbK.lib.REMOVED.git-id deleted file mode 100644 index 2c585758..00000000 --- a/Old Matlab Interface/bin/lib/static/x86/libusbK.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f5ccfdfb550ef5608c7faac6769f63905ab5b927 \ No newline at end of file diff --git a/Old Matlab Interface/bin/lib/x86/libusbK.lib.REMOVED.git-id b/Old Matlab Interface/bin/lib/x86/libusbK.lib.REMOVED.git-id deleted file mode 100644 index 1fa8e8a2..00000000 --- a/Old Matlab Interface/bin/lib/x86/libusbK.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2f390040f2c3f79b8dafb442c993ac36e2f6dc26 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/BenchmarkTestDevice.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/BenchmarkTestDevice.cs.REMOVED.git-id deleted file mode 100644 index 71fdf9d0..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/BenchmarkTestDevice.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7eeeaa55680e26d316c94f6d028ff338d2fca3c9 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Handle.Test.csproj.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Handle.Test.csproj.REMOVED.git-id deleted file mode 100644 index a9094385..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Handle.Test.csproj.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -acc8fef190b6ec148c9cb702a566cc0f64ad2718 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Program.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Program.cs.REMOVED.git-id deleted file mode 100644 index 6876816c..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Program.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c361e69d0f58c1880f3f4844dcfaaf9f4395519a \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/AssemblyInfo.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/AssemblyInfo.cs.REMOVED.git-id deleted file mode 100644 index 0c3dd62d..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/AssemblyInfo.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7e54ebd918c087ffb73de536166c5fc8831b2d2b \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/Resources.Designer.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/Resources.Designer.cs.REMOVED.git-id deleted file mode 100644 index debf5f40..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/Resources.Designer.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fe0a07942496794dcabe55cc2bb41b8dc1fe8de9 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/Resources.resx.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/Resources.resx.REMOVED.git-id deleted file mode 100644 index f3dbd193..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/Resources.resx.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -af7dbebbacef595e3089c01c05671016c21a8304 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/Settings.Designer.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/Settings.Designer.cs.REMOVED.git-id deleted file mode 100644 index b38643cb..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/Settings.Designer.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9beca6a8bb5f64cb65d854d6344dff409ca274b5 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/Settings.settings.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/Settings.settings.REMOVED.git-id deleted file mode 100644 index bb199510..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/Properties/Settings.settings.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -39645652af62950ebf3b28ec3a5400dcec30b1c4 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/TextBoxTraceListener.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Handle.Test/TextBoxTraceListener.cs.REMOVED.git-id deleted file mode 100644 index e83a7468..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/TextBoxTraceListener.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -53654e97afad0c4edce0bc20d1a93e8009a2c6f1 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/fHandleTest.Designer.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Handle.Test/fHandleTest.Designer.cs.REMOVED.git-id deleted file mode 100644 index b44cc427..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/fHandleTest.Designer.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b2be80470c157c93a0accd10759cc94203eebc16 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/fHandleTest.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Handle.Test/fHandleTest.cs.REMOVED.git-id deleted file mode 100644 index 2ba2ba3f..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/fHandleTest.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f6623d605e2f3c67a8ccbb65ad45a11e4f98db04 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/fHandleTest.resx.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Handle.Test/fHandleTest.resx.REMOVED.git-id deleted file mode 100644 index 9491d87f..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Handle.Test/fHandleTest.resx.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -541af56ee228f1e5df3d2a1a9b52e0d6d70f8d1c \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/HiPerfTimer.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/HiPerfTimer.cs.REMOVED.git-id deleted file mode 100644 index 8958dd78..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/HiPerfTimer.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d81057dd7db630d6342743103cdcc436f2ddea7d \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Form1.Designer.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Form1.Designer.cs.REMOVED.git-id deleted file mode 100644 index f0c64bdf..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Form1.Designer.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a266b8268927ec11066eb44f2ade205a926fad98 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Form1.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Form1.cs.REMOVED.git-id deleted file mode 100644 index d3b7cfe4..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Form1.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -339bc805e8ad8a5b1bc3cd13073c8467818ea013 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Form1.resx.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Form1.resx.REMOVED.git-id deleted file mode 100644 index bf826dea..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Form1.resx.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f5b0ea0cf061c25b145fecdf0d6d728b2856525b \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Hot.Plug.Detect.GUI.csproj.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Hot.Plug.Detect.GUI.csproj.REMOVED.git-id deleted file mode 100644 index 98144807..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Hot.Plug.Detect.GUI.csproj.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -20ca2cfe5c773bd5f92009831c62f3fe62dbeae1 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Program.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Program.cs.REMOVED.git-id deleted file mode 100644 index 117c1b51..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Program.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7e23f28d943734718a670e2100bea3f72040f574 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/AssemblyInfo.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/AssemblyInfo.cs.REMOVED.git-id deleted file mode 100644 index c59c0ed0..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/AssemblyInfo.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a3f6e4223c01ec4b6452b8d6a6a030bf5fd8ec0b \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/Resources.Designer.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/Resources.Designer.cs.REMOVED.git-id deleted file mode 100644 index 844bd158..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/Resources.Designer.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -910ca72bbf02d1103692ab58ed45b91d737a224f \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/Resources.resx.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/Resources.resx.REMOVED.git-id deleted file mode 100644 index f3dbd193..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/Resources.resx.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -af7dbebbacef595e3089c01c05671016c21a8304 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/Settings.Designer.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/Settings.Designer.cs.REMOVED.git-id deleted file mode 100644 index db187309..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/Settings.Designer.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -276ddd0af705a850997ddc5908bf50e1f702f0eb \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/Settings.settings.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/Settings.settings.REMOVED.git-id deleted file mode 100644 index bb199510..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect.GUI/Properties/Settings.settings.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -39645652af62950ebf3b28ec3a5400dcec30b1c4 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect/Hot.Plug.Detect.csproj.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect/Hot.Plug.Detect.csproj.REMOVED.git-id deleted file mode 100644 index 355dae73..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect/Hot.Plug.Detect.csproj.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -baf03dbe2d0df5195360bfdd533d0df510fda273 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect/Program.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect/Program.cs.REMOVED.git-id deleted file mode 100644 index edd5248a..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect/Program.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6dbbd773a7f3c4bb55b1de93bffa2e67dad26a0e \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect/Properties/AssemblyInfo.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect/Properties/AssemblyInfo.cs.REMOVED.git-id deleted file mode 100644 index cfe81dd0..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Hot.Plug.Detect/Properties/AssemblyInfo.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -252ebda40efe7f17c7f0a51a274088f1c0305a5c \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/List.Devices/List.Devices.csproj.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/List.Devices/List.Devices.csproj.REMOVED.git-id deleted file mode 100644 index 4e1ff61c..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/List.Devices/List.Devices.csproj.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bbca8d486e83995ebeb813b9e55220bf0b63ec26 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/List.Devices/Program.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/List.Devices/Program.cs.REMOVED.git-id deleted file mode 100644 index d959cfd9..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/List.Devices/Program.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4d5d74c26ef18251ff9aed9baa601354392ba703 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/List.Devices/Properties/AssemblyInfo.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/List.Devices/Properties/AssemblyInfo.cs.REMOVED.git-id deleted file mode 100644 index 64eb8325..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/List.Devices/Properties/AssemblyInfo.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bdd2f7706a477d800d64a6905c06fd10dc7b0f16 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Read.Isochronous/Program.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Read.Isochronous/Program.cs.REMOVED.git-id deleted file mode 100644 index 6437e2ab..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Read.Isochronous/Program.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fae4ac323869d20e55b64822018d1064479f0109 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Read.Isochronous/Properties/AssemblyInfo.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Read.Isochronous/Properties/AssemblyInfo.cs.REMOVED.git-id deleted file mode 100644 index c9d0952f..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Read.Isochronous/Properties/AssemblyInfo.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6b77b17dcb6e0c3a839fa567ef4883572fb13b96 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Read.Isochronous/Read.Isochronous.csproj.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Read.Isochronous/Read.Isochronous.csproj.REMOVED.git-id deleted file mode 100644 index a046b7f2..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Read.Isochronous/Read.Isochronous.csproj.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6f1e8d3020e185bf1167ee105a3a949a94c93be3 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Read.Isochronous/app.config.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Read.Isochronous/app.config.REMOVED.git-id deleted file mode 100644 index ce751ee8..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Read.Isochronous/app.config.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -df20690a1c499895428626c88ee3ca5e74d1d08d \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/TestParameters.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/TestParameters.cs.REMOVED.git-id deleted file mode 100644 index 599f026f..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/TestParameters.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -462e7ecd870da210ff9cb712ea23a787e8931aa9 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Xfer.Async/Program.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Xfer.Async/Program.cs.REMOVED.git-id deleted file mode 100644 index 6d0c4930..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Xfer.Async/Program.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0ba3803006dfa360dfab621e9a376f7aac13392b \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Xfer.Async/Properties/AssemblyInfo.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Xfer.Async/Properties/AssemblyInfo.cs.REMOVED.git-id deleted file mode 100644 index 9de84a3e..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Xfer.Async/Properties/AssemblyInfo.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5e9d6a49e950c31020f427e41fc6a42290705524 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Xfer.Async/Xfer.Async.csproj.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Xfer.Async/Xfer.Async.csproj.REMOVED.git-id deleted file mode 100644 index b8ab0634..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Xfer.Async/Xfer.Async.csproj.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cdb959ec63bfffc20ef366b8795256851e53e38a \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Xfer.Sync/Program.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Xfer.Sync/Program.cs.REMOVED.git-id deleted file mode 100644 index e8580a54..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Xfer.Sync/Program.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -02a976c5defd3120bc01475570fd321dddf80194 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Xfer.Sync/Properties/AssemblyInfo.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Xfer.Sync/Properties/AssemblyInfo.cs.REMOVED.git-id deleted file mode 100644 index b301c879..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Xfer.Sync/Properties/AssemblyInfo.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1be234aba825c981dc9f9e607e82846cd927a349 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Xfer.Sync/Xfer.Sync.csproj.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Xfer.Sync/Xfer.Sync.csproj.REMOVED.git-id deleted file mode 100644 index b68b34db..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Xfer.Sync/Xfer.Sync.csproj.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1479c989413bdf6aabc54e3ef32f65a2a942c1fc \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Xfer.Threaded.Stream/Program.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Xfer.Threaded.Stream/Program.cs.REMOVED.git-id deleted file mode 100644 index dac96ee5..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Xfer.Threaded.Stream/Program.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c8e9715427a40f8f94e73f22c51a28d012e00e11 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Xfer.Threaded.Stream/Properties/AssemblyInfo.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Xfer.Threaded.Stream/Properties/AssemblyInfo.cs.REMOVED.git-id deleted file mode 100644 index 3e794884..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Xfer.Threaded.Stream/Properties/AssemblyInfo.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ddc00a05e2e65dc3560e0686d92739749a1cff34 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Xfer.Threaded.Stream/Xfer.Stm.csproj.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Xfer.Threaded.Stream/Xfer.Stm.csproj.REMOVED.git-id deleted file mode 100644 index 777b1fdc..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Xfer.Threaded.Stream/Xfer.Stm.csproj.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -84b1c5d3d8c969566dd7ba6ad706b90af055c762 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Xfer.UsbStream/Program.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Xfer.UsbStream/Program.cs.REMOVED.git-id deleted file mode 100644 index 45d23606..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Xfer.UsbStream/Program.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -448c3b1d09507a0159e394513cd71fba1a707413 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Xfer.UsbStream/Properties/AssemblyInfo.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Xfer.UsbStream/Properties/AssemblyInfo.cs.REMOVED.git-id deleted file mode 100644 index b7bef8c8..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Xfer.UsbStream/Properties/AssemblyInfo.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -be39bb28b7ea71787d75c643bd8229c7a04d601c \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Xfer.UsbStream/UsbStream.cs.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Xfer.UsbStream/UsbStream.cs.REMOVED.git-id deleted file mode 100644 index 592e77dc..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Xfer.UsbStream/UsbStream.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4280bc3ce10a5bf77d49db8ab253694608ec217d \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/Xfer.UsbStream/Xfer.UsbStream.csproj.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/Xfer.UsbStream/Xfer.UsbStream.csproj.REMOVED.git-id deleted file mode 100644 index d3654023..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/Xfer.UsbStream/Xfer.UsbStream.csproj.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c230e609a0096946c0f4da86c1c47c0b2b0832c2 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_csharp/libusbK_Examples.sln.REMOVED.git-id b/Old Matlab Interface/bindings/examples_csharp/libusbK_Examples.sln.REMOVED.git-id deleted file mode 100644 index eac35bf4..00000000 --- a/Old Matlab Interface/bindings/examples_csharp/libusbK_Examples.sln.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7c032cf37e0629c9e0a5bb00cf24a0e1adb7f406 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_delphi/enumerate.dpr.REMOVED.git-id b/Old Matlab Interface/bindings/examples_delphi/enumerate.dpr.REMOVED.git-id deleted file mode 100644 index 2df36643..00000000 --- a/Old Matlab Interface/bindings/examples_delphi/enumerate.dpr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -25fbf807e3a1f15bde118fc0a473afa9784ee5c2 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/examples_delphi/opendevice.dpr.REMOVED.git-id b/Old Matlab Interface/bindings/examples_delphi/opendevice.dpr.REMOVED.git-id deleted file mode 100644 index 1ff8df85..00000000 --- a/Old Matlab Interface/bindings/examples_delphi/opendevice.dpr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ca0f7a9f5b243193e99c44b3d4cbf7b4278513fa \ No newline at end of file diff --git a/Old Matlab Interface/bindings/libusbK.boo.REMOVED.git-id b/Old Matlab Interface/bindings/libusbK.boo.REMOVED.git-id deleted file mode 100644 index 5f27e626..00000000 --- a/Old Matlab Interface/bindings/libusbK.boo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -64876bbdfd6d08dc6f34450ef8e5886e64745649 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/libusbK.cs.REMOVED.git-id b/Old Matlab Interface/bindings/libusbK.cs.REMOVED.git-id deleted file mode 100644 index 66e74f21..00000000 --- a/Old Matlab Interface/bindings/libusbK.cs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -80402b0e92eec5eba199b0a1ebe6964427218acc \ No newline at end of file diff --git a/Old Matlab Interface/bindings/libusbK.pas.REMOVED.git-id b/Old Matlab Interface/bindings/libusbK.pas.REMOVED.git-id deleted file mode 100644 index 156dba89..00000000 --- a/Old Matlab Interface/bindings/libusbK.pas.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b0e2050bd4d9af92e7c5fbf2c64deacd64414ae8 \ No newline at end of file diff --git a/Old Matlab Interface/bindings/libusbK.vb.REMOVED.git-id b/Old Matlab Interface/bindings/libusbK.vb.REMOVED.git-id deleted file mode 100644 index 61a89922..00000000 --- a/Old Matlab Interface/bindings/libusbK.vb.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -906db7fc0cf3a88f14846b248acfaec44e3c0aac \ No newline at end of file diff --git a/Old Matlab Interface/cmeasuretest.m.REMOVED.git-id b/Old Matlab Interface/cmeasuretest.m.REMOVED.git-id deleted file mode 100644 index 365dbb19..00000000 --- a/Old Matlab Interface/cmeasuretest.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d83acd1d63d3685698374ee1413c857a8a21fcb3 \ No newline at end of file diff --git a/Old Matlab Interface/compile.m.REMOVED.git-id b/Old Matlab Interface/compile.m.REMOVED.git-id deleted file mode 100644 index ff645e9f..00000000 --- a/Old Matlab Interface/compile.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2a030327369a56844c210c88339964120b6c7466 \ No newline at end of file diff --git a/Old Matlab Interface/conv_ana.m.REMOVED.git-id b/Old Matlab Interface/conv_ana.m.REMOVED.git-id deleted file mode 100644 index c3c28bcd..00000000 --- a/Old Matlab Interface/conv_ana.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ad31dc657c40d9aa8e0b86af759c0484642d54bc \ No newline at end of file diff --git a/Old Matlab Interface/conv_ana_notrig.m.REMOVED.git-id b/Old Matlab Interface/conv_ana_notrig.m.REMOVED.git-id deleted file mode 100644 index 8541823f..00000000 --- a/Old Matlab Interface/conv_ana_notrig.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f7569a7d363d61fd4748953d00ea1ffb9e4169aa \ No newline at end of file diff --git a/Old Matlab Interface/conv_dig.m.REMOVED.git-id b/Old Matlab Interface/conv_dig.m.REMOVED.git-id deleted file mode 100644 index 2fba024e..00000000 --- a/Old Matlab Interface/conv_dig.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3e1285c0f7a587dcb0fdf67abc74dbd3e5eb45be \ No newline at end of file diff --git a/Old Matlab Interface/crash_recover.m.REMOVED.git-id b/Old Matlab Interface/crash_recover.m.REMOVED.git-id deleted file mode 100644 index 866e06ae..00000000 --- a/Old Matlab Interface/crash_recover.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f9649c33cd2120c8fce19d375a5cd18f9723eca9 \ No newline at end of file diff --git a/Old Matlab Interface/displaypacket.m.REMOVED.git-id b/Old Matlab Interface/displaypacket.m.REMOVED.git-id deleted file mode 100644 index 1d0aec7a..00000000 --- a/Old Matlab Interface/displaypacket.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -867ff334a8e32192a87d88061cf260d88ab56a88 \ No newline at end of file diff --git a/Old Matlab Interface/dofrontend.m.REMOVED.git-id b/Old Matlab Interface/dofrontend.m.REMOVED.git-id deleted file mode 100644 index 8b788905..00000000 --- a/Old Matlab Interface/dofrontend.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4d8d76183d95f76b2ceca3b720961aa6031fa40d \ No newline at end of file diff --git a/Old Matlab Interface/dotheplot.m.REMOVED.git-id b/Old Matlab Interface/dotheplot.m.REMOVED.git-id deleted file mode 100644 index c939c4c9..00000000 --- a/Old Matlab Interface/dotheplot.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2906160be2f21f8466d8a3a4d0da2c031307c30d \ No newline at end of file diff --git a/Old Matlab Interface/draw_triggered.m.REMOVED.git-id b/Old Matlab Interface/draw_triggered.m.REMOVED.git-id deleted file mode 100644 index 74525be8..00000000 --- a/Old Matlab Interface/draw_triggered.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9f980ed9ada78349c8ab22c8fa1f5089ead80a4e \ No newline at end of file diff --git a/Old Matlab Interface/drawdick.m.REMOVED.git-id b/Old Matlab Interface/drawdick.m.REMOVED.git-id deleted file mode 100644 index a12bc39c..00000000 --- a/Old Matlab Interface/drawdick.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -930d948bb53af42aa74955585a117c2cbbff7612 \ No newline at end of file diff --git a/Old Matlab Interface/expected_adc.m.REMOVED.git-id b/Old Matlab Interface/expected_adc.m.REMOVED.git-id deleted file mode 100644 index db15eb65..00000000 --- a/Old Matlab Interface/expected_adc.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0a21e192b64941ab5da1ada602edff4823b166a6 \ No newline at end of file diff --git a/Old Matlab Interface/findtest.m.REMOVED.git-id b/Old Matlab Interface/findtest.m.REMOVED.git-id deleted file mode 100644 index d032c0b4..00000000 --- a/Old Matlab Interface/findtest.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f86821bd55a21ac4fdf01e5bb5983d70ba00c070 \ No newline at end of file diff --git a/Old Matlab Interface/first_gui.fig.REMOVED.git-id b/Old Matlab Interface/first_gui.fig.REMOVED.git-id deleted file mode 100644 index 99fbf7b0..00000000 --- a/Old Matlab Interface/first_gui.fig.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b14b8e292a65b26e3f34cba72444147972548e6b \ No newline at end of file diff --git a/Old Matlab Interface/first_gui.m.REMOVED.git-id b/Old Matlab Interface/first_gui.m.REMOVED.git-id deleted file mode 100644 index 3c55baa2..00000000 --- a/Old Matlab Interface/first_gui.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ae9e431da72eda131870f2d7d4e1fe5251bb24ff \ No newline at end of file diff --git a/Old Matlab Interface/first_gui_test.m.REMOVED.git-id b/Old Matlab Interface/first_gui_test.m.REMOVED.git-id deleted file mode 100644 index 09fe936e..00000000 --- a/Old Matlab Interface/first_gui_test.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9409e06c65ed66967a18c8e127a07ce1b7398ff0 \ No newline at end of file diff --git a/Old Matlab Interface/helloworld.cpp.REMOVED.git-id b/Old Matlab Interface/helloworld.cpp.REMOVED.git-id deleted file mode 100644 index b459ccd5..00000000 --- a/Old Matlab Interface/helloworld.cpp.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7c3080c9e499d4d40510ddc868f11843e476fd11 \ No newline at end of file diff --git a/Old Matlab Interface/helloworld.mexw64.REMOVED.git-id b/Old Matlab Interface/helloworld.mexw64.REMOVED.git-id deleted file mode 100644 index 5e0381e8..00000000 --- a/Old Matlab Interface/helloworld.mexw64.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4cabd8c0374aa1ca34f36c143f476a5882feb4a1 \ No newline at end of file diff --git a/Old Matlab Interface/hexoffset.m.REMOVED.git-id b/Old Matlab Interface/hexoffset.m.REMOVED.git-id deleted file mode 100644 index dc233b71..00000000 --- a/Old Matlab Interface/hexoffset.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2a9d895af1c59c3ab68f2f994d6ff7a48fe30bc7 \ No newline at end of file diff --git a/Old Matlab Interface/hs_err_pid1976.log.REMOVED.git-id b/Old Matlab Interface/hs_err_pid1976.log.REMOVED.git-id deleted file mode 100644 index 13b28b6f..00000000 --- a/Old Matlab Interface/hs_err_pid1976.log.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8a6a7a40e7132bba14065127ea87f70b14844054 \ No newline at end of file diff --git a/Old Matlab Interface/hs_err_pid4968.log.REMOVED.git-id b/Old Matlab Interface/hs_err_pid4968.log.REMOVED.git-id deleted file mode 100644 index 189a624c..00000000 --- a/Old Matlab Interface/hs_err_pid4968.log.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e27026ef902fcff7bce4b76c3fd573d9664f54e1 \ No newline at end of file diff --git a/Old Matlab Interface/includes/libusbk.h.REMOVED.git-id b/Old Matlab Interface/includes/libusbk.h.REMOVED.git-id deleted file mode 100644 index 1455df63..00000000 --- a/Old Matlab Interface/includes/libusbk.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bac5f81b4b7c7358636ed45329651ea7bd92d647 \ No newline at end of file diff --git a/Old Matlab Interface/includes/lusbk_dynapi.c.REMOVED.git-id b/Old Matlab Interface/includes/lusbk_dynapi.c.REMOVED.git-id deleted file mode 100644 index 0efb631b..00000000 --- a/Old Matlab Interface/includes/lusbk_dynapi.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3b414327d759fdb4927753daeab25ad6c3d00855 \ No newline at end of file diff --git a/Old Matlab Interface/includes/lusbk_shared.h.REMOVED.git-id b/Old Matlab Interface/includes/lusbk_shared.h.REMOVED.git-id deleted file mode 100644 index 803612dc..00000000 --- a/Old Matlab Interface/includes/lusbk_shared.h.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ddfa3fa9ee3b225f7f62f2f089d39b1fd0c3ca2c \ No newline at end of file diff --git a/Old Matlab Interface/isoLog.txt.REMOVED.git-id b/Old Matlab Interface/isoLog.txt.REMOVED.git-id deleted file mode 100644 index d2ac96c2..00000000 --- a/Old Matlab Interface/isoLog.txt.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7d562888e6020241f56717b426932990b316904f \ No newline at end of file diff --git a/Old Matlab Interface/iso_incoming.m.REMOVED.git-id b/Old Matlab Interface/iso_incoming.m.REMOVED.git-id deleted file mode 100644 index b4b75327..00000000 --- a/Old Matlab Interface/iso_incoming.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9705f823e15bcc30e45c0f42be26e3caefbad5a3 \ No newline at end of file diff --git a/Old Matlab Interface/keep_in_sync.m.REMOVED.git-id b/Old Matlab Interface/keep_in_sync.m.REMOVED.git-id deleted file mode 100644 index b97b5b67..00000000 --- a/Old Matlab Interface/keep_in_sync.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -083c5514f89a39ccb14f1d3c5537dff34ef08557 \ No newline at end of file diff --git a/Old Matlab Interface/launchgui.m.REMOVED.git-id b/Old Matlab Interface/launchgui.m.REMOVED.git-id deleted file mode 100644 index c8e8dfa8..00000000 --- a/Old Matlab Interface/launchgui.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3db346e8ebd4aa0fb2a593a246d667e2a9feef1f \ No newline at end of file diff --git a/Old Matlab Interface/lcdtoggle.m.REMOVED.git-id b/Old Matlab Interface/lcdtoggle.m.REMOVED.git-id deleted file mode 100644 index badb554d..00000000 --- a/Old Matlab Interface/lcdtoggle.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6ce771ae00b6f1655f1b2c8cad47ad29c926d0ef \ No newline at end of file diff --git a/Old Matlab Interface/make_waveforms.m.REMOVED.git-id b/Old Matlab Interface/make_waveforms.m.REMOVED.git-id deleted file mode 100644 index cdf9bf63..00000000 --- a/Old Matlab Interface/make_waveforms.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d75de892394bd3e39c88a911ba32d27a110eacd6 \ No newline at end of file diff --git a/Old Matlab Interface/mexHW.m.REMOVED.git-id b/Old Matlab Interface/mexHW.m.REMOVED.git-id deleted file mode 100644 index f75de14b..00000000 --- a/Old Matlab Interface/mexHW.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5178aa5251bfa9b880ede3f787001393d18a4b71 \ No newline at end of file diff --git a/Old Matlab Interface/mex_usb_init.m.REMOVED.git-id b/Old Matlab Interface/mex_usb_init.m.REMOVED.git-id deleted file mode 100644 index c6689faf..00000000 --- a/Old Matlab Interface/mex_usb_init.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cf30a774ebd540eb818fded441e996f8c489af91 \ No newline at end of file diff --git a/Old Matlab Interface/mex_usb_iso_init.m.REMOVED.git-id b/Old Matlab Interface/mex_usb_iso_init.m.REMOVED.git-id deleted file mode 100644 index 77918502..00000000 --- a/Old Matlab Interface/mex_usb_iso_init.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e4d69f15bc675917b7ce8d8ddce30de5dd56a3f8 \ No newline at end of file diff --git a/Old Matlab Interface/mex_usb_iso_loop.m.REMOVED.git-id b/Old Matlab Interface/mex_usb_iso_loop.m.REMOVED.git-id deleted file mode 100644 index a11737b7..00000000 --- a/Old Matlab Interface/mex_usb_iso_loop.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f434d15f596cae220931ac710ff52e9c5a54602d \ No newline at end of file diff --git a/Old Matlab Interface/mex_usb_send_control.m.REMOVED.git-id b/Old Matlab Interface/mex_usb_send_control.m.REMOVED.git-id deleted file mode 100644 index 01df8cac..00000000 --- a/Old Matlab Interface/mex_usb_send_control.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -77a9c0fe8639eb4e66f732c38266aef2075b7d55 \ No newline at end of file diff --git a/Old Matlab Interface/plotcursors.m.REMOVED.git-id b/Old Matlab Interface/plotcursors.m.REMOVED.git-id deleted file mode 100644 index c810fdcd..00000000 --- a/Old Matlab Interface/plotcursors.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -387016ca66afaee382c66b4bc75f3afe21d8066d \ No newline at end of file diff --git a/Old Matlab Interface/plotiso.m.REMOVED.git-id b/Old Matlab Interface/plotiso.m.REMOVED.git-id deleted file mode 100644 index 78b172e1..00000000 --- a/Old Matlab Interface/plotiso.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9dfcb4d414e37e4562db1fe9ec4f64d1ed55c1ca \ No newline at end of file diff --git a/Old Matlab Interface/plotmem.m.REMOVED.git-id b/Old Matlab Interface/plotmem.m.REMOVED.git-id deleted file mode 100644 index 1398cb4b..00000000 --- a/Old Matlab Interface/plotmem.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d8e62241fc4220be3e459a3ce8d68727b2173fdb \ No newline at end of file diff --git a/Old Matlab Interface/plotspeedtest.m.REMOVED.git-id b/Old Matlab Interface/plotspeedtest.m.REMOVED.git-id deleted file mode 100644 index e4538073..00000000 --- a/Old Matlab Interface/plotspeedtest.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9f1d532103d18813901e5a5ea6cf3fac1bbb4283 \ No newline at end of file diff --git a/Old Matlab Interface/plotyy_test.m.REMOVED.git-id b/Old Matlab Interface/plotyy_test.m.REMOVED.git-id deleted file mode 100644 index 38cd5e0b..00000000 --- a/Old Matlab Interface/plotyy_test.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -50d5d46d9a1b198918e80946f15dc62784d16399 \ No newline at end of file diff --git a/Old Matlab Interface/printusb.m.REMOVED.git-id b/Old Matlab Interface/printusb.m.REMOVED.git-id deleted file mode 100644 index 2644f33f..00000000 --- a/Old Matlab Interface/printusb.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fd54ba80e7651ca7f3d077705c84982775bac90a \ No newline at end of file diff --git a/Old Matlab Interface/psucal.m.REMOVED.git-id b/Old Matlab Interface/psucal.m.REMOVED.git-id deleted file mode 100644 index 04137c51..00000000 --- a/Old Matlab Interface/psucal.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -30bd56e2d159385a7bdcaae5c7a12d72056e2079 \ No newline at end of file diff --git a/Old Matlab Interface/psutest_boost.m.REMOVED.git-id b/Old Matlab Interface/psutest_boost.m.REMOVED.git-id deleted file mode 100644 index 8a08a43e..00000000 --- a/Old Matlab Interface/psutest_boost.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b391df84b80addf52371dd440c583a826c216404 \ No newline at end of file diff --git a/Old Matlab Interface/resynchronise.m.REMOVED.git-id b/Old Matlab Interface/resynchronise.m.REMOVED.git-id deleted file mode 100644 index 9819de3b..00000000 --- a/Old Matlab Interface/resynchronise.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -420e7d70ebfa8f93a41532268d3dab2eb4aa86f0 \ No newline at end of file diff --git a/Old Matlab Interface/returnempty.m.REMOVED.git-id b/Old Matlab Interface/returnempty.m.REMOVED.git-id deleted file mode 100644 index 88f42ce5..00000000 --- a/Old Matlab Interface/returnempty.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -000f42e69ba16842f302232f95a83332aaff755d \ No newline at end of file diff --git a/Old Matlab Interface/samplestoshow_not_on_500.PNG.REMOVED.git-id b/Old Matlab Interface/samplestoshow_not_on_500.PNG.REMOVED.git-id deleted file mode 100644 index 124126ad..00000000 --- a/Old Matlab Interface/samplestoshow_not_on_500.PNG.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7f2cb1cf25a8c212ea0074dc181d414fb67b8263 \ No newline at end of file diff --git a/Old Matlab Interface/samplestoshow_on_500.png.REMOVED.git-id b/Old Matlab Interface/samplestoshow_on_500.png.REMOVED.git-id deleted file mode 100644 index dab78be8..00000000 --- a/Old Matlab Interface/samplestoshow_on_500.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6e1586a0d844a699ac499df128a0c60bbf9a018b \ No newline at end of file diff --git a/Old Matlab Interface/scroll_function.m.REMOVED.git-id b/Old Matlab Interface/scroll_function.m.REMOVED.git-id deleted file mode 100644 index c52ff869..00000000 --- a/Old Matlab Interface/scroll_function.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b0da30fbcf70f9e1e51d61b635a6d0689dc57333 \ No newline at end of file diff --git a/Old Matlab Interface/seconds_recorded.m.REMOVED.git-id b/Old Matlab Interface/seconds_recorded.m.REMOVED.git-id deleted file mode 100644 index d571c367..00000000 --- a/Old Matlab Interface/seconds_recorded.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0f49a779000fdcbf001589c694baae56dc359145 \ No newline at end of file diff --git a/Old Matlab Interface/set_gain_auto.m.REMOVED.git-id b/Old Matlab Interface/set_gain_auto.m.REMOVED.git-id deleted file mode 100644 index f68d3c19..00000000 --- a/Old Matlab Interface/set_gain_auto.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -32d989d5a3f252360731a6f36661d70e6dd91899 \ No newline at end of file diff --git a/Old Matlab Interface/setpsu.m.REMOVED.git-id b/Old Matlab Interface/setpsu.m.REMOVED.git-id deleted file mode 100644 index e2669c15..00000000 --- a/Old Matlab Interface/setpsu.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7dae927baab0d4bcb8a8aa628b8afa7132bc59e5 \ No newline at end of file diff --git a/Old Matlab Interface/setpsu_boost.m.REMOVED.git-id b/Old Matlab Interface/setpsu_boost.m.REMOVED.git-id deleted file mode 100644 index 31b0ae32..00000000 --- a/Old Matlab Interface/setpsu_boost.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b98a9911263eedc1f3759791da760da13b0f2712 \ No newline at end of file diff --git a/Old Matlab Interface/setscopegain.m.REMOVED.git-id b/Old Matlab Interface/setscopegain.m.REMOVED.git-id deleted file mode 100644 index 611158c6..00000000 --- a/Old Matlab Interface/setscopegain.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ab2a692dd8803712e73c6080517c03f77742988c \ No newline at end of file diff --git a/Old Matlab Interface/setscopemode.m.REMOVED.git-id b/Old Matlab Interface/setscopemode.m.REMOVED.git-id deleted file mode 100644 index a730154b..00000000 --- a/Old Matlab Interface/setscopemode.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5fd33a01bed1f1606fafcb6c52e1097e55183314 \ No newline at end of file diff --git a/Old Matlab Interface/setscopewindowsize.m.REMOVED.git-id b/Old Matlab Interface/setscopewindowsize.m.REMOVED.git-id deleted file mode 100644 index d006fa54..00000000 --- a/Old Matlab Interface/setscopewindowsize.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6008fdd5eb61ec865f948d5e3d69f1ef7eb38b1a \ No newline at end of file diff --git a/Old Matlab Interface/signal_trip.m.REMOVED.git-id b/Old Matlab Interface/signal_trip.m.REMOVED.git-id deleted file mode 100644 index f7ff8e6f..00000000 --- a/Old Matlab Interface/signal_trip.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -65b7fa05b6ce763001e1c09565bdafc8b9fe9360 \ No newline at end of file diff --git a/Old Matlab Interface/sisprintf.m.REMOVED.git-id b/Old Matlab Interface/sisprintf.m.REMOVED.git-id deleted file mode 100644 index 91c8144c..00000000 --- a/Old Matlab Interface/sisprintf.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -81718ab43d5570fe71272588cb5f0d5a402f06e7 \ No newline at end of file diff --git a/Old Matlab Interface/static_draw.m b/Old Matlab Interface/static_draw.m deleted file mode 100644 index e69de29b..00000000 diff --git a/Old Matlab Interface/test.m.REMOVED.git-id b/Old Matlab Interface/test.m.REMOVED.git-id deleted file mode 100644 index ce6ee138..00000000 --- a/Old Matlab Interface/test.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -163041d65fe80b7477e13116c7afd95b8d0c6c44 \ No newline at end of file diff --git a/Old Matlab Interface/test1.m.REMOVED.git-id b/Old Matlab Interface/test1.m.REMOVED.git-id deleted file mode 100644 index 18ed0b9a..00000000 --- a/Old Matlab Interface/test1.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e79dc68785f43c7c1645009c58ee2fce719a3211 \ No newline at end of file diff --git a/Old Matlab Interface/test12bit.m.REMOVED.git-id b/Old Matlab Interface/test12bit.m.REMOVED.git-id deleted file mode 100644 index 6eda3fc8..00000000 --- a/Old Matlab Interface/test12bit.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5919c653373f71a5f75da0689f007d9f23f1e6f7 \ No newline at end of file diff --git a/Old Matlab Interface/tet.m.REMOVED.git-id b/Old Matlab Interface/tet.m.REMOVED.git-id deleted file mode 100644 index 98c0fa57..00000000 --- a/Old Matlab Interface/tet.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3a7cf3e2e4df3f531374fa61f6472c102baa7308 \ No newline at end of file diff --git a/Old Matlab Interface/timer30ms_callback.m.REMOVED.git-id b/Old Matlab Interface/timer30ms_callback.m.REMOVED.git-id deleted file mode 100644 index e79280a3..00000000 --- a/Old Matlab Interface/timer30ms_callback.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7c14731cc11b072688496e3055b716fb1041571f \ No newline at end of file diff --git a/Old Matlab Interface/timer_strap.m.REMOVED.git-id b/Old Matlab Interface/timer_strap.m.REMOVED.git-id deleted file mode 100644 index d262ebf6..00000000 --- a/Old Matlab Interface/timer_strap.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3da91c29a2a680b6c73d577247010ccb857aa3d8 \ No newline at end of file diff --git a/Old Matlab Interface/tiny_send_auxwf.m.REMOVED.git-id b/Old Matlab Interface/tiny_send_auxwf.m.REMOVED.git-id deleted file mode 100644 index cbb3a43e..00000000 --- a/Old Matlab Interface/tiny_send_auxwf.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -03679a276a1ceb4eda4eaa3367f345496e415986 \ No newline at end of file diff --git a/Old Matlab Interface/tiny_send_dig.m.REMOVED.git-id b/Old Matlab Interface/tiny_send_dig.m.REMOVED.git-id deleted file mode 100644 index 65d13538..00000000 --- a/Old Matlab Interface/tiny_send_dig.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0e819efa6d3d672f77740df5f229023ca12ab576 \ No newline at end of file diff --git a/Old Matlab Interface/tiny_send_waveform.m.REMOVED.git-id b/Old Matlab Interface/tiny_send_waveform.m.REMOVED.git-id deleted file mode 100644 index c0e0903f..00000000 --- a/Old Matlab Interface/tiny_send_waveform.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -47980eea95a0cf714d064a9acff67ff933a72f2c \ No newline at end of file diff --git a/Old Matlab Interface/tiny_wave_conv.m.REMOVED.git-id b/Old Matlab Interface/tiny_wave_conv.m.REMOVED.git-id deleted file mode 100644 index 98bdb722..00000000 --- a/Old Matlab Interface/tiny_wave_conv.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a73fca5ec38b2f0a2cad4d42b3c409cc26ed685b \ No newline at end of file diff --git a/Old Matlab Interface/tiny_wave_conv_aux.m.REMOVED.git-id b/Old Matlab Interface/tiny_wave_conv_aux.m.REMOVED.git-id deleted file mode 100644 index 84e0f260..00000000 --- a/Old Matlab Interface/tiny_wave_conv_aux.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5cab9c992a0b092f6480a1b842fb08f3a5869261 \ No newline at end of file diff --git a/Old Matlab Interface/undofrontend.m.REMOVED.git-id b/Old Matlab Interface/undofrontend.m.REMOVED.git-id deleted file mode 100644 index cf13dbf2..00000000 --- a/Old Matlab Interface/undofrontend.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -017f35ebd95a2259a9b26429653357a190c5ab98 \ No newline at end of file diff --git a/Old Matlab Interface/updatescopeaxes.m.REMOVED.git-id b/Old Matlab Interface/updatescopeaxes.m.REMOVED.git-id deleted file mode 100644 index 8247484d..00000000 --- a/Old Matlab Interface/updatescopeaxes.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b1da4215bb144bf82bc28218877d0299bf4da375 \ No newline at end of file diff --git a/Old Matlab Interface/verr.m.REMOVED.git-id b/Old Matlab Interface/verr.m.REMOVED.git-id deleted file mode 100644 index baae6660..00000000 --- a/Old Matlab Interface/verr.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -335ce7f6492f67ab88a877e15707744c0cbcb1f3 \ No newline at end of file diff --git a/Old Matlab Interface/vexconv.m.REMOVED.git-id b/Old Matlab Interface/vexconv.m.REMOVED.git-id deleted file mode 100644 index c1430e78..00000000 --- a/Old Matlab Interface/vexconv.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8a3093e06133d6833e31cae53d41a5d1a4f4f1c6 \ No newline at end of file diff --git a/Old Matlab Interface/weave.m.REMOVED.git-id b/Old Matlab Interface/weave.m.REMOVED.git-id deleted file mode 100644 index 3b5e653e..00000000 --- a/Old Matlab Interface/weave.m.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -05ad2639022f19fc4363c6f16f32e0a512b5f551 \ No newline at end of file diff --git a/PCB/.pretty/1pin.kicad_mod b/PCB/.pretty/1pin.kicad_mod new file mode 100644 index 00000000..c06374cc --- /dev/null +++ b/PCB/.pretty/1pin.kicad_mod @@ -0,0 +1,12 @@ +(module 1pin (layer F.Cu) (tedit 0) + (descr "module 1 pin (ou trou mecanique de percage)") + (tags DEV) + (fp_text reference REF** (at 0 -3.048) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value 1pin (at 0 2.794) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_circle (center 0 0) (end 0 -2.286) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole circle (at 0 0) (size 4.064 4.064) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/1pin.kicad_mod.REMOVED.git-id b/PCB/.pretty/1pin.kicad_mod.REMOVED.git-id deleted file mode 100644 index b961da3f..00000000 --- a/PCB/.pretty/1pin.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c06374cc336ac348add4ffabc5bac3b36ba50c7d \ No newline at end of file diff --git a/PCB/.pretty/3M-N7E50.kicad_mod b/PCB/.pretty/3M-N7E50.kicad_mod new file mode 100644 index 00000000..103cc65b --- /dev/null +++ b/PCB/.pretty/3M-N7E50.kicad_mod @@ -0,0 +1,113 @@ +(module 3M-N7E50 (layer F.Cu) (tedit 0) + (descr "Connecteur PCMCIA + carte") + (tags CONN) + (fp_text reference REF** (at 0 4.445) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value 3M-N7E50 (at 0 7.62) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 21.59 31.115) (end 21.59 38.1) (layer F.SilkS) (width 0.15)) + (fp_line (start 21.59 27.94) (end 21.59 29.845) (layer F.SilkS) (width 0.15)) + (fp_line (start 21.59 20.32) (end 21.59 26.67) (layer F.SilkS) (width 0.15)) + (fp_line (start 21.59 17.145) (end 21.59 19.05) (layer F.SilkS) (width 0.15)) + (fp_line (start 21.59 9.525) (end 21.59 15.875) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.415 38.1) (end 20.32 38.1) (layer F.SilkS) (width 0.15)) + (fp_line (start 10.795 38.1) (end 17.145 38.1) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 38.1) (end 9.525 38.1) (layer F.SilkS) (width 0.15)) + (fp_line (start 0 38.1) (end 6.35 38.1) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.175 38.1) (end -1.27 38.1) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.795 38.1) (end -4.445 38.1) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.97 38.1) (end -12.065 38.1) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.59 38.1) (end -15.24 38.1) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.59 31.115) (end -21.59 38.1) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.59 27.94) (end -21.59 29.845) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.59 20.32) (end -21.59 26.67) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.59 17.145) (end -21.59 19.05) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.59 9.525) (end -21.59 15.875) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.5575 -0.9525) (end 14.9225 0.3175) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.9225 0.3175) (end 16.1925 0.3175) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.1925 0.3175) (end 15.5575 -0.9525) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.635 -0.635) (end -0.635 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.635 -0.635) (end 0.635 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 21.5138 8.3058) (end 21.5138 2.0066) (layer F.SilkS) (width 0.15)) + (fp_line (start 21.5138 2.0066) (end 21.1328 1.6256) (layer F.SilkS) (width 0.15)) + (fp_line (start 21.1328 1.6256) (end 20.5486 1.6256) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.5138 8.3058) (end -21.5138 2.0066) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.5138 2.0066) (end -21.1328 1.6256) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.1328 1.6256) (end -20.5486 1.6256) (layer F.SilkS) (width 0.15)) + (fp_line (start -22.479 2.6416) (end -22.479 8.3058) (layer F.SilkS) (width 0.15)) + (fp_line (start -22.479 8.3058) (end -20.5486 8.3058) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.5486 8.3058) (end -20.5486 1.6256) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.5486 1.6256) (end 20.5486 1.6256) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.5486 1.6256) (end 20.5486 8.3058) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.5486 8.3058) (end 22.479 8.3058) (layer F.SilkS) (width 0.15)) + (fp_line (start 22.479 8.3058) (end 22.479 2.6416) (layer F.SilkS) (width 0.15)) + (fp_line (start -22.479 -3.048) (end -22.479 -5.4102) (layer F.SilkS) (width 0.15)) + (fp_line (start -22.479 -5.4102) (end -17.4244 -5.4102) (layer F.SilkS) (width 0.15)) + (fp_line (start -17.4244 -5.4102) (end -17.4244 -7.2898) (layer F.SilkS) (width 0.15)) + (fp_line (start -17.4244 -7.2898) (end -16.4084 -7.2898) (layer F.SilkS) (width 0.15)) + (fp_line (start -16.4084 -7.2898) (end -16.4084 -1.6764) (layer F.SilkS) (width 0.15)) + (fp_line (start -16.4084 -1.6764) (end 16.4084 -1.6764) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.4084 -1.6764) (end 16.4084 -7.2898) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.4084 -7.2898) (end 17.4244 -7.2898) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.4244 -7.2898) (end 17.4244 -5.4102) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.4244 -5.4102) (end 22.479 -5.4102) (layer F.SilkS) (width 0.15)) + (fp_line (start 22.479 -5.4102) (end 22.479 -3.048) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at 15.5575 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 26 smd rect (at 14.9225 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at 14.2875 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 27 smd rect (at 13.6525 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at 13.0175 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 28 smd rect (at 12.3825 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 4 smd rect (at 11.7475 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 29 smd rect (at 11.1125 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 5 smd rect (at 10.4775 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 30 smd rect (at 9.8425 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 6 smd rect (at 9.2075 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 31 smd rect (at 8.5725 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 7 smd rect (at 7.9375 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 32 smd rect (at 7.3025 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 8 smd rect (at 6.6675 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 33 smd rect (at 6.0325 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 9 smd rect (at 5.3975 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 34 smd rect (at 4.7625 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 10 smd rect (at 4.1275 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 35 smd rect (at 3.4925 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 11 smd rect (at 2.8575 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 36 smd rect (at 2.2225 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 12 smd rect (at 1.5875 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 37 smd rect (at 0.9525 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 13 smd rect (at 0.3175 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 38 smd rect (at -0.3175 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 14 smd rect (at -0.9525 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 39 smd rect (at -1.5875 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 15 smd rect (at -2.2225 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 40 smd rect (at -2.8575 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 16 smd rect (at -3.4925 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 41 smd rect (at -4.1275 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 17 smd rect (at -4.7625 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 42 smd rect (at -5.3975 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 18 smd rect (at -6.0325 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 43 smd rect (at -6.6675 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 19 smd rect (at -7.3025 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 44 smd rect (at -7.9375 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 20 smd rect (at -8.5725 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 45 smd rect (at -9.2075 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 21 smd rect (at -9.8425 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 46 smd rect (at -10.4775 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 22 smd rect (at -11.1125 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 47 smd rect (at -11.7475 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 23 smd rect (at -12.3825 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 48 smd rect (at -13.0175 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 24 smd rect (at -13.6525 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 49 smd rect (at -14.2875 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 25 smd rect (at -14.9225 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad 50 smd rect (at -15.5575 -5.8674) (size 0.4064 3.5052) (layers F.Cu F.Paste F.Mask)) + (pad "" thru_hole circle (at -19.3675 -2.8702) (size 3.9878 3.9878) (drill 2.2098) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 19.3675 -2.8702) (size 3.9878 3.9878) (drill 2.2098) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -19.3675 0.127) (size 1.7018 1.7018) (drill 1.7018) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 19.3675 0.127) (size 1.7018 1.7018) (drill 1.7018) (layers *.Cu *.Mask F.SilkS)) + (pad "" smd rect (at 23.3426 -0.2032) (size 2.4892 4.572) (layers F.Cu F.Paste B.SilkS F.Mask)) + (pad "" smd rect (at -23.3426 -0.2032) (size 2.4892 4.572) (layers F.Cu F.Paste B.SilkS F.Mask)) +) diff --git a/PCB/.pretty/3M-N7E50.kicad_mod.REMOVED.git-id b/PCB/.pretty/3M-N7E50.kicad_mod.REMOVED.git-id deleted file mode 100644 index 07787cbd..00000000 --- a/PCB/.pretty/3M-N7E50.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -103cc65bc7be4ed7c7de393fea72450001b1e68e \ No newline at end of file diff --git a/PCB/.pretty/AK300-2.kicad_mod b/PCB/.pretty/AK300-2.kicad_mod new file mode 100644 index 00000000..cab9f1dd --- /dev/null +++ b/PCB/.pretty/AK300-2.kicad_mod @@ -0,0 +1,98 @@ +(module AK300-2 (layer F.Cu) (tedit 54792136) + (descr CONNECTOR) + (tags CONNECTOR) + (attr virtual) + (fp_text reference REF** (at -1.92 -6.985) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value AK300-2 (at 2.779 7.747) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 8.363 -6.473) (end -2.83 -6.473) (layer F.CrtYd) (width 0.05)) + (fp_line (start 8.363 6.473) (end 8.363 -6.473) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.83 6.473) (end 8.363 6.473) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.83 -6.473) (end -2.83 6.473) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.2596 2.54) (end 1.2804 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.2804 2.54) (end 1.2804 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.2596 -0.254) (end 1.2804 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.2596 2.54) (end -1.2596 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.7442 2.54) (end 6.2842 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.2842 2.54) (end 6.2842 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.7442 -0.254) (end 6.2842 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.7442 2.54) (end 3.7442 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.605 -6.223) (end 7.605 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.605 -6.223) (end -2.58 -6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.605 -6.223) (end 8.113 -6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.113 -6.223) (end 8.113 -1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.113 -1.397) (end 7.605 -1.651) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.113 5.461) (end 7.605 5.207) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.605 5.207) (end 7.605 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.113 3.81) (end 7.605 4.064) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.605 4.064) (end 7.605 5.207) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.113 3.81) (end 8.113 5.461) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9822 6.223) (end 2.9822 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0462 -0.254) (end 7.0462 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9822 6.223) (end 7.0462 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0462 6.223) (end 7.605 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0424 6.223) (end 2.0424 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0424 6.223) (end 2.9822 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0216 -0.254) (end -2.0216 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 6.223) (end -2.0216 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0216 6.223) (end 2.0424 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9822 4.318) (end 7.0462 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9822 4.318) (end 2.9822 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0462 4.318) (end 7.0462 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0424 4.318) (end -2.0216 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0424 4.318) (end 2.0424 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0216 4.318) (end -2.0216 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.6652 3.683) (end 6.6652 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.6652 3.683) (end 3.3632 3.683) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.3632 3.683) (end 3.3632 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.6614 3.683) (end 1.6614 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.6614 3.683) (end -1.6406 3.683) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.6406 3.683) (end -1.6406 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.6406 0.508) (end -1.2596 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.6614 0.508) (end 1.2804 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.3632 0.508) (end 3.7442 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.6652 0.508) (end 6.2842 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 6.223) (end -2.58 -0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 -0.635) (end -2.58 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.605 -1.651) (end 7.605 -0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.605 -0.635) (end 7.605 4.064) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 -3.175) (end 7.605 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 -3.175) (end -2.58 -6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.605 -3.175) (end 7.605 -1.651) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9822 -3.429) (end 2.9822 -5.969) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9822 -5.969) (end 7.0462 -5.969) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0462 -5.969) (end 7.0462 -3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0462 -3.429) (end 2.9822 -3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0424 -3.429) (end 2.0424 -5.969) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0424 -3.429) (end -2.0216 -3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0216 -3.429) (end -2.0216 -5.969) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0424 -5.969) (end -2.0216 -5.969) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.3886 -4.445) (end 6.4366 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.5156 -4.318) (end 6.5636 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.6152 -4.445) (end 1.43534 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.4882 -4.318) (end 1.5598 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0216 -0.254) (end -1.6406 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0424 -0.254) (end 1.6614 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.6614 -0.254) (end -1.6406 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 -0.635) (end -1.6406 -0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.6406 -0.635) (end 1.6614 -0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.6614 -0.635) (end 3.3632 -0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.605 -0.635) (end 6.6652 -0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.6652 -0.635) (end 3.3632 -0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0462 -0.254) (end 6.6652 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9822 -0.254) (end 3.3632 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.3632 -0.254) (end 6.6652 -0.254) (layer F.SilkS) (width 0.15)) + (fp_arc (start 6.0302 -4.59486) (end 6.53566 -5.05206) (angle 90.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start 5.065 -6.0706) (end 6.52804 -4.11734) (angle 75.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start 4.98626 -3.7084) (end 3.3886 -5.0038) (angle 100) (layer F.SilkS) (width 0.15)) + (fp_arc (start 3.8712 -4.64566) (end 3.58164 -4.1275) (angle 104.2) (layer F.SilkS) (width 0.15)) + (fp_arc (start 1.0264 -4.59486) (end 1.5344 -5.05206) (angle 90.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start 0.06374 -6.0706) (end 1.52678 -4.11734) (angle 75.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start -0.01246 -3.7084) (end -1.6152 -5.0038) (angle 100) (layer F.SilkS) (width 0.15)) + (fp_arc (start -1.1326 -4.64566) (end -1.41962 -4.1275) (angle 104.2) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole oval (at 0 0) (size 1.9812 3.9624) (drill 1.3208) (layers *.Cu F.Paste F.SilkS F.Mask)) + (pad 2 thru_hole oval (at 5 0) (size 1.9812 3.9624) (drill 1.3208) (layers *.Cu F.Paste F.SilkS F.Mask)) +) diff --git a/PCB/.pretty/AK300-2.kicad_mod.REMOVED.git-id b/PCB/.pretty/AK300-2.kicad_mod.REMOVED.git-id deleted file mode 100644 index e5b60466..00000000 --- a/PCB/.pretty/AK300-2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cab9f1ddf75b5206fd1c90fe16d0e5bb5dfed2f9 \ No newline at end of file diff --git a/PCB/.pretty/AK300-3.kicad_mod b/PCB/.pretty/AK300-3.kicad_mod new file mode 100644 index 00000000..b3eaf956 --- /dev/null +++ b/PCB/.pretty/AK300-3.kicad_mod @@ -0,0 +1,127 @@ +(module AK300-3 (layer F.Cu) (tedit 54791EF3) + (descr CONNECTOR) + (tags CONNECTOR) + (attr virtual) + (fp_text reference REF** (at -1.945 -6.995) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value AK300-3 (at 2.754 7.737) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 13.418 -6.473) (end -2.83 -6.473) (layer F.CrtYd) (width 0.05)) + (fp_line (start 13.418 6.473) (end 13.418 -6.473) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.83 6.473) (end 13.418 6.473) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.83 -6.473) (end -2.83 6.473) (layer F.CrtYd) (width 0.05)) + (fp_line (start 12.66 -0.645) (end -2.5165 -0.645) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.0245 3.9905) (end 8.0245 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.0885 6.213) (end 7.58 6.213) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.58 -3.185) (end 12.5965 -3.185) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 -6.233) (end 12.66 -6.233) (layer F.SilkS) (width 0.15)) + (fp_arc (start 8.9262 -4.65566) (end 8.63664 -4.1375) (angle 104.2) (layer F.SilkS) (width 0.15)) + (fp_arc (start 10.04126 -3.7184) (end 8.4436 -5.0138) (angle 100) (layer F.SilkS) (width 0.15)) + (fp_arc (start 10.12 -6.0806) (end 11.58304 -4.12734) (angle 75.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start 11.0852 -4.60486) (end 11.59066 -5.06206) (angle 90.5) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.4182 -0.264) (end 11.7202 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.0372 -0.264) (end 8.4182 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.1012 -0.264) (end 11.7202 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.5706 -4.328) (end 11.6186 -4.963) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.4436 -4.455) (end 11.4916 -5.09) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.1012 -3.439) (end 8.0372 -3.439) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.1012 -5.979) (end 12.1012 -3.439) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.0372 -5.979) (end 12.1012 -5.979) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.0372 -3.439) (end 8.0372 -5.979) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.66 -3.185) (end 12.66 -1.661) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.66 -0.645) (end 12.66 4.054) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.66 -1.661) (end 12.66 -0.645) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.7202 0.498) (end 11.3392 0.498) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.4182 0.498) (end 8.7992 0.498) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.4182 3.673) (end 8.4182 0.498) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.7202 3.673) (end 8.4182 3.673) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.7202 3.673) (end 11.7202 0.498) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.1012 4.308) (end 12.1012 6.213) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.0372 4.308) (end 12.1012 4.308) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.1012 6.213) (end 12.66 6.213) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.1012 -0.264) (end 12.1012 4.308) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.0372 6.213) (end 8.0372 4.308) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.168 3.8) (end 13.168 5.451) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.66 4.054) (end 12.66 5.197) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.168 3.8) (end 12.66 4.054) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.66 5.197) (end 12.66 6.213) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.168 5.451) (end 12.66 5.197) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.168 -1.407) (end 12.66 -1.661) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.168 -6.233) (end 13.168 -1.407) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.66 -6.233) (end 13.168 -6.233) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.66 -6.233) (end 12.66 -3.185) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.7992 2.53) (end 8.7992 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.7992 -0.264) (end 11.3392 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.3392 2.53) (end 11.3392 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.7992 2.53) (end 11.3392 2.53) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.2846 2.53) (end 1.2554 2.53) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.2554 2.53) (end 1.2554 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.2846 -0.264) (end 1.2554 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.2846 2.53) (end -1.2846 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.7192 2.53) (end 6.2592 2.53) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.2592 2.53) (end 6.2592 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.7192 -0.264) (end 6.2592 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.7192 2.53) (end 3.7192 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.0245 5.197) (end 8.0245 6.213) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.0245 4.054) (end 8.0245 5.197) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9572 6.213) (end 2.9572 4.308) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0212 -0.264) (end 7.0212 4.308) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9572 6.213) (end 7.0212 6.213) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0212 6.213) (end 7.58 6.213) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 6.213) (end 2.0174 4.308) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 6.213) (end 2.9572 6.213) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0466 -0.264) (end -2.0466 4.308) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 6.213) (end -2.0466 6.213) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0466 6.213) (end 2.0174 6.213) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9572 4.308) (end 7.0212 4.308) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9572 4.308) (end 2.9572 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0212 4.308) (end 7.0212 6.213) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 4.308) (end -2.0466 4.308) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 4.308) (end 2.0174 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0466 4.308) (end -2.0466 6.213) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.6402 3.673) (end 6.6402 0.498) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.6402 3.673) (end 3.3382 3.673) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.3382 3.673) (end 3.3382 0.498) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.6364 3.673) (end 1.6364 0.498) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.6364 3.673) (end -1.6656 3.673) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.6656 3.673) (end -1.6656 0.498) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.6656 0.498) (end -1.2846 0.498) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.6364 0.498) (end 1.2554 0.498) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.3382 0.498) (end 3.7192 0.498) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.6402 0.498) (end 6.2592 0.498) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 6.213) (end -2.58 -0.645) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 -0.645) (end -2.58 -3.185) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 -3.185) (end 7.58 -3.185) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 -3.185) (end -2.58 -6.233) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9572 -3.439) (end 2.9572 -5.979) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9572 -5.979) (end 7.0212 -5.979) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0212 -5.979) (end 7.0212 -3.439) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0212 -3.439) (end 2.9572 -3.439) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 -3.439) (end 2.0174 -5.979) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 -3.439) (end -2.0466 -3.439) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0466 -3.439) (end -2.0466 -5.979) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 -5.979) (end -2.0466 -5.979) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.3636 -4.455) (end 6.4116 -5.09) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.4906 -4.328) (end 6.5386 -4.963) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.6402 -4.455) (end 1.41034 -5.09) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.5132 -4.328) (end 1.5348 -4.963) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0466 -0.264) (end -1.6656 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 -0.264) (end 1.6364 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.6364 -0.264) (end -1.6656 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0212 -0.264) (end 6.6402 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9572 -0.264) (end 3.3382 -0.264) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.3382 -0.264) (end 6.6402 -0.264) (layer F.SilkS) (width 0.15)) + (fp_arc (start 6.0052 -4.60486) (end 6.51066 -5.06206) (angle 90.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start 5.04 -6.0806) (end 6.50304 -4.12734) (angle 75.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start 4.96126 -3.7184) (end 3.3636 -5.0138) (angle 100) (layer F.SilkS) (width 0.15)) + (fp_arc (start 3.8462 -4.65566) (end 3.55664 -4.1375) (angle 104.2) (layer F.SilkS) (width 0.15)) + (fp_arc (start 1.0014 -4.60486) (end 1.5094 -5.06206) (angle 90.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start 0.03874 -6.0806) (end 1.50178 -4.12734) (angle 75.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start -0.03746 -3.7184) (end -1.6402 -5.0138) (angle 100) (layer F.SilkS) (width 0.15)) + (fp_arc (start -1.1576 -4.65566) (end -1.44462 -4.1375) (angle 104.2) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole oval (at 0 0) (size 1.9812 3.9624) (drill 1.3208) (layers *.Cu F.Paste F.SilkS F.Mask)) + (pad 2 thru_hole oval (at 5 0) (size 1.9812 3.9624) (drill 1.3208) (layers *.Cu F.Paste F.SilkS F.Mask)) + (pad 3 thru_hole oval (at 10 0) (size 1.9812 3.9624) (drill 1.3208) (layers *.Cu F.Paste F.SilkS F.Mask)) +) diff --git a/PCB/.pretty/AK300-3.kicad_mod.REMOVED.git-id b/PCB/.pretty/AK300-3.kicad_mod.REMOVED.git-id deleted file mode 100644 index d5a9e155..00000000 --- a/PCB/.pretty/AK300-3.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b3eaf956a700814d846905be785916f0510b1c9d \ No newline at end of file diff --git a/PCB/.pretty/AK300-4.kicad_mod b/PCB/.pretty/AK300-4.kicad_mod new file mode 100644 index 00000000..ca53533d --- /dev/null +++ b/PCB/.pretty/AK300-4.kicad_mod @@ -0,0 +1,150 @@ +(module AK300-4 (layer F.Cu) (tedit 54791E04) + (descr CONNECTOR) + (tags CONNECTOR) + (attr virtual) + (fp_text reference REF** (at -1.945 -6.985) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value AK300-4 (at 2.754 7.747) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 18.35 -6.473) (end 18.35 6.473) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.83 -6.473) (end -2.83 6.473) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.83 6.473) (end 18.35 6.473) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.83 -6.473) (end 18.35 -6.473) (layer F.CrtYd) (width 0.05)) + (fp_line (start 8.75 -0.254) (end 8.75 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.75 2.54) (end 11.29 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.29 2.54) (end 11.29 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.9372 -3.429) (end 7.9372 -5.969) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.9372 -5.969) (end 12.0012 -5.969) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.0012 -5.969) (end 12.0012 -3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.0012 -3.429) (end 7.9372 -3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.3436 -4.445) (end 11.3916 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.4706 -4.318) (end 11.5186 -4.953) (layer F.SilkS) (width 0.15)) + (fp_arc (start 10.9852 -4.59486) (end 11.49066 -5.05206) (angle 90.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start 10.02 -6.0706) (end 11.48304 -4.11734) (angle 75.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start 9.94126 -3.7084) (end 8.3436 -5.0038) (angle 100) (layer F.SilkS) (width 0.15)) + (fp_arc (start 8.8262 -4.64566) (end 8.53664 -4.1275) (angle 104.2) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.988 4.318) (end 12.052 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.052 6.223) (end 12.052 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.369 0.508) (end 8.75 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.369 0.508) (end 8.369 3.683) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.369 3.683) (end 11.671 3.683) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.671 3.683) (end 11.671 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.671 0.508) (end 11.29 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.51 -0.635) (end 17.59 -0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.988 6.223) (end 7.988 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.988 -0.254) (end 12.052 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.955 6.223) (end 13.018 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.168 6.223) (end 7.072 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.59 -3.048) (end -2.58 -3.048) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.74 -6.223) (end -2.58 -6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.66 -0.635) (end -2.5165 -0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.9545 4.0005) (end 12.9545 -0.254) (layer F.SilkS) (width 0.15)) + (fp_arc (start 13.8562 -4.64566) (end 13.56664 -4.1275) (angle 104.2) (layer F.SilkS) (width 0.15)) + (fp_arc (start 14.97126 -3.7084) (end 13.3736 -5.0038) (angle 100) (layer F.SilkS) (width 0.15)) + (fp_arc (start 15.05 -6.0706) (end 16.51304 -4.11734) (angle 75.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start 16.0152 -4.59486) (end 16.52066 -5.05206) (angle 90.5) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.3482 -0.254) (end 16.6502 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.9672 -0.254) (end 13.3482 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.0312 -0.254) (end 16.6502 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.5006 -4.318) (end 16.5486 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.3736 -4.445) (end 16.4216 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.0312 -3.429) (end 12.9672 -3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.0312 -5.969) (end 17.0312 -3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.9672 -5.969) (end 17.0312 -5.969) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.9672 -3.429) (end 12.9672 -5.969) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.59 -3.175) (end 17.59 -1.651) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.59 -0.635) (end 17.59 4.064) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.59 -1.651) (end 17.59 -0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.6502 0.508) (end 16.2692 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.3482 0.508) (end 13.7292 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.3482 3.683) (end 13.3482 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.6502 3.683) (end 13.3482 3.683) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.6502 3.683) (end 16.6502 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.0312 4.318) (end 17.0312 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.9672 4.318) (end 17.0312 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.0312 6.223) (end 17.59 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.0312 -0.254) (end 17.0312 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.9672 6.223) (end 12.9672 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.098 3.81) (end 18.098 5.461) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.59 4.064) (end 17.59 5.207) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.098 3.81) (end 17.59 4.064) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.59 5.207) (end 17.59 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.098 5.461) (end 17.59 5.207) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.098 -1.397) (end 17.59 -1.651) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.098 -6.223) (end 18.098 -1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.59 -6.223) (end 18.098 -6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.59 -6.223) (end 17.59 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.7292 2.54) (end 13.7292 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.7292 -0.254) (end 16.2692 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.2692 2.54) (end 16.2692 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.7292 2.54) (end 16.2692 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.2846 2.54) (end 1.2554 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.2554 2.54) (end 1.2554 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.2846 -0.254) (end 1.2554 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.2846 2.54) (end -1.2846 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.7192 2.54) (end 6.2592 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.2592 2.54) (end 6.2592 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.7192 -0.254) (end 6.2592 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.7192 2.54) (end 3.7192 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.9545 5.207) (end 12.9545 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.9545 4.064) (end 12.9545 5.207) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9572 6.223) (end 2.9572 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0212 -0.254) (end 7.0212 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9572 6.223) (end 7.0212 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 6.223) (end 2.0174 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 6.223) (end 2.9572 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0466 -0.254) (end -2.0466 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 6.223) (end -2.0466 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0466 6.223) (end 2.0174 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9572 4.318) (end 7.0212 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9572 4.318) (end 2.9572 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0212 4.318) (end 7.0212 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 4.318) (end -2.0466 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 4.318) (end 2.0174 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0466 4.318) (end -2.0466 6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.6402 3.683) (end 6.6402 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.6402 3.683) (end 3.3382 3.683) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.3382 3.683) (end 3.3382 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.6364 3.683) (end 1.6364 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.6364 3.683) (end -1.6656 3.683) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.6656 3.683) (end -1.6656 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.6656 0.508) (end -1.2846 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.6364 0.508) (end 1.2554 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.3382 0.508) (end 3.7192 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.6402 0.508) (end 6.2592 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 6.223) (end -2.58 -0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 -0.635) (end -2.58 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.58 -3.175) (end -2.58 -6.223) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9572 -3.429) (end 2.9572 -5.969) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9572 -5.969) (end 7.0212 -5.969) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0212 -5.969) (end 7.0212 -3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0212 -3.429) (end 2.9572 -3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 -3.429) (end 2.0174 -5.969) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 -3.429) (end -2.0466 -3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0466 -3.429) (end -2.0466 -5.969) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 -5.969) (end -2.0466 -5.969) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.3636 -4.445) (end 6.4116 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.4906 -4.318) (end 6.5386 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.6402 -4.445) (end 1.41034 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.5132 -4.318) (end 1.5348 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.0466 -0.254) (end -1.6656 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.0174 -0.254) (end 1.6364 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.6364 -0.254) (end -1.6656 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.0212 -0.254) (end 6.6402 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.9572 -0.254) (end 3.3382 -0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.3382 -0.254) (end 6.6402 -0.254) (layer F.SilkS) (width 0.15)) + (fp_arc (start 6.0052 -4.59486) (end 6.51066 -5.05206) (angle 90.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start 5.04 -6.0706) (end 6.50304 -4.11734) (angle 75.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start 4.96126 -3.7084) (end 3.3636 -5.0038) (angle 100) (layer F.SilkS) (width 0.15)) + (fp_arc (start 3.8462 -4.64566) (end 3.55664 -4.1275) (angle 104.2) (layer F.SilkS) (width 0.15)) + (fp_arc (start 1.0014 -4.59486) (end 1.5094 -5.05206) (angle 90.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start 0.03874 -6.0706) (end 1.50178 -4.11734) (angle 75.5) (layer F.SilkS) (width 0.15)) + (fp_arc (start -0.03746 -3.7084) (end -1.6402 -5.0038) (angle 100) (layer F.SilkS) (width 0.15)) + (fp_arc (start -1.1576 -4.64566) (end -1.44462 -4.1275) (angle 104.2) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole oval (at 0 0) (size 1.9812 3.9624) (drill 1.3208) (layers *.Cu F.Paste F.SilkS F.Mask)) + (pad 2 thru_hole oval (at 5 0) (size 1.9812 3.9624) (drill 1.3208) (layers *.Cu F.Paste F.SilkS F.Mask)) + (pad 4 thru_hole oval (at 15 0) (size 1.9812 3.9624) (drill 1.3208) (layers *.Cu F.Paste F.SilkS F.Mask)) + (pad 3 thru_hole oval (at 10 0) (size 1.9812 3.9624) (drill 1.3208) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/AK300-4.kicad_mod.REMOVED.git-id b/PCB/.pretty/AK300-4.kicad_mod.REMOVED.git-id deleted file mode 100644 index 0839c77b..00000000 --- a/PCB/.pretty/AK300-4.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ca53533d571a2218fc069aaaacc8be78d861ab4c \ No newline at end of file diff --git a/PCB/.pretty/BARREL_JACK.kicad_mod b/PCB/.pretty/BARREL_JACK.kicad_mod new file mode 100644 index 00000000..c465691e --- /dev/null +++ b/PCB/.pretty/BARREL_JACK.kicad_mod @@ -0,0 +1,18 @@ +(module BARREL_JACK (layer F.Cu) (tedit 0) + (descr "DC Barrel Jack") + (tags "Power Jack") + (fp_text reference REF** (at 10.09904 0 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value BARREL_JACK (at 0 -5.99948) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -4.0005 -4.50088) (end -4.0005 4.50088) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.50062 -4.50088) (end -7.50062 4.50088) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.50062 4.50088) (end 7.00024 4.50088) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.00024 4.50088) (end 7.00024 -4.50088) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.00024 -4.50088) (end -7.50062 -4.50088) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 6.20014 0) (size 3.50012 3.50012) (drill oval 1.00076 2.99974) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole rect (at 0.20066 0) (size 3.50012 3.50012) (drill oval 1.00076 2.99974) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole rect (at 3.2004 4.699) (size 3.50012 3.50012) (drill oval 2.99974 1.00076) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/BARREL_JACK.kicad_mod.REMOVED.git-id b/PCB/.pretty/BARREL_JACK.kicad_mod.REMOVED.git-id deleted file mode 100644 index 67df58e6..00000000 --- a/PCB/.pretty/BARREL_JACK.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c465691ed28d9f635b457f1efc29bae0c4f95cfd \ No newline at end of file diff --git a/PCB/.pretty/BUSPCI.kicad_mod b/PCB/.pretty/BUSPCI.kicad_mod new file mode 100644 index 00000000..e541a62c --- /dev/null +++ b/PCB/.pretty/BUSPCI.kicad_mod @@ -0,0 +1,257 @@ +(module BUSPCI (layer F.Cu) (tedit 0) + (descr "Connecteur Bus PCI") + (tags "PCI CONN") + (fp_text reference REF** (at -35.941 -4.699) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value BUSPCI (at -5.842 -4.699) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -63.754 -3.81) (end -63.754 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -63.754 4.445) (end -0.889 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.889 4.445) (end -0.889 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.889 -3.81) (end 0.889 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.889 -3.81) (end 0.889 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.889 4.445) (end 15.494 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.494 4.445) (end 15.494 -3.81) (layer F.SilkS) (width 0.15)) + (pad B1 connect rect (at -62.865 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B2 connect rect (at -61.595 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B3 connect rect (at -60.325 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B4 connect rect (at -59.055 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B5 connect rect (at -57.785 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B6 connect rect (at -56.515 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B7 connect rect (at -55.245 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B8 connect rect (at -53.975 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B9 connect rect (at -52.705 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B10 connect rect (at -51.435 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B11 connect rect (at -50.165 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B12 connect rect (at -48.895 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B13 connect rect (at -47.625 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B14 connect rect (at -46.355 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B15 connect rect (at -45.085 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B16 connect rect (at -43.815 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B17 connect rect (at -42.545 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B18 connect rect (at -41.275 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B19 connect rect (at -40.005 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B20 connect rect (at -38.735 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B21 connect rect (at -37.465 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B22 connect rect (at -36.195 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B23 connect rect (at -34.925 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B24 connect rect (at -33.655 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B25 connect rect (at -32.385 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B26 connect rect (at -31.115 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B27 connect rect (at -29.845 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B28 connect rect (at -28.575 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B29 connect rect (at -27.305 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B30 connect rect (at -26.035 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B31 connect rect (at -24.765 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B32 connect rect (at -23.495 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B33 connect rect (at -22.225 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B34 connect rect (at -20.955 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B35 connect rect (at -19.685 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B36 connect rect (at -18.415 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B37 connect rect (at -17.145 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B38 connect rect (at -15.875 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B39 connect rect (at -14.605 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B40 connect rect (at -13.335 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B41 connect rect (at -12.065 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B42 connect rect (at -10.795 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B43 connect rect (at -9.525 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B44 connect rect (at -8.255 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B45 connect rect (at -6.985 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B46 connect rect (at -5.715 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B47 connect rect (at -4.445 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B48 connect rect (at -3.175 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B49 connect rect (at -1.905 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B52 connect rect (at 1.905 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B53 connect rect (at 3.175 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B54 connect rect (at 4.445 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B55 connect rect (at 5.715 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B56 connect rect (at 6.985 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B57 connect rect (at 8.255 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B58 connect rect (at 9.525 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B59 connect rect (at 10.795 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B60 connect rect (at 12.065 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B61 connect rect (at 13.335 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad B62 connect rect (at 14.605 -0.254) (size 1.016 4.572) (layers F.Cu F.Mask)) + (pad A1 connect rect (at -62.865 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A2 connect rect (at -61.595 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A3 connect rect (at -60.325 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A4 connect rect (at -59.055 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A5 connect rect (at -57.785 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A6 connect rect (at -56.515 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A7 connect rect (at -55.245 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A8 connect rect (at -53.975 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A9 connect rect (at -52.705 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A10 connect rect (at -51.435 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A11 connect rect (at -50.165 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A12 connect rect (at -48.895 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A13 connect rect (at -47.625 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A14 connect rect (at -46.355 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A15 connect rect (at -45.085 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A16 connect rect (at -43.815 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A17 connect rect (at -42.545 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A18 connect rect (at -41.275 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A19 connect rect (at -40.005 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A20 connect rect (at -38.735 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A21 connect rect (at -37.465 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A22 connect rect (at -36.195 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A23 connect rect (at -34.925 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A24 connect rect (at -33.655 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A25 connect rect (at -32.385 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A26 connect rect (at -31.115 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A27 connect rect (at -29.845 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A28 connect rect (at -28.575 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A29 connect rect (at -27.305 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A30 connect rect (at -26.035 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A31 connect rect (at -24.765 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A32 connect rect (at -23.495 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A33 connect rect (at -22.225 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A34 connect rect (at -20.955 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A35 connect rect (at -19.685 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A36 connect rect (at -18.415 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A37 connect rect (at -17.145 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A38 connect rect (at -15.875 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A39 connect rect (at -14.605 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A40 connect rect (at -13.335 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A41 connect rect (at -12.065 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A42 connect rect (at -10.795 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A43 connect rect (at -9.525 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A44 connect rect (at -8.255 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A45 connect rect (at -6.985 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A46 connect rect (at -5.715 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A47 connect rect (at -4.445 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A48 connect rect (at -3.175 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A49 connect rect (at -1.905 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A52 connect rect (at 1.905 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A53 connect rect (at 3.175 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A54 connect rect (at 4.445 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A55 connect rect (at 5.715 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A56 connect rect (at 6.985 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A57 connect rect (at 8.255 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A58 connect rect (at 9.525 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A59 connect rect (at 10.795 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A60 connect rect (at 12.065 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A61 connect rect (at 13.335 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad A62 connect rect (at 14.605 -0.254) (size 1.016 4.572) (layers B.Cu B.Mask)) + (pad B2 connect rect (at -61.595 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B3 connect rect (at -60.325 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B4 connect rect (at -59.055 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B5 connect rect (at -57.785 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B6 connect rect (at -56.515 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B7 connect rect (at -55.245 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B8 connect rect (at -53.975 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B9 connect rect (at -52.705 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B10 connect rect (at -51.435 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B11 connect rect (at -50.165 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B12 connect rect (at -48.895 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B13 connect rect (at -47.625 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B14 connect rect (at -46.355 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B15 connect rect (at -45.085 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B16 connect rect (at -43.815 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B17 connect rect (at -42.545 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B18 connect rect (at -41.275 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B19 connect rect (at -40.005 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B20 connect rect (at -38.735 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B21 connect rect (at -37.465 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B22 connect rect (at -36.195 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B23 connect rect (at -34.925 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B24 connect rect (at -33.655 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B25 connect rect (at -32.385 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B26 connect rect (at -31.115 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B27 connect rect (at -29.845 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B28 connect rect (at -28.575 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B29 connect rect (at -27.305 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B30 connect rect (at -26.035 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B31 connect rect (at -24.765 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B32 connect rect (at -23.495 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B33 connect rect (at -22.225 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B34 connect rect (at -20.955 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B35 connect rect (at -19.685 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B36 connect rect (at -18.415 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B37 connect rect (at -17.145 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B38 connect rect (at -15.875 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B39 connect rect (at -14.605 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B40 connect rect (at -13.335 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B41 connect rect (at -12.065 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B42 connect rect (at -10.795 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B43 connect rect (at -9.525 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B44 connect rect (at -8.255 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B45 connect rect (at -6.985 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B46 connect rect (at -5.715 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B47 connect rect (at -4.445 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B48 connect rect (at -3.175 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B49 connect rect (at -1.905 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B52 connect rect (at 1.905 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B53 connect rect (at 3.175 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B54 connect rect (at 4.445 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B55 connect rect (at 5.715 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B56 connect rect (at 6.985 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B57 connect rect (at 8.255 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B58 connect rect (at 9.525 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B59 connect rect (at 10.795 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B60 connect rect (at 12.065 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B61 connect rect (at 13.335 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B62 connect rect (at 14.605 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad B1 connect rect (at -62.865 2.413) (size 0.508 0.762) (layers F.Cu F.Mask)) + (pad A1 connect rect (at -62.865 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A2 connect rect (at -61.595 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A3 connect rect (at -60.325 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A4 connect rect (at -59.055 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A5 connect rect (at -57.785 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A6 connect rect (at -56.515 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A7 connect rect (at -55.245 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A8 connect rect (at -53.975 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A9 connect rect (at -52.705 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A10 connect rect (at -51.435 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A11 connect rect (at -50.165 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A12 connect rect (at -48.895 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A13 connect rect (at -47.625 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A14 connect rect (at -46.355 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A15 connect rect (at -45.085 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A16 connect rect (at -43.815 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A17 connect rect (at -42.545 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A18 connect rect (at -41.275 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A19 connect rect (at -40.005 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A20 connect rect (at -38.735 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A21 connect rect (at -37.465 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A22 connect rect (at -36.195 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A23 connect rect (at -34.925 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A24 connect rect (at -33.655 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A25 connect rect (at -32.385 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A26 connect rect (at -31.115 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A27 connect rect (at -29.845 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A28 connect rect (at -28.575 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A29 connect rect (at -27.305 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A30 connect rect (at -26.035 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A31 connect rect (at -24.765 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A32 connect rect (at -23.495 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A33 connect rect (at -22.225 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A34 connect rect (at -20.955 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A35 connect rect (at -19.685 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A36 connect rect (at -18.415 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A37 connect rect (at -17.145 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A38 connect rect (at -15.875 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A39 connect rect (at -14.605 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A40 connect rect (at -13.335 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A41 connect rect (at -12.065 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A42 connect rect (at -10.795 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A43 connect rect (at -9.525 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A44 connect rect (at -8.255 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A45 connect rect (at -6.985 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A46 connect rect (at -5.715 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A47 connect rect (at -4.445 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A48 connect rect (at -3.175 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A49 connect rect (at -1.905 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A52 connect rect (at 1.905 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A53 connect rect (at 3.175 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A54 connect rect (at 4.445 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A55 connect rect (at 5.715 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A56 connect rect (at 6.985 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A57 connect rect (at 8.255 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A58 connect rect (at 9.525 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A59 connect rect (at 10.795 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A60 connect rect (at 12.065 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A61 connect rect (at 13.335 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) + (pad A62 connect rect (at 14.605 2.413) (size 0.508 0.762) (layers B.Cu B.Mask)) +) diff --git a/PCB/.pretty/BUSPCI.kicad_mod.REMOVED.git-id b/PCB/.pretty/BUSPCI.kicad_mod.REMOVED.git-id deleted file mode 100644 index 3553dd07..00000000 --- a/PCB/.pretty/BUSPCI.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e541a62c29517e64a69d527fa91743dbb7d3afc0 \ No newline at end of file diff --git a/PCB/.pretty/BUS_AT.kicad_mod b/PCB/.pretty/BUS_AT.kicad_mod new file mode 100644 index 00000000..9fe14dd5 --- /dev/null +++ b/PCB/.pretty/BUS_AT.kicad_mod @@ -0,0 +1,116 @@ +(module BUS_AT (layer F.Cu) (tedit 0) + (descr "Connecteur Bus AT ISA 16 bits") + (tags "CONN BUS ISA") + (fp_text reference REF** (at -22.86 -6.985) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value BUS_AT (at -43.815 -6.985) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 40.64 3.81) (end -40.64 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -40.64 3.81) (end -40.64 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -40.64 -3.81) (end -45.72 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -45.72 -3.81) (end -45.72 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -45.72 3.81) (end -93.98 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -93.98 3.81) (end -93.98 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -93.98 -5.08) (end 40.64 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 40.64 -5.08) (end 40.64 3.81) (layer F.SilkS) (width 0.15)) + (pad 1 connect rect (at 38.1 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 2 connect rect (at 35.56 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 3 connect rect (at 33.02 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 4 connect rect (at 30.48 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 5 connect rect (at 27.94 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 6 connect rect (at 25.4 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 7 connect rect (at 22.86 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 8 connect rect (at 20.32 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 9 connect rect (at 17.78 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 10 connect rect (at 15.24 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 11 connect rect (at 12.7 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 12 connect rect (at 10.16 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 13 connect rect (at 7.62 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 14 connect rect (at 5.08 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 15 connect rect (at 2.54 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 16 connect rect (at 0 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 17 connect rect (at -2.54 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 18 connect rect (at -5.08 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 19 connect rect (at -7.62 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 20 connect rect (at -10.16 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 21 connect rect (at -12.7 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 22 connect rect (at -15.24 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 23 connect rect (at -17.78 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 24 connect rect (at -20.32 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 25 connect rect (at -22.86 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 26 connect rect (at -25.4 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 27 connect rect (at -27.94 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 28 connect rect (at -30.48 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 29 connect rect (at -33.02 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 30 connect rect (at -35.56 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 31 connect rect (at -38.1 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 32 connect rect (at 38.1 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 33 connect rect (at 35.56 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 34 connect rect (at 33.02 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 35 connect rect (at 30.48 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 36 connect rect (at 27.94 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 37 connect rect (at 25.4 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 38 connect rect (at 22.86 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 39 connect rect (at 20.32 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 40 connect rect (at 17.78 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 41 connect rect (at 15.24 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 42 connect rect (at 12.7 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 43 connect rect (at 10.16 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 44 connect rect (at 7.62 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 45 connect rect (at 5.08 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 46 connect rect (at 2.54 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 47 connect rect (at 0 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 48 connect rect (at -2.54 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 49 connect rect (at -5.08 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 50 connect rect (at -7.62 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 51 connect rect (at -10.16 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 52 connect rect (at -12.7 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 53 connect rect (at -15.24 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 54 connect rect (at -17.78 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 55 connect rect (at -20.32 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 56 connect rect (at -22.86 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 57 connect rect (at -25.4 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 58 connect rect (at -27.94 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 59 connect rect (at -30.48 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 60 connect rect (at -33.02 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 61 connect rect (at -35.56 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 62 connect rect (at -38.1 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 63 connect rect (at -48.26 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 64 connect rect (at -50.8 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 65 connect rect (at -53.34 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 66 connect rect (at -55.88 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 67 connect rect (at -58.42 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 68 connect rect (at -60.96 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 69 connect rect (at -63.5 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 70 connect rect (at -66.04 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 71 connect rect (at -68.58 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 72 connect rect (at -71.12 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 73 connect rect (at -73.66 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 74 connect rect (at -76.2 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 75 connect rect (at -78.74 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 76 connect rect (at -81.28 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 77 connect rect (at -83.82 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 78 connect rect (at -86.36 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 79 connect rect (at -88.9 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 80 connect rect (at -91.44 0) (size 1.778 7.62) (layers B.Cu B.Mask)) + (pad 81 connect rect (at -48.26 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 82 connect rect (at -50.8 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 83 connect rect (at -53.34 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 84 connect rect (at -55.88 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 85 connect rect (at -58.42 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 86 connect rect (at -60.96 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 87 connect rect (at -63.5 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 88 connect rect (at -66.04 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 89 connect rect (at -68.58 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 90 connect rect (at -71.12 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 91 connect rect (at -73.66 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 92 connect rect (at -76.2 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 93 connect rect (at -78.74 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 94 connect rect (at -81.28 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 95 connect rect (at -83.82 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 96 connect rect (at -86.36 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 97 connect rect (at -88.9 0) (size 1.778 7.62) (layers F.Cu F.Mask)) + (pad 98 connect rect (at -91.44 0) (size 1.778 7.62) (layers F.Cu F.Mask)) +) diff --git a/PCB/.pretty/BUS_AT.kicad_mod.REMOVED.git-id b/PCB/.pretty/BUS_AT.kicad_mod.REMOVED.git-id deleted file mode 100644 index 9d8ff895..00000000 --- a/PCB/.pretty/BUS_AT.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9fe14dd590db6c0fa62d4aacd902adcd3623cda9 \ No newline at end of file diff --git a/PCB/.pretty/Banana_Jack_1Pin.kicad_mod b/PCB/.pretty/Banana_Jack_1Pin.kicad_mod new file mode 100644 index 00000000..49cea79f --- /dev/null +++ b/PCB/.pretty/Banana_Jack_1Pin.kicad_mod @@ -0,0 +1,17 @@ +(module Banana_Jack_1Pin (layer F.Cu) (tedit 0) + (descr "Single banana socket, footprint - 6mm drill") + (tags "banana socket") + (fp_text reference REF** (at 0.508 -6.858) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Banana_Jack_1Pin (at 0.762 -8.382) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_circle (center 0 0) (end 0 -6.096) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole circle (at 0 0) (size 10.16 10.16) (drill 6.096) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/Banana_Jack_1Pin.wrl + (at (xyz 0 0 0)) + (scale (xyz 2 2 2)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/Banana_Jack_1Pin.kicad_mod.REMOVED.git-id b/PCB/.pretty/Banana_Jack_1Pin.kicad_mod.REMOVED.git-id deleted file mode 100644 index 86ae0787..00000000 --- a/PCB/.pretty/Banana_Jack_1Pin.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -49cea79fdee9474953b216bb5855c1097fc782ed \ No newline at end of file diff --git a/PCB/.pretty/Banana_Jack_2Pin.kicad_mod b/PCB/.pretty/Banana_Jack_2Pin.kicad_mod new file mode 100644 index 00000000..1c13a9c9 --- /dev/null +++ b/PCB/.pretty/Banana_Jack_2Pin.kicad_mod @@ -0,0 +1,21 @@ +(module Banana_Jack_2Pin (layer F.Cu) (tedit 0) + (descr "Dual banana socket, footprint - 2 x 6mm drills") + (tags "banana socket") + (fp_text reference REF** (at 0 1.27) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Banana_Jack_2Pin (at 0 -1.27) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -21.59 -6.35) (end 21.59 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start 21.59 -6.35) (end 21.59 6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start 21.59 6.35) (end -21.59 6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.59 6.35) (end -21.59 -6.35) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole circle (at -14.986 0) (size 10.16 10.16) (drill 6.096) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 14.986 0) (size 10.16 10.16) (drill 6.096) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/Banana_Jack_2Pin.wrl + (at (xyz 0 0 0)) + (scale (xyz 2 2 2)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/Banana_Jack_2Pin.kicad_mod.REMOVED.git-id b/PCB/.pretty/Banana_Jack_2Pin.kicad_mod.REMOVED.git-id deleted file mode 100644 index 27615438..00000000 --- a/PCB/.pretty/Banana_Jack_2Pin.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1c13a9c9353557bc397645dd98189428c1931cb9 \ No newline at end of file diff --git a/PCB/.pretty/Banana_Jack_3Pin.kicad_mod b/PCB/.pretty/Banana_Jack_3Pin.kicad_mod new file mode 100644 index 00000000..b747422e --- /dev/null +++ b/PCB/.pretty/Banana_Jack_3Pin.kicad_mod @@ -0,0 +1,22 @@ +(module Banana_Jack_3Pin (layer F.Cu) (tedit 0) + (descr "Triple banana socket, footprint - 3 x 6mm drills") + (tags "banana socket") + (fp_text reference REF** (at 10.16 -7.62) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Banana_Jack_3Pin (at -7.62 -7.62) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -21.59 -6.35) (end 21.59 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start 21.59 -6.35) (end 21.59 6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start 21.59 6.35) (end -21.59 6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.59 6.35) (end -21.59 -6.35) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole circle (at -14.986 0) (size 10.16 10.16) (drill 6.096) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 14.986 0) (size 10.16 10.16) (drill 6.096) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 0 0) (size 10.16 10.16) (drill 6.096) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/Banana_Jack_3Pin.wrl + (at (xyz 0 0 0)) + (scale (xyz 2 2 2)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/Banana_Jack_3Pin.kicad_mod.REMOVED.git-id b/PCB/.pretty/Banana_Jack_3Pin.kicad_mod.REMOVED.git-id deleted file mode 100644 index e89a0f83..00000000 --- a/PCB/.pretty/Banana_Jack_3Pin.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b747422e14b3c4a7571943aa2cbc63c22ea318cb \ No newline at end of file diff --git a/PCB/.pretty/C96ABCFD.kicad_mod b/PCB/.pretty/C96ABCFD.kicad_mod new file mode 100644 index 00000000..44132d65 --- /dev/null +++ b/PCB/.pretty/C96ABCFD.kicad_mod @@ -0,0 +1,123 @@ +(module C96ABCFD (layer F.Cu) (tedit 0) + (descr "Connecteur DIN Europe 96 contacts ABC male droit") + (tags "CONN DIN") + (fp_text reference REF** (at -26.035 -7.62) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C96ABCFD (at 20.955 -7.62) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -46.99 5.08) (end 46.99 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 46.99 5.08) (end 46.99 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -46.99 -2.54) (end -46.99 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -41.91 -2.54) (end -41.91 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 41.91 -2.54) (end 41.91 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -46.99 -2.54) (end -46.99 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -46.99 -5.08) (end 46.99 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 46.99 -5.08) (end 46.99 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 41.91 -5.08) (end 41.91 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -41.91 -2.54) (end -41.91 -5.08) (layer F.SilkS) (width 0.15)) + (pad 65 thru_hole circle (at -44.45 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 66 thru_hole circle (at 44.45 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad A3 thru_hole circle (at -34.29 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A4 thru_hole circle (at -31.75 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A5 thru_hole circle (at -29.21 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A6 thru_hole circle (at -26.67 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A7 thru_hole circle (at -24.13 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A8 thru_hole circle (at -21.59 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A9 thru_hole circle (at -19.05 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A10 thru_hole circle (at -16.51 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A11 thru_hole circle (at -13.97 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A12 thru_hole circle (at -11.43 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A13 thru_hole circle (at -8.89 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A14 thru_hole circle (at -6.35 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A15 thru_hole circle (at -3.81 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A16 thru_hole circle (at -1.27 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A17 thru_hole circle (at 1.27 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A18 thru_hole circle (at 3.81 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A19 thru_hole circle (at 6.35 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A20 thru_hole circle (at 8.89 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A21 thru_hole circle (at 11.43 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A22 thru_hole circle (at 13.97 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A23 thru_hole circle (at 16.51 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A24 thru_hole circle (at 19.05 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A25 thru_hole circle (at 21.59 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A26 thru_hole circle (at 24.13 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A27 thru_hole circle (at 26.67 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A28 thru_hole circle (at 29.21 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A29 thru_hole circle (at 31.75 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A30 thru_hole circle (at 34.29 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A31 thru_hole circle (at 36.83 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A32 thru_hole circle (at 39.37 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A2 thru_hole circle (at -36.83 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A1 thru_hole rect (at -39.37 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B1 thru_hole circle (at -39.37 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B2 thru_hole circle (at -36.83 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B3 thru_hole circle (at -34.29 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B4 thru_hole circle (at -31.75 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B5 thru_hole circle (at -29.21 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B6 thru_hole circle (at -26.67 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B7 thru_hole circle (at -24.13 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B8 thru_hole circle (at -21.59 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B9 thru_hole circle (at -19.05 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B10 thru_hole circle (at -16.51 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B11 thru_hole circle (at -13.97 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B12 thru_hole circle (at -11.43 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B13 thru_hole circle (at -8.89 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B14 thru_hole circle (at -6.35 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B15 thru_hole circle (at -3.81 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B16 thru_hole circle (at -1.27 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B17 thru_hole circle (at 1.27 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B18 thru_hole circle (at 3.81 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B19 thru_hole circle (at 6.35 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B20 thru_hole circle (at 8.89 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B21 thru_hole circle (at 11.43 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B22 thru_hole circle (at 13.97 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B23 thru_hole circle (at 16.51 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B24 thru_hole circle (at 19.05 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B25 thru_hole circle (at 21.59 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B26 thru_hole circle (at 24.13 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B27 thru_hole circle (at 26.67 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B28 thru_hole circle (at 29.21 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B29 thru_hole circle (at 31.75 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B30 thru_hole circle (at 34.29 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B31 thru_hole circle (at 36.83 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B32 thru_hole circle (at 39.37 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C1 thru_hole circle (at -39.37 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C2 thru_hole circle (at -36.83 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C3 thru_hole circle (at -34.29 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C4 thru_hole circle (at -31.75 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C5 thru_hole circle (at -29.21 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C6 thru_hole circle (at -26.67 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C7 thru_hole circle (at -24.13 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C8 thru_hole circle (at -21.59 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C9 thru_hole circle (at -19.05 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C10 thru_hole circle (at -16.51 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C11 thru_hole circle (at -13.97 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C12 thru_hole circle (at -11.43 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C13 thru_hole circle (at -8.89 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C14 thru_hole circle (at -6.35 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C15 thru_hole circle (at -3.81 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C16 thru_hole circle (at -1.27 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C17 thru_hole circle (at 1.27 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C18 thru_hole circle (at 3.81 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C19 thru_hole circle (at 6.35 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C20 thru_hole circle (at 8.89 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C21 thru_hole circle (at 11.43 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C22 thru_hole circle (at 13.97 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C23 thru_hole circle (at 16.51 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C24 thru_hole circle (at 19.05 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C25 thru_hole circle (at 21.59 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C26 thru_hole circle (at 24.13 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C27 thru_hole circle (at 26.67 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C28 thru_hole circle (at 29.21 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C29 thru_hole circle (at 31.75 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C30 thru_hole circle (at 34.29 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C31 thru_hole circle (at 36.83 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C32 thru_hole circle (at 39.37 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/C96ABCFD.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/C96ABCFD.kicad_mod.REMOVED.git-id b/PCB/.pretty/C96ABCFD.kicad_mod.REMOVED.git-id deleted file mode 100644 index 42fef03b..00000000 --- a/PCB/.pretty/C96ABCFD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -44132d653091e96500285ef9ae0cec67f0124104 \ No newline at end of file diff --git a/PCB/.pretty/C96ABCMD.kicad_mod b/PCB/.pretty/C96ABCMD.kicad_mod new file mode 100644 index 00000000..babd9ce7 --- /dev/null +++ b/PCB/.pretty/C96ABCMD.kicad_mod @@ -0,0 +1,123 @@ +(module C96ABCMD (layer F.Cu) (tedit 0) + (descr "Connecteur DIN Europe 96 contacts ABC male droit") + (tags "CONN DIN") + (fp_text reference REF** (at -26.035 -7.62) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C96ABCMD (at 20.955 -7.62) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -46.99 -5.08) (end 46.99 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 46.99 -5.08) (end 46.99 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -46.99 2.54) (end -46.99 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -41.91 2.54) (end -41.91 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 41.91 2.54) (end 41.91 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -46.99 2.54) (end -46.99 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -46.99 5.08) (end 46.99 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 46.99 5.08) (end 46.99 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 41.91 5.08) (end 41.91 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -41.91 2.54) (end -41.91 5.08) (layer F.SilkS) (width 0.15)) + (pad 65 thru_hole circle (at -44.45 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 66 thru_hole circle (at 44.45 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad A3 thru_hole circle (at -34.29 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A4 thru_hole circle (at -31.75 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A5 thru_hole circle (at -29.21 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A6 thru_hole circle (at -26.67 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A7 thru_hole circle (at -24.13 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A8 thru_hole circle (at -21.59 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A9 thru_hole circle (at -19.05 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A10 thru_hole circle (at -16.51 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A11 thru_hole circle (at -13.97 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A12 thru_hole circle (at -11.43 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A13 thru_hole circle (at -8.89 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A14 thru_hole circle (at -6.35 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A15 thru_hole circle (at -3.81 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A16 thru_hole circle (at -1.27 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A17 thru_hole circle (at 1.27 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A18 thru_hole circle (at 3.81 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A19 thru_hole circle (at 6.35 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A20 thru_hole circle (at 8.89 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A21 thru_hole circle (at 11.43 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A22 thru_hole circle (at 13.97 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A23 thru_hole circle (at 16.51 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A24 thru_hole circle (at 19.05 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A25 thru_hole circle (at 21.59 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A26 thru_hole circle (at 24.13 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A27 thru_hole circle (at 26.67 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A28 thru_hole circle (at 29.21 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A29 thru_hole circle (at 31.75 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A30 thru_hole circle (at 34.29 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A31 thru_hole circle (at 36.83 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A32 thru_hole circle (at 39.37 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A2 thru_hole circle (at -36.83 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A1 thru_hole rect (at -39.37 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B1 thru_hole circle (at -39.37 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B2 thru_hole circle (at -36.83 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B3 thru_hole circle (at -34.29 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B4 thru_hole circle (at -31.75 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B5 thru_hole circle (at -29.21 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B6 thru_hole circle (at -26.67 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B7 thru_hole circle (at -24.13 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B8 thru_hole circle (at -21.59 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B9 thru_hole circle (at -19.05 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B10 thru_hole circle (at -16.51 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B11 thru_hole circle (at -13.97 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B12 thru_hole circle (at -11.43 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B13 thru_hole circle (at -8.89 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B14 thru_hole circle (at -6.35 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B15 thru_hole circle (at -3.81 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B16 thru_hole circle (at -1.27 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B17 thru_hole circle (at 1.27 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B18 thru_hole circle (at 3.81 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B19 thru_hole circle (at 6.35 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B20 thru_hole circle (at 8.89 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B21 thru_hole circle (at 11.43 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B22 thru_hole circle (at 13.97 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B23 thru_hole circle (at 16.51 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B24 thru_hole circle (at 19.05 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B25 thru_hole circle (at 21.59 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B26 thru_hole circle (at 24.13 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B27 thru_hole circle (at 26.67 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B28 thru_hole circle (at 29.21 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B29 thru_hole circle (at 31.75 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B30 thru_hole circle (at 34.29 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B31 thru_hole circle (at 36.83 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B32 thru_hole circle (at 39.37 0) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C1 thru_hole circle (at -39.37 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C2 thru_hole circle (at -36.83 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C3 thru_hole circle (at -34.29 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C4 thru_hole circle (at -31.75 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C5 thru_hole circle (at -29.21 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C6 thru_hole circle (at -26.67 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C7 thru_hole circle (at -24.13 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C8 thru_hole circle (at -21.59 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C9 thru_hole circle (at -19.05 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C10 thru_hole circle (at -16.51 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C11 thru_hole circle (at -13.97 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C12 thru_hole circle (at -11.43 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C13 thru_hole circle (at -8.89 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C14 thru_hole circle (at -6.35 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C15 thru_hole circle (at -3.81 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C16 thru_hole circle (at -1.27 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C17 thru_hole circle (at 1.27 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C18 thru_hole circle (at 3.81 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C19 thru_hole circle (at 6.35 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C20 thru_hole circle (at 8.89 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C21 thru_hole circle (at 11.43 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C22 thru_hole circle (at 13.97 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C23 thru_hole circle (at 16.51 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C24 thru_hole circle (at 19.05 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C25 thru_hole circle (at 21.59 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C26 thru_hole circle (at 24.13 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C27 thru_hole circle (at 26.67 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C28 thru_hole circle (at 29.21 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C29 thru_hole circle (at 31.75 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C30 thru_hole circle (at 34.29 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C31 thru_hole circle (at 36.83 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C32 thru_hole circle (at 39.37 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/C96ABCMD.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/C96ABCMD.kicad_mod.REMOVED.git-id b/PCB/.pretty/C96ABCMD.kicad_mod.REMOVED.git-id deleted file mode 100644 index 2fecd18a..00000000 --- a/PCB/.pretty/C96ABCMD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -babd9ce7c70c44d5a0c96a9f2d6f0be2b606df4a \ No newline at end of file diff --git a/PCB/.pretty/CNT3BRCMS.kicad_mod b/PCB/.pretty/CNT3BRCMS.kicad_mod new file mode 100644 index 00000000..be921d4b --- /dev/null +++ b/PCB/.pretty/CNT3BRCMS.kicad_mod @@ -0,0 +1,26 @@ +(module CNT3BRCMS (layer F.Cu) (tedit 0) + (attr smd) + (fp_text reference REF** (at 2.54 0 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value CNT3BRCMS (at 2.54 0 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 4.7625 -2.667) (end 3.81 -2.667) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 -2.667) (end 3.81 2.667) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 2.667) (end 4.7625 2.667) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.635 0) (end 0.635 -2.794) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.635 -2.794) (end 1.397 -2.794) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.397 -2.794) (end 1.397 -4.826) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.397 -4.826) (end 4.7625 -4.826) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.7625 -4.826) (end 4.7625 4.826) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.7625 4.826) (end 1.397 4.826) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.397 4.826) (end 1.397 2.794) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.397 2.794) (end 0.635 2.794) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.635 2.794) (end 0.635 0) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at 0 -1.27) (size 1.778 0.8128) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at 0 0) (size 1.778 0.8128) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at 0 1.27) (size 1.778 0.8128) (layers F.Cu F.Paste F.Mask)) + (pad "" smd rect (at 2.9845 -3.81) (size 3.048 2.032) (layers F.Cu F.Paste F.Mask)) + (pad "" smd rect (at 2.9845 3.81) (size 3.048 2.032) (layers F.Cu F.Paste F.Mask)) +) diff --git a/PCB/.pretty/CNT3BRCMS.kicad_mod.REMOVED.git-id b/PCB/.pretty/CNT3BRCMS.kicad_mod.REMOVED.git-id deleted file mode 100644 index d2221ef2..00000000 --- a/PCB/.pretty/CNT3BRCMS.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -be921d4bd59feab93387ef8d454d749c461e5376 \ No newline at end of file diff --git a/PCB/.pretty/CR1220.kicad_mod b/PCB/.pretty/CR1220.kicad_mod new file mode 100644 index 00000000..6b049dea --- /dev/null +++ b/PCB/.pretty/CR1220.kicad_mod @@ -0,0 +1,22 @@ +(module CR1220 (layer F.Cu) (tedit 0) + (fp_text reference REF** (at 6.858 0 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value CR1220 (at 2.286 0 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -6.35 2.54) (end -2.667 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.35 -2.54) (end -2.667 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.35 2.54) (end -7.62 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 1.27) (end -7.62 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 -1.27) (end -6.35 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.001 -4.318) (end 9.525 -5.588) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.001 4.318) (end 9.525 5.588) (layer F.SilkS) (width 0.15)) + (fp_circle (center 4.445 0) (end -1.143 0) (layer F.SilkS) (width 0.15)) + (fp_circle (center 4.445 0) (end -2.667 2.54) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole circle (at -5.08 0) (size 3.556 3.556) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 4.445 0) (size 2.54 2.54) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 4.445 5.08) (size 2.159 2.159) (drill 2.032) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 8.89 -2.54) (size 2.159 2.159) (drill 2.032) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 0 -2.54) (size 2.159 2.159) (drill 2.032) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/CR1220.kicad_mod.REMOVED.git-id b/PCB/.pretty/CR1220.kicad_mod.REMOVED.git-id deleted file mode 100644 index d3737da8..00000000 --- a/PCB/.pretty/CR1220.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6b049dea60222f17c967b923b15db988c3610e92 \ No newline at end of file diff --git a/PCB/.pretty/CR2032H.kicad_mod b/PCB/.pretty/CR2032H.kicad_mod new file mode 100644 index 00000000..a768c87e --- /dev/null +++ b/PCB/.pretty/CR2032H.kicad_mod @@ -0,0 +1,23 @@ +(module CR2032H (layer F.Cu) (tedit 0) + (fp_text reference REF** (at 0 -12.7) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value CR2032H (at 0 12.7) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 15.24 3.81) (end 15.24 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.605 4.445) (end 15.875 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 10.795 -2.54) (end 17.145 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.145 -2.54) (end 17.145 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.145 2.54) (end 10.795 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.145 -3.175) (end 17.78 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.78 -3.175) (end 17.78 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.78 3.175) (end 17.145 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.875 -3.175) (end 17.145 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.145 3.175) (end 10.795 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 10.795 -3.175) (end 15.875 -3.175) (layer F.SilkS) (width 0.15)) + (fp_circle (center 0 0) (end -1.27 -8.89) (layer F.SilkS) (width 0.15)) + (fp_circle (center 0 0) (end 6.35 8.89) (layer F.SilkS) (width 0.15)) + (pad 2 thru_hole circle (at -7.62 0) (size 2.286 2.286) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole circle (at 15.24 0) (size 2.286 2.286) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/CR2032H.kicad_mod.REMOVED.git-id b/PCB/.pretty/CR2032H.kicad_mod.REMOVED.git-id deleted file mode 100644 index 7832ae65..00000000 --- a/PCB/.pretty/CR2032H.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a768c87e6a9e7d91e66d07b517ee135bc3e9ac3f \ No newline at end of file diff --git a/PCB/.pretty/CR2032V.kicad_mod b/PCB/.pretty/CR2032V.kicad_mod new file mode 100644 index 00000000..3c49cecf --- /dev/null +++ b/PCB/.pretty/CR2032V.kicad_mod @@ -0,0 +1,19 @@ +(module CR2032V (layer F.Cu) (tedit 0) + (fp_text reference REF** (at -7.62 -5.08) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value CR2032V (at 0 5.08) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -12.065 -3.302) (end 12.065 -3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.778 -1.778) (end 2.794 -1.778) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.874 2.286) (end 7.874 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.366 1.778) (end 8.382 1.778) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.065 3.175) (end 12.065 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.065 -2.667) (end -12.065 -2.667) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.065 -3.175) (end -12.065 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.065 3.175) (end 12.065 3.175) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole circle (at -5.08 1.778) (size 2.286 2.286) (drill 1.27) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole circle (at 5.08 1.778) (size 2.286 2.286) (drill 1.27) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 0 -1.524) (size 2.286 2.286) (drill 1.27) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/CR2032V.kicad_mod.REMOVED.git-id b/PCB/.pretty/CR2032V.kicad_mod.REMOVED.git-id deleted file mode 100644 index 3613108a..00000000 --- a/PCB/.pretty/CR2032V.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3c49cecfc116a4f3d35e94fd09562f77659f84d5 \ No newline at end of file diff --git a/PCB/.pretty/DB15FC.kicad_mod b/PCB/.pretty/DB15FC.kicad_mod new file mode 100644 index 00000000..4344932f --- /dev/null +++ b/PCB/.pretty/DB15FC.kicad_mod @@ -0,0 +1,51 @@ +(module DB15FC (layer F.Cu) (tedit 0) + (descr "Connecteur DB15 femelle couche") + (tags "CONN DB15") + (fp_text reference REF** (at 0 -15.24) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB15FC (at 0 -6.35) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 19.812 -11.43) (end -19.812 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.812 -12.7) (end -19.812 -12.7) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.462 -8.255) (end -13.462 -8.255) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.462 -18.415) (end 13.462 -18.415) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.462 -12.7) (end 13.462 -18.415) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.462 -8.255) (end 13.462 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.097 -6.35) (end 14.097 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.446 -6.35) (end 19.812 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.446 2.54) (end 12.446 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.812 2.54) (end 12.446 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.812 2.54) (end 19.812 -12.7) (layer F.SilkS) (width 0.15)) + (fp_line (start -14.097 -11.43) (end -14.097 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.192 -6.35) (end -12.192 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.812 2.54) (end -19.812 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.812 -6.35) (end -12.192 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.462 -8.255) (end -13.462 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.462 -18.415) (end -13.462 -12.7) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.812 -12.7) (end -19.812 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.812 2.54) (end -12.192 2.54) (layer F.SilkS) (width 0.15)) + (pad "" thru_hole circle (at 16.764 -1.016) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -16.764 -1.27) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -9.652 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -6.858 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -4.191 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -1.397 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 1.397 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 4.191 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 6.858 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 9.652 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -8.0772 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -5.5372 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -2.7432 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at 0 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at 2.7432 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at 5.5372 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at 8.2804 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/DB15FC.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/DB15FC.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB15FC.kicad_mod.REMOVED.git-id deleted file mode 100644 index 9b7388a0..00000000 --- a/PCB/.pretty/DB15FC.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4344932fb812ae92ab5e41aa10936c0b735ecfbc \ No newline at end of file diff --git a/PCB/.pretty/DB15FD.kicad_mod b/PCB/.pretty/DB15FD.kicad_mod new file mode 100644 index 00000000..095ef70c --- /dev/null +++ b/PCB/.pretty/DB15FD.kicad_mod @@ -0,0 +1,36 @@ +(module DB15FD (layer F.Cu) (tedit 0) + (descr "Connecteur DB15 femelle droit") + (tags "CONN DB15") + (fp_text reference REF** (at -10.16 -5.08 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB15FD (at 10.16 -5.08 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -18.415 -3.048) (end -18.415 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -18.415 3.302) (end 19.431 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.431 3.302) (end 19.431 -3.048) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.431 -3.048) (end -18.415 -3.048) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -16.129 0.127) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 17.145 0.127) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 10.16 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 7.366 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 4.699 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 1.905 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -0.889 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -3.556 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -6.35 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -9.017 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 8.763 1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at 5.969 1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at 3.302 1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at 0.508 1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -2.159 1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -4.953 1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -7.747 1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/DB15FD.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/DB15FD.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB15FD.kicad_mod.REMOVED.git-id deleted file mode 100644 index 28dfbbed..00000000 --- a/PCB/.pretty/DB15FD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -095ef70c84caa4af19f67521002bb9632aa71b91 \ No newline at end of file diff --git a/PCB/.pretty/DB15F_CI.kicad_mod b/PCB/.pretty/DB15F_CI.kicad_mod new file mode 100644 index 00000000..ba2ac1c4 --- /dev/null +++ b/PCB/.pretty/DB15F_CI.kicad_mod @@ -0,0 +1,48 @@ +(module DB15F_CI (layer F.Cu) (tedit 0) + (descr "Connecteur DB15 femelle encarte") + (tags "CONN DB15") + (fp_text reference REF** (at 0 -8.382) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB15F_CI (at 0 -2.667) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -12.7 -5.588) (end -12.7 -11.938) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.7 -11.938) (end 12.7 -11.938) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.7 -11.938) (end 12.7 -5.588) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.97 -4.318) (end -19.685 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.685 -4.318) (end -19.685 -5.588) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.685 -5.588) (end 19.685 -5.588) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.685 -5.588) (end 19.685 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.685 -4.318) (end 13.97 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.335 -1.143) (end -13.97 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.97 -1.143) (end -13.97 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.97 -4.318) (end 13.97 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.97 -4.318) (end 13.97 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.97 -1.143) (end 13.335 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.43 0.127) (end -13.335 0.127) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.335 0.127) (end -13.335 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.335 -1.143) (end 13.335 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.335 -1.143) (end 13.335 0.127) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.335 0.127) (end 11.43 0.127) (layer F.SilkS) (width 0.15)) + (pad 4 connect rect (at -1.397 2.667) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 3 connect rect (at -4.191 2.667) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 2 connect rect (at -6.985 2.667) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 1 connect rect (at -9.779 2.667) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 5 connect rect (at 1.397 2.667) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 6 connect rect (at 4.191 2.667) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 7 connect rect (at 6.985 2.667) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 8 connect rect (at 9.779 2.667) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 9 connect rect (at -8.382 2.667) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 10 connect rect (at -5.588 2.667) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 11 connect rect (at -2.794 2.667) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 12 connect rect (at 0 2.667) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 13 connect rect (at 2.794 2.667) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 14 connect rect (at 5.588 2.667) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 15 connect rect (at 8.382 2.667) (size 1.778 5.08) (layers B.Cu B.Mask)) + (model Connect.3dshapes/DB15F_CI.wrl + (at (xyz 0 0 -0.033)) + (scale (xyz 1 1 1)) + (rotate (xyz 90 180 0)) + ) +) diff --git a/PCB/.pretty/DB15F_CI.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB15F_CI.kicad_mod.REMOVED.git-id deleted file mode 100644 index db9012e4..00000000 --- a/PCB/.pretty/DB15F_CI.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ba2ac1c4f6892d5eb56a03aab11c83ba53ca2d0e \ No newline at end of file diff --git a/PCB/.pretty/DB15MC.kicad_mod b/PCB/.pretty/DB15MC.kicad_mod new file mode 100644 index 00000000..ebdd164f --- /dev/null +++ b/PCB/.pretty/DB15MC.kicad_mod @@ -0,0 +1,51 @@ +(module DB15MC (layer F.Cu) (tedit 0) + (descr "Connecteur DB15 MALE couche") + (tags "CONN DB15") + (fp_text reference REF** (at 0 -15.24) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB15MC (at 0 -6.35) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 19.812 -11.43) (end -19.812 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.812 -12.7) (end -19.812 -12.7) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.462 -8.255) (end -13.462 -8.255) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.462 -18.415) (end 13.462 -18.415) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.462 -12.7) (end 13.462 -18.415) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.462 -8.255) (end 13.462 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.097 -6.35) (end 14.097 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.446 -6.35) (end 19.812 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.446 2.54) (end 12.446 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.812 2.54) (end 12.446 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.812 2.54) (end 19.812 -12.7) (layer F.SilkS) (width 0.15)) + (fp_line (start -14.097 -11.43) (end -14.097 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.192 -6.35) (end -12.192 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.812 2.54) (end -19.812 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.812 -6.35) (end -12.192 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.462 -8.255) (end -13.462 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.462 -18.415) (end -13.462 -12.7) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.812 -12.7) (end -19.812 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.812 2.54) (end -12.192 2.54) (layer F.SilkS) (width 0.15)) + (pad "" thru_hole circle (at 16.764 -1.016) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -16.764 -1.27) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -9.652 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -6.858 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -4.191 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -1.397 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 1.397 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 4.191 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 6.858 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 9.652 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -8.0772 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -5.5372 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -2.7432 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at 0 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at 2.7432 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at 5.5372 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 8.2804 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/DB15MC.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/DB15MC.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB15MC.kicad_mod.REMOVED.git-id deleted file mode 100644 index 401e8a51..00000000 --- a/PCB/.pretty/DB15MC.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ebdd164fc6902e9291d3f225ffa8379c69da4386 \ No newline at end of file diff --git a/PCB/.pretty/DB15MD.kicad_mod b/PCB/.pretty/DB15MD.kicad_mod new file mode 100644 index 00000000..a7678976 --- /dev/null +++ b/PCB/.pretty/DB15MD.kicad_mod @@ -0,0 +1,36 @@ +(module DB15MD (layer F.Cu) (tedit 0) + (descr "Connecteur DB15 male droit") + (tags "CONN DB15") + (fp_text reference REF** (at -11.43 -5.08 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB15MD (at 8.89 -5.08 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -19.558 -3.048) (end -19.558 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.558 3.302) (end 18.288 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.288 3.302) (end 18.288 -3.048) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.288 -3.048) (end -19.558 -3.048) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -17.272 0.127) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 16.002 0.127) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -10.16 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -7.493 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -4.699 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -2.032 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 0.762 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 3.556 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 6.223 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 9.017 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -8.89 1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -6.096 1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -3.302 1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -0.635 1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at 2.159 1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at 4.826 1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at 7.62 1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/DB15MD.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/DB15MD.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB15MD.kicad_mod.REMOVED.git-id deleted file mode 100644 index 8bc1b962..00000000 --- a/PCB/.pretty/DB15MD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a76789767b940ab27597c2b54a43497f7cd88289 \ No newline at end of file diff --git a/PCB/.pretty/DB15M_CI.kicad_mod b/PCB/.pretty/DB15M_CI.kicad_mod new file mode 100644 index 00000000..59164808 --- /dev/null +++ b/PCB/.pretty/DB15M_CI.kicad_mod @@ -0,0 +1,48 @@ +(module DB15M_CI (layer F.Cu) (tedit 0) + (descr "Connecteur DB15 femelle encarte") + (tags "CONN DB15") + (fp_text reference REF** (at 0 -8.763) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB15M_CI (at 0 -2.667) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 12.7 -5.588) (end 12.7 -11.938) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.7 -11.938) (end -12.7 -11.938) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.7 -11.938) (end -12.7 -5.588) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.97 -4.318) (end 19.685 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.685 -4.318) (end 19.685 -5.588) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.685 -5.588) (end -19.685 -5.588) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.685 -5.588) (end -19.685 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.685 -4.318) (end -13.97 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.335 -1.143) (end 13.97 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.97 -1.143) (end 13.97 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.97 -4.318) (end -13.97 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.97 -4.318) (end -13.97 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.97 -1.143) (end -13.335 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.43 0.127) (end 13.335 0.127) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.335 0.127) (end 13.335 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.335 -1.143) (end -13.335 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.335 -1.143) (end -13.335 0.127) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.335 0.127) (end -11.43 0.127) (layer F.SilkS) (width 0.15)) + (pad 4 connect rect (at 1.397 2.667 180) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 3 connect rect (at 4.191 2.667 180) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 2 connect rect (at 6.985 2.667 180) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 1 connect rect (at 9.779 2.667 180) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 5 connect rect (at -1.397 2.667 180) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 6 connect rect (at -4.191 2.667 180) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 7 connect rect (at -6.985 2.667 180) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 8 connect rect (at -9.779 2.667 180) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 9 connect rect (at 8.382 2.667 180) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 10 connect rect (at 5.588 2.667 180) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 11 connect rect (at 2.794 2.667 180) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 12 connect rect (at 0 2.667 180) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 13 connect rect (at -2.794 2.667 180) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 14 connect rect (at -5.588 2.667 180) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 15 connect rect (at -8.382 2.667 180) (size 1.778 5.08) (layers B.Cu B.Mask)) + (model Connect.3dshapes/DB15M_CI.wrl + (at (xyz 0 0 -0.033)) + (scale (xyz 1 1 1)) + (rotate (xyz 90 180 0)) + ) +) diff --git a/PCB/.pretty/DB15M_CI.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB15M_CI.kicad_mod.REMOVED.git-id deleted file mode 100644 index ddd86da0..00000000 --- a/PCB/.pretty/DB15M_CI.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -59164808192957181fffd1ee4c2f7ffccf975cd9 \ No newline at end of file diff --git a/PCB/.pretty/DB25FC.kicad_mod b/PCB/.pretty/DB25FC.kicad_mod new file mode 100644 index 00000000..41d67f03 --- /dev/null +++ b/PCB/.pretty/DB25FC.kicad_mod @@ -0,0 +1,62 @@ +(module DB25FC (layer F.Cu) (tedit 0) + (descr "Connecteur DB25 femelle couche") + (tags "CONN DB25") + (fp_text reference REF** (at 0 -15.24) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB25FC (at 0 -6.35) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 26.67 -11.43) (end 26.67 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.05 -6.35) (end 19.05 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.955 -11.43) (end 20.955 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.955 -11.43) (end -20.955 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.05 -6.35) (end -19.05 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.67 2.54) (end -26.67 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.67 -6.35) (end 19.05 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.67 -6.35) (end -19.05 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.32 -8.255) (end 20.32 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -8.255) (end -20.32 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.32 -18.415) (end 20.32 -12.7) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -18.415) (end -20.32 -12.7) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.67 -11.43) (end 26.67 -12.7) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.67 -12.7) (end -26.67 -12.7) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.67 -12.7) (end -26.67 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.67 -11.43) (end 26.67 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.05 2.54) (end 26.67 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -8.255) (end 20.32 -8.255) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -18.415) (end 20.32 -18.415) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.67 2.54) (end -19.05 2.54) (layer F.SilkS) (width 0.15)) + (pad "" thru_hole circle (at 23.495 -1.27) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -23.495 -1.27) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -16.51 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -13.716 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -11.049 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -8.255 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -5.461 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -2.667 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 0 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 2.794 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 5.588 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at 8.382 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at 11.049 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at 13.843 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at 16.637 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -14.9352 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -12.3952 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at -9.6012 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at -6.858 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at -4.1148 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at -1.3208 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at 1.4224 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at 4.1656 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at 7.0104 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at 9.7028 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at 12.446 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at 15.24 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/DB25FC.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/DB25FC.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB25FC.kicad_mod.REMOVED.git-id deleted file mode 100644 index 4419ebf0..00000000 --- a/PCB/.pretty/DB25FC.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -41d67f0313060e4a00ef07a31348b167cab07de4 \ No newline at end of file diff --git a/PCB/.pretty/DB25FD.kicad_mod b/PCB/.pretty/DB25FD.kicad_mod new file mode 100644 index 00000000..991411db --- /dev/null +++ b/PCB/.pretty/DB25FD.kicad_mod @@ -0,0 +1,48 @@ +(module DB25FD (layer F.Cu) (tedit 0) + (descr "Connecteur DB25 femelle droit") + (tags "CONN DB25") + (fp_text reference REF** (at -15.24 -5.08 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB25FD (at 12.7 -5.08 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -25.654 -3.175) (end -25.654 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -25.654 -3.175) (end -25.654 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -25.654 3.175) (end 25.781 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 25.781 3.175) (end 25.781 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 25.781 -3.175) (end -25.527 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -25.527 -3.175) (end -25.654 -3.175) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -23.495 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 23.495 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 16.637 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 13.843 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 11.049 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 8.255 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 5.461 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 2.794 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 0 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -2.794 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -5.588 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -8.382 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -11.049 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -13.843 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -16.637 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at 15.24 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at 12.446 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at 9.652 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at 6.985 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at 4.191 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at 1.397 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at -1.397 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at -4.191 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at -6.858 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at -9.652 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at -12.446 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at -15.24 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/DB25FD.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/DB25FD.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB25FD.kicad_mod.REMOVED.git-id deleted file mode 100644 index e498bf3a..00000000 --- a/PCB/.pretty/DB25FD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -991411db0f1bc4f75506b16e064b654e83941dc2 \ No newline at end of file diff --git a/PCB/.pretty/DB25F_CI.kicad_mod b/PCB/.pretty/DB25F_CI.kicad_mod new file mode 100644 index 00000000..5286660e --- /dev/null +++ b/PCB/.pretty/DB25F_CI.kicad_mod @@ -0,0 +1,59 @@ +(module DB25F_CI (layer F.Cu) (tedit 0) + (descr "Connecteur DB25 femelle encarte") + (tags "CONN DB25") + (fp_text reference REF** (at 0 -2.54 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB25F_CI (at 0 -8.89 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 19.05 -0.508) (end 19.05 1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.05 1.143) (end 17.653 1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.05 -0.508) (end -19.05 1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.05 1.016) (end -17.78 1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.32 -0.508) (end -20.32 -0.508) (layer F.SilkS) (width 0.15)) + (fp_text user 1 (at -16.51 -1.905 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -20.32 -0.508) (end -20.32 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -4.318) (end 20.32 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.32 -4.318) (end 20.32 -0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -4.318) (end -25.4 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -25.4 -4.318) (end -25.4 -5.588) (layer F.SilkS) (width 0.15)) + (fp_line (start -25.4 -5.588) (end 25.4 -5.588) (layer F.SilkS) (width 0.15)) + (fp_line (start 25.4 -5.588) (end 25.4 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 25.4 -4.318) (end 20.32 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -5.588) (end -20.32 -11.303) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -11.303) (end 20.32 -11.303) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.32 -11.303) (end 20.32 -5.588) (layer F.SilkS) (width 0.15)) + (pad 1 connect rect (at -16.51 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 2 connect rect (at -13.716 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 3 connect rect (at -11.049 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 4 connect rect (at -8.255 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 5 connect rect (at -5.588 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 6 connect rect (at -2.794 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 7 connect rect (at 0 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 8 connect rect (at 2.667 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 9 connect rect (at 5.461 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 10 connect rect (at 8.128 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 11 connect rect (at 10.922 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 12 connect rect (at 13.716 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 13 connect rect (at 16.383 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 14 connect rect (at -15.113 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 15 connect rect (at -12.446 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 16 connect rect (at -9.652 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 17 connect rect (at -6.858 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 18 connect rect (at -4.191 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 19 connect rect (at -1.397 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 20 connect rect (at 1.27 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 21 connect rect (at 4.064 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 22 connect rect (at 6.858 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 23 connect rect (at 9.525 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 24 connect rect (at 12.319 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 25 connect rect (at 14.986 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (model Connect.3dshapes/DB25F_CI.wrl + (at (xyz 0 0 -0.033)) + (scale (xyz 0.98 1 1)) + (rotate (xyz 90 180 0)) + ) +) diff --git a/PCB/.pretty/DB25F_CI.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB25F_CI.kicad_mod.REMOVED.git-id deleted file mode 100644 index 0b6f2db3..00000000 --- a/PCB/.pretty/DB25F_CI.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5286660e8e948169fdaf2f1b2302be27d9ab9d5f \ No newline at end of file diff --git a/PCB/.pretty/DB25MC.kicad_mod b/PCB/.pretty/DB25MC.kicad_mod new file mode 100644 index 00000000..7987c74b --- /dev/null +++ b/PCB/.pretty/DB25MC.kicad_mod @@ -0,0 +1,62 @@ +(module DB25MC (layer F.Cu) (tedit 0) + (descr "Connecteur DB25 MALE couche") + (tags "CONN DB25") + (fp_text reference REF** (at 0 -15.24) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB25MC (at 0 -6.35) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 26.67 -11.43) (end 26.67 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.05 -6.35) (end 19.05 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.955 -11.43) (end 20.955 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.955 -11.43) (end -20.955 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.05 -6.35) (end -19.05 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.67 2.54) (end -26.67 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.67 -6.35) (end 19.05 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.67 -6.35) (end -19.05 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.32 -8.255) (end 20.32 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -8.255) (end -20.32 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.32 -18.415) (end 20.32 -12.7) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -18.415) (end -20.32 -12.7) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.67 -11.43) (end 26.67 -12.7) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.67 -12.7) (end -26.67 -12.7) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.67 -12.7) (end -26.67 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.67 -11.43) (end 26.67 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.05 2.54) (end 26.67 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -8.255) (end 20.32 -8.255) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -18.415) (end 20.32 -18.415) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.67 2.54) (end -19.05 2.54) (layer F.SilkS) (width 0.15)) + (pad "" thru_hole circle (at 23.495 -1.27) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -23.495 -1.27) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -16.51 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -13.716 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -11.049 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -8.255 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -5.461 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -2.667 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 0 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 2.794 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 5.588 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 8.382 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 11.049 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 13.843 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 16.637 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at -14.9352 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at -12.3952 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at -9.6012 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at -6.858 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at -4.1148 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at -1.3208 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at 1.4224 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at 4.1656 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at 7.0104 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at 9.7028 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at 12.446 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at 15.24 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/DB25MC.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/DB25MC.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB25MC.kicad_mod.REMOVED.git-id deleted file mode 100644 index c09dac56..00000000 --- a/PCB/.pretty/DB25MC.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7987c74bf49215be3166970b81c2f131fd63bea4 \ No newline at end of file diff --git a/PCB/.pretty/DB25MD.kicad_mod b/PCB/.pretty/DB25MD.kicad_mod new file mode 100644 index 00000000..68f9bc3c --- /dev/null +++ b/PCB/.pretty/DB25MD.kicad_mod @@ -0,0 +1,48 @@ +(module DB25MD (layer F.Cu) (tedit 0) + (descr "Connecteur DB25 male droit") + (tags "CONN DB25") + (fp_text reference REF** (at -17.78 -5.08 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB25MD (at 15.24 -5.08 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -25.654 -3.175) (end -25.654 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -25.654 -3.175) (end -25.654 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -25.654 3.175) (end 25.781 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 25.781 3.175) (end 25.781 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 25.781 -3.175) (end -25.527 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -25.527 -3.175) (end -25.654 -3.175) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -23.495 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 23.495 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -16.637 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -13.843 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -11.049 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -8.382 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -5.588 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -2.794 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 0 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 2.794 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 5.461 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at 8.255 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at 11.049 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at 13.843 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at 16.637 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -15.24 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -12.446 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at -9.652 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at -6.858 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at -4.191 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at -1.397 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at 1.397 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at 4.191 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at 6.985 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at 9.652 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at 12.446 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at 15.24 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/DB25MD.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/DB25MD.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB25MD.kicad_mod.REMOVED.git-id deleted file mode 100644 index fb189284..00000000 --- a/PCB/.pretty/DB25MD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -68f9bc3c58e8d302cb222d8ff34f35f696f908c0 \ No newline at end of file diff --git a/PCB/.pretty/DB25M_CI.kicad_mod b/PCB/.pretty/DB25M_CI.kicad_mod new file mode 100644 index 00000000..0004a65f --- /dev/null +++ b/PCB/.pretty/DB25M_CI.kicad_mod @@ -0,0 +1,56 @@ +(module DB25M_CI (layer F.Cu) (tedit 0) + (descr "Connecteur DB25 male couche") + (tags "CONN DB25") + (fp_text reference REF** (at 0 -2.667 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB25M_CI (at 0 -8.763 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 15.875 -0.508) (end 16.891 -3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.891 -3.302) (end 17.907 -0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.67 -4.318) (end 26.67 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.67 -5.588) (end -26.67 -5.588) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.67 -5.588) (end 26.67 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.67 -5.588) (end -26.67 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.32 -0.508) (end -20.32 -0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.05 -0.508) (end 19.05 1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.05 1.143) (end 17.78 1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.05 -0.508) (end -19.05 1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.05 1.016) (end -17.78 1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -0.508) (end -20.32 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.32 -4.318) (end 20.32 -0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -5.588) (end -20.32 -11.303) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -11.303) (end 20.32 -11.303) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.32 -11.303) (end 20.32 -5.588) (layer F.SilkS) (width 0.15)) + (pad 13 connect rect (at -16.51 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 12 connect rect (at -13.716 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 11 connect rect (at -11.049 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 10 connect rect (at -8.255 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 9 connect rect (at -5.588 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 8 connect rect (at -2.794 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 7 connect rect (at 0 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 6 connect rect (at 2.667 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 5 connect rect (at 5.461 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 4 connect rect (at 8.128 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 3 connect rect (at 10.922 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 2 connect rect (at 13.716 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 1 connect rect (at 16.383 2.667 90) (size 5.08 1.524) (layers F.Cu F.Mask)) + (pad 25 connect rect (at -15.113 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 24 connect rect (at -12.446 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 23 connect rect (at -9.652 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 22 connect rect (at -6.858 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 21 connect rect (at -4.191 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 20 connect rect (at -1.397 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 19 connect rect (at 1.27 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 18 connect rect (at 4.064 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 17 connect rect (at 6.858 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 16 connect rect (at 9.525 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 15 connect rect (at 12.319 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (pad 14 connect rect (at 14.986 2.667 90) (size 5.08 1.524) (layers B.Cu B.Mask)) + (model Connect.3dshapes/DB25M_CI.wrl + (at (xyz 0 0 -0.033)) + (scale (xyz 0.98 1 1)) + (rotate (xyz 90 180 0)) + ) +) diff --git a/PCB/.pretty/DB25M_CI.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB25M_CI.kicad_mod.REMOVED.git-id deleted file mode 100644 index 428a4a07..00000000 --- a/PCB/.pretty/DB25M_CI.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0004a65f1789e93d3f3852bde7b066cc629fef8f \ No newline at end of file diff --git a/PCB/.pretty/DB37FC.kicad_mod b/PCB/.pretty/DB37FC.kicad_mod new file mode 100644 index 00000000..f7da29b4 --- /dev/null +++ b/PCB/.pretty/DB37FC.kicad_mod @@ -0,0 +1,63 @@ +(module DB37FC (layer F.Cu) (tedit 0) + (descr "Connecteur DB37 femelle couche") + (tags "CONN DB37") + (fp_text reference REF** (at 0 -5.08 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB37FC (at 0 -7.62 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 34.925 3.175) (end -34.925 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -34.925 3.175) (end -34.925 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start -34.925 -12.065) (end 34.925 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start 34.925 -12.065) (end 34.925 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 25.4 -12.065) (end 25.4 -19.05) (layer F.SilkS) (width 0.15)) + (fp_line (start 25.4 -19.05) (end -25.4 -19.05) (layer F.SilkS) (width 0.15)) + (fp_line (start -25.4 -19.05) (end -25.4 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start 27.305 -12.065) (end 27.305 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -27.305 -12.065) (end -27.305 3.175) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -24.9174 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.SilkS *.Mask)) + (pad 2 thru_hole circle (at -22.1488 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -19.3802 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -16.6116 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -13.843 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -11.0744 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -8.3058 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -5.5372 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -2.7686 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad ? thru_hole circle (at -31.623 0 180) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad ? thru_hole circle (at 31.877 0 180) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at 0 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at 2.7686 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at 5.5372 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at 8.3058 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at 11.0744 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at 13.843 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at 16.6116 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at 19.3802 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at 22.1488 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at 24.9174 1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at -23.5458 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at -20.7772 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at -18.0086 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at -15.24 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at -12.4714 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at -9.7028 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 26 thru_hole circle (at -6.9342 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 27 thru_hole circle (at -4.1656 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 28 thru_hole circle (at -1.397 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 29 thru_hole circle (at 1.3716 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 30 thru_hole circle (at 4.1402 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 31 thru_hole circle (at 6.9088 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 32 thru_hole circle (at 9.6774 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 33 thru_hole circle (at 12.446 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 34 thru_hole circle (at 15.2146 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 35 thru_hole circle (at 17.9832 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 36 thru_hole circle (at 20.7518 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 37 thru_hole circle (at 23.5204 -1.4224 180) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/DB37FC.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/DB37FC.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB37FC.kicad_mod.REMOVED.git-id deleted file mode 100644 index d2894007..00000000 --- a/PCB/.pretty/DB37FC.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f7da29b4cc7611b7bd69b37d4e4cda8712a58e8e \ No newline at end of file diff --git a/PCB/.pretty/DB37FD.kicad_mod b/PCB/.pretty/DB37FD.kicad_mod new file mode 100644 index 00000000..c51d04fc --- /dev/null +++ b/PCB/.pretty/DB37FD.kicad_mod @@ -0,0 +1,53 @@ +(module DB37FD (layer F.Cu) (tedit 0) + (descr "Connecteur DB37 femelle droit") + (tags "CONN DB37") + (fp_text reference REF** (at -13.97 -5.08) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB37FD (at 12.7 -5.08) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -34.163 -3.175) (end -34.163 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -34.163 3.175) (end 33.909 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 33.909 3.175) (end 33.909 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 33.909 -3.175) (end -34.163 -3.175) (layer F.SilkS) (width 0.15)) + (pad "" thru_hole circle (at -31.75 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 31.75 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 24.892 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 22.098 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 19.431 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 16.637 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 13.843 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 11.049 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 8.255 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 5.588 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 2.794 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at 0 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -2.794 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -5.588 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -8.255 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -11.049 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -13.843 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at -16.637 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at -19.431 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at -22.098 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at -24.892 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at 23.495 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at 20.701 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at 17.907 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at 15.24 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at 12.446 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at 9.652 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 26 thru_hole circle (at 6.858 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 27 thru_hole circle (at 4.064 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 28 thru_hole circle (at 1.397 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 29 thru_hole circle (at -1.397 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 30 thru_hole circle (at -4.191 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 31 thru_hole circle (at -6.985 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 32 thru_hole circle (at -9.906 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 33 thru_hole circle (at -12.446 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 34 thru_hole circle (at -15.24 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 35 thru_hole circle (at -18.034 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 36 thru_hole circle (at -20.828 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 37 thru_hole circle (at -23.622 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/DB37FD.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB37FD.kicad_mod.REMOVED.git-id deleted file mode 100644 index 3acac029..00000000 --- a/PCB/.pretty/DB37FD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c51d04fc77a0bab7a6a47b20531e029004c584e5 \ No newline at end of file diff --git a/PCB/.pretty/DB37MD.kicad_mod b/PCB/.pretty/DB37MD.kicad_mod new file mode 100644 index 00000000..7e153664 --- /dev/null +++ b/PCB/.pretty/DB37MD.kicad_mod @@ -0,0 +1,54 @@ +(module DB37MD (layer F.Cu) (tedit 0) + (descr "Connecteur DB37 male droit") + (tags "CONN DB37") + (fp_text reference REF** (at -12.7 -5.08) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB37MD (at 12.7 -5.08) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -34.163 -3.175) (end -34.163 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -34.163 -3.175) (end -34.163 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -34.163 3.175) (end 33.909 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 33.909 3.175) (end 33.909 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 33.909 -3.175) (end -34.163 -3.175) (layer F.SilkS) (width 0.15)) + (pad "" thru_hole circle (at -31.75 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 31.75 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -24.892 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -22.098 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -19.431 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -16.637 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -13.843 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -11.049 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -8.255 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -5.588 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -2.794 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at 0 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at 2.794 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at 5.461 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at 8.255 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at 11.049 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at 13.843 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at 16.637 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at 19.431 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at 22.098 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at 24.892 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at -23.622 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at -20.828 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at -18.034 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at -15.24 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at -12.446 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at -9.906 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 26 thru_hole circle (at -6.985 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 27 thru_hole circle (at -4.191 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 28 thru_hole circle (at -1.397 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 29 thru_hole circle (at 1.397 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 30 thru_hole circle (at 4.064 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 31 thru_hole circle (at 6.858 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 32 thru_hole circle (at 9.652 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 33 thru_hole circle (at 12.446 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 34 thru_hole circle (at 15.24 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 35 thru_hole circle (at 17.907 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 36 thru_hole circle (at 20.701 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 37 thru_hole circle (at 23.495 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/DB37MD.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB37MD.kicad_mod.REMOVED.git-id deleted file mode 100644 index e90f7a79..00000000 --- a/PCB/.pretty/DB37MD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7e153664417d3cf34f3acc52fea02b959eff32cd \ No newline at end of file diff --git a/PCB/.pretty/DB9FC.kicad_mod b/PCB/.pretty/DB9FC.kicad_mod new file mode 100644 index 00000000..754d72ea --- /dev/null +++ b/PCB/.pretty/DB9FC.kicad_mod @@ -0,0 +1,36 @@ +(module DB9FC (layer F.Cu) (tedit 0) + (descr "Connecteur DB9 femelle couche") + (tags "CONN DB9") + (fp_text reference REF** (at 1.27 -10.16) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB9FC (at 1.27 -3.81) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -16.129 2.286) (end 16.383 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.383 2.286) (end 16.383 -15.494) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.383 -15.494) (end -16.129 -15.494) (layer F.SilkS) (width 0.15)) + (fp_line (start -16.129 -15.494) (end -16.129 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.017 -15.494) (end -9.017 -7.874) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.017 -7.874) (end 9.271 -7.874) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.271 -7.874) (end 9.271 -15.494) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.493 -15.494) (end -7.493 -24.13) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.493 -24.13) (end 7.747 -24.13) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.747 -24.13) (end 7.747 -15.494) (layer F.SilkS) (width 0.15)) + (pad "" thru_hole circle (at 12.827 -1.27) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -12.573 -1.27) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -5.461 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -2.667 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 0 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 2.794 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 5.588 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -4.064 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -1.27 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 1.397 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 4.191 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/DB9FC.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/DB9FC.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB9FC.kicad_mod.REMOVED.git-id deleted file mode 100644 index 2fc889e2..00000000 --- a/PCB/.pretty/DB9FC.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -754d72ea4f0089b7e485de602f7a50f82d172083 \ No newline at end of file diff --git a/PCB/.pretty/DB9FD.kicad_mod b/PCB/.pretty/DB9FD.kicad_mod new file mode 100644 index 00000000..c9134750 --- /dev/null +++ b/PCB/.pretty/DB9FD.kicad_mod @@ -0,0 +1,30 @@ +(module DB9FD (layer F.Cu) (tedit 0) + (descr "Connecteur DB9 femelle droit") + (tags "CONN DB9") + (fp_text reference REF** (at -6.096 -4.826 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB9FD (at 6.096 -4.826) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -14.986 -3.302) (end -14.986 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -14.986 3.302) (end 14.986 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.986 3.302) (end 14.986 -3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.986 -3.302) (end -14.986 -3.302) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -12.446 -0.127) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 12.573 -0.127) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 5.461 -1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.794 -1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 0 -1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -2.667 -1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -5.461 -1.524) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 4.191 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 1.397 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -1.27 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -4.064 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/DB9FD.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/DB9FD.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB9FD.kicad_mod.REMOVED.git-id deleted file mode 100644 index dc2fc87c..00000000 --- a/PCB/.pretty/DB9FD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c91347509ef2f6d95498ef301cd6ea97ea103955 \ No newline at end of file diff --git a/PCB/.pretty/DB9F_CI.kicad_mod b/PCB/.pretty/DB9F_CI.kicad_mod new file mode 100644 index 00000000..920d7b28 --- /dev/null +++ b/PCB/.pretty/DB9F_CI.kicad_mod @@ -0,0 +1,42 @@ +(module DB9F_CI (layer F.Cu) (tedit 0) + (descr "Connecteur DB9 femelle encarte") + (tags "CONN DB9") + (fp_text reference REF** (at 0 -9.144) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB9F_CI (at 0 -3.048) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -8.509 -12.065) (end 8.636 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.271 -1.27) (end -9.144 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.906 -1.27) (end 9.271 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.906 -4.445) (end -9.779 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.621 -4.445) (end 9.906 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.494 -5.715) (end 15.621 -5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.636 -5.715) (end 8.636 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.621 -4.445) (end 15.621 -5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.906 -1.27) (end 9.906 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.366 0) (end 9.271 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.271 0) (end 9.271 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.509 -5.715) (end -8.509 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.779 -4.445) (end -15.494 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.494 -4.445) (end -15.494 -5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.144 -1.27) (end -9.779 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.779 -1.27) (end -9.779 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.239 0) (end -9.144 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.144 0) (end -9.144 -1.27) (layer F.SilkS) (width 0.15)) + (pad 4 connect rect (at 2.794 2.54) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 3 connect rect (at 0 2.54) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 2 connect rect (at -2.794 2.54) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 1 connect rect (at -5.588 2.54) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 5 connect rect (at 5.588 2.54) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 6 connect rect (at -4.191 2.54) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 7 connect rect (at -1.397 2.54) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 8 connect rect (at 1.397 2.54) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 9 connect rect (at 4.191 2.54) (size 1.778 5.08) (layers B.Cu B.Mask)) + (model Connect.3dshapes/DB9F_CI.wrl + (at (xyz 0 0 -0.033)) + (scale (xyz 1 1 1)) + (rotate (xyz 90 180 0)) + ) +) diff --git a/PCB/.pretty/DB9F_CI.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB9F_CI.kicad_mod.REMOVED.git-id deleted file mode 100644 index dbf18a2d..00000000 --- a/PCB/.pretty/DB9F_CI.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -920d7b28a2fb450d31e616992cfe55b64f480f0c \ No newline at end of file diff --git a/PCB/.pretty/DB9F_CI_INVERT.kicad_mod b/PCB/.pretty/DB9F_CI_INVERT.kicad_mod new file mode 100644 index 00000000..bab5cc53 --- /dev/null +++ b/PCB/.pretty/DB9F_CI_INVERT.kicad_mod @@ -0,0 +1,42 @@ +(module DB9F_CI_INVERT (layer F.Cu) (tedit 0) + (descr "Connecteur DB9 male encarte") + (tags "CONN DB9") + (fp_text reference REF** (at 0 -9.144) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB9F_CI_INVERT (at 0 -2.667) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -8.509 -12.065) (end 8.636 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.271 -1.27) (end -9.144 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.906 -1.27) (end 9.271 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.906 -4.445) (end -9.779 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.621 -4.445) (end 9.906 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.494 -5.715) (end 15.621 -5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.636 -5.715) (end 8.636 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.621 -4.445) (end 15.621 -5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.906 -1.27) (end 9.906 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.366 0) (end 9.271 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.271 0) (end 9.271 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.509 -5.715) (end -8.509 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.779 -4.445) (end -15.494 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.494 -4.445) (end -15.494 -5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.144 -1.27) (end -9.779 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.779 -1.27) (end -9.779 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.239 0) (end -9.144 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.144 0) (end -9.144 -1.27) (layer F.SilkS) (width 0.15)) + (pad 2 connect rect (at 2.794 2.54) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 3 connect rect (at 0 2.54) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 4 connect rect (at -2.794 2.54) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 5 connect rect (at -5.588 2.54) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 1 connect rect (at 5.588 2.54) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 9 connect rect (at -4.191 2.54) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 8 connect rect (at -1.397 2.54) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 7 connect rect (at 1.397 2.54) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 6 connect rect (at 4.191 2.54) (size 1.778 5.08) (layers F.Cu F.Mask)) + (model Connect.3dshapes/DB9F_CI_INVERT.wrl + (at (xyz 0 0 -0.033)) + (scale (xyz 1 1 1)) + (rotate (xyz 90 0 0)) + ) +) diff --git a/PCB/.pretty/DB9F_CI_INVERT.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB9F_CI_INVERT.kicad_mod.REMOVED.git-id deleted file mode 100644 index 42d8fb6f..00000000 --- a/PCB/.pretty/DB9F_CI_INVERT.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bab5cc53cc64ca0c1d84a4ab5785d564829b8604 \ No newline at end of file diff --git a/PCB/.pretty/DB9MC.kicad_mod b/PCB/.pretty/DB9MC.kicad_mod new file mode 100644 index 00000000..33315dd7 --- /dev/null +++ b/PCB/.pretty/DB9MC.kicad_mod @@ -0,0 +1,36 @@ +(module DB9MC (layer F.Cu) (tedit 0) + (descr "Connecteur DB9 male couche") + (tags "CONN DB9") + (fp_text reference REF** (at 1.27 -10.16) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB9MC (at 1.27 -3.81) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -16.129 2.286) (end 16.383 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.383 2.286) (end 16.383 -15.494) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.383 -15.494) (end -16.129 -15.494) (layer F.SilkS) (width 0.15)) + (fp_line (start -16.129 -15.494) (end -16.129 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.017 -15.494) (end -9.017 -7.874) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.017 -7.874) (end 9.271 -7.874) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.271 -7.874) (end 9.271 -15.494) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.493 -15.494) (end -7.493 -24.13) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.493 -24.13) (end 7.747 -24.13) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.747 -24.13) (end 7.747 -15.494) (layer F.SilkS) (width 0.15)) + (pad "" thru_hole circle (at 12.827 -1.27) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -12.573 -1.27) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 5.588 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.794 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 0 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -2.667 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -5.461 1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -4.064 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -1.27 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 1.397 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 4.191 -1.27) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/DB9MC.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/DB9MC.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB9MC.kicad_mod.REMOVED.git-id deleted file mode 100644 index b700f9bc..00000000 --- a/PCB/.pretty/DB9MC.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -33315dd7e7cdb34549e778064e34e79cf7ea3070 \ No newline at end of file diff --git a/PCB/.pretty/DB9MD.kicad_mod b/PCB/.pretty/DB9MD.kicad_mod new file mode 100644 index 00000000..445e1316 --- /dev/null +++ b/PCB/.pretty/DB9MD.kicad_mod @@ -0,0 +1,30 @@ +(module DB9MD (layer F.Cu) (tedit 0) + (descr "Connecteur DB9 male droit") + (tags "CONN DB9") + (fp_text reference REF** (at -6.604 -4.572) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB9MD (at 5.08 -4.572) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -14.986 -3.175) (end -14.986 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start -14.986 3.429) (end 14.986 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.986 3.429) (end 14.986 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.986 -3.175) (end -14.986 -3.175) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -12.446 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 12.573 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -5.461 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -2.667 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 0 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 2.794 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 5.461 -1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -4.064 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -1.27 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 1.397 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 4.191 1.397) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/DB9MD.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/DB9MD.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB9MD.kicad_mod.REMOVED.git-id deleted file mode 100644 index fd937561..00000000 --- a/PCB/.pretty/DB9MD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -445e13168937984e6c5a4d01a808bff732bd5db2 \ No newline at end of file diff --git a/PCB/.pretty/DB9M_CI.kicad_mod b/PCB/.pretty/DB9M_CI.kicad_mod new file mode 100644 index 00000000..983cacad --- /dev/null +++ b/PCB/.pretty/DB9M_CI.kicad_mod @@ -0,0 +1,42 @@ +(module DB9M_CI (layer F.Cu) (tedit 0) + (descr "Connecteur DB9 male encarte") + (tags "CONN DB9") + (fp_text reference REF** (at 0 -8.382) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB9M_CI (at 0 -3.048) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -8.509 -11.938) (end 8.636 -11.938) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.271 -1.143) (end -9.144 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.906 -1.143) (end 9.271 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.906 -4.318) (end -9.779 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.621 -4.318) (end 9.906 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.494 -5.588) (end 15.621 -5.588) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.636 -5.588) (end 8.636 -11.938) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.621 -4.318) (end 15.621 -5.588) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.906 -1.143) (end 9.906 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.366 0.127) (end 9.271 0.127) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.271 0.127) (end 9.271 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.509 -5.588) (end -8.509 -11.938) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.779 -4.318) (end -15.494 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.494 -4.318) (end -15.494 -5.588) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.144 -1.143) (end -9.779 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.779 -1.143) (end -9.779 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.239 0.127) (end -9.144 0.127) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.144 0.127) (end -9.144 -1.143) (layer F.SilkS) (width 0.15)) + (pad 2 connect rect (at 2.794 2.667) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 3 connect rect (at 0 2.667) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 4 connect rect (at -2.794 2.667) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 5 connect rect (at -5.588 2.667) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 1 connect rect (at 5.588 2.667) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 9 connect rect (at -4.191 2.667) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 8 connect rect (at -1.397 2.667) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 7 connect rect (at 1.397 2.667) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 6 connect rect (at 4.191 2.667) (size 1.778 5.08) (layers B.Cu B.Mask)) + (model Connect.3dshapes/DB9M_CI.wrl + (at (xyz 0 0 -0.033)) + (scale (xyz 1 1 1)) + (rotate (xyz 90 180 0)) + ) +) diff --git a/PCB/.pretty/DB9M_CI.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB9M_CI.kicad_mod.REMOVED.git-id deleted file mode 100644 index e349d286..00000000 --- a/PCB/.pretty/DB9M_CI.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -983cacad3350f9fe74cbcc71030574ae559fa028 \ No newline at end of file diff --git a/PCB/.pretty/DB9M_CI_INVERT.kicad_mod b/PCB/.pretty/DB9M_CI_INVERT.kicad_mod new file mode 100644 index 00000000..0f9d6601 --- /dev/null +++ b/PCB/.pretty/DB9M_CI_INVERT.kicad_mod @@ -0,0 +1,42 @@ +(module DB9M_CI_INVERT (layer F.Cu) (tedit 0) + (descr "Connecteur DB9 femelle encarte") + (tags "CONN DB9") + (fp_text reference REF** (at 0 -9.144) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DB9M_CI_INVERT (at 0 -3.048) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -8.509 -12.065) (end 8.636 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.271 -1.27) (end -9.144 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.906 -1.27) (end 9.271 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.906 -4.445) (end -9.779 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.621 -4.445) (end 9.906 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.494 -5.715) (end 15.621 -5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.636 -5.715) (end 8.636 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.621 -4.445) (end 15.621 -5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.906 -1.27) (end 9.906 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.366 0) (end 9.271 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.271 0) (end 9.271 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.509 -5.715) (end -8.509 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.779 -4.445) (end -15.494 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.494 -4.445) (end -15.494 -5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.144 -1.27) (end -9.779 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.779 -1.27) (end -9.779 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.239 0) (end -9.144 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.144 0) (end -9.144 -1.27) (layer F.SilkS) (width 0.15)) + (pad 4 connect rect (at 2.794 2.54) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 3 connect rect (at 0 2.54) (size 1.778 5.08) (layers B.Cu B.SilkS)) + (pad 2 connect rect (at -2.794 2.54) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 1 connect rect (at -5.588 2.54) (size 1.778 5.08) (layers B.Cu F.Mask)) + (pad 5 connect rect (at 5.588 2.54) (size 1.778 5.08) (layers B.Cu B.Mask)) + (pad 6 connect rect (at -4.191 2.54) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 7 connect rect (at -1.397 2.54) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 8 connect rect (at 1.397 2.54) (size 1.778 5.08) (layers F.Cu F.Mask)) + (pad 9 connect rect (at 4.191 2.54) (size 1.778 5.08) (layers F.Cu F.Mask)) + (model Connect.3dshapes/DB9M_CI_INVERT.wrl + (at (xyz 0 0 -0.033)) + (scale (xyz 1 1 1)) + (rotate (xyz 90 0 0)) + ) +) diff --git a/PCB/.pretty/DB9M_CI_INVERT.kicad_mod.REMOVED.git-id b/PCB/.pretty/DB9M_CI_INVERT.kicad_mod.REMOVED.git-id deleted file mode 100644 index 121c01dd..00000000 --- a/PCB/.pretty/DB9M_CI_INVERT.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0f9d66011caf6d32f75ef26b9031a6f74c74b51a \ No newline at end of file diff --git a/PCB/.pretty/FMC_LPC_ASP-134604-01.kicad_mod b/PCB/.pretty/FMC_LPC_ASP-134604-01.kicad_mod new file mode 100644 index 00000000..60fceebc --- /dev/null +++ b/PCB/.pretty/FMC_LPC_ASP-134604-01.kicad_mod @@ -0,0 +1,341 @@ +(module FMC_LPC_ASP-134604-01 (layer F.Cu) (tedit 0) + (descr http://www.samtec.com/standards/vita.aspx) + (tags "FMC LPC VITA ") + (attr smd) + (fp_text reference REF** (at 29.32 -1.65 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value FMC_LPC_ASP-134604-01 (at -0.45 -5.78) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -28.5 -7.34) (end -28.5 7.34) (layer F.SilkS) (width 0.15)) + (fp_line (start -28.5 -7.34) (end 28.5 -7.34) (layer F.SilkS) (width 0.15)) + (fp_line (start 28.5 -7.34) (end 28.5 7.34) (layer F.SilkS) (width 0.15)) + (fp_line (start 28.5 7.34) (end -28.5 7.34) (layer F.SilkS) (width 0.15)) + (pad G40 thru_hole circle (at -31.19 2) (size 4 4) (drill 2.7) (layers *.Cu *.Mask) + (clearance 0.1)) + (pad C02 smd circle (at 23.495 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad "" np_thru_hole circle (at 27.19 0) (size 1.27 1.27) (drill 1.27) (layers *.Cu *.Mask F.SilkS) + (clearance 0.1)) + (pad G01 smd circle (at 24.765 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G02 smd circle (at 23.495 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H01 smd circle (at 24.765 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H02 smd circle (at 23.495 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G07 smd circle (at 17.145 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H07 smd circle (at 17.145 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H08 smd circle (at 15.875 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G08 smd circle (at 15.875 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G10 smd circle (at 13.335 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H10 smd circle (at 13.335 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H09 smd circle (at 14.605 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G09 smd circle (at 14.605 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G05 smd circle (at 19.685 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H05 smd circle (at 19.685 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H06 smd circle (at 18.415 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G06 smd circle (at 18.415 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G04 smd circle (at 20.955 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H04 smd circle (at 20.955 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H03 smd circle (at 22.225 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G03 smd circle (at 22.225 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G19 smd circle (at 1.905 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H19 smd circle (at 1.905 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H20 smd circle (at 0.635 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G20 smd circle (at 0.635 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G21 smd circle (at -0.635 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H21 smd circle (at -0.625 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G24 smd circle (at -4.445 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H24 smd circle (at -4.445 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H25 smd circle (at -5.715 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G25 smd circle (at -5.715 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G23 smd circle (at -3.175 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H23 smd circle (at -3.175 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H22 smd circle (at -1.905 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G22 smd circle (at -1.905 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G15 smd circle (at 6.985 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H15 smd circle (at 6.985 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H16 smd circle (at 5.715 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G16 smd circle (at 5.715 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G18 smd circle (at 3.175 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H18 smd circle (at 3.175 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H17 smd circle (at 4.445 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G17 smd circle (at 4.445 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G13 smd circle (at 9.525 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H13 smd circle (at 9.525 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H14 smd circle (at 8.255 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G14 smd circle (at 8.255 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G12 smd circle (at 10.795 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H12 smd circle (at 10.795 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H11 smd circle (at 12.065 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G11 smd circle (at 12.065 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G29 smd circle (at -10.795 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H29 smd circle (at -10.795 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H30 smd circle (at -12.065 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G30 smd circle (at -12.065 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G32 smd circle (at -14.605 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H32 smd circle (at -14.605 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H31 smd circle (at -13.335 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G31 smd circle (at -13.335 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H28 smd circle (at -9.525 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G28 smd circle (at -9.525 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G27 smd circle (at -8.255 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H27 smd circle (at -8.255 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H26 smd circle (at -6.985 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G26 smd circle (at -6.985 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G35 smd circle (at -18.415 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H35 smd circle (at -18.415 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H36 smd circle (at -19.685 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G36 smd circle (at -19.685 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G37 smd circle (at -20.955 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H37 smd circle (at -20.955 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G40 smd circle (at -24.765 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H40 smd circle (at -24.765 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G39 smd circle (at -23.495 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H39 smd circle (at -23.495 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H38 smd circle (at -22.225 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G38 smd circle (at -22.225 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G34 smd circle (at -17.145 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H34 smd circle (at -17.145 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad H33 smd circle (at -15.875 3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad G33 smd circle (at -15.875 1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C33 smd circle (at -15.875 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D33 smd circle (at -15.875 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D34 smd circle (at -17.145 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C34 smd circle (at -17.145 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C38 smd circle (at -22.225 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D38 smd circle (at -22.225 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D39 smd circle (at -23.495 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C39 smd circle (at -23.495 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D40 smd circle (at -24.765 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C40 smd circle (at -24.765 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D37 smd circle (at -20.955 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C37 smd circle (at -20.955 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C36 smd circle (at -19.685 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D36 smd circle (at -19.685 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D35 smd circle (at -18.415 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C35 smd circle (at -18.415 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C26 smd circle (at -6.985 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D26 smd circle (at -6.985 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D27 smd circle (at -8.255 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C27 smd circle (at -8.255 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C28 smd circle (at -9.525 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D28 smd circle (at -9.525 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C31 smd circle (at -13.335 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D31 smd circle (at -13.335 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D32 smd circle (at -14.605 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C32 smd circle (at -14.605 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C30 smd circle (at -12.065 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D30 smd circle (at -12.065 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D29 smd circle (at -10.795 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C29 smd circle (at -10.795 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C11 smd circle (at 12.065 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D11 smd circle (at 12.065 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D12 smd circle (at 10.795 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C12 smd circle (at 10.795 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C14 smd circle (at 8.255 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D14 smd circle (at 8.255 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D13 smd circle (at 9.525 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C13 smd circle (at 9.525 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C17 smd circle (at 4.445 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D17 smd circle (at 4.445 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D18 smd circle (at 3.175 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C18 smd circle (at 3.175 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C16 smd circle (at 5.715 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D16 smd circle (at 5.715 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D15 smd circle (at 6.985 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C15 smd circle (at 6.985 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C22 smd circle (at -1.905 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D22 smd circle (at -1.905 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D23 smd circle (at -3.175 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C23 smd circle (at -3.175 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C25 smd circle (at -5.715 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D25 smd circle (at -5.715 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D24 smd circle (at -4.445 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C24 smd circle (at -4.445 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D21 smd circle (at -0.625 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C21 smd circle (at -0.635 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C20 smd circle (at 0.635 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D20 smd circle (at 0.635 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D19 smd circle (at 1.905 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C19 smd circle (at 1.905 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C03 smd circle (at 22.225 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D03 smd circle (at 22.225 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D04 smd circle (at 20.955 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C04 smd circle (at 20.955 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C06 smd circle (at 18.415 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D06 smd circle (at 18.415 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D05 smd circle (at 19.685 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C05 smd circle (at 19.685 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C09 smd circle (at 14.605 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D09 smd circle (at 14.605 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D10 smd circle (at 13.335 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C10 smd circle (at 13.335 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C08 smd circle (at 15.875 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D08 smd circle (at 15.875 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D07 smd circle (at 17.145 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C07 smd circle (at 17.145 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D02 smd circle (at 23.495 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad D01 smd circle (at 24.765 -1.905) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask) + (clearance 0.1)) + (pad C01 smd circle (at 24.765 -3.175) (size 0.64 0.64) (layers F.Cu F.Paste F.Mask)) + (pad "" np_thru_hole circle (at -27.19 3.05) (size 1.27 1.27) (drill 1.27) (layers *.Cu *.Mask F.SilkS) + (clearance 0.1)) + (pad C01 thru_hole circle (at 31.19 2) (size 4 4) (drill 2.7) (layers *.Cu *.Mask)) +) diff --git a/PCB/.pretty/FMC_LPC_ASP-134604-01.kicad_mod.REMOVED.git-id b/PCB/.pretty/FMC_LPC_ASP-134604-01.kicad_mod.REMOVED.git-id deleted file mode 100644 index eecf5c7b..00000000 --- a/PCB/.pretty/FMC_LPC_ASP-134604-01.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -60fceebcc1ae22fd7eba30b9f9da4b3e5a542aba \ No newline at end of file diff --git a/PCB/.pretty/GS2.kicad_mod b/PCB/.pretty/GS2.kicad_mod new file mode 100644 index 00000000..81383b0a --- /dev/null +++ b/PCB/.pretty/GS2.kicad_mod @@ -0,0 +1,16 @@ +(module GS2 (layer F.Cu) (tedit 0) + (descr "Pontet Goute de soudure") + (attr virtual) + (fp_text reference REF** (at 1.778 0 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value GS2 (at 1.524 0 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -0.889 -1.27) (end -0.889 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.889 1.27) (end 0.889 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.889 1.27) (end -0.889 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.889 -1.27) (end 0.889 -1.27) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at 0 -0.635) (size 1.27 0.9652) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at 0 0.635) (size 1.27 0.9652) (layers F.Cu F.Paste F.Mask)) +) diff --git a/PCB/.pretty/GS2.kicad_mod.REMOVED.git-id b/PCB/.pretty/GS2.kicad_mod.REMOVED.git-id deleted file mode 100644 index 38e10d74..00000000 --- a/PCB/.pretty/GS2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -81383b0a1b306765618f13333d43656480ffa7d1 \ No newline at end of file diff --git a/PCB/.pretty/GS3.kicad_mod b/PCB/.pretty/GS3.kicad_mod new file mode 100644 index 00000000..c0eef0c4 --- /dev/null +++ b/PCB/.pretty/GS3.kicad_mod @@ -0,0 +1,17 @@ +(module GS3 (layer F.Cu) (tedit 0) + (descr "Pontet Goute de soudure") + (attr virtual) + (fp_text reference REF** (at 1.524 0 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value GS3 (at 1.524 0 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -0.889 -1.905) (end -0.889 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.889 1.905) (end 0.889 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.889 1.905) (end 0.889 -1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.889 -1.905) (end 0.889 -1.905) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at 0 -1.27) (size 1.27 0.9652) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at 0 0) (size 1.27 0.9652) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at 0 1.27) (size 1.27 0.9652) (layers F.Cu F.Paste F.Mask)) +) diff --git a/PCB/.pretty/GS3.kicad_mod.REMOVED.git-id b/PCB/.pretty/GS3.kicad_mod.REMOVED.git-id deleted file mode 100644 index 0777d971..00000000 --- a/PCB/.pretty/GS3.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c0eef0c4e87433639877c8f6475f688209ffd1e1 \ No newline at end of file diff --git a/PCB/.pretty/GS_6x2.kicad_mod b/PCB/.pretty/GS_6x2.kicad_mod new file mode 100644 index 00000000..6b08f7c1 --- /dev/null +++ b/PCB/.pretty/GS_6x2.kicad_mod @@ -0,0 +1,26 @@ +(module GS_6x2 (layer F.Cu) (tedit 0) + (descr "Double rangee de contacts 2 x 8 pins") + (tags CONN) + (fp_text reference REF** (at -2.15646 -2.02946) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value GS_6x2 (at 3.937 -2.032) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -5.715 -1.27) (end 6.35 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.35 -1.27) (end 6.35 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.35 1.27) (end -5.715 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.715 1.27) (end -5.715 -1.27) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -4.445 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at -4.445 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at -2.54 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 4 smd rect (at -2.54 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 5 smd rect (at -0.635 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 6 smd rect (at -0.635 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 7 smd rect (at 1.27 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 8 smd rect (at 1.27 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 9 smd rect (at 3.175 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 10 smd rect (at 3.175 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 11 smd rect (at 5.08 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 12 smd rect (at 5.08 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) +) diff --git a/PCB/.pretty/GS_6x2.kicad_mod.REMOVED.git-id b/PCB/.pretty/GS_6x2.kicad_mod.REMOVED.git-id deleted file mode 100644 index 956001d6..00000000 --- a/PCB/.pretty/GS_6x2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6b08f7c1891e73ebdefdad654650fac142945ac4 \ No newline at end of file diff --git a/PCB/.pretty/GS_8x2.kicad_mod b/PCB/.pretty/GS_8x2.kicad_mod new file mode 100644 index 00000000..835938f8 --- /dev/null +++ b/PCB/.pretty/GS_8x2.kicad_mod @@ -0,0 +1,30 @@ +(module GS_8x2 (layer F.Cu) (tedit 0) + (descr "Double rangee de contacts 2 x 8 pins") + (tags CONN) + (fp_text reference REF** (at -3.048 -1.905) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value GS_8x2 (at 3.937 -1.905) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -7.62 -1.27) (end 8.255 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.255 -1.27) (end 8.255 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.255 1.27) (end -7.62 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 1.27) (end -7.62 -1.27) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -6.35 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at -6.35 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at -4.445 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 4 smd rect (at -4.445 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 5 smd rect (at -2.54 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 6 smd rect (at -2.54 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 7 smd rect (at -0.635 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 8 smd rect (at -0.635 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 9 smd rect (at 1.27 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 10 smd rect (at 1.27 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 11 smd rect (at 3.175 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 12 smd rect (at 3.175 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 13 smd rect (at 5.08 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 14 smd rect (at 5.08 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 15 smd rect (at 6.985 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 16 smd rect (at 6.985 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) +) diff --git a/PCB/.pretty/GS_8x2.kicad_mod.REMOVED.git-id b/PCB/.pretty/GS_8x2.kicad_mod.REMOVED.git-id deleted file mode 100644 index fac630ba..00000000 --- a/PCB/.pretty/GS_8x2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -835938f8ca195808f5a42ee456da6b3e98a1b8c0 \ No newline at end of file diff --git a/PCB/.pretty/GS_9x2.kicad_mod b/PCB/.pretty/GS_9x2.kicad_mod new file mode 100644 index 00000000..f8e9fde7 --- /dev/null +++ b/PCB/.pretty/GS_9x2.kicad_mod @@ -0,0 +1,35 @@ +(module GS_9x2 (layer F.Cu) (tedit 0) + (descr "Double rangee de contacts 2 x 8 pins") + (tags CONN) + (fp_text reference REF** (at -3.556 -2.032) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value GS_9x2 (at 3.937 -2.15646) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -8.89 0.635) (end -8.255 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.985 -1.27) (end 8.89 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.89 -1.27) (end 8.89 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.89 1.27) (end 6.985 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.89 -1.27) (end 6.985 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.985 1.27) (end -8.89 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.89 1.27) (end -8.89 -1.27) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -7.62 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at -7.62 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at -5.715 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 4 smd rect (at -5.715 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 5 smd rect (at -3.81 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 6 smd rect (at -3.81 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 7 smd rect (at -1.905 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 8 smd rect (at -1.905 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 9 smd rect (at 0 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 10 smd rect (at 0 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 11 smd rect (at 1.905 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 12 smd rect (at 1.905 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 13 smd rect (at 3.81 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 14 smd rect (at 3.81 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 15 smd rect (at 5.715 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 16 smd rect (at 5.715 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 17 smd rect (at 7.62 0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) + (pad 18 smd rect (at 7.62 -0.635) (size 1.27 1.016) (layers F.Cu F.Paste F.Mask)) +) diff --git a/PCB/.pretty/GS_9x2.kicad_mod.REMOVED.git-id b/PCB/.pretty/GS_9x2.kicad_mod.REMOVED.git-id deleted file mode 100644 index cdcf76b0..00000000 --- a/PCB/.pretty/GS_9x2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f8e9fde75f095d02747ac40e3265ab243aa9267a \ No newline at end of file diff --git a/PCB/.pretty/GTK2400-H2.kicad_mod b/PCB/.pretty/GTK2400-H2.kicad_mod new file mode 100644 index 00000000..0be2e78c --- /dev/null +++ b/PCB/.pretty/GTK2400-H2.kicad_mod @@ -0,0 +1,19 @@ +(module GTK2400-H2 (layer F.Cu) (tedit 0) + (fp_text reference REF** (at -11.1125 -2.794) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value GTK2400-H2 (at 0 3.556) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 1.9685 0) (end 1.9685 -4.8895) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.9685 0) (end -1.9685 -4.8895) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.445 -7.62) (end -4.445 -16.51) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.445 -16.51) (end 4.445 -16.51) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.445 -16.51) (end 4.445 -7.62) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.445 -5.08) (end -4.445 -7.62) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.445 -7.62) (end 4.445 -7.62) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.445 -7.62) (end 4.445 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.445 -5.08) (end -4.445 -5.08) (layer F.SilkS) (width 0.15)) + (pad 2 thru_hole rect (at 1.9685 0) (size 2.49936 2.49936) (drill 1.80086) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -1.9685 0) (size 2.49936 2.49936) (drill 1.80086) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/GTK2400-H2.kicad_mod.REMOVED.git-id b/PCB/.pretty/GTK2400-H2.kicad_mod.REMOVED.git-id deleted file mode 100644 index f2a13482..00000000 --- a/PCB/.pretty/GTK2400-H2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0be2e78cc177a864b43375bd88ec609e5f0e1b44 \ No newline at end of file diff --git a/PCB/.pretty/GTK2400-V2.kicad_mod b/PCB/.pretty/GTK2400-V2.kicad_mod new file mode 100644 index 00000000..b93b7702 --- /dev/null +++ b/PCB/.pretty/GTK2400-V2.kicad_mod @@ -0,0 +1,18 @@ +(module GTK2400-V2 (layer F.Cu) (tedit 0) + (fp_text reference REF** (at -6.35 0 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value GTK2400-V2 (at 0 7.62) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -4.445 2.54) (end 4.445 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.445 0) (end -4.445 -5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.445 -5.715) (end -4.445 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.445 -6.35) (end 4.445 -6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.445 -6.35) (end 4.445 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.445 0) (end 4.445 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.445 5.08) (end -4.445 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.445 5.08) (end -4.445 0) (layer F.SilkS) (width 0.15)) + (pad 2 thru_hole rect (at 1.9685 0) (size 2.49936 2.49936) (drill 1.80086) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -1.9685 0) (size 2.49936 2.49936) (drill 1.80086) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/GTK2400-V2.kicad_mod.REMOVED.git-id b/PCB/.pretty/GTK2400-V2.kicad_mod.REMOVED.git-id deleted file mode 100644 index d5e9a91b..00000000 --- a/PCB/.pretty/GTK2400-V2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b93b770229cd539f0da3a62da87d34dd77ebe613 \ No newline at end of file diff --git a/PCB/.pretty/GoldTek_SCP20GR11.kicad_mod b/PCB/.pretty/GoldTek_SCP20GR11.kicad_mod new file mode 100644 index 00000000..1f58a389 --- /dev/null +++ b/PCB/.pretty/GoldTek_SCP20GR11.kicad_mod @@ -0,0 +1,71 @@ +(module GoldTek_SCP20GR11 (layer F.Cu) (tedit 556C2970) + (descr "GoldTek SCP20GR11") + (tags "CONN GoldTek SCP20GR11") + (fp_text reference REF** (at 3.81 -13.335) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value GoldTek_SCP20GR11 (at 24.765 -13.335) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 34.5 1.5) (end -11.65 1.5) (layer F.CrtYd) (width 0.05)) + (fp_line (start -11.65 1.5) (end -11.65 -27.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -11.65 -27.65) (end 34.5 -27.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 34.5 -27.65) (end 34.5 1.5) (layer F.CrtYd) (width 0.05)) + (fp_line (start 28.702 -2.413) (end 28.702 1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.924 -0.635) (end 30.48 -0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.842 -2.413) (end -5.842 1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 -0.635) (end -4.064 -0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.635 -11.43) (end 0.635 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.635 -11.43) (end 0 -10.795) (layer F.SilkS) (width 0.15)) + (fp_line (start 0 -10.795) (end -0.635 -11.43) (layer F.SilkS) (width 0.15)) + (fp_line (start 33.02 -15.24) (end 33.02 -26.67) (layer F.SilkS) (width 0.15)) + (fp_line (start 33.02 -26.67) (end 32.385 -27.305) (layer F.SilkS) (width 0.15)) + (fp_line (start 32.385 -27.305) (end 31.75 -27.305) (layer F.SilkS) (width 0.15)) + (fp_line (start 31.75 -27.305) (end 26.035 -25.4) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.035 -25.4) (end 26.035 -23.495) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.035 -23.495) (end 27.305 -23.495) (layer F.SilkS) (width 0.15)) + (fp_line (start 27.305 -23.495) (end 27.94 -24.13) (layer F.SilkS) (width 0.15)) + (fp_line (start 27.94 -24.13) (end 28.575 -24.13) (layer F.SilkS) (width 0.15)) + (fp_line (start 28.575 -24.13) (end 28.575 -15.24) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.16 -15.24) (end -10.16 -26.67) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.16 -26.67) (end -9.525 -27.305) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.525 -27.305) (end -8.89 -27.305) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.89 -27.305) (end -3.175 -25.4) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.175 -25.4) (end -3.175 -23.495) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.175 -23.495) (end -4.445 -23.495) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.445 -23.495) (end -5.08 -24.13) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.08 -24.13) (end -5.715 -24.13) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.715 -24.13) (end -5.715 -15.24) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.43 1.27) (end -11.43 -8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.43 -8.89) (end -10.795 -15.24) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.795 -15.24) (end -5.08 -15.24) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.08 -15.24) (end -5.08 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start 34.29 1.27) (end 34.29 -8.255) (layer F.SilkS) (width 0.15)) + (fp_line (start 34.29 -8.255) (end 33.655 -15.24) (layer F.SilkS) (width 0.15)) + (fp_line (start 33.655 -15.24) (end 27.94 -15.24) (layer F.SilkS) (width 0.15)) + (fp_line (start 27.94 -15.24) (end 27.94 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start 27.94 -12.065) (end -5.08 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.43 1.27) (end 34.29 1.27) (layer F.SilkS) (width 0.15)) + (fp_circle (center -5.842 -0.635) (end -4.445 -0.635) (layer F.SilkS) (width 0.15)) + (fp_circle (center 28.702 -0.635) (end 30.099 -0.635) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 0 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 2.54 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 2.54 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 5.08 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 5.08 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 7.62 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 7.62 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 10.16 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at 10.16 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at 12.7 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at 12.7 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at 15.24 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at 15.24 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at 17.78 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at 17.78 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at 20.32 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at 20.32 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at 22.86 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at 22.86 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/GoldTek_SCP20GR11.kicad_mod.REMOVED.git-id b/PCB/.pretty/GoldTek_SCP20GR11.kicad_mod.REMOVED.git-id deleted file mode 100644 index 9089eb63..00000000 --- a/PCB/.pretty/GoldTek_SCP20GR11.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1f58a3897ffa379f6e7ac0a96a946f0e4b3bc7a8 \ No newline at end of file diff --git a/PCB/.pretty/GoldTek_SCP20GS11.kicad_mod b/PCB/.pretty/GoldTek_SCP20GS11.kicad_mod new file mode 100644 index 00000000..0c65d93c --- /dev/null +++ b/PCB/.pretty/GoldTek_SCP20GS11.kicad_mod @@ -0,0 +1,75 @@ +(module GoldTek_SCP20GS11 (layer F.Cu) (tedit 556C2993) + (descr "GoldTek SCP20GS11") + (tags "CONN GoldTek SCP20GS11") + (fp_text reference REF** (at -1.27 -6.985) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value GoldTek_SCP20GS11 (at 20.955 -6.985) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -11.15 -5.8) (end 34 -5.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 34 -5.8) (end 34 3.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 34 3.3) (end -11.15 3.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -11.15 3.3) (end -11.15 -5.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.635 1.905) (end 0 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 0 1.27) (end 0.635 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.635 1.905) (end -0.635 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.175 -3.175) (end -2.54 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 -3.175) (end -2.54 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 0.635) (end -3.175 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.81 -3.175) (end -3.175 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.175 -3.175) (end -3.175 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.175 0.635) (end -3.81 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.445 -4.445) (end -4.445 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.67 -3.175) (end 26.035 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.035 -3.175) (end 26.035 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.035 0.635) (end 26.67 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.67 0.635) (end 26.035 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.035 0.635) (end 25.4 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 25.4 0.635) (end 25.4 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 25.4 -3.175) (end 26.035 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 27.305 -4.445) (end 27.305 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.525 -3.175) (end -9.525 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 32.385 -3.175) (end 32.385 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 0.635) (end -10.795 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 -3.175) (end -10.795 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 30.48 0.635) (end 33.655 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 30.48 -3.175) (end 33.655 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.81 -4.445) (end -7.62 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 -4.445) (end -7.62 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 1.905) (end -3.81 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.67 -4.445) (end 30.48 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 30.48 -4.445) (end 30.48 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start 30.48 1.905) (end 26.67 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.652 3.048) (end 9.652 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.652 2.286) (end -3.81 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.81 2.286) (end -3.81 -4.826) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.81 -4.826) (end 26.67 -4.826) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.67 -4.826) (end 26.67 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.67 2.286) (end 13.208 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.208 2.286) (end 13.208 3.048) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.922 -5.588) (end -10.922 3.048) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.922 3.048) (end 33.782 3.048) (layer F.SilkS) (width 0.15)) + (fp_line (start 33.782 3.048) (end 33.782 -5.588) (layer F.SilkS) (width 0.15)) + (fp_line (start 33.782 -5.588) (end -10.922 -5.588) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 0 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 2.54 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 2.54 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 5.08 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 5.08 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 7.62 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 7.62 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 10.16 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at 10.16 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at 12.7 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at 12.7 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at 15.24 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at 15.24 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at 17.78 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at 17.78 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at 20.32 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at 20.32 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at 22.86 0) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at 22.86 -2.54) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/GoldTek_SCP20GS11.kicad_mod.REMOVED.git-id b/PCB/.pretty/GoldTek_SCP20GS11.kicad_mod.REMOVED.git-id deleted file mode 100644 index 18051ca6..00000000 --- a/PCB/.pretty/GoldTek_SCP20GS11.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0c65d93c3cd4c330430f452c6b3fc6d3461c913f \ No newline at end of file diff --git a/PCB/.pretty/HE10-10C.kicad_mod b/PCB/.pretty/HE10-10C.kicad_mod new file mode 100644 index 00000000..2b5ff121 --- /dev/null +++ b/PCB/.pretty/HE10-10C.kicad_mod @@ -0,0 +1,44 @@ +(module HE10-10C (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 10 contacts couche") + (tags "CONN HE10") + (fp_text reference REF** (at -1.524 5.08 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value HE10-10C (at -2.032 8.128) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -8.636 -2.54) (end -8.636 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.636 2.032) (end -9.906 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.906 3.302) (end -11.938 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.938 3.302) (end -13.208 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.208 2.032) (end -13.208 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.208 -2.54) (end 13.208 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.208 2.032) (end 11.938 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.938 3.302) (end 9.652 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.652 3.302) (end 8.382 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.382 2.032) (end 8.382 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.24 -2.54) (end 15.24 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.24 4.445) (end 12.065 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.065 14.605) (end 8.255 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.24 -2.54) (end -15.24 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.24 -2.54) (end -15.24 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.24 4.445) (end -12.065 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.065 14.605) (end -8.255 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.255 14.605) (end -6.35 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.35 10.16) (end 6.35 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.255 14.605) (end 6.35 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.699 10.16) (end 3.683 8.128) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.683 8.128) (end 2.667 10.16) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -10.922 0.508) (size 3.048 3.048) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 10.922 0.508) (size 3.048 3.048) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 5.08 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 5.08 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 2.54 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 2.54 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 0 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 0 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -2.54 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -2.54 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -5.08 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -5.08 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/HE10-10C.kicad_mod.REMOVED.git-id b/PCB/.pretty/HE10-10C.kicad_mod.REMOVED.git-id deleted file mode 100644 index 4b30a00d..00000000 --- a/PCB/.pretty/HE10-10C.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2b5ff121b5a14e46ecc4625617be33aa5e3b5727 \ No newline at end of file diff --git a/PCB/.pretty/HE10_20D.kicad_mod b/PCB/.pretty/HE10_20D.kicad_mod new file mode 100644 index 00000000..59febe55 --- /dev/null +++ b/PCB/.pretty/HE10_20D.kicad_mod @@ -0,0 +1,51 @@ +(module HE10_20D (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 20 contacts droit") + (tags "CONN HE10") + (fp_text reference REF** (at -12.7 -5.715) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value HE10_20D (at 9.525 -5.715) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.778 4.318) (end -1.778 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 3.556) (end -15.24 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.24 3.556) (end -15.24 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.24 -3.556) (end 15.24 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.24 -3.556) (end 15.24 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.24 3.556) (end 1.778 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.778 3.556) (end 1.778 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.954 1.27) (end -14.224 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -14.224 0.508) (end -14.224 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -14.224 2.032) (end -12.954 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -22.352 -4.318) (end -22.352 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -22.352 4.318) (end 22.352 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 22.352 4.318) (end 22.352 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 22.352 -4.318) (end -22.352 -4.318) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -11.43 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -11.43 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -8.89 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -8.89 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -6.35 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -6.35 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -3.81 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -3.81 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -1.27 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -1.27 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at 1.27 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at 1.27 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at 3.81 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at 3.81 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at 6.35 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at 6.35 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at 8.89 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at 8.89 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at 11.43 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at 11.43 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -20.32 0.254) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 20.32 0.254) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/HE10_20D.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/HE10_20D.kicad_mod.REMOVED.git-id b/PCB/.pretty/HE10_20D.kicad_mod.REMOVED.git-id deleted file mode 100644 index 6f6f0ca7..00000000 --- a/PCB/.pretty/HE10_20D.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -59febe55e4786779750e3cafd59801734362125c \ No newline at end of file diff --git a/PCB/.pretty/HE10_26D.kicad_mod b/PCB/.pretty/HE10_26D.kicad_mod new file mode 100644 index 00000000..47460537 --- /dev/null +++ b/PCB/.pretty/HE10_26D.kicad_mod @@ -0,0 +1,52 @@ +(module HE10_26D (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 26 contacts droit") + (tags "CONN HE10") + (fp_text reference REF** (at -15.24 -5.715) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value HE10_26D (at 13.335 -5.715) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -16.764 1.27) (end -18.034 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -18.034 0.508) (end -18.034 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -18.034 2.032) (end -16.764 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.162 -4.318) (end -26.162 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.162 4.318) (end 26.162 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.162 4.318) (end 26.162 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 26.162 -4.318) (end -26.162 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 4.318) (end -1.778 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 3.556) (end -19.05 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.05 3.556) (end -19.05 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.05 -3.556) (end 19.05 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.05 -3.556) (end 19.05 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.05 3.556) (end 1.778 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.778 3.556) (end 1.778 4.318) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -15.24 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -15.24 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -12.7 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -12.7 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -10.16 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -10.16 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -7.62 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -7.62 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -5.08 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -5.08 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -2.54 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -2.54 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at 0 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at 0 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at 2.54 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at 2.54 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at 5.08 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at 5.08 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at 7.62 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at 7.62 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -24.13 0.254) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at 10.16 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at 10.16 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at 12.7 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at 12.7 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at 15.24 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 26 thru_hole circle (at 15.24 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 24.13 0.254) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/HE10_26D.kicad_mod.REMOVED.git-id b/PCB/.pretty/HE10_26D.kicad_mod.REMOVED.git-id deleted file mode 100644 index 43ce89d4..00000000 --- a/PCB/.pretty/HE10_26D.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4746053787ad5fb9a31433b5a924fd6b46d58bcc \ No newline at end of file diff --git a/PCB/.pretty/HE10_34D.kicad_mod b/PCB/.pretty/HE10_34D.kicad_mod new file mode 100644 index 00000000..56bbcaf5 --- /dev/null +++ b/PCB/.pretty/HE10_34D.kicad_mod @@ -0,0 +1,60 @@ +(module HE10_34D (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 34 contacts droit") + (tags "CONN HE10") + (fp_text reference REF** (at -8.89 -5.842) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value HE10_34D (at 9.144 -5.842) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -21.844 1.27) (end -23.114 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -23.114 0.508) (end -23.114 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -23.114 2.032) (end -21.844 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -31.242 -4.318) (end -31.242 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -31.242 4.318) (end 31.242 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 31.242 4.318) (end 31.242 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 31.242 -4.318) (end -31.242 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 4.318) (end -1.778 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 3.556) (end -24.13 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -24.13 3.556) (end -24.13 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -24.13 -3.556) (end 24.13 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 24.13 -3.556) (end 24.13 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 24.13 3.556) (end 1.778 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.778 3.556) (end 1.778 4.318) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -20.32 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -20.32 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -17.78 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -17.78 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -15.24 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -15.24 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -12.7 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -12.7 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -10.16 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -10.16 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -7.62 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -7.62 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -5.08 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -5.08 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -2.54 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at -2.54 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at 0 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at 0 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at 2.54 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at 2.54 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -29.21 0.254) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at 5.08 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at 5.08 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at 7.62 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at 7.62 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at 10.16 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 26 thru_hole circle (at 10.16 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 27 thru_hole circle (at 12.7 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 28 thru_hole circle (at 12.7 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 29 thru_hole circle (at 15.24 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 30 thru_hole circle (at 15.24 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 31 thru_hole circle (at 17.78 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 32 thru_hole circle (at 17.78 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 33 thru_hole circle (at 20.32 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 34 thru_hole circle (at 20.32 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 29.21 0.254) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/HE10_34D.kicad_mod.REMOVED.git-id b/PCB/.pretty/HE10_34D.kicad_mod.REMOVED.git-id deleted file mode 100644 index 1732387e..00000000 --- a/PCB/.pretty/HE10_34D.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -56bbcaf514ab0fc2dea24b13af68a4b0636fcbf4 \ No newline at end of file diff --git a/PCB/.pretty/HE10_40D.kicad_mod b/PCB/.pretty/HE10_40D.kicad_mod new file mode 100644 index 00000000..3ec96818 --- /dev/null +++ b/PCB/.pretty/HE10_40D.kicad_mod @@ -0,0 +1,66 @@ +(module HE10_40D (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 40 contacts droit") + (tags "CONN HE10") + (fp_text reference REF** (at -17.145 -5.715) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value HE10_40D (at 17.78 -5.715) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -25.654 1.27) (end -26.924 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.924 0.508) (end -26.924 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -26.924 2.032) (end -25.654 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -35.052 -4.318) (end -35.052 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -35.052 4.318) (end 35.052 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 35.052 4.318) (end 35.052 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 35.052 -4.318) (end -35.052 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 4.318) (end -1.778 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 3.556) (end -27.94 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -27.94 3.556) (end -27.94 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -27.94 -3.556) (end 27.94 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 27.94 -3.556) (end 27.94 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 27.94 3.556) (end 1.778 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.778 3.556) (end 1.778 4.318) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -24.13 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -24.13 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -21.59 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -21.59 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -19.05 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -19.05 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -16.51 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -16.51 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -13.97 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -13.97 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -11.43 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -11.43 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -8.89 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -8.89 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -6.35 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at -6.35 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at -3.81 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at -3.81 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at -1.27 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at -1.27 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -33.02 0.254) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at 1.27 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at 1.27 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at 3.81 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at 3.81 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at 6.35 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 26 thru_hole circle (at 6.35 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 27 thru_hole circle (at 8.89 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 28 thru_hole circle (at 8.89 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 29 thru_hole circle (at 11.43 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 30 thru_hole circle (at 11.43 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 31 thru_hole circle (at 13.97 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 32 thru_hole circle (at 13.97 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 33 thru_hole circle (at 16.51 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 34 thru_hole circle (at 16.51 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 35 thru_hole circle (at 19.05 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 36 thru_hole circle (at 19.05 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 37 thru_hole circle (at 21.59 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 38 thru_hole circle (at 21.59 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 39 thru_hole circle (at 24.13 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 40 thru_hole circle (at 24.13 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 33.02 0.254) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/HE10_40D.kicad_mod.REMOVED.git-id b/PCB/.pretty/HE10_40D.kicad_mod.REMOVED.git-id deleted file mode 100644 index b87fa827..00000000 --- a/PCB/.pretty/HE10_40D.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3ec968187864b7f30e2033047432fa608a9bd20e \ No newline at end of file diff --git a/PCB/.pretty/HE10_50D.kicad_mod b/PCB/.pretty/HE10_50D.kicad_mod new file mode 100644 index 00000000..8ac9487f --- /dev/null +++ b/PCB/.pretty/HE10_50D.kicad_mod @@ -0,0 +1,76 @@ +(module HE10_50D (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 50 contacts droit") + (tags "CONN HE10") + (fp_text reference REF** (at -8.128 -5.842) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value HE10_50D (at 11.43 -6.096) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -32.004 1.27) (end -33.274 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -33.274 0.508) (end -33.274 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -33.274 2.032) (end -32.004 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -41.402 -4.318) (end -41.402 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -41.402 4.318) (end 41.402 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 41.402 4.318) (end 41.402 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 41.402 -4.318) (end -41.402 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 4.318) (end -1.778 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 3.556) (end -34.29 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -34.29 3.556) (end -34.29 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -34.29 -3.556) (end 34.29 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 34.29 -3.556) (end 34.29 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 34.29 3.556) (end 1.778 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.778 3.556) (end 1.778 4.318) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -30.48 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -30.48 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -27.94 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -27.94 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -25.4 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -25.4 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -22.86 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -22.86 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -20.32 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -20.32 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -17.78 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -17.78 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -15.24 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -15.24 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -12.7 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at -12.7 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at -10.16 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at -10.16 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at -7.62 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at -7.62 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -39.37 0.254) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at -5.08 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at -5.08 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at -2.54 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at -2.54 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at 0 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 26 thru_hole circle (at 0 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 27 thru_hole circle (at 2.54 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 28 thru_hole circle (at 2.54 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 29 thru_hole circle (at 5.08 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 30 thru_hole circle (at 5.08 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 31 thru_hole circle (at 7.62 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 32 thru_hole circle (at 7.62 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 33 thru_hole circle (at 10.16 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 34 thru_hole circle (at 10.16 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 35 thru_hole circle (at 12.7 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 36 thru_hole circle (at 12.7 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 37 thru_hole circle (at 15.24 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 38 thru_hole circle (at 15.24 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 39 thru_hole circle (at 17.78 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 40 thru_hole circle (at 17.78 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 41 thru_hole circle (at 20.32 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 42 thru_hole circle (at 20.32 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 43 thru_hole circle (at 22.86 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 44 thru_hole circle (at 22.86 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 45 thru_hole circle (at 25.4 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 46 thru_hole circle (at 25.4 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 47 thru_hole circle (at 27.94 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 48 thru_hole circle (at 27.94 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 49 thru_hole circle (at 30.48 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 50 thru_hole circle (at 30.48 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 39.37 0.254) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/HE10_50D.kicad_mod.REMOVED.git-id b/PCB/.pretty/HE10_50D.kicad_mod.REMOVED.git-id deleted file mode 100644 index a1e8e412..00000000 --- a/PCB/.pretty/HE10_50D.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8ac9487fce5fc4ba5f682b89b205d42fc5a293b7 \ No newline at end of file diff --git a/PCB/.pretty/HE10_60D.kicad_mod b/PCB/.pretty/HE10_60D.kicad_mod new file mode 100644 index 00000000..f58ffb68 --- /dev/null +++ b/PCB/.pretty/HE10_60D.kicad_mod @@ -0,0 +1,86 @@ +(module HE10_60D (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 60 contacts droit") + (tags "CONN HE10") + (fp_text reference REF** (at -16.51 -6.35) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value HE10_60D (at 10.795 -6.35) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -38.354 1.016) (end -39.624 0.254) (layer F.SilkS) (width 0.15)) + (fp_line (start -39.624 0.254) (end -39.624 1.778) (layer F.SilkS) (width 0.15)) + (fp_line (start -39.624 1.778) (end -38.354 1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -47.752 -4.572) (end -47.752 4.064) (layer F.SilkS) (width 0.15)) + (fp_line (start -47.752 4.064) (end 47.752 4.064) (layer F.SilkS) (width 0.15)) + (fp_line (start 47.752 4.064) (end 47.752 -4.572) (layer F.SilkS) (width 0.15)) + (fp_line (start 47.752 -4.572) (end -47.752 -4.572) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 4.064) (end -1.778 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 3.302) (end -40.64 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -40.64 3.302) (end -40.64 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -40.64 -3.81) (end 40.64 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 40.64 -3.81) (end 40.64 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 40.64 3.302) (end 1.778 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.778 3.302) (end 1.778 4.064) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -36.83 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -36.83 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -34.29 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -34.29 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -31.75 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -31.75 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -29.21 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -29.21 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -26.67 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -26.67 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -24.13 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -24.13 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -21.59 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -21.59 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -19.05 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at -19.05 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at -16.51 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at -16.51 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at -13.97 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at -13.97 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -45.72 0) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at -11.43 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at -11.43 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at -8.89 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at -8.89 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at -6.35 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 26 thru_hole circle (at -6.35 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 27 thru_hole circle (at -3.81 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 28 thru_hole circle (at -3.81 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 29 thru_hole circle (at -1.27 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 30 thru_hole circle (at -1.27 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 31 thru_hole circle (at 1.27 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 32 thru_hole circle (at 1.27 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 33 thru_hole circle (at 3.81 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 34 thru_hole circle (at 3.81 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 35 thru_hole circle (at 6.35 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 36 thru_hole circle (at 6.35 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 37 thru_hole circle (at 8.89 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 38 thru_hole circle (at 8.89 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 39 thru_hole circle (at 11.43 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 40 thru_hole circle (at 11.43 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 41 thru_hole circle (at 13.97 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 42 thru_hole circle (at 13.97 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 43 thru_hole circle (at 16.51 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 44 thru_hole circle (at 16.51 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 45 thru_hole circle (at 19.05 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 46 thru_hole circle (at 19.05 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 47 thru_hole circle (at 21.59 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 48 thru_hole circle (at 21.59 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 49 thru_hole circle (at 24.13 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 50 thru_hole circle (at 24.13 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 51 thru_hole circle (at 26.67 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 52 thru_hole circle (at 26.67 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 53 thru_hole circle (at 29.21 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 54 thru_hole circle (at 29.21 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 55 thru_hole circle (at 31.75 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 56 thru_hole circle (at 31.75 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 57 thru_hole circle (at 34.29 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 58 thru_hole circle (at 34.29 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 59 thru_hole circle (at 36.83 1.016) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 60 thru_hole circle (at 36.83 -1.524) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 45.72 0) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/HE10_60D.kicad_mod.REMOVED.git-id b/PCB/.pretty/HE10_60D.kicad_mod.REMOVED.git-id deleted file mode 100644 index 3c14bf35..00000000 --- a/PCB/.pretty/HE10_60D.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f58ffb684fe9e65397f7588c22275fdae84f3642 \ No newline at end of file diff --git a/PCB/.pretty/HE10_64D.kicad_mod b/PCB/.pretty/HE10_64D.kicad_mod new file mode 100644 index 00000000..af5435fb --- /dev/null +++ b/PCB/.pretty/HE10_64D.kicad_mod @@ -0,0 +1,90 @@ +(module HE10_64D (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 64 contacts droit") + (tags "CONN HE10") + (fp_text reference REF** (at -10.922 -5.842) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value HE10_64D (at 5.334 -5.842) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -40.894 1.27) (end -42.164 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -42.164 0.508) (end -42.164 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -42.164 2.032) (end -40.894 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -50.292 -4.318) (end -50.292 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -50.292 4.318) (end 50.292 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 50.292 4.318) (end 50.292 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 50.292 -4.318) (end -50.292 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 4.318) (end -1.778 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 3.556) (end -43.18 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -43.18 3.556) (end -43.18 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -43.18 -3.556) (end 43.18 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 43.18 -3.556) (end 43.18 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 43.18 3.556) (end 1.778 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.778 3.556) (end 1.778 4.318) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -39.37 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -39.37 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -36.83 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -36.83 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -34.29 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -34.29 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -31.75 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -31.75 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -29.21 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -29.21 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -26.67 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -26.67 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -24.13 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -24.13 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -21.59 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at -21.59 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at -19.05 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at -19.05 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at -16.51 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at -16.51 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -48.26 0.254) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at -13.97 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at -13.97 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at -11.43 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at -11.43 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at -8.89 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 26 thru_hole circle (at -8.89 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 27 thru_hole circle (at -6.35 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 28 thru_hole circle (at -6.35 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 29 thru_hole circle (at -3.81 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 30 thru_hole circle (at -3.81 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 31 thru_hole circle (at -1.27 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 32 thru_hole circle (at -1.27 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 33 thru_hole circle (at 1.27 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 34 thru_hole circle (at 1.27 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 35 thru_hole circle (at 3.81 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 36 thru_hole circle (at 3.81 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 37 thru_hole circle (at 6.35 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 38 thru_hole circle (at 6.35 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 39 thru_hole circle (at 8.89 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 40 thru_hole circle (at 8.89 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 41 thru_hole circle (at 11.43 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 42 thru_hole circle (at 11.43 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 43 thru_hole circle (at 13.97 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 44 thru_hole circle (at 13.97 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 45 thru_hole circle (at 16.51 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 46 thru_hole circle (at 16.51 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 47 thru_hole circle (at 19.05 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 48 thru_hole circle (at 19.05 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 49 thru_hole circle (at 21.59 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 50 thru_hole circle (at 21.59 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 51 thru_hole circle (at 24.13 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 52 thru_hole circle (at 24.13 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 53 thru_hole circle (at 26.67 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 54 thru_hole circle (at 26.67 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 55 thru_hole circle (at 29.21 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 56 thru_hole circle (at 29.21 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 57 thru_hole circle (at 31.75 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 58 thru_hole circle (at 31.75 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 59 thru_hole circle (at 34.29 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 60 thru_hole circle (at 34.29 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 61 thru_hole circle (at 36.83 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 62 thru_hole circle (at 36.83 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 63 thru_hole circle (at 39.37 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 64 thru_hole circle (at 39.37 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 48.26 0.254) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/HE10_64D.kicad_mod.REMOVED.git-id b/PCB/.pretty/HE10_64D.kicad_mod.REMOVED.git-id deleted file mode 100644 index 8e2328bb..00000000 --- a/PCB/.pretty/HE10_64D.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -af5435fbed1cdfd267668b26df44e93636addac6 \ No newline at end of file diff --git a/PCB/.pretty/JACK_ALIM.kicad_mod b/PCB/.pretty/JACK_ALIM.kicad_mod new file mode 100644 index 00000000..d7e77a58 --- /dev/null +++ b/PCB/.pretty/JACK_ALIM.kicad_mod @@ -0,0 +1,25 @@ +(module JACK_ALIM (layer F.Cu) (tedit 0) + (descr "module 1 pin (ou trou mecanique de percage)") + (tags "CONN JACK") + (fp_text reference REF** (at 0.254 -5.588) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value JACK_ALIM (at -5.08 5.588) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -7.112 -4.318) (end -7.874 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.874 -4.318) (end -7.874 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.874 4.318) (end -7.112 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.064 -4.318) (end -4.064 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.588 -4.318) (end 5.588 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.112 4.318) (end 5.588 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.112 -4.318) (end 5.588 -4.318) (layer F.SilkS) (width 0.15)) + (pad 2 thru_hole circle (at 0 0) (size 4.8006 4.8006) (drill oval 1.016 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 6.096 0) (size 4.8006 4.8006) (drill oval 1.016 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 2.286 5.08) (size 4.8006 4.8006) (drill oval 2.54 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/JACK_ALIM.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.8 0.8 0.8)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/JACK_ALIM.kicad_mod.REMOVED.git-id b/PCB/.pretty/JACK_ALIM.kicad_mod.REMOVED.git-id deleted file mode 100644 index cca0b061..00000000 --- a/PCB/.pretty/JACK_ALIM.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d7e77a5867612e49ab2b41d408ef457286f4a08f \ No newline at end of file diff --git a/PCB/.pretty/JWT_Vertical_A3963-RM3.96mm-2.kicad_mod b/PCB/.pretty/JWT_Vertical_A3963-RM3.96mm-2.kicad_mod new file mode 100644 index 00000000..08bc6e94 --- /dev/null +++ b/PCB/.pretty/JWT_Vertical_A3963-RM3.96mm-2.kicad_mod @@ -0,0 +1,31 @@ +(module JWT_Vertical_A3963-RM3.96mm-2 (layer F.Cu) (tedit 556C2ADD) + (descr "JWT A3963, 3.96mm pitch Pin head connector") + (tags "JWT A3963 pinhead") + (fp_text reference REF** (at 1.905 -5.08) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value JWT_Vertical_A3963-RM3.96mm-2 (at 1.905 6.35) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.5 -3.55) (end 6.35 -3.55) (layer F.CrtYd) (width 0.05)) + (fp_line (start 6.35 -3.55) (end 6.35 5.05) (layer F.CrtYd) (width 0.05)) + (fp_line (start 6.35 5.05) (end -2.5 5.05) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.5 5.05) (end -2.5 -3.55) (layer F.CrtYd) (width 0.05)) + (fp_line (start 2.286 4.826) (end 5.969 4.826) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 4.826) (end -2.159 4.826) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 4.826) (end 1.524 4.572) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 4.572) (end 2.286 4.572) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.286 4.572) (end 2.286 4.826) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.889 -2.159) (end 4.699 -2.159) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.889 -3.048) (end 4.699 -3.048) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.969 -1.905) (end 5.969 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.159 -1.905) (end -2.159 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.889 -3.302) (end 4.699 -3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.699 -1.905) (end 4.699 -3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.889 -1.905) (end -0.889 -3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.159 -1.905) (end 5.969 -1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.159 0) (end -2.159 4.826) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.969 4.826) (end 5.969 0) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 3 3) (drill 1.75) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 3.885 0) (size 3 3) (drill 1.75) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/JWT_Vertical_A3963-RM3.96mm-2.kicad_mod.REMOVED.git-id b/PCB/.pretty/JWT_Vertical_A3963-RM3.96mm-2.kicad_mod.REMOVED.git-id deleted file mode 100644 index d15a400d..00000000 --- a/PCB/.pretty/JWT_Vertical_A3963-RM3.96mm-2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -08bc6e94960bcd7e9d7acad489aade680aa1efd0 \ No newline at end of file diff --git a/PCB/.pretty/NMJ6HCD2.kicad_mod b/PCB/.pretty/NMJ6HCD2.kicad_mod new file mode 100644 index 00000000..45d58d6d --- /dev/null +++ b/PCB/.pretty/NMJ6HCD2.kicad_mod @@ -0,0 +1,41 @@ +(module NMJ6HCD2 (layer F.Cu) (tedit 551E8E62) + (descr "NMJ6HCD2, TRS 1/4\" jack connector, stereo, switched") + (tags "NMJ6HCD2 TRS stereo jack connector") + (fp_text reference REF** (at 0.889 18.415) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value NMJ6HCD2 (at 7.9153 -8.12) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -7.25) (end -1.75 20.15) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 20.15) (end 17.95 20.15) (layer F.CrtYd) (width 0.05)) + (fp_line (start 17.95 20.15) (end 17.95 -7.25) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -7.25) (end 17.95 -7.25) (layer F.CrtYd) (width 0.05)) + (fp_line (start 12.2555 16.637) (end 12.2555 19.857) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.7465 19.8755) (end 12.2325 19.8755) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.7465 16.637) (end 3.7465 19.857) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.159 -7) (end 2.159 -4) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.159 -7) (end 13.859 -7) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.859 -7) (end 13.859 -4) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.135 16.6095) (end 17.15 16.6095) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.15 16.6095) (end 17.15 14.1605) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.135 16.6095) (end -1.135 14.1605) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.135 -1.45) (end -1.135 -4) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.135 4.8895) (end -1.135 1.4605) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.135 11.2395) (end -1.135 7.8105) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.15 7.8105) (end 17.15 11.2395) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.15 1.4605) (end 17.15 4.8895) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.15 -4) (end 17.15 -1.45) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.135 -4) (end 17.15 -4) (layer F.SilkS) (width 0.15)) + (pad 6 thru_hole circle (at 16.23 6.35) (size 3 3) (drill 1.5) (layers *.Cu *.Mask)) + (pad 5 thru_hole circle (at 16.23 12.7) (size 3 3) (drill 1.5) (layers *.Cu *.Mask)) + (pad 4 thru_hole circle (at 16.23 0) (size 3 3) (drill 1.5) (layers *.Cu *.Mask)) + (pad 3 thru_hole circle (at 0 6.35) (size 3 3) (drill 1.5) (layers *.Cu *.Mask)) + (pad 2 thru_hole circle (at 0 12.7) (size 3 3) (drill 1.5) (layers *.Cu *.Mask)) + (pad 1 thru_hole circle (at 0 0) (size 3 3) (drill 1.5) (layers *.Cu *.Mask)) + (model Connect.3dshapes/NMJ6HCD2.wrl + (at (xyz 0.32 0.165 0)) + (scale (xyz 0.39 0.39 0.39)) + (rotate (xyz -90 0 180)) + ) +) diff --git a/PCB/.pretty/NMJ6HCD2.kicad_mod.REMOVED.git-id b/PCB/.pretty/NMJ6HCD2.kicad_mod.REMOVED.git-id deleted file mode 100644 index eff0dd48..00000000 --- a/PCB/.pretty/NMJ6HCD2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -45d58d6d80828fba0365d1a2a7d1258175c6ac39 \ No newline at end of file diff --git a/PCB/.pretty/PCI-EXPRESS.kicad_mod b/PCB/.pretty/PCI-EXPRESS.kicad_mod new file mode 100644 index 00000000..d370bcac --- /dev/null +++ b/PCB/.pretty/PCI-EXPRESS.kicad_mod @@ -0,0 +1,89 @@ +(module PCI-EXPRESS (layer F.Cu) (tedit 545FBBB8) + (fp_text reference REF** (at -4.445 -3.81) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value PCI-EXPRESS (at 6.985 -3.81) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 1.09982 -2.49936) (end 1.09982 -5.69976) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.09982 -5.69976) (end 2.90068 -5.69976) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.90068 -5.69976) (end 2.90068 -2.49936) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.20064 -2.49936) (end 1.09982 -2.49936) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.09982 -2.49936) (end 1.09982 3.29946) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.09982 3.29946) (end -10.20064 3.29946) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.20064 3.29946) (end -10.20064 -2.49936) (layer F.SilkS) (width 0.15)) + (fp_line (start 10.20064 -2.49936) (end 2.90068 -2.49936) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.90068 3.29946) (end 10.20064 3.29946) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.90068 -2.49936) (end 2.90068 3.29946) (layer F.SilkS) (width 0.15)) + (fp_line (start 10.20064 -2.49936) (end 10.20064 3.29946) (layer F.SilkS) (width 0.15)) + (pad "" connect circle (at 9.4996 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad B1 connect rect (at -9.4996 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B2 connect rect (at -8.49884 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B3 connect rect (at -7.50062 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B4 connect rect (at -6.49986 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B5 connect rect (at -5.4991 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B6 connect rect (at -4.50088 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B7 connect rect (at -3.50012 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B8 connect rect (at -2.49936 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B9 connect rect (at -1.50114 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B10 connect rect (at -0.50038 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B11 connect rect (at 0.50038 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B14 connect rect (at 5.4991 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B15 connect rect (at 6.49986 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B16 connect rect (at 7.50062 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B17 connect rect (at 8.49884 -0.50038) (size 0.65024 3.59918) (layers F.Cu F.Mask)) + (pad B18 connect rect (at 9.4996 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B12 connect rect (at 3.50012 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad B13 connect rect (at 4.50088 0) (size 0.65024 4.59994) (layers F.Cu F.Mask)) + (pad A1 connect rect (at -9.4996 -0.50038) (size 0.65024 3.59918) (layers B.Cu B.Mask)) + (pad A2 connect rect (at -8.49884 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A3 connect rect (at -7.50062 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A4 connect rect (at -6.49986 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A5 connect rect (at -5.4991 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A6 connect rect (at -4.50088 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A7 connect rect (at -3.50012 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A8 connect rect (at -2.49936 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A9 connect rect (at -1.50114 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A10 connect rect (at -0.50038 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A11 connect rect (at 0.50038 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A14 connect rect (at 5.4991 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A15 connect rect (at 6.49986 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A16 connect rect (at 7.50062 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A17 connect rect (at 8.49884 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A18 connect rect (at 9.4996 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A12 connect rect (at 3.50012 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad A13 connect rect (at 4.50088 0) (size 0.65024 4.59994) (layers B.Cu B.Mask)) + (pad "" connect circle (at -7.50062 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at -6.49986 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at -5.4991 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at -4.50088 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at -3.50012 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at -2.49936 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at -1.50114 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at -0.50038 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at 0.50038 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at -9.4996 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at 3.50012 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at 4.50088 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at 5.4991 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at 6.49986 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at 7.50062 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect circle (at -8.49884 2.30124) (size 0.65024 0.65024) (layers F.Cu F.Mask)) + (pad "" connect oval (at -6.49986 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at -5.4991 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at -4.50088 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at -3.50012 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at -2.49936 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at -1.50114 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at -0.50038 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at 5.4991 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at 6.49986 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at -7.50062 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at 4.50088 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at 7.50062 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at 0.50038 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at 3.50012 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at 8.49884 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at 9.4996 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) + (pad "" connect oval (at -8.49884 2.30124 90) (size 0.65024 0.65024) (layers B.Cu B.Mask)) +) diff --git a/PCB/.pretty/PCI-EXPRESS.kicad_mod.REMOVED.git-id b/PCB/.pretty/PCI-EXPRESS.kicad_mod.REMOVED.git-id deleted file mode 100644 index 7e0a4594..00000000 --- a/PCB/.pretty/PCI-EXPRESS.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d370bcace1197ab4f9397f0b7b8643fed896dad7 \ No newline at end of file diff --git a/PCB/.pretty/PINHEAD1-2.kicad_mod b/PCB/.pretty/PINHEAD1-2.kicad_mod new file mode 100644 index 00000000..9c339a3d --- /dev/null +++ b/PCB/.pretty/PINHEAD1-2.kicad_mod @@ -0,0 +1,16 @@ +(module PINHEAD1-2 (layer F.Cu) (tedit 0) + (attr virtual) + (fp_text reference REF** (at 0 -3.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value PINHEAD1-2 (at 0 3.81) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 2.54 -1.27) (end -2.54 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 3.175) (end -2.54 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 -3.175) (end 2.54 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 -3.175) (end -2.54 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 -3.175) (end 2.54 3.175) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole oval (at -1.27 0) (size 1.50622 3.01498) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 2 thru_hole oval (at 1.27 0) (size 1.50622 3.01498) (drill 0.99822) (layers *.Cu *.Mask)) +) diff --git a/PCB/.pretty/PINHEAD1-2.kicad_mod.REMOVED.git-id b/PCB/.pretty/PINHEAD1-2.kicad_mod.REMOVED.git-id deleted file mode 100644 index 362c296b..00000000 --- a/PCB/.pretty/PINHEAD1-2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9c339a3db6bcc21c4b182bfb600d4e4a321e3a78 \ No newline at end of file diff --git a/PCB/.pretty/PINHEAD1-3.kicad_mod b/PCB/.pretty/PINHEAD1-3.kicad_mod new file mode 100644 index 00000000..a1d1849d --- /dev/null +++ b/PCB/.pretty/PINHEAD1-3.kicad_mod @@ -0,0 +1,17 @@ +(module PINHEAD1-3 (layer F.Cu) (tedit 0) + (attr virtual) + (fp_text reference REF** (at 0.05 -3.8) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value PINHEAD1-3 (at 0 3.81) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -3.81 -3.175) (end -3.81 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 -3.175) (end 3.81 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 -1.27) (end -3.81 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.81 -3.175) (end 3.81 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 3.175) (end -3.81 3.175) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole oval (at -2.54 0) (size 1.50622 3.01498) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 2 thru_hole oval (at 0 0) (size 1.50622 3.01498) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 3 thru_hole oval (at 2.54 0) (size 1.50622 3.01498) (drill 0.99822) (layers *.Cu *.Mask)) +) diff --git a/PCB/.pretty/PINHEAD1-3.kicad_mod.REMOVED.git-id b/PCB/.pretty/PINHEAD1-3.kicad_mod.REMOVED.git-id deleted file mode 100644 index 679ebeed..00000000 --- a/PCB/.pretty/PINHEAD1-3.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a1d1849d785e764c41d2c7d8eb3cc293fcce899d \ No newline at end of file diff --git a/PCB/.pretty/PINHEAD1-6.kicad_mod b/PCB/.pretty/PINHEAD1-6.kicad_mod new file mode 100644 index 00000000..b269528e --- /dev/null +++ b/PCB/.pretty/PINHEAD1-6.kicad_mod @@ -0,0 +1,23 @@ +(module PINHEAD1-6 (layer F.Cu) (tedit 0) + (attr virtual) + (fp_text reference REF** (at 0 -3.75) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value PINHEAD1-6 (at 0 3.81) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 0 3.175) (end 7.62 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 0 -1.27) (end 7.62 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 0 -3.175) (end 7.62 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 -3.175) (end -7.62 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 -3.175) (end 7.62 3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 0 -1.27) (end -7.62 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 -3.175) (end 0 -3.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 0 3.175) (end -7.62 3.175) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole oval (at -6.35 0) (size 1.50622 3.01498) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 2 thru_hole oval (at -3.81 0) (size 1.50622 3.01498) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 3 thru_hole oval (at -1.27 0) (size 1.50622 3.01498) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 4 thru_hole oval (at 1.27 0) (size 1.50622 3.01498) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 5 thru_hole oval (at 3.81 0) (size 1.50622 3.01498) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 6 thru_hole oval (at 6.35 0) (size 1.50622 3.01498) (drill 0.99822) (layers *.Cu *.Mask)) +) diff --git a/PCB/.pretty/PINHEAD1-6.kicad_mod.REMOVED.git-id b/PCB/.pretty/PINHEAD1-6.kicad_mod.REMOVED.git-id deleted file mode 100644 index a52e7ec9..00000000 --- a/PCB/.pretty/PINHEAD1-6.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b269528e7d352d91f8fac65ee64b6bdb896525ce \ No newline at end of file diff --git a/PCB/.pretty/PINTST.kicad_mod b/PCB/.pretty/PINTST.kicad_mod new file mode 100644 index 00000000..b43d6b40 --- /dev/null +++ b/PCB/.pretty/PINTST.kicad_mod @@ -0,0 +1,17 @@ +(module PINTST (layer F.Cu) (tedit 0) + (descr "module 1 pin (ou trou mecanique de percage)") + (tags DEV) + (fp_text reference REF** (at 0 -1.26746) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value PINTST (at 0 1.27) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_circle (center 0 0) (end -0.254 -0.762) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole circle (at 0 0) (size 1.143 1.143) (drill 0.635) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/PINTST.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/PINTST.kicad_mod.REMOVED.git-id b/PCB/.pretty/PINTST.kicad_mod.REMOVED.git-id deleted file mode 100644 index dee1027c..00000000 --- a/PCB/.pretty/PINTST.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b43d6b405e10463a5a6f427d92f8fceee96afb82 \ No newline at end of file diff --git a/PCB/.pretty/QMS-1X52-FEMALE-SMD.kicad_mod b/PCB/.pretty/QMS-1X52-FEMALE-SMD.kicad_mod new file mode 100644 index 00000000..726b1769 --- /dev/null +++ b/PCB/.pretty/QMS-1X52-FEMALE-SMD.kicad_mod @@ -0,0 +1,94 @@ +(module QMS-1X52-FEMALE-SMD (layer F.Cu) (tedit 0) + (attr smd) + (fp_text reference REF** (at 0.4 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value QMS-1X52-FEMALE-SMD (at -0.1 2) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 9.398 -1.27) (end -9.398 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.398 1.27) (end 9.398 1.27) (layer F.SilkS) (width 0.15)) + (fp_text user 52 (at -9.4488 3.5306) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -8.636 -4.2418) (end -11.684 -4.2418) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.636 4.318) (end -11.684 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.684 -4.318) (end -11.684 4.318) (layer F.SilkS) (width 0.15)) + (fp_text user 2 (at 9.0678 3.3274) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text user 1 (at 8.9916 -3.0226) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 9.398 1.27) (end 9.398 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.398 -1.27) (end -9.398 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.684 4.318) (end 11.684 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.684 -4.318) (end 8.636 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.636 -4.318) (end 8.636 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.636 -3.7338) (end -8.636 -3.7338) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.636 -3.7338) (end -8.636 -4.2418) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.636 4.318) (end -8.636 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.636 3.81) (end 8.636 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.636 3.81) (end 8.636 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.636 4.318) (end 11.684 4.318) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at 7.9375 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at 7.9375 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at 7.3025 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 4 smd rect (at 7.3025 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 5 smd rect (at 6.6675 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 6 smd rect (at 6.6675 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 7 smd rect (at 6.0325 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 8 smd rect (at 6.0325 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 9 smd rect (at 5.3975 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 10 smd rect (at 5.3975 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 11 smd rect (at 4.7625 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 12 smd rect (at 4.7625 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 13 smd rect (at 4.1275 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 14 smd rect (at 4.1275 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 15 smd rect (at 3.4925 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 16 smd rect (at 3.4925 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 17 smd rect (at 2.8575 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 18 smd rect (at 2.8575 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 19 smd rect (at 2.2225 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 20 smd rect (at 2.2225 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 21 smd rect (at 1.5875 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 22 smd rect (at 1.5875 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 23 smd rect (at 0.9525 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 24 smd rect (at 0.9525 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 25 smd rect (at 0.3175 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 26 smd rect (at 0.3175 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 27 smd rect (at -0.3175 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 28 smd rect (at -0.3175 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 29 smd rect (at -0.9525 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 30 smd rect (at -0.9525 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 31 smd rect (at -1.5875 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 32 smd rect (at -1.5875 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 33 smd rect (at -2.2225 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 34 smd rect (at -2.2225 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 35 smd rect (at -2.8575 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 36 smd rect (at -2.8575 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 37 smd rect (at -3.4925 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 38 smd rect (at -3.4925 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 39 smd rect (at -4.1275 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 40 smd rect (at -4.1275 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 41 smd rect (at -4.7625 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 42 smd rect (at -4.7625 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 43 smd rect (at -5.3975 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 44 smd rect (at -5.3975 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 45 smd rect (at -6.0325 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 46 smd rect (at -6.0325 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 47 smd rect (at -6.6675 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 48 smd rect (at -6.6675 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 49 smd rect (at -7.3025 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 50 smd rect (at -7.3025 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 51 smd rect (at -7.9375 -3.4163) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 52 smd rect (at -7.9375 3.429) (size 0.381 1.39954) (layers F.Cu F.Paste F.Mask)) + (pad 53 smd oval (at 0 0) (size 18.034 0.508) (layers F.Cu F.Paste F.Mask)) + (pad "" thru_hole circle (at -9.29132 1.78562) (size 1.524 1.524) (drill 1.27) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 9.3599 1.78562) (size 1.524 1.524) (drill 1.27) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/QMS-1X52-FEMALE-SMD.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.4 0.4 0.4)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/QMS-1X52-FEMALE-SMD.kicad_mod.REMOVED.git-id b/PCB/.pretty/QMS-1X52-FEMALE-SMD.kicad_mod.REMOVED.git-id deleted file mode 100644 index a1233437..00000000 --- a/PCB/.pretty/QMS-1X52-FEMALE-SMD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -726b17699039bc3ff9fb94efa3f409ca0cf6ad37 \ No newline at end of file diff --git a/PCB/.pretty/QMS-1X52-SMD.kicad_mod b/PCB/.pretty/QMS-1X52-SMD.kicad_mod new file mode 100644 index 00000000..72fd0c54 --- /dev/null +++ b/PCB/.pretty/QMS-1X52-SMD.kicad_mod @@ -0,0 +1,89 @@ +(module QMS-1X52-SMD (layer F.Cu) (tedit 0) + (attr smd) + (fp_text reference REF** (at 10.668 -1.651 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value QMS-1X52-SMD (at 0 -5.461) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 9.398 1.27) (end -9.398 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.398 -1.27) (end 9.398 -1.27) (layer F.SilkS) (width 0.15)) + (fp_text user 52 (at -9.2075 -2.7305) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -8.636 4.318) (end -11.684 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.636 -4.318) (end -11.684 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.684 4.318) (end -11.684 -4.318) (layer F.SilkS) (width 0.15)) + (fp_text user 2 (at 8.8265 -2.7305) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text user 1 (at 8.8265 2.7305) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 9.398 -1.27) (end 9.398 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.398 1.27) (end -9.398 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.684 -4.318) (end 11.684 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.684 4.318) (end 8.636 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.636 4.318) (end 8.636 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.636 3.81) (end -8.636 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.636 3.81) (end -8.636 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.636 -4.318) (end -8.636 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.636 -3.81) (end 8.636 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.636 -3.81) (end 8.636 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.636 -4.318) (end 11.684 -4.318) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at 7.9375 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at 7.9375 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at 7.3025 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 4 smd rect (at 7.3025 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 5 smd rect (at 6.6675 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 6 smd rect (at 6.6675 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 7 smd rect (at 6.0325 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 8 smd rect (at 6.0325 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 9 smd rect (at 5.3975 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 10 smd rect (at 5.3975 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 11 smd rect (at 4.7625 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 12 smd rect (at 4.7625 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 13 smd rect (at 4.1275 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 14 smd rect (at 4.1275 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 15 smd rect (at 3.4925 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 16 smd rect (at 3.4925 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 17 smd rect (at 2.8575 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 18 smd rect (at 2.8575 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 19 smd rect (at 2.2225 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 20 smd rect (at 2.2225 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 21 smd rect (at 1.5875 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 22 smd rect (at 1.5875 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 23 smd rect (at 0.9525 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 24 smd rect (at 0.9525 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 25 smd rect (at 0.3175 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 26 smd rect (at 0.3175 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 27 smd rect (at -0.3175 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 28 smd rect (at -0.3175 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 29 smd rect (at -0.9525 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 30 smd rect (at -0.9525 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 31 smd rect (at -1.5875 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 32 smd rect (at -1.5875 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 33 smd rect (at -2.2225 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 34 smd rect (at -2.2225 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 35 smd rect (at -2.8575 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 36 smd rect (at -2.8575 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 37 smd rect (at -3.4925 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 38 smd rect (at -3.4925 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 39 smd rect (at -4.1275 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 40 smd rect (at -4.1275 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 41 smd rect (at -4.7625 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 42 smd rect (at -4.7625 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 43 smd rect (at -5.3975 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 44 smd rect (at -5.3975 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 45 smd rect (at -6.0325 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 46 smd rect (at -6.0325 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 47 smd rect (at -6.6675 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 48 smd rect (at -6.6675 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 49 smd rect (at -7.3025 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 50 smd rect (at -7.3025 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 51 smd rect (at -7.9375 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 52 smd rect (at -7.9375 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 53 smd rect (at 0 0) (size 18.034 0.508) (layers F.Cu F.Paste F.Mask)) + (pad "" thru_hole circle (at -10.287 2.032) (size 1.524 1.524) (drill 1.27) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 10.287 2.032) (size 1.524 1.524) (drill 1.27) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/QMS-1X52-SMD.kicad_mod.REMOVED.git-id b/PCB/.pretty/QMS-1X52-SMD.kicad_mod.REMOVED.git-id deleted file mode 100644 index 9f52b958..00000000 --- a/PCB/.pretty/QMS-1X52-SMD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -72fd0c54c5515c9591352b2773a9a5d8df236a0e \ No newline at end of file diff --git a/PCB/.pretty/QMS-2X52-SMD.kicad_mod b/PCB/.pretty/QMS-2X52-SMD.kicad_mod new file mode 100644 index 00000000..812b53c7 --- /dev/null +++ b/PCB/.pretty/QMS-2X52-SMD.kicad_mod @@ -0,0 +1,148 @@ +(module QMS-2X52-SMD (layer F.Cu) (tedit 0) + (attr smd) + (fp_text reference REF** (at 21.336 -1.397 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value QMS-2X52-SMD (at 0 -5.588) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 20.066 1.27) (end 1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 -1.27) (end 20.066 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 1.27) (end -20.066 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.066 -1.27) (end -1.27 -1.27) (layer F.SilkS) (width 0.15)) + (fp_text user 2 (at 20.20062 -3.40106) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text user 1 (at 19.99996 3.29946) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.27 1.27) (end -1.27 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.066 -1.27) (end -20.066 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.066 -1.27) (end 20.066 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end 1.27 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 22.352 -4.318) (end 22.352 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 22.352 4.318) (end 19.304 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.304 4.318) (end 19.304 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.032 3.81) (end 2.032 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.032 4.318) (end -2.032 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.032 4.318) (end -2.032 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.304 3.81) (end -19.304 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.304 4.318) (end -22.352 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -22.352 4.318) (end -22.352 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -22.352 -4.318) (end -19.304 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.304 -4.318) (end -19.304 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.032 -3.81) (end -2.032 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.032 -4.318) (end 2.032 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.032 -4.318) (end 2.032 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.304 -3.81) (end 19.304 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.304 -4.318) (end 22.352 -4.318) (layer F.SilkS) (width 0.15)) + (fp_circle (center 0 0) (end 0 -1.143) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at 18.6055 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at 18.6055 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at 17.9705 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 4 smd rect (at 17.9705 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 5 smd rect (at 17.3355 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 6 smd rect (at 17.3355 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 7 smd rect (at 16.7005 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 8 smd rect (at 16.7005 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 9 smd rect (at 16.0655 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 10 smd rect (at 16.0655 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 11 smd rect (at 15.4305 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 12 smd rect (at 15.4305 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 13 smd rect (at 14.7955 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 14 smd rect (at 14.7955 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 15 smd rect (at 14.1605 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 16 smd rect (at 14.1605 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 17 smd rect (at 13.5255 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 18 smd rect (at 13.5255 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 19 smd rect (at 12.8905 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 20 smd rect (at 12.8905 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 21 smd rect (at 12.2555 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 22 smd rect (at 12.2555 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 23 smd rect (at 11.6205 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 24 smd rect (at 11.6205 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 25 smd rect (at 10.9855 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 26 smd rect (at 10.9855 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 27 smd rect (at 10.3505 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 28 smd rect (at 10.3505 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 29 smd rect (at 9.7155 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 30 smd rect (at 9.7155 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 31 smd rect (at 9.0805 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 32 smd rect (at 9.0805 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 33 smd rect (at 8.4455 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 34 smd rect (at 8.4455 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 35 smd rect (at 7.8105 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 36 smd rect (at 7.8105 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 37 smd rect (at 7.1755 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 38 smd rect (at 7.1755 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 39 smd rect (at 6.5405 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 40 smd rect (at 6.5405 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 41 smd rect (at 5.9055 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 42 smd rect (at 5.9055 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 43 smd rect (at 5.2705 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 44 smd rect (at 5.2705 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 45 smd rect (at 4.6355 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 46 smd rect (at 4.6355 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 47 smd rect (at 4.0005 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 48 smd rect (at 4.0005 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 49 smd rect (at 3.3655 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 50 smd rect (at 3.3655 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 51 smd rect (at 2.7305 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 52 smd rect (at 2.7305 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 53 smd rect (at -2.7305 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 54 smd rect (at -2.7305 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 55 smd rect (at -3.3655 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 56 smd rect (at -3.3655 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 57 smd rect (at -4.0005 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 58 smd rect (at -4.0005 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 59 smd rect (at -4.6355 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 60 smd rect (at -4.6355 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 61 smd rect (at -5.2705 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 62 smd rect (at -5.2705 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 63 smd rect (at -5.9055 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 64 smd rect (at -5.9055 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 65 smd rect (at -6.5405 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 66 smd rect (at -6.5405 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 67 smd rect (at -7.1755 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 68 smd rect (at -7.1755 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 69 smd rect (at -7.8105 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 70 smd rect (at -7.8105 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 71 smd rect (at -8.4455 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 72 smd rect (at -8.4455 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 73 smd rect (at -9.0805 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 74 smd rect (at -9.0805 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 75 smd rect (at -9.7155 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 76 smd rect (at -9.7155 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 77 smd rect (at -10.3505 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 78 smd rect (at -10.3505 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 79 smd rect (at -10.9855 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 80 smd rect (at -10.9855 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 81 smd rect (at -11.6205 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 82 smd rect (at -11.6205 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 83 smd rect (at -12.2555 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 84 smd rect (at -12.2555 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 85 smd rect (at -12.8905 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 86 smd rect (at -12.8905 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 87 smd rect (at -13.5255 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 88 smd rect (at -13.5255 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 89 smd rect (at -14.1605 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 90 smd rect (at -14.1605 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 91 smd rect (at -14.7955 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 92 smd rect (at -14.7955 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 93 smd rect (at -15.4305 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 94 smd rect (at -15.4305 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 95 smd rect (at -16.0655 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 96 smd rect (at -16.0655 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 97 smd rect (at -16.7005 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 98 smd rect (at -16.7005 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 99 smd rect (at -17.3355 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 100 smd rect (at -17.3355 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 101 smd rect (at -17.9705 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 102 smd rect (at -17.9705 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 103 smd rect (at -18.6055 3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 104 smd rect (at -18.6055 -3.302) (size 0.381 2.159) (layers F.Cu F.Paste F.Mask)) + (pad 106 smd rect (at -10.668 0) (size 18.034 0.508) (layers F.Cu F.Paste F.Mask)) + (pad 105 smd rect (at 10.668 0) (size 18.034 0.508) (layers F.Cu F.Paste F.Mask)) + (pad "" thru_hole circle (at -20.955 2.032) (size 1.524 1.524) (drill 1.27) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 20.955 2.032) (size 1.524 1.524) (drill 1.27) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/QMS-2X52-SMD.kicad_mod.REMOVED.git-id b/PCB/.pretty/QMS-2X52-SMD.kicad_mod.REMOVED.git-id deleted file mode 100644 index 85b515fb..00000000 --- a/PCB/.pretty/QMS-2X52-SMD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -812b53c7f84f5c18685d4e957b49d85e14c43842 \ No newline at end of file diff --git a/PCB/.pretty/RJ12_E.kicad_mod b/PCB/.pretty/RJ12_E.kicad_mod new file mode 100644 index 00000000..1fc55807 --- /dev/null +++ b/PCB/.pretty/RJ12_E.kicad_mod @@ -0,0 +1,21 @@ +(module RJ12_E (layer F.Cu) (tedit 0) + (fp_text reference REF** (at 0 0) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value RJ12_E (at 0 -2.54) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -6.858 -10.922) (end -6.858 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.604 -10.922) (end 6.604 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.858 2.286) (end 6.604 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.842 -10.922) (end 6.604 -10.922) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.858 -10.922) (end 5.842 -10.922) (layer F.SilkS) (width 0.15)) + (pad 4 thru_hole circle (at 0.508 -8.89) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -2.032 -8.89) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 3.048 -8.89) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole circle (at -3.302 -6.35) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -0.762 -6.35) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 1.778 -6.35) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 6.604 -4.318) (size 2.99974 2.99974) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -6.858 -4.318) (size 2.99974 2.99974) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/RJ12_E.kicad_mod.REMOVED.git-id b/PCB/.pretty/RJ12_E.kicad_mod.REMOVED.git-id deleted file mode 100644 index 53eba1b1..00000000 --- a/PCB/.pretty/RJ12_E.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1fc5580770036c759cf26139878f86d9951938b1 \ No newline at end of file diff --git a/PCB/.pretty/RJ45_8.kicad_mod b/PCB/.pretty/RJ45_8.kicad_mod new file mode 100644 index 00000000..542aeaf0 --- /dev/null +++ b/PCB/.pretty/RJ45_8.kicad_mod @@ -0,0 +1,28 @@ +(module RJ45_8 (layer F.Cu) (tedit 0) + (tags RJ45) + (fp_text reference REF** (at 0.254 4.826) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value RJ45_8 (at 0.14224 -0.1016) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -7.62 7.874) (end 7.62 7.874) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 7.874) (end 7.62 -10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 -10.16) (end -7.62 -10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 -10.16) (end -7.62 7.874) (layer F.SilkS) (width 0.15)) + (pad Hole np_thru_hole circle (at 5.93852 0) (size 3.64998 3.64998) (drill 3.2512) (layers *.Cu *.SilkS *.Mask)) + (pad Hole np_thru_hole circle (at -5.9309 0) (size 3.64998 3.64998) (drill 3.2512) (layers *.Cu *.SilkS *.Mask)) + (pad 1 thru_hole rect (at -4.445 -6.35) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -3.175 -8.89) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -1.905 -6.35) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -0.635 -8.89) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 0.635 -6.35) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 1.905 -8.89) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 3.175 -6.35) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 4.445 -8.89) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/RJ45_8.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.4 0.4 0.4)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/RJ45_8.kicad_mod.REMOVED.git-id b/PCB/.pretty/RJ45_8.kicad_mod.REMOVED.git-id deleted file mode 100644 index aa4834ed..00000000 --- a/PCB/.pretty/RJ45_8.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -542aeaf0be1a16b762e978d20e5cc623d8541432 \ No newline at end of file diff --git a/PCB/.pretty/RJ45_TRANSFO.kicad_mod b/PCB/.pretty/RJ45_TRANSFO.kicad_mod new file mode 100644 index 00000000..d8f913cc --- /dev/null +++ b/PCB/.pretty/RJ45_TRANSFO.kicad_mod @@ -0,0 +1,33 @@ +(module RJ45_TRANSFO (layer F.Cu) (tedit 0) + (tags RJ45) + (fp_text reference REF** (at -3.81 15.24) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value RJ45_TRANSFO (at -3.81 11.43) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 3.937 20.066) (end 3.937 8.128) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.937 4.953) (end 3.937 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.065 20.066) (end -12.065 8.128) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.065 4.953) (end -12.065 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.937 -4.953) (end 2.921 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.461 -4.953) (end -2.159 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.065 -4.953) (end -10.795 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.065 20.11172) (end 3.937 20.11172) (layer F.SilkS) (width 0.15)) + (pad Hole thru_hole circle (at 1.905 8.89) (size 3.85064 3.85064) (drill 3.302) (layers *.Cu *.SilkS *.Mask)) + (pad Hole thru_hole circle (at -9.525 8.89) (size 3.85064 3.85064) (drill 3.302) (layers *.Cu *.SilkS *.Mask)) + (pad 8 thru_hole circle (at -8.255 2.54) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -7.62 0) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -5.715 2.54) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -5.08 0) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -3.175 2.54) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -2.54 0) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -0.635 2.54) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at 3.937 5.842) (size 2.54 2.54) (drill 1.778) (layers *.Cu *.SilkS *.Mask)) + (pad 13 thru_hole circle (at -11.557 5.842) (size 2.54 2.54) (drill 1.778) (layers *.Cu *.SilkS *.Mask)) + (pad YK thru_hole circle (at -6.731 -4.826) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad GA thru_hole circle (at -0.889 -4.826) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad YA thru_hole circle (at -9.271 -4.826) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad GK thru_hole circle (at 1.651 -4.826) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 0 0) (size 1.524 1.524) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/RJ45_TRANSFO.kicad_mod.REMOVED.git-id b/PCB/.pretty/RJ45_TRANSFO.kicad_mod.REMOVED.git-id deleted file mode 100644 index aabd252e..00000000 --- a/PCB/.pretty/RJ45_TRANSFO.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d8f913cca00b9cc8a12b79d98bff0007e2178f45 \ No newline at end of file diff --git a/PCB/.pretty/RJ45_TRANSFO_ver2.kicad_mod b/PCB/.pretty/RJ45_TRANSFO_ver2.kicad_mod new file mode 100644 index 00000000..d47ea036 --- /dev/null +++ b/PCB/.pretty/RJ45_TRANSFO_ver2.kicad_mod @@ -0,0 +1,32 @@ +(module RJ45_TRANSFO_ver2 (layer F.Cu) (tedit 0) + (tags RJ45) + (fp_text reference REF** (at 0 8.128) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value RJ45_TRANSFO_ver2 (at 0.14224 -0.1016) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 8.001 12.954) (end 8.001 1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.001 -2.159) (end 8.001 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.001 12.954) (end -8.001 1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.001 -2.159) (end -8.001 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.001 -12.065) (end 6.985 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 -12.065) (end 1.524 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.001 -12.065) (end -6.731 -12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.001 12.99972) (end 8.001 12.99972) (layer F.SilkS) (width 0.15)) + (pad Hole thru_hole circle (at 5.42798 2.49936) (size 3.85064 3.85064) (drill 3.05054) (layers *.Cu *.SilkS *.Mask)) + (pad Hole thru_hole circle (at -5.42544 2.48666) (size 3.85064 3.85064) (drill 3.05054) (layers *.Cu *.SilkS *.Mask)) + (pad 1 thru_hole rect (at -3.58648 -4.572) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -4.85648 -7.112) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -1.04648 -4.572) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -2.31648 -7.112) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 1.49352 -4.572) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 0.22352 -7.112) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 4.03352 -4.572) (size 1.50114 1.50114) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 7.99846 -0.49276) (size 2.032 2.032) (drill 1.00076) (layers *.Cu *.SilkS *.Mask)) + (pad 9 thru_hole circle (at -8.001 -0.49276) (size 2.032 2.032) (drill 1.00076) (layers *.Cu *.SilkS *.Mask)) + (pad Hole thru_hole circle (at -3.048 -12.192) (size 1.5113 1.5113) (drill 0.89916) (layers *.Cu *.SilkS *.Mask)) + (pad Hole thru_hole circle (at 3.048 -12.192) (size 1.5113 1.5113) (drill 0.89916) (layers *.Cu *.SilkS *.Mask)) + (pad Hole thru_hole circle (at -5.588 -12.192) (size 1.5113 1.5113) (drill 0.89916) (layers *.Cu *.SilkS *.Mask)) + (pad Hole thru_hole circle (at 5.588 -12.192) (size 1.5113 1.5113) (drill 0.89916) (layers *.Cu *.SilkS *.Mask)) +) diff --git a/PCB/.pretty/RJ45_TRANSFO_ver2.kicad_mod.REMOVED.git-id b/PCB/.pretty/RJ45_TRANSFO_ver2.kicad_mod.REMOVED.git-id deleted file mode 100644 index 64056702..00000000 --- a/PCB/.pretty/RJ45_TRANSFO_ver2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d47ea036ccc91fd5b25467e37a01b01c8cf85b66 \ No newline at end of file diff --git a/PCB/.pretty/RJHSE538X.kicad_mod b/PCB/.pretty/RJHSE538X.kicad_mod new file mode 100644 index 00000000..1ea6828f --- /dev/null +++ b/PCB/.pretty/RJHSE538X.kicad_mod @@ -0,0 +1,41 @@ +(module RJHSE538X (layer F.Cu) (tedit 55225793) + (descr "mod. jack, ethernet, 8P8C, RJ45 connector, 2 leds, shielded") + (tags "RJHSE538X 8P8C RJ45 ethernet jack") + (fp_text reference REF** (at 3.4925 -6.9215) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value RJHSE538X (at 3.937 9.2075) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -5.8 -8.45) (end -5.8 7.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start -5.8 7.9) (end 12.9 7.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start 12.9 7.9) (end 12.9 -8.45) (layer F.CrtYd) (width 0.05)) + (fp_line (start 12.9 -8.45) (end -5.8 -8.45) (layer F.CrtYd) (width 0.05)) + (fp_line (start 11.8745 7.62) (end 11.8745 2.0955) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.7625 7.62) (end -4.7625 2.0955) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.8745 -8.1915) (end -4.7625 -8.1915) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.8745 -8.1915) (end 11.8745 -0.3175) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.7625 -8.1915) (end -4.7625 -0.3175) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.8745 7.62) (end -4.7625 7.62) (layer F.SilkS) (width 0.15)) + (pad "" thru_hole circle (at 11.684 0.889) (size 2 2) (drill 1.57) (layers *.Cu *.Mask)) + (pad 9 thru_hole circle (at -3.302 6.604) (size 1.50114 1.50114) (drill 0.889) (layers *.Cu *.Mask)) + (pad 10 thru_hole circle (at -1.016 6.604) (size 1.50114 1.50114) (drill 0.889) (layers *.Cu *.Mask)) + (pad 11 thru_hole circle (at 8.128 6.604) (size 1.50114 1.50114) (drill 0.889) (layers *.Cu *.Mask)) + (pad 12 thru_hole circle (at 10.414 6.604) (size 1.50114 1.50114) (drill 0.889) (layers *.Cu *.Mask)) + (pad 8 thru_hole circle (at 7.112 1.778) (size 1.50114 1.50114) (drill 0.889) (layers *.Cu *.Mask)) + (pad 6 thru_hole circle (at 5.08 1.778) (size 1.50114 1.50114) (drill 0.889) (layers *.Cu *.Mask)) + (pad 4 thru_hole circle (at 3.048 1.778) (size 1.50114 1.50114) (drill 0.889) (layers *.Cu *.Mask)) + (pad 2 thru_hole circle (at 1.016 1.778) (size 1.50114 1.50114) (drill 0.889) (layers *.Cu *.Mask)) + (pad 5 thru_hole circle (at 4.064 0) (size 1.50114 1.50114) (drill 0.889) (layers *.Cu *.Mask)) + (pad 3 thru_hole circle (at 2.032 0) (size 1.50114 1.50114) (drill 0.889) (layers *.Cu *.Mask)) + (pad 7 thru_hole circle (at 6.096 0) (size 1.50114 1.50114) (drill 0.889) (layers *.Cu *.Mask)) + (pad 1 thru_hole circle (at 0 0) (size 1.50114 1.50114) (drill 0.889) (layers *.Cu *.Mask)) + (pad "" thru_hole circle (at -2.794 -2.54) (size 3.3 3.3) (drill 3.3) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 9.906 -2.54) (size 3.3 3.3) (drill 3.3) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -4.572 0.889) (size 2 2) (drill 1.57) (layers *.Cu *.Mask)) + (model Connect.3dshapes/RJHSE538X.wrl + (at (xyz 0.138 0.06 0.125)) + (scale (xyz 0.4 0.4 0.4)) + (rotate (xyz -90 0 180)) + ) +) diff --git a/PCB/.pretty/RJHSE538X.kicad_mod.REMOVED.git-id b/PCB/.pretty/RJHSE538X.kicad_mod.REMOVED.git-id deleted file mode 100644 index a29269e5..00000000 --- a/PCB/.pretty/RJHSE538X.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1ea6828fe34d4045e0b365fc62e7eaa6a09a8ebe \ No newline at end of file diff --git a/PCB/.pretty/SAS_mini_1888174.kicad_mod b/PCB/.pretty/SAS_mini_1888174.kicad_mod new file mode 100644 index 00000000..468e02e0 --- /dev/null +++ b/PCB/.pretty/SAS_mini_1888174.kicad_mod @@ -0,0 +1,66 @@ +(module SAS_mini_1888174 (layer F.Cu) (tedit 0) + (descr "36pin mini SAS connector") + (tags "SAS mini connector") + (fp_text reference REF** (at 4 -7.4) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SAS_mini_1888174 (at 0 0) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 9.5 -6.5) (end -9.5 -6.5) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.5 -6.5) (end -9.5 6.5) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.5 6.5) (end 9.5 6.5) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.5 6.5) (end 9.5 -6.5) (layer F.SilkS) (width 0.15)) + (pad B1 smd oval (at -7 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B2 smd oval (at -6.2 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B3 smd oval (at -5.4 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B4 smd oval (at -4.6 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B5 smd oval (at -3.8 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B6 smd oval (at -3 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B7 smd oval (at -2.2 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B8 smd oval (at -1.4 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B9 smd oval (at -0.6 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B10 smd oval (at 0.2 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B11 smd oval (at 1 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B12 smd oval (at 1.8 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B13 smd oval (at 2.6 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B14 smd oval (at 3.4 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B15 smd oval (at 4.2 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B16 smd oval (at 5 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad B17 smd oval (at 5.8 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A1 smd oval (at -6.5 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A2 smd oval (at -5.7 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A3 smd oval (at -4.9 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A4 smd oval (at -4.1 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A5 smd oval (at -3.3 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A6 smd oval (at -2.5 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A7 smd oval (at -1.7 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A8 smd oval (at -0.9 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A9 smd oval (at -0.1 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A10 smd oval (at 0.7 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A11 smd oval (at 1.5 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A12 smd oval (at 2.3 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A13 smd oval (at 3.1 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A14 smd oval (at 3.9 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A15 smd oval (at 4.7 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A16 smd oval (at 5.5 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A17 smd oval (at 6.3 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad 1 thru_hole circle (at -8.9 -5.24) (size 1.55 1.55) (drill 0.8) (layers *.Cu *.Mask F.SilkS) + (zone_connect 2)) + (pad 2 thru_hole circle (at -8.9 -2) (size 1.55 1.55) (drill 0.8) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -8.9 4.03) (size 1.55 1.55) (drill 0.8) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -8.9 2) (size 1.55 1.55) (drill 0.8) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 8.9 -6.24) (size 1.55 1.55) (drill 0.8) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 8.9 -2) (size 1.55 1.55) (drill 0.8) (layers *.Cu *.Mask F.SilkS)) + (pad "" np_thru_hole circle (at -8 0) (size 1.55 1.55) (drill 1.55) (layers *.Mask B.Cu F.SilkS)) + (pad "" np_thru_hole circle (at 8 0) (size 1.55 1.55) (drill 1.55) (layers *.Mask B.Cu F.SilkS)) + (pad 8 thru_hole circle (at 8.9 4.03) (size 1.55 1.55) (drill 0.8) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 8.9 2) (size 1.55 1.55) (drill 0.8) (layers *.Cu *.Mask F.SilkS)) + (pad B18 smd oval (at 6.6 -2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (pad A18 smd oval (at 7.1 2.91) (size 0.35 1.8) (layers F.Cu F.Paste F.Mask)) + (model Connect.3dshapes/SAS_mini_1888174.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/SAS_mini_1888174.kicad_mod.REMOVED.git-id b/PCB/.pretty/SAS_mini_1888174.kicad_mod.REMOVED.git-id deleted file mode 100644 index e5014eea..00000000 --- a/PCB/.pretty/SAS_mini_1888174.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -468e02e033dfe81e9df7f4b27401ce4a24b7f617 \ No newline at end of file diff --git a/PCB/.pretty/SATA-22_SMD.kicad_mod b/PCB/.pretty/SATA-22_SMD.kicad_mod new file mode 100644 index 00000000..7ce64b67 --- /dev/null +++ b/PCB/.pretty/SATA-22_SMD.kicad_mod @@ -0,0 +1,64 @@ +(module SATA-22_SMD (layer F.Cu) (tedit 0) + (fp_text reference REF** (at 0 3.175) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SATA-22_SMD (at 0 5.715) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -17.145 -0.6096) (end -17.145 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.415 10.5664) (end 18.415 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.415 5.08) (end 20.32 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.32 5.08) (end 20.32 -0.6096) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.32 -0.6096) (end 17.145 -0.6096) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.145 -0.6096) (end 17.145 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -18.415 10.5664) (end 18.415 10.5664) (layer F.SilkS) (width 0.15)) + (fp_line (start -17.145 -0.6096) (end -20.32 -0.6096) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -0.6096) (end -20.32 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 5.08) (end -18.415 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -18.415 5.08) (end -18.415 10.5664) (layer F.SilkS) (width 0.15)) + (fp_line (start -17.145 0.635) (end 1.27 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 0.635) (end 1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end 2.54 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 1.27) (end 2.54 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 0.635) (end 11.43 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.43 0.635) (end 11.43 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.43 1.27) (end 12.7 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.7 1.27) (end 12.7 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.7 0.635) (end 17.145 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.415 10.541) (end 19.05 11.811) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.05 11.811) (end 19.685 11.811) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.685 11.811) (end 20.32 10.541) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.32 10.541) (end 20.32 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.32 9.271) (end 18.415 6.731) (layer F.SilkS) (width 0.15)) + (fp_line (start -18.415 10.541) (end -19.05 11.811) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.05 11.811) (end -19.685 11.811) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.685 11.811) (end -20.32 10.541) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 10.541) (end -20.32 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 9.271) (end -18.415 6.731) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -15.875 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at -14.605 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at -13.335 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 4 smd rect (at -12.065 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 5 smd rect (at -10.795 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 6 smd rect (at -9.525 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 7 smd rect (at -8.255 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 8 smd rect (at -1.905 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 9 smd rect (at -0.635 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 10 smd rect (at 0.635 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 11 smd rect (at 1.905 0.508) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 12 smd rect (at 3.175 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 13 smd rect (at 4.445 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 14 smd rect (at 5.715 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 15 smd rect (at 6.985 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad "" thru_hole circle (at 16.5862 2.9972) (size 1.50114 1.50114) (drill 1.50114) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -16.5862 2.9972) (size 1.50114 1.50114) (drill 1.50114) (layers *.Cu *.Mask F.SilkS)) + (pad 16 smd rect (at 8.255 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 17 smd rect (at 9.525 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 18 smd rect (at 10.795 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 19 smd rect (at 12.065 0.508) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 20 smd rect (at 13.335 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 21 smd rect (at 14.605 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad 22 smd rect (at 15.875 0) (size 0.8636 2.286) (layers F.Cu F.Paste F.Mask)) + (pad "" thru_hole circle (at 18.7198 2.2352) (size 2.79908 2.79908) (drill 2.30124) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -18.7198 2.2352) (size 2.79908 2.79908) (drill 2.30124) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/SATA-22_SMD.kicad_mod.REMOVED.git-id b/PCB/.pretty/SATA-22_SMD.kicad_mod.REMOVED.git-id deleted file mode 100644 index 3384f87c..00000000 --- a/PCB/.pretty/SATA-22_SMD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7ce64b6707fca307b0e40a94eaeccb1a76b6a0a7 \ No newline at end of file diff --git a/PCB/.pretty/SATA-7_SMD.kicad_mod b/PCB/.pretty/SATA-7_SMD.kicad_mod new file mode 100644 index 00000000..4af0efa2 --- /dev/null +++ b/PCB/.pretty/SATA-7_SMD.kicad_mod @@ -0,0 +1,127 @@ +(module SATA-7_SMD (layer F.Cu) (tedit 0) + (descr "SERIAL ATA 7P R/A SMT") + (tags "SERIAL ATA SATA") + (attr smd) + (fp_text reference REF** (at -3.81 -13.335) (layer B.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SATA-7_SMD (at 3.175 -13.335) (layer B.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -6.04774 -9.99998) (end -6.04774 -8.49884) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.74878 -8.49884) (end -6.74878 -9.99998) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.74878 -9.99998) (end 6.74878 -8.49884) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.04774 -8.49884) (end 6.04774 -9.99998) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.22706 0.35052) (end -8.22706 -5.01142) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.22706 -5.01142) (end -8.22706 -11.16838) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.22706 -11.16838) (end -7.43458 -11.16838) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.43458 -11.16838) (end -5.06222 -11.16838) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.06222 -11.16838) (end -5.06222 -6.9469) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.43458 -11.16838) (end -7.43458 -6.9469) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.43458 -6.9469) (end 5.13588 -6.9469) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.13588 -6.9469) (end 7.42442 -6.9469) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.42442 -6.9469) (end 7.42442 -11.16838) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.13588 -6.9469) (end 5.13588 -11.16838) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.13588 -11.16838) (end 6.54304 -11.16838) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.54304 -11.16838) (end 8.128 -11.16838) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.128 -11.16838) (end 8.128 -6.9469) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.128 -6.9469) (end 9.1821 -6.9469) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.1821 -6.9469) (end 9.1821 0.35052) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.1821 0.35052) (end 7.59968 0.35052) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.59968 0.35052) (end 7.16026 -0.08636) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.16026 -0.08636) (end 7.16026 -5.01142) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.16026 -5.01142) (end 5.7531 -5.01142) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.7531 -5.01142) (end 5.7531 -0.17526) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.7531 -0.17526) (end 5.7531 -0.17526) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.7531 -0.17526) (end 5.22478 0.35052) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.22478 0.35052) (end -4.07416 0.34798) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.731 0.35052) (end -8.22706 0.35052) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.20522 -0.17526) (end -6.731 0.35052) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.20522 -0.17526) (end -6.20522 -4.572) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.20522 -4.572) (end -5.7658 -5.01142) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.22706 -5.01142) (end 5.7531 -5.01142) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.6642 -0.17526) (end 4.6101 -0.17526) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.6101 -0.17526) (end -4.6228 -0.17526) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.09702 0.33782) (end -4.6228 -0.17526) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.6228 -0.17526) (end -4.6228 -4.92252) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.381 -4.953) (end -0.381 -0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.381 -0.508) (end 0.381 -0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.381 -0.508) (end 0.381 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.651 -4.953) (end -1.651 -0.889) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.651 -0.889) (end -0.889 -0.889) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.889 -0.889) (end -0.889 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.889 -4.953) (end 0.889 -0.889) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.889 -0.889) (end 1.651 -0.889) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.651 -0.889) (end 1.651 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.159 -4.953) (end 2.159 -0.889) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.159 -0.889) (end 2.921 -0.889) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.921 -0.889) (end 2.921 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.429 -4.953) (end 3.429 -0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.429 -0.508) (end 4.191 -0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.191 -0.508) (end 4.191 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.6101 -0.17526) (end 4.6101 -4.92252) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.429 -4.953) (end -3.429 -0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.429 -0.508) (end -4.191 -0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.191 -0.508) (end -4.191 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.921 -4.953) (end -2.921 -0.889) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.921 -0.889) (end -2.159 -0.889) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.159 -0.889) (end -2.159 -4.953) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.191 -6.985) (end -4.064 -7.23646) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.064 -7.23646) (end -4.064 -11.176) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.064 -11.176) (end -3.556 -11.176) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.556 -11.176) (end -3.556 -7.23646) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.556 -7.23646) (end -3.429 -6.985) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.921 -6.985) (end -2.794 -7.23646) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.794 -7.23646) (end -2.794 -11.176) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.794 -11.176) (end -2.286 -11.176) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.286 -11.176) (end -2.286 -7.23646) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.286 -7.23646) (end -2.159 -6.985) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.651 -6.985) (end -1.524 -7.23646) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.524 -7.23646) (end -1.524 -11.176) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.524 -11.176) (end -1.016 -11.176) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.016 -11.176) (end -1.016 -7.23646) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.016 -7.23646) (end -0.889 -6.985) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.381 -6.985) (end -0.254 -7.23646) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.254 -7.23646) (end -0.254 -11.176) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.254 -11.176) (end 0.254 -11.176) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.254 -11.176) (end 0.254 -7.23646) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.254 -7.23646) (end 0.381 -6.985) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.889 -6.985) (end 1.016 -7.23646) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.016 -7.23646) (end 1.016 -11.176) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.016 -11.176) (end 1.524 -11.176) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 -11.176) (end 1.524 -7.23646) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 -7.23646) (end 1.651 -6.985) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.159 -6.985) (end 2.286 -7.23646) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.286 -7.23646) (end 2.286 -11.176) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.286 -11.176) (end 2.794 -11.176) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.794 -11.176) (end 2.794 -7.23646) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.794 -7.23646) (end 2.921 -6.985) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.429 -6.985) (end 3.556 -7.23646) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.556 -7.23646) (end 3.556 -11.176) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.556 -11.176) (end 4.064 -11.176) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.064 -11.176) (end 4.064 -7.23646) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.064 -7.23646) (end 4.191 -6.985) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.55574 -11.07948) (end -6.55574 -7.73684) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.55574 -7.73684) (end -6.20522 -7.73684) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.20522 -7.73684) (end -6.20522 -11.07948) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.19252 -11.07948) (end 6.19252 -7.73684) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.19252 -7.73684) (end 6.54304 -7.73684) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.54304 -7.73684) (end 6.54304 -11.16838) (layer F.SilkS) (width 0.15)) + (fp_arc (start -6.39826 -9.99998) (end -6.74878 -9.99998) (angle 90) (layer F.SilkS) (width 0.15)) + (fp_arc (start -6.39826 -9.99998) (end -6.39826 -10.34796) (angle 90) (layer F.SilkS) (width 0.15)) + (fp_arc (start -6.39826 -8.49884) (end -6.04774 -8.49884) (angle 90) (layer F.SilkS) (width 0.15)) + (fp_arc (start -6.39826 -8.49884) (end -6.39826 -8.14832) (angle 90) (layer F.SilkS) (width 0.15)) + (fp_arc (start 6.39826 -9.99998) (end 6.04774 -9.99998) (angle 90) (layer F.SilkS) (width 0.15)) + (fp_arc (start 6.39826 -9.99998) (end 6.39826 -10.34796) (angle 90) (layer F.SilkS) (width 0.15)) + (fp_arc (start 6.39826 -8.49884) (end 6.74878 -8.49884) (angle 90) (layer F.SilkS) (width 0.15)) + (fp_arc (start 6.39826 -8.49884) (end 6.39826 -8.14832) (angle 90) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -3.81 -11.19886) (size 0.99822 2.09804) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at -2.54 -11.19886) (size 0.99822 2.09804) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at -1.27 -11.19886) (size 0.99822 2.09804) (layers F.Cu F.Paste F.Mask)) + (pad 4 smd rect (at 0 -11.19886) (size 0.99822 2.09804) (layers F.Cu F.Paste F.Mask)) + (pad 5 smd rect (at 1.27 -11.19886) (size 0.99822 2.09804) (layers F.Cu F.Paste F.Mask)) + (pad 6 smd rect (at 2.54 -11.19886) (size 0.99822 2.09804) (layers F.Cu F.Paste F.Mask)) + (pad 7 smd rect (at 3.81 -11.19886) (size 0.99822 2.09804) (layers F.Cu F.Paste F.Mask)) + (pad M1 thru_hole oval (at -6.39826 -9.24814) (size 1.27 2.54) (drill 0.6985) (layers F&B.Cu F.Paste F.SilkS F.Mask)) + (pad M2 thru_hole oval (at 6.39826 -9.24814) (size 1.27 2.54) (drill 0.6985) (layers F&B.Cu F.Paste F.SilkS F.Mask)) +) diff --git a/PCB/.pretty/SATA-7_SMD.kicad_mod.REMOVED.git-id b/PCB/.pretty/SATA-7_SMD.kicad_mod.REMOVED.git-id deleted file mode 100644 index 20a876b9..00000000 --- a/PCB/.pretty/SATA-7_SMD.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4af0efa22a68f1631ce34ebc8babd2f6e69075ff \ No newline at end of file diff --git a/PCB/.pretty/SATA-7_THT_VERT_1.kicad_mod b/PCB/.pretty/SATA-7_THT_VERT_1.kicad_mod new file mode 100644 index 00000000..ccfc7164 --- /dev/null +++ b/PCB/.pretty/SATA-7_THT_VERT_1.kicad_mod @@ -0,0 +1,21 @@ +(module SATA-7_THT_VERT_1 (layer F.Cu) (tedit 0) + (fp_text reference REF** (at 0 -4.191) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SATA-7_THT_VERT_1 (at 0 -2.286) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -8.45 -3.225) (end 8.45 -3.225) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.45 -3.225) (end 8.45 3.225) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.45 3.225) (end -8.45 3.225) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.45 3.225) (end -8.45 -3.225) (layer F.SilkS) (width 0.15)) + (pad 9 thru_hole circle (at 6.48 0) (size 2.5 2.5) (drill 1.35) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole oval (at 2.54 -0.5) (size 1.1 1.3) (drill 0.74) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -6.48 0) (size 2.5 2.5) (drill 1.35) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole oval (at 1.27 -0.5) (size 1.1 1.3) (drill 0.74) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole oval (at -1.27 -0.5) (size 1.1 1.3) (drill 0.74) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole oval (at -2.54 -0.5) (size 1.1 1.3) (drill 0.74) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole oval (at -3.81 0.5) (size 1.1 1.3) (drill 0.74) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole oval (at 0 0.5) (size 1.1 1.3) (drill 0.74) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole oval (at 3.81 0.5) (size 1.1 1.3) (drill 0.74) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/SATA-7_THT_VERT_1.kicad_mod.REMOVED.git-id b/PCB/.pretty/SATA-7_THT_VERT_1.kicad_mod.REMOVED.git-id deleted file mode 100644 index cc21376e..00000000 --- a/PCB/.pretty/SATA-7_THT_VERT_1.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ccfc7164045f17dc48ee9da6f4614058a8259f4c \ No newline at end of file diff --git a/PCB/.pretty/SATA-7_THT_VERT_2.kicad_mod b/PCB/.pretty/SATA-7_THT_VERT_2.kicad_mod new file mode 100644 index 00000000..3926c10d --- /dev/null +++ b/PCB/.pretty/SATA-7_THT_VERT_2.kicad_mod @@ -0,0 +1,21 @@ +(module SATA-7_THT_VERT_2 (layer F.Cu) (tedit 0) + (fp_text reference REF** (at 0.6 -3.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SATA-7_THT_VERT_2 (at 0.5 -1.7) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -8.3 -2.5) (end 8.3 -2.5) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.3 -2.5) (end 8.3 2.5) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.3 2.5) (end -8.3 2.5) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.3 2.5) (end -8.3 -2.5) (layer F.SilkS) (width 0.15)) + (pad 9 thru_hole circle (at 6.27 0) (size 2.5 2.5) (drill 1.35) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole oval (at 2.54 0) (size 1.1 1.3) (drill 0.74) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -6.56 -1) (size 2.5 2.5) (drill 1.35) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole oval (at 1.27 0) (size 1.1 1.3) (drill 0.74) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole oval (at -1.27 0) (size 1.1 1.3) (drill 0.74) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole oval (at -2.54 0) (size 1.1 1.3) (drill 0.74) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole oval (at -3.81 1.5) (size 1.1 1.3) (drill 0.74) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole oval (at 0 1.5) (size 1.1 1.3) (drill 0.74) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole oval (at 3.81 1.5) (size 1.1 1.3) (drill 0.74) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/SATA-7_THT_VERT_2.kicad_mod.REMOVED.git-id b/PCB/.pretty/SATA-7_THT_VERT_2.kicad_mod.REMOVED.git-id deleted file mode 100644 index 6c09b95f..00000000 --- a/PCB/.pretty/SATA-7_THT_VERT_2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3926c10dea4a4790b090767fc04c323950bbd12f \ No newline at end of file diff --git a/PCB/.pretty/SDS-50J.kicad_mod b/PCB/.pretty/SDS-50J.kicad_mod new file mode 100644 index 00000000..0c9283b3 --- /dev/null +++ b/PCB/.pretty/SDS-50J.kicad_mod @@ -0,0 +1,32 @@ +(module SDS-50J (layer F.Cu) (tedit 5602A6D3) + (descr "SDS-50J, standard DIN connector, 5 pins, midi") + (tags "SDS-50J DIN 5-pins connector midi") + (fp_text reference REF** (at 0 4.75) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SDS-50J (at 7.493 -4.2672 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 17.75 3.9) (end 17.75 -12.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 17.75 -12.8) (end -2.75 -12.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.75 -12.8) (end -2.75 3.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start 17.75 3.9) (end -2.75 3.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.46 3.389) (end -2.5 3.389) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.444 3.389) (end 3.57 3.389) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.5 3.389) (end -2.5 -12.538) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.5 -12.538) (end -2.5 -12.538) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.5 3.389) (end 17.5 -12.538) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.5 3.389) (end 13.5395 3.389) (layer F.SilkS) (width 0.15)) + (pad 5 thru_hole circle (at 12.5 2.5) (size 2.3 2.3) (drill 1.3) (layers *.Cu *.Mask)) + (pad "" thru_hole circle (at 5 -10) (size 2 2) (drill 1.3) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 15 0) (size 2.3 2.3) (drill 1.3) (layers *.Cu *.Mask)) + (pad 2 thru_hole circle (at 7.5 0) (size 2.3 2.3) (drill 1.3) (layers *.Cu *.Mask)) + (pad 1 thru_hole circle (at 0 0) (size 2.3 2.3) (drill 1.3) (layers *.Cu *.Mask)) + (pad 4 thru_hole circle (at 2.5 2.5) (size 2.3 2.3) (drill 1.3) (layers *.Cu *.Mask)) + (pad "" thru_hole circle (at 10 -10) (size 2 2) (drill 1.3) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/SDS-50J.wrl + (at (xyz 0.295 0.495 0)) + (scale (xyz 0.39 0.39 0.39)) + (rotate (xyz -90 0 180)) + ) +) diff --git a/PCB/.pretty/SDS-50J.kicad_mod.REMOVED.git-id b/PCB/.pretty/SDS-50J.kicad_mod.REMOVED.git-id deleted file mode 100644 index 97dade35..00000000 --- a/PCB/.pretty/SDS-50J.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0c9283b3b4bc6e3bc3941ff547fe572fcc6fa046 \ No newline at end of file diff --git a/PCB/.pretty/SD_Card_Receptacle.kicad_mod b/PCB/.pretty/SD_Card_Receptacle.kicad_mod new file mode 100644 index 00000000..563fcd80 --- /dev/null +++ b/PCB/.pretty/SD_Card_Receptacle.kicad_mod @@ -0,0 +1,39 @@ +(module SD_Card_Receptacle (layer F.Cu) (tedit 54A89A84) + (fp_text reference REF** (at 9.96386 19.9312) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SD_Card_Receptacle (at -1.2 9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -14.7 41.05) (end 15.5 41.05) (layer F.CrtYd) (width 0.05)) + (fp_line (start 15.5 41.05) (end 15.5 -1.25) (layer F.CrtYd) (width 0.05)) + (fp_line (start 15.5 -1.25) (end -14.7 -1.25) (layer F.CrtYd) (width 0.05)) + (fp_line (start -14.7 -1.25) (end -14.7 41.05) (layer F.CrtYd) (width 0.05)) + (fp_line (start 7.9 0) (end 8.4 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.4 0) (end 5.9 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.1 0) (end -1.6 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.6 0) (end -4.1 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -7 0) (end -6.6 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.1 0) (end -10.7 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -14 20.6) (end -14 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.9 19.4) (end 14.9 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.9 0) (end 10.4 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.9 29.8) (end -14 29.8) (layer F.SilkS) (width 0.15)) + (fp_line (start -14 29.8) (end -14 23.8) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.9 29.8) (end 14.9 22.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at 6.875 0) (size 1 1.5) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at 4.375 0) (size 1 1.5) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at 1.075 0) (size 1 1.5) (layers F.Cu F.Paste F.Mask)) + (pad 4 smd rect (at -0.625 0) (size 1 1.5) (layers F.Cu F.Paste F.Mask)) + (pad 5 smd rect (at -3.125 0) (size 1 1.5) (layers F.Cu F.Paste F.Mask)) + (pad 6 smd rect (at -5.625 0) (size 1 1.5) (layers F.Cu F.Paste F.Mask)) + (pad 7 smd rect (at -8.05 0) (size 1 1.5) (layers F.Cu F.Paste F.Mask)) + (pad 8 smd rect (at -9.75 0) (size 1 1.5) (layers F.Cu F.Paste F.Mask)) + (pad 9 smd rect (at 9.375 0) (size 1 1.5) (layers F.Cu F.Paste F.Mask)) + (pad 10 smd rect (at 2.725 0) (size 1 1.5) (layers F.Cu F.Paste F.Mask)) + (pad 11 smd rect (at -13.1 0) (size 1 1.5) (layers F.Cu F.Paste F.Mask)) + (pad 12 smd rect (at 14.4 21) (size 1.2 2.2) (layers F.Cu F.Paste F.Mask)) + (pad 13 smd rect (at -13.6 22.2) (size 1.2 2.2) (layers F.Cu F.Paste F.Mask)) + (pad "" np_thru_hole circle (at 12.1 24.3) (size 1.5 1.5) (drill 1.5) (layers *.Cu *.Mask F.SilkS)) + (pad "" np_thru_hole circle (at -12.1 24.3) (size 1.5 1.5) (drill 1.5) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/SD_Card_Receptacle.kicad_mod.REMOVED.git-id b/PCB/.pretty/SD_Card_Receptacle.kicad_mod.REMOVED.git-id deleted file mode 100644 index c6398e52..00000000 --- a/PCB/.pretty/SD_Card_Receptacle.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -563fcd802a8d8648ccc0897ca1b3bdfd74f08694 \ No newline at end of file diff --git a/PCB/.pretty/SMB_Straight.kicad_mod b/PCB/.pretty/SMB_Straight.kicad_mod new file mode 100644 index 00000000..4ce4041d --- /dev/null +++ b/PCB/.pretty/SMB_Straight.kicad_mod @@ -0,0 +1,32 @@ +(module SMB_Straight (layer F.Cu) (tedit 5541ED7C) + (descr "SMB pcb mounting jack") + (tags "SMB Jack Striaght") + (fp_text reference REF** (at -2 -5) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SMB_Straight (at 0.25 0) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -4.25 -4.25) (end 4.25 -4.25) (layer B.CrtYd) (width 0.05)) + (fp_line (start 4.25 -4.25) (end 4.25 4.25) (layer B.CrtYd) (width 0.05)) + (fp_line (start 4.25 4.25) (end -4.25 4.25) (layer B.CrtYd) (width 0.05)) + (fp_line (start -4.25 4.25) (end -4.25 -4.25) (layer B.CrtYd) (width 0.05)) + (fp_line (start 4.25 4.25) (end -4.25 4.25) (layer F.CrtYd) (width 0.05)) + (fp_line (start -4.25 4.25) (end -4.25 -4.25) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.25 -4.25) (end 4.25 4.25) (layer F.CrtYd) (width 0.05)) + (fp_line (start -4.25 -4.25) (end 4.25 -4.25) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1 -3.5052) (end 1 -3.5052) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.5052 -1) (end 3.5052 1) (layer F.SilkS) (width 0.15)) + (fp_line (start 1 3.5052) (end -1 3.5052) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.5052 1) (end -3.5052 -1) (layer F.SilkS) (width 0.15)) + (pad 2 thru_hole circle (at -2.54 2.54) (size 2.74 2.74) (drill 1.7) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.54 2.54) (size 2.74 2.74) (drill 1.7) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.54 -2.54) (size 2.74 2.74) (drill 1.7) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -2.54 -2.54) (size 2.74 2.74) (drill 1.7) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole circle (at 0 0) (size 2.24 2.24) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/SMB_Straight.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/SMB_Straight.kicad_mod.REMOVED.git-id b/PCB/.pretty/SMB_Straight.kicad_mod.REMOVED.git-id deleted file mode 100644 index ec74ab89..00000000 --- a/PCB/.pretty/SMB_Straight.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4ce4041dafd09aef2652a8049a3d0b7fdbf10fe5 \ No newline at end of file diff --git a/PCB/.pretty/SOC676BR.kicad_mod b/PCB/.pretty/SOC676BR.kicad_mod new file mode 100644 index 00000000..5d24e597 --- /dev/null +++ b/PCB/.pretty/SOC676BR.kicad_mod @@ -0,0 +1,29 @@ +(module SOC676BR (layer F.Cu) (tedit 0) + (descr "SOCAPEX 6 pins vertical shape - large") + (tags "SOCAPEX CONN") + (fp_text reference REF** (at 4.953 -2.54) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SOC676BR (at -6.858 -2.667) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_circle (center 3.81 0) (end 3.81 -1.016) (layer F.SilkS) (width 0.15)) + (fp_circle (center -1.27 0) (end -1.27 -1.016) (layer F.SilkS) (width 0.15)) + (fp_circle (center -6.35 0) (end -6.35 -1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 2.159) (end -10.16 2.159) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.16 2.159) (end -10.16 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 2.159) (end 10.16 2.159) (layer F.SilkS) (width 0.15)) + (fp_line (start 10.16 2.159) (end 10.16 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.065 -1.397) (end 12.065 -1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.065 -1.397) (end 12.065 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.065 1.397) (end -12.065 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.065 1.397) (end -12.065 -1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 2.159) (end -7.62 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 1.397) (end 7.62 2.159) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -6.35 0) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -3.81 0) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -1.27 0) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 1.27 0) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 3.81 0) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 6.35 0) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/SOC676BR.kicad_mod.REMOVED.git-id b/PCB/.pretty/SOC676BR.kicad_mod.REMOVED.git-id deleted file mode 100644 index c3f408fa..00000000 --- a/PCB/.pretty/SOC676BR.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5d24e597619276e6c160fcc3b40b1637e3715b36 \ No newline at end of file diff --git a/PCB/.pretty/SOC676C.kicad_mod b/PCB/.pretty/SOC676C.kicad_mod new file mode 100644 index 00000000..11c5a38d --- /dev/null +++ b/PCB/.pretty/SOC676C.kicad_mod @@ -0,0 +1,45 @@ +(module SOC676C (layer F.Cu) (tedit 0) + (descr "SOCAPEX 6 pins horizontal shape") + (tags "SOCAPEX CONN") + (fp_text reference REF** (at 0 7.366 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SOC676C (at 0 4.318 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 6.35 0) (end 6.35 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 0) (end 3.81 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 0) (end 1.27 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 0) (end -1.27 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.81 0) (end -3.81 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.35 0) (end -6.35 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.794 12.065) (end 2.794 14.478) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.794 14.478) (end 4.826 14.478) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.826 14.478) (end 4.826 12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.366 14.478) (end -5.334 14.478) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.334 14.478) (end -5.334 12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.366 12.065) (end -7.366 14.478) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.254 12.065) (end -0.254 14.478) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.254 14.478) (end -2.286 14.478) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.286 14.478) (end -2.286 12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 6.985) (end -10.795 6.985) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.065 10.795) (end -12.065 8.255) (layer F.SilkS) (width 0.15)) + (fp_line (start 10.795 12.065) (end -10.795 12.065) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.065 8.255) (end 12.065 10.795) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 6.985) (end 10.795 6.985) (layer F.SilkS) (width 0.15)) + (fp_arc (start -10.795 10.795) (end -10.795 12.065) (angle 90) (layer F.SilkS) (width 0.15)) + (fp_arc (start -10.795 8.255) (end -12.065 8.255) (angle 90) (layer F.SilkS) (width 0.15)) + (fp_arc (start 10.795 8.255) (end 10.795 6.985) (angle 90) (layer F.SilkS) (width 0.15)) + (fp_arc (start 10.795 10.795) (end 12.065 10.795) (angle 90) (layer F.SilkS) (width 0.15)) + (fp_circle (center -9.017 9.525) (end -9.017 8.255) (layer F.SilkS) (width 0.15)) + (fp_circle (center 9.017 9.525) (end 10.287 9.525) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 1.905) (end 7.62 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 1.905) (end 7.62 6.985) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 6.985) (end -7.62 1.905) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -6.35 0 90) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -3.81 0 90) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -1.27 0 90) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 1.27 0 90) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 3.81 0 90) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 6.35 0 90) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/SOC676C.kicad_mod.REMOVED.git-id b/PCB/.pretty/SOC676C.kicad_mod.REMOVED.git-id deleted file mode 100644 index 42f72dee..00000000 --- a/PCB/.pretty/SOC676C.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -11c5a38d5980379dbe8517a60a26a553e5c804e8 \ No newline at end of file diff --git a/PCB/.pretty/SOC676NY.kicad_mod b/PCB/.pretty/SOC676NY.kicad_mod new file mode 100644 index 00000000..6b39dd34 --- /dev/null +++ b/PCB/.pretty/SOC676NY.kicad_mod @@ -0,0 +1,27 @@ +(module SOC676NY (layer F.Cu) (tedit 0) + (descr "SOCAPEX 6 pins vertical shape - narrow") + (tags "SOCAPEX CONN") + (fp_text reference REF** (at 4.826 -2.413) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SOC676NY (at -5.461 -2.667) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -8.89 -0.127) (end -8.89 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.89 1.397) (end 8.89 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.89 1.397) (end 8.89 -1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.89 -1.397) (end -8.89 -1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.89 -1.397) (end -8.89 -0.127) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.89 1.397) (end -8.89 2.159) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.89 2.159) (end -7.62 2.159) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 2.159) (end -7.62 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 1.397) (end 7.62 2.159) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 2.159) (end 8.89 2.159) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.89 2.159) (end 8.89 1.397) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -6.35 0) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -3.81 0) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -1.27 0) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 1.27 0) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 3.81 0) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 6.35 0) (size 1.397 1.397) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/SOC676NY.kicad_mod.REMOVED.git-id b/PCB/.pretty/SOC676NY.kicad_mod.REMOVED.git-id deleted file mode 100644 index 20164926..00000000 --- a/PCB/.pretty/SOC676NY.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6b39dd34d52fdb6d93d247765d14f878e61c5833 \ No newline at end of file diff --git a/PCB/.pretty/SUBCLICK.kicad_mod b/PCB/.pretty/SUBCLICK.kicad_mod new file mode 100644 index 00000000..5b092a9f --- /dev/null +++ b/PCB/.pretty/SUBCLICK.kicad_mod @@ -0,0 +1,34 @@ +(module SUBCLICK (layer F.Cu) (tedit 0) + (descr "Connecteur Subclick") + (tags "CONN DEV") + (fp_text reference REF** (at 0 6.35) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SUBCLICK (at -0.254 -6.35) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.54 -1.27) (end -1.27 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 -2.54) (end 17.78 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.78 -2.54) (end 17.78 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.78 2.54) (end -1.27 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 2.54) (end -2.54 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 1.27) (end -2.54 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.81 -5.08) (end 3.81 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 -5.08) (end 5.08 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.08 -3.81) (end 5.08 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.08 3.81) (end 3.81 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 5.08) (end -3.81 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.81 5.08) (end -5.08 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.08 3.81) (end -5.08 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.08 -3.81) (end -3.81 -5.08) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole circle (at 0 0) (size 1.778 1.778) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -2.54 -2.54) (size 3.048 3.048) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.54 -2.54) (size 3.048 3.048) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.54 2.54) (size 3.048 3.048) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -2.54 2.54) (size 3.048 3.048) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/SUBCLICK.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/SUBCLICK.kicad_mod.REMOVED.git-id b/PCB/.pretty/SUBCLICK.kicad_mod.REMOVED.git-id deleted file mode 100644 index 5faf5374..00000000 --- a/PCB/.pretty/SUBCLICK.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5b092a9f3c141f1847e3aa29fe778401e73d603c \ No newline at end of file diff --git a/PCB/.pretty/TE_Futurebus+_5536607-1.kicad_mod b/PCB/.pretty/TE_Futurebus+_5536607-1.kicad_mod new file mode 100644 index 00000000..fec071f6 --- /dev/null +++ b/PCB/.pretty/TE_Futurebus+_5536607-1.kicad_mod @@ -0,0 +1,43 @@ +(module TE_Futurebus+_5536607-1 (layer F.Cu) (tedit 5448B92E) + (tags connector) + (fp_text reference REF** (at 0 -3) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value TE_Futurebus+_5536607-1 (at 0 13) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -13.7 -1.25) (end 7.25 -1.25) (layer F.CrtYd) (width 0.05)) + (fp_line (start 7.25 -1.25) (end 7.25 11.25) (layer F.CrtYd) (width 0.05)) + (fp_line (start 7.25 11.25) (end -13.7 11.25) (layer F.CrtYd) (width 0.05)) + (fp_line (start -13.7 11.25) (end -13.7 -1.25) (layer F.CrtYd) (width 0.05)) + (fp_line (start 7 11) (end -1 11) (layer F.SilkS) (width 0.15)) + (fp_line (start -7 -1) (end 7 -1) (layer F.SilkS) (width 0.15)) + (fp_line (start 7 -1) (end 7 11) (layer F.SilkS) (width 0.15)) + (pad "" thru_hole circle (at -4 5) (size 2.05 2.05) (drill 2.05) (layers *.Cu *.Mask)) + (pad "" thru_hole circle (at -4 1) (size 1.5 1.5) (drill 1.5) (layers *.Cu *.Mask)) + (pad "" thru_hole circle (at -4 9) (size 1.5 1.5) (drill 1.5) (layers *.Cu *.Mask)) + (pad 1 thru_hole rect (at 0 4) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 0 2) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 0 0) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2 4) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2 2) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2 0) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 4 4) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 4 2) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 4 0) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 6 4) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 6 2) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 6 0) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 0 6) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 0 8) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 0 10) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 2 10) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 2 8) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 2 6) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 4 6) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 4 8) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 4 10) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 6 10) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 6 8) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 6 6) (size 1.25 1.25) (drill 0.725) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/TE_Futurebus+_5536607-1.kicad_mod.REMOVED.git-id b/PCB/.pretty/TE_Futurebus+_5536607-1.kicad_mod.REMOVED.git-id deleted file mode 100644 index 130141b2..00000000 --- a/PCB/.pretty/TE_Futurebus+_5536607-1.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fec071f66ca7be4472f41033942e37a8827cca03 \ No newline at end of file diff --git a/PCB/.pretty/USB_A.kicad_mod b/PCB/.pretty/USB_A.kicad_mod new file mode 100644 index 00000000..e53d8601 --- /dev/null +++ b/PCB/.pretty/USB_A.kicad_mod @@ -0,0 +1,29 @@ +(module USB_A (layer F.Cu) (tedit 5543E289) + (descr "USB A connector") + (tags "USB USB_A") + (fp_text reference REF** (at 0 -2.35) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value USB_A (at 3.83794 7.43458) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -5.3 13.2) (end -5.3 -1.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start 11.95 -1.4) (end 11.95 13.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -5.3 13.2) (end 11.95 13.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -5.3 -1.4) (end 11.95 -1.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start 11.04986 -1.14512) (end 11.04986 12.95188) (layer F.SilkS) (width 0.15)) + (fp_line (start -3.93614 12.95188) (end -3.93614 -1.14512) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.04986 -1.14512) (end -3.93614 -1.14512) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.04986 12.95188) (end -3.93614 12.95188) (layer F.SilkS) (width 0.15)) + (pad 4 thru_hole circle (at 7.11286 -0.00212 270) (size 1.50114 1.50114) (drill 1.00076) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 4.57286 -0.00212 270) (size 1.50114 1.50114) (drill 1.00076) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.54086 -0.00212 270) (size 1.50114 1.50114) (drill 1.00076) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole circle (at 0.00086 -0.00212 270) (size 1.50114 1.50114) (drill 1.00076) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 10.16086 2.66488 270) (size 2.99974 2.99974) (drill 2.30124) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -3.55514 2.66488 270) (size 2.99974 2.99974) (drill 2.30124) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/USB_A.wrl + (at (xyz 0.14 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) +) diff --git a/PCB/.pretty/USB_A.kicad_mod.REMOVED.git-id b/PCB/.pretty/USB_A.kicad_mod.REMOVED.git-id deleted file mode 100644 index 690db12b..00000000 --- a/PCB/.pretty/USB_A.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e53d86017524d6e6176f0016530392b24efe03e6 \ No newline at end of file diff --git a/PCB/.pretty/USB_A_Vertical.kicad_mod b/PCB/.pretty/USB_A_Vertical.kicad_mod new file mode 100644 index 00000000..080d9b10 --- /dev/null +++ b/PCB/.pretty/USB_A_Vertical.kicad_mod @@ -0,0 +1,33 @@ +(module USB_A_Vertical (layer F.Cu) (tedit 554409CC) + (descr "USB A vertical female connector, right angle") + (tags "USB_A_Vertical female connector angled 73725-0110BLF") + (fp_text reference REF** (at 0 8.95) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value USB_A_Vertical (at -0.05 -5.8) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 3.9 -12.75) (end 3.9 7.55) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.9 7.55) (end -3.9 7.55) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.9 7.55) (end -3.9 -12.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.9 -12.75) (end 3.9 -12.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3 -1.82) (end 3 -12.5) (layer F.SilkS) (width 0.15)) + (fp_line (start -3 -1.82) (end -3 -12.5) (layer F.SilkS) (width 0.15)) + (fp_line (start -3 -12.5) (end 3 -12.5) (layer F.SilkS) (width 0.15)) + (fp_line (start -3 0.36) (end -3 5.18) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.2 7.2735) (end -2.2 7.2735) (layer F.SilkS) (width 0.15)) + (fp_line (start 3 0.36) (end 3 5.18) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole circle (at 0 0) (size 1.62 1.62) (drill 0.92) (layers *.Cu *.Mask)) + (pad 2 thru_hole circle (at 0 2) (size 1.62 1.62) (drill 0.92) (layers *.Cu *.Mask)) + (pad 3 thru_hole circle (at 0 4) (size 1.62 1.62) (drill 0.92) (layers *.Cu *.Mask)) + (pad 5 thru_hole circle (at 2.72 -0.73) (size 1.85 1.85) (drill 1.35) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 0 6) (size 1.62 1.62) (drill 0.92) (layers *.Cu *.Mask)) + (pad 5 thru_hole circle (at 2.72 6.27) (size 1.85 1.85) (drill 1.35) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -2.72 -0.73) (size 1.85 1.85) (drill 1.35) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -2.72 6.27) (size 1.85 1.85) (drill 1.35) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/USB_A_Vertical.wrl + (at (xyz 0.015 -0.02 0.05)) + (scale (xyz 0.412 0.412 0.412)) + (rotate (xyz 0 -90 180)) + ) +) diff --git a/PCB/.pretty/USB_A_Vertical.kicad_mod.REMOVED.git-id b/PCB/.pretty/USB_A_Vertical.kicad_mod.REMOVED.git-id deleted file mode 100644 index 2798f8a7..00000000 --- a/PCB/.pretty/USB_A_Vertical.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -080d9b10895576c5b68dbb8333c28e8f1c64f3c1 \ No newline at end of file diff --git a/PCB/.pretty/USB_B.kicad_mod b/PCB/.pretty/USB_B.kicad_mod new file mode 100644 index 00000000..f63ca566 --- /dev/null +++ b/PCB/.pretty/USB_B.kicad_mod @@ -0,0 +1,31 @@ +(module USB_B (layer F.Cu) (tedit 55B36073) + (descr "USB B connector") + (tags "USB_B USB_DEV") + (fp_text reference REF** (at 11.049 1.27 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value USB_B (at 4.699 1.27 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 15.25 8.9) (end -2.3 8.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.3 8.9) (end -2.3 -6.35) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.3 -6.35) (end 15.25 -6.35) (layer F.CrtYd) (width 0.05)) + (fp_line (start 15.25 -6.35) (end 15.25 8.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start 6.35 7.366) (end 14.986 7.366) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.032 7.366) (end 3.048 7.366) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.35 -4.826) (end 14.986 -4.826) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.032 -4.826) (end 3.048 -4.826) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.986 -4.826) (end 14.986 7.366) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.032 7.366) (end -2.032 -4.826) (layer F.SilkS) (width 0.15)) + (pad 2 thru_hole circle (at 0 2.54 270) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole circle (at 0 0 270) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 1.99898 0 270) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 1.99898 2.54 270) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 4.699 7.26948 270) (size 2.70002 2.70002) (drill 2.30124) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 4.699 -4.72948 270) (size 2.70002 2.70002) (drill 2.30124) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/USB_B.wrl + (at (xyz 0.185 -0.05 0.001)) + (scale (xyz 0.3937 0.3937 0.3937)) + (rotate (xyz 0 0 -90)) + ) +) diff --git a/PCB/.pretty/USB_B.kicad_mod.REMOVED.git-id b/PCB/.pretty/USB_B.kicad_mod.REMOVED.git-id deleted file mode 100644 index cfbc8022..00000000 --- a/PCB/.pretty/USB_B.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f63ca56682373f7f2272a1d7892ea920b320b327 \ No newline at end of file diff --git a/PCB/.pretty/USB_Micro-B.kicad_mod b/PCB/.pretty/USB_Micro-B.kicad_mod new file mode 100644 index 00000000..708accf9 --- /dev/null +++ b/PCB/.pretty/USB_Micro-B.kicad_mod @@ -0,0 +1,29 @@ +(module USB_Micro-B (layer F.Cu) (tedit 5543E447) + (descr "Micro USB Type B Receptacle") + (tags "USB USB_B USB_micro USB_OTG") + (attr smd) + (fp_text reference REF** (at 0 -3.45) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value USB_Micro-B (at 0 4.8) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -4.6 -2.8) (end 4.6 -2.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.6 -2.8) (end 4.6 4.05) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.6 4.05) (end -4.6 4.05) (layer F.CrtYd) (width 0.05)) + (fp_line (start -4.6 4.05) (end -4.6 -2.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -4.3509 3.81746) (end 4.3491 3.81746) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.3509 -2.58754) (end 4.3491 -2.58754) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.3491 -2.58754) (end 4.3491 3.81746) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.3491 2.58746) (end -4.3509 2.58746) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.3509 3.81746) (end -4.3509 -2.58754) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.3009 -1.56254 90) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at -0.6509 -1.56254 90) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at -0.0009 -1.56254 90) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask)) + (pad 4 smd rect (at 0.6491 -1.56254 90) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask)) + (pad 5 smd rect (at 1.2991 -1.56254 90) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask)) + (pad 6 thru_hole oval (at -2.5009 -1.56254 90) (size 0.95 1.25) (drill oval 0.55 0.85) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole oval (at 2.4991 -1.56254 90) (size 0.95 1.25) (drill oval 0.55 0.85) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole oval (at -3.5009 1.13746 90) (size 1.55 1) (drill oval 1.15 0.5) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole oval (at 3.4991 1.13746 90) (size 1.55 1) (drill oval 1.15 0.5) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/USB_Micro-B.kicad_mod.REMOVED.git-id b/PCB/.pretty/USB_Micro-B.kicad_mod.REMOVED.git-id deleted file mode 100644 index f9274350..00000000 --- a/PCB/.pretty/USB_Micro-B.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -708accf92455528d0bc8167433ed5e3f79661a0f \ No newline at end of file diff --git a/PCB/.pretty/USB_Micro-B_WIDE.kicad_mod b/PCB/.pretty/USB_Micro-B_WIDE.kicad_mod new file mode 100644 index 00000000..658d273b --- /dev/null +++ b/PCB/.pretty/USB_Micro-B_WIDE.kicad_mod @@ -0,0 +1,29 @@ +(module USB_Micro-B_WIDE (layer F.Cu) (tedit 56F1EFCA) + (descr "Micro USB Type B Receptacle") + (tags "USB USB_B USB_micro USB_OTG") + (attr smd) + (fp_text reference REF** (at 0 -3.45) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value USB_Micro-B (at 0 4.8) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -4.6 -2.8) (end 4.6 -2.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.6 -2.8) (end 4.6 4.05) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.6 4.05) (end -4.6 4.05) (layer F.CrtYd) (width 0.05)) + (fp_line (start -4.6 4.05) (end -4.6 -2.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -4.3509 3.81746) (end 4.3491 3.81746) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.3509 -2.58754) (end 4.3491 -2.58754) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.3491 -2.58754) (end 4.3491 3.81746) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.3491 2.58746) (end -4.3509 2.58746) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.3509 3.81746) (end -4.3509 -2.58754) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.3009 -1.56254 90) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at -0.6509 -1.56254 90) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at -0.0009 -1.56254 90) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask)) + (pad 4 smd rect (at 0.6491 -1.56254 90) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask)) + (pad 5 smd rect (at 1.2991 -1.56254 90) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask)) + (pad 6 thru_hole oval (at -2.5009 -1.56254 90) (size 0.95 1.4) (drill oval 0.55 1) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole oval (at 2.4991 -1.56254 90) (size 0.95 1.4) (drill oval 0.55 1) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole oval (at -3.5009 1.13746 90) (size 1.55 1.2) (drill oval 1.15 0.7) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole oval (at 3.4991 1.13746 90) (size 1.55 1.2) (drill oval 1.15 0.7) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/USB_Micro-B_WIDE.kicad_mod.REMOVED.git-id b/PCB/.pretty/USB_Micro-B_WIDE.kicad_mod.REMOVED.git-id deleted file mode 100644 index 464c4cb5..00000000 --- a/PCB/.pretty/USB_Micro-B_WIDE.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -658d273b3bfbb54b4c46a1f5b547cf72866ad5b9 \ No newline at end of file diff --git a/PCB/.pretty/USB_Mini-B.kicad_mod b/PCB/.pretty/USB_Mini-B.kicad_mod new file mode 100644 index 00000000..ceb45e0b --- /dev/null +++ b/PCB/.pretty/USB_Mini-B.kicad_mod @@ -0,0 +1,31 @@ +(module USB_Mini-B (layer F.Cu) (tedit 5543E571) + (descr "USB Mini-B 5-pin SMD connector") + (tags "USB USB_B USB_Mini connector") + (attr smd) + (fp_text reference REF** (at 0 6.90118) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value USB_Mini-B (at 0 -7.0993) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -4.85 -5.7) (end 4.85 -5.7) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.85 -5.7) (end 4.85 5.7) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.85 5.7) (end -4.85 5.7) (layer F.CrtYd) (width 0.05)) + (fp_line (start -4.85 5.7) (end -4.85 -5.7) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.59918 -3.85064) (end -3.59918 3.85064) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.59994 -3.85064) (end -4.59994 3.85064) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.59994 3.85064) (end 4.59994 3.85064) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.59994 3.85064) (end 4.59994 -3.85064) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.59994 -3.85064) (end -4.59994 -3.85064) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at 3.44932 -1.6002) (size 2.30124 0.50038) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at 3.44932 -0.8001) (size 2.30124 0.50038) (layers F.Cu F.Paste F.Mask)) + (pad 3 smd rect (at 3.44932 0) (size 2.30124 0.50038) (layers F.Cu F.Paste F.Mask)) + (pad 4 smd rect (at 3.44932 0.8001) (size 2.30124 0.50038) (layers F.Cu F.Paste F.Mask)) + (pad 5 smd rect (at 3.44932 1.6002) (size 2.30124 0.50038) (layers F.Cu F.Paste F.Mask)) + (pad 6 smd rect (at 3.35026 -4.45008) (size 2.49936 1.99898) (layers F.Cu F.Paste F.Mask)) + (pad 6 smd rect (at -2.14884 -4.45008) (size 2.49936 1.99898) (layers F.Cu F.Paste F.Mask)) + (pad 6 smd rect (at 3.35026 4.45008) (size 2.49936 1.99898) (layers F.Cu F.Paste F.Mask)) + (pad 6 smd rect (at -2.14884 4.45008) (size 2.49936 1.99898) (layers F.Cu F.Paste F.Mask)) + (pad "" np_thru_hole circle (at 0.8509 -2.19964) (size 0.89916 0.89916) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) + (pad "" np_thru_hole circle (at 0.8509 2.19964) (size 0.89916 0.89916) (drill 0.89916) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/USB_Mini-B.kicad_mod.REMOVED.git-id b/PCB/.pretty/USB_Mini-B.kicad_mod.REMOVED.git-id deleted file mode 100644 index 3a9db4b3..00000000 --- a/PCB/.pretty/USB_Mini-B.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ceb45e0bb2dee505e1fb6d59ccfedda0580a4f9b \ No newline at end of file diff --git a/PCB/.pretty/VASCH10x2.kicad_mod b/PCB/.pretty/VASCH10x2.kicad_mod new file mode 100644 index 00000000..8bb4d8d4 --- /dev/null +++ b/PCB/.pretty/VASCH10x2.kicad_mod @@ -0,0 +1,49 @@ +(module VASCH10x2 (layer F.Cu) (tedit 0) + (descr CONNECTOR) + (tags CONNECTOR) + (attr virtual) + (fp_text reference REF** (at -15.875 -5.715) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value VASCH10x2 (at 0 6.35) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 15.875 3.81) (end 16.51 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.875 -3.81) (end 16.51 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.875 3.81) (end -16.51 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -16.51 -4.445) (end -15.875 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.875 -3.81) (end -15.875 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.875 3.81) (end -1.905 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.905 3.81) (end -1.905 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.875 -3.81) (end 15.875 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.875 -3.81) (end 15.875 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.875 3.81) (end 1.905 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.905 3.81) (end 1.905 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.51 -4.445) (end -16.51 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -16.51 4.445) (end 16.51 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -16.51 -4.445) (end -16.51 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.51 -4.445) (end 16.51 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.84808 1.9685) (end -13.14958 3.03784) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.14958 3.03784) (end -12.44854 1.9685) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.44854 1.9685) (end -13.84808 1.9685) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole circle (at -11.43 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 2 thru_hole circle (at -11.43 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 3 thru_hole circle (at -8.89 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 4 thru_hole circle (at -8.89 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 5 thru_hole circle (at -6.35 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 6 thru_hole circle (at -6.35 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 7 thru_hole circle (at -3.81 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 8 thru_hole circle (at -3.81 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 9 thru_hole circle (at -1.27 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 10 thru_hole circle (at -1.27 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 11 thru_hole circle (at 1.27 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 12 thru_hole circle (at 1.27 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 13 thru_hole circle (at 3.81 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 14 thru_hole circle (at 3.81 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 15 thru_hole circle (at 6.35 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 16 thru_hole circle (at 6.35 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 17 thru_hole circle (at 8.89 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 18 thru_hole circle (at 8.89 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 19 thru_hole circle (at 11.43 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 20 thru_hole circle (at 11.43 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) +) diff --git a/PCB/.pretty/VASCH10x2.kicad_mod.REMOVED.git-id b/PCB/.pretty/VASCH10x2.kicad_mod.REMOVED.git-id deleted file mode 100644 index 2f025f7a..00000000 --- a/PCB/.pretty/VASCH10x2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8bb4d8d44bbf936bcd5ae569a3b2d2a1161c7064 \ No newline at end of file diff --git a/PCB/.pretty/VASCH5x2.kicad_mod b/PCB/.pretty/VASCH5x2.kicad_mod new file mode 100644 index 00000000..aba72806 --- /dev/null +++ b/PCB/.pretty/VASCH5x2.kicad_mod @@ -0,0 +1,39 @@ +(module VASCH5x2 (layer F.Cu) (tedit 0) + (descr CONNECTOR) + (tags CONNECTOR) + (attr virtual) + (fp_text reference REF** (at -8.89 -5.08) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value VASCH5x2 (at 1.27 6.35) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -9.525 -3.81) (end -10.16 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.525 3.81) (end -10.16 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.525 3.81) (end 10.16 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.525 -3.81) (end 10.16 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.905 4.445) (end 1.905 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.905 3.81) (end 9.525 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.525 3.81) (end 9.525 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.525 -3.81) (end -9.525 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.525 -3.81) (end -9.525 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.525 3.81) (end -1.905 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.905 3.81) (end -1.905 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.16 4.445) (end 10.16 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 10.16 -4.445) (end -10.16 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.16 -4.445) (end -10.16 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 10.16 -4.445) (end 10.16 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.49808 1.9685) (end -6.79958 3.03784) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.79958 3.03784) (end -6.09854 1.9685) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.09854 1.9685) (end -7.49808 1.9685) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole circle (at -5.08 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 2 thru_hole circle (at -5.08 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 3 thru_hole circle (at -2.54 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 4 thru_hole circle (at -2.54 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 5 thru_hole circle (at 0 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 6 thru_hole circle (at 0 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 7 thru_hole circle (at 2.54 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 8 thru_hole circle (at 2.54 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 9 thru_hole circle (at 5.08 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 10 thru_hole circle (at 5.08 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) +) diff --git a/PCB/.pretty/VASCH5x2.kicad_mod.REMOVED.git-id b/PCB/.pretty/VASCH5x2.kicad_mod.REMOVED.git-id deleted file mode 100644 index 39330cfb..00000000 --- a/PCB/.pretty/VASCH5x2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aba72806ced919ddd4ec52769e86431e339aa709 \ No newline at end of file diff --git a/PCB/.pretty/VASCH8x2.kicad_mod b/PCB/.pretty/VASCH8x2.kicad_mod new file mode 100644 index 00000000..eb20eda3 --- /dev/null +++ b/PCB/.pretty/VASCH8x2.kicad_mod @@ -0,0 +1,45 @@ +(module VASCH8x2 (layer F.Cu) (tedit 0) + (descr CONNECTOR) + (tags CONNECTOR) + (attr virtual) + (fp_text reference REF** (at -12.7 -5.08) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value VASCH8x2 (at 0 6.35) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 13.335 3.81) (end 13.97 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.335 -3.81) (end 13.97 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.335 -3.81) (end -13.97 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.905 4.445) (end 1.905 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.905 3.81) (end 13.335 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.335 3.81) (end 13.335 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.335 -3.81) (end -13.335 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.335 -3.81) (end -13.335 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.335 3.81) (end -13.97 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.335 3.81) (end -1.905 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.905 3.81) (end -1.905 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.97 4.445) (end -13.97 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.97 -4.445) (end 13.97 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.97 -4.445) (end -13.97 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.97 -4.445) (end 13.97 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.30808 1.9685) (end -10.60958 3.03784) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.60958 3.03784) (end -9.90854 1.9685) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.90854 1.9685) (end -11.30808 1.9685) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole circle (at -8.89 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 2 thru_hole circle (at -8.89 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 3 thru_hole circle (at -6.35 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 4 thru_hole circle (at -6.35 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 5 thru_hole circle (at -3.81 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 6 thru_hole circle (at -3.81 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 7 thru_hole circle (at -1.27 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 8 thru_hole circle (at -1.27 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 9 thru_hole circle (at 1.27 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 10 thru_hole circle (at 1.27 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 11 thru_hole circle (at 3.81 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 12 thru_hole circle (at 3.81 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 13 thru_hole circle (at 6.35 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 14 thru_hole circle (at 6.35 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 15 thru_hole circle (at 8.89 1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) + (pad 16 thru_hole circle (at 8.89 -1.27) (size 1.50622 1.50622) (drill 0.99822) (layers *.Cu *.Mask)) +) diff --git a/PCB/.pretty/VASCH8x2.kicad_mod.REMOVED.git-id b/PCB/.pretty/VASCH8x2.kicad_mod.REMOVED.git-id deleted file mode 100644 index 1492b783..00000000 --- a/PCB/.pretty/VASCH8x2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -eb20eda3b12a9cb07f1180ca0cb8155d969152fa \ No newline at end of file diff --git a/PCB/.pretty/Wafer_Horizontal10x5.8x7RM2.5-3.kicad_mod b/PCB/.pretty/Wafer_Horizontal10x5.8x7RM2.5-3.kicad_mod new file mode 100644 index 00000000..84d93058 --- /dev/null +++ b/PCB/.pretty/Wafer_Horizontal10x5.8x7RM2.5-3.kicad_mod @@ -0,0 +1,38 @@ +(module Wafer_Horizontal10x5.8x7RM2.5-3 (layer F.Cu) (tedit 556C2A14) + (descr "Gold-Tek horizontal wafer connector with 2.5mm pitch") + (tags "wafer connector horizontal") + (fp_text reference REF** (at 2.54 -3.81) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Wafer_Horizontal10x5.8x7RM2.5-3 (at 2.54 10.414) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.75 -2.75) (end 7.85 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 7.85 -2.75) (end 7.85 9.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 7.85 9.65) (end -2.75 9.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.75 9.65) (end -2.75 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.413 9.271) (end 7.493 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.413 2.286) (end 7.493 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.5819 2.286) (end 7.5819 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.0419 2.159) (end 5.0419 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.5019 2.286) (end 2.5019 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.0889 1.397) (end 0.0889 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.4511 2.286) (end -2.4511 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.4069 9.271) (end 4.4069 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.4069 5.715) (end 5.6769 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.6769 5.715) (end 5.6769 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5461 9.271) (end -0.5461 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5461 5.715) (end 0.7239 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.7239 5.715) (end 0.7239 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.5819 2.286) (end 7.5819 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.5819 -2.413) (end 6.4389 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.4389 -2.413) (end 6.4389 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.4511 -2.413) (end -1.3081 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.3081 -2.413) (end -1.3081 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.4511 2.413) (end -2.4511 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.5819 2.286) (end 7.5819 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.4511 9.271) (end -2.4511 2.286) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.54 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 5.04 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/Wafer_Horizontal10x5.8x7RM2.5-3.kicad_mod.REMOVED.git-id b/PCB/.pretty/Wafer_Horizontal10x5.8x7RM2.5-3.kicad_mod.REMOVED.git-id deleted file mode 100644 index 9d32ba90..00000000 --- a/PCB/.pretty/Wafer_Horizontal10x5.8x7RM2.5-3.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -84d93058a87d8b6c2c8b3f2944452a43dd37fe37 \ No newline at end of file diff --git a/PCB/.pretty/Wafer_Horizontal15x5.8x7RM2.5-5.kicad_mod b/PCB/.pretty/Wafer_Horizontal15x5.8x7RM2.5-5.kicad_mod new file mode 100644 index 00000000..48fafcf1 --- /dev/null +++ b/PCB/.pretty/Wafer_Horizontal15x5.8x7RM2.5-5.kicad_mod @@ -0,0 +1,45 @@ +(module Wafer_Horizontal15x5.8x7RM2.5-5 (layer F.Cu) (tedit 556C2A29) + (descr "Gold-Tek horizontal wafer connector with 2.5mm pitch") + (tags "wafer connector horizontal") + (fp_text reference REF** (at 5.0165 -3.81) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Wafer_Horizontal15x5.8x7RM2.5-5 (at 5.08 10.414) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.75 -2.75) (end 12.95 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 12.95 -2.75) (end 12.95 9.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 12.95 9.65) (end -2.75 9.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.75 9.65) (end -2.75 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 10.0584 2.286) (end 10.0584 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.5184 2.159) (end 7.5184 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.9784 2.286) (end 4.9784 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.5654 1.397) (end 2.5654 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.0254 2.286) (end 0.0254 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.4234 9.271) (end 9.4234 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.4234 5.715) (end 10.6934 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 10.6934 5.715) (end 10.6934 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.6096 9.271) (end -0.6096 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.6096 5.715) (end 0.6604 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.6604 5.715) (end 0.6604 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.5984 2.286) (end 12.5984 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.5984 -2.413) (end 11.4554 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.4554 -2.413) (end 11.4554 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.5146 -2.413) (end -1.3716 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.3716 -2.413) (end -1.3716 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.5146 2.413) (end -2.5146 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.5146 2.286) (end 12.5984 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.5984 2.286) (end 12.5984 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.5984 9.271) (end -2.5146 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.5146 9.271) (end -2.5146 2.286) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.5165 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 5.0165 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 7.5165 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 10.0165 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/Wafer_Horizontal15x5.8x7RM2.5-5.wrl + (at (xyz 0 0 0)) + (scale (xyz 4 4 4)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/Wafer_Horizontal15x5.8x7RM2.5-5.kicad_mod.REMOVED.git-id b/PCB/.pretty/Wafer_Horizontal15x5.8x7RM2.5-5.kicad_mod.REMOVED.git-id deleted file mode 100644 index 840bce2e..00000000 --- a/PCB/.pretty/Wafer_Horizontal15x5.8x7RM2.5-5.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -48fafcf17b85a4ee0f8e018dbba92f9044fb504b \ No newline at end of file diff --git a/PCB/.pretty/Wafer_Horizontal17.5x5.8x7RM2.5-6.kicad_mod b/PCB/.pretty/Wafer_Horizontal17.5x5.8x7RM2.5-6.kicad_mod new file mode 100644 index 00000000..3da8ef40 --- /dev/null +++ b/PCB/.pretty/Wafer_Horizontal17.5x5.8x7RM2.5-6.kicad_mod @@ -0,0 +1,48 @@ +(module Wafer_Horizontal17.5x5.8x7RM2.5-6 (layer F.Cu) (tedit 556C2A3A) + (descr "Gold-Tek horizontal wafer connector with 2.5mm pitch") + (tags "wafer connector horizontal") + (fp_text reference REF** (at 6.4135 -3.81) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Wafer_Horizontal17.5x5.8x7RM2.5-6 (at 6.35 10.414) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.75 -2.75) (end 15.45 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 15.45 -2.75) (end 15.45 9.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 15.45 9.65) (end -2.75 9.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.75 9.65) (end -2.75 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 15.0495 2.286) (end 15.0495 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.0495 -2.413) (end 13.7795 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.7795 -2.413) (end 13.7795 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.4765 2.286) (end -2.4765 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.4765 -2.413) (end -1.4605 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.4605 -2.413) (end -1.2065 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.2065 -2.413) (end -1.2065 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.4765 2.286) (end 15.0495 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.4765 9.271) (end 15.0495 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.4445 5.842) (end -0.4445 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.0495 2.286) (end 15.0495 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.4765 2.286) (end -2.4765 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.0015 9.271) (end 12.0015 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.0015 5.715) (end 13.2715 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.2715 5.715) (end 13.2715 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.4445 5.842) (end 0.6985 5.842) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.6985 5.842) (end 0.6985 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.6365 2.286) (end 12.6365 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.9695 2.286) (end 9.9695 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.5565 2.286) (end 7.5565 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.0165 2.286) (end 5.0165 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.6035 2.286) (end 2.6035 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.0635 2.286) (end 0.0635 1.397) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.5365 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 5.0365 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 7.5365 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 10.0365 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 12.5365 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/Wafer_Horizontal17.5x5.8x7RM2.5-6.wrl + (at (xyz 0 0 0)) + (scale (xyz 4 4 4)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/Wafer_Horizontal17.5x5.8x7RM2.5-6.kicad_mod.REMOVED.git-id b/PCB/.pretty/Wafer_Horizontal17.5x5.8x7RM2.5-6.kicad_mod.REMOVED.git-id deleted file mode 100644 index 1871735f..00000000 --- a/PCB/.pretty/Wafer_Horizontal17.5x5.8x7RM2.5-6.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3da8ef401f4db630b1051600bba1b2cdb086b3dd \ No newline at end of file diff --git a/PCB/.pretty/Wafer_Horizontal20x5.8x7RM2.5-7.kicad_mod b/PCB/.pretty/Wafer_Horizontal20x5.8x7RM2.5-7.kicad_mod new file mode 100644 index 00000000..3b18d9d7 --- /dev/null +++ b/PCB/.pretty/Wafer_Horizontal20x5.8x7RM2.5-7.kicad_mod @@ -0,0 +1,49 @@ +(module Wafer_Horizontal20x5.8x7RM2.5-7 (layer F.Cu) (tedit 556C2A51) + (descr "Gold-Tek horizontal wafer connector with 2.5mm pitch") + (tags "wafer connector horizontal") + (fp_text reference REF** (at 7.62 -3.81) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Wafer_Horizontal20x5.8x7RM2.5-7 (at 7.62 10.414) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.5 -2.75) (end 18 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 18 -2.75) (end 18 9.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 18 9.65) (end -2.5 9.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.5 9.65) (end -2.5 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 14.351 9.271) (end 14.351 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.351 5.715) (end 15.621 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.621 5.715) (end 15.621 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.508 9.271) (end -0.508 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.508 5.715) (end 0.635 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.635 5.715) (end 0.635 9.144) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.986 2.286) (end 14.986 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.573 2.286) (end 12.573 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.906 2.286) (end 9.906 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.493 2.286) (end 7.493 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.953 2.286) (end 4.953 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 2.286) (end 2.54 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 0 2.286) (end 0 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.653 2.413) (end 17.653 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.653 -2.413) (end 16.383 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.383 -2.413) (end 16.383 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.286 2.286) (end -2.286 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.286 -2.413) (end -1.397 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.397 -2.413) (end -1.397 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.286 2.286) (end 17.653 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.653 2.286) (end 17.653 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.653 9.271) (end -2.286 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.286 9.271) (end -2.286 2.286) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.493 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 4.993 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 7.493 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 9.993 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 12.493 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 14.993 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/Wafer_Horizontal20x5.8x7RM2.5-7.wrl + (at (xyz 0 0 0)) + (scale (xyz 4 4 4)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/Wafer_Horizontal20x5.8x7RM2.5-7.kicad_mod.REMOVED.git-id b/PCB/.pretty/Wafer_Horizontal20x5.8x7RM2.5-7.kicad_mod.REMOVED.git-id deleted file mode 100644 index bff040cc..00000000 --- a/PCB/.pretty/Wafer_Horizontal20x5.8x7RM2.5-7.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3b18d9d7a0748c7c5c05061c01097436e97c54cd \ No newline at end of file diff --git a/PCB/.pretty/Wafer_Horizontal22.5x5.8x7RM2.5-8.kicad_mod b/PCB/.pretty/Wafer_Horizontal22.5x5.8x7RM2.5-8.kicad_mod new file mode 100644 index 00000000..b9c4460e --- /dev/null +++ b/PCB/.pretty/Wafer_Horizontal22.5x5.8x7RM2.5-8.kicad_mod @@ -0,0 +1,51 @@ +(module Wafer_Horizontal22.5x5.8x7RM2.5-8 (layer F.Cu) (tedit 556C2A63) + (descr "Gold-Tek horizontal wafer connector with 2.5mm pitch") + (tags "wafer connector horizontal") + (fp_text reference REF** (at 8.89 -3.81) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Wafer_Horizontal22.5x5.8x7RM2.5-8 (at 8.89 10.414) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.75 -2.75) (end 20.3 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 20.3 -2.75) (end 20.3 9.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 20.3 9.65) (end -2.75 9.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.75 9.65) (end -2.75 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 17.526 2.286) (end 17.526 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.066 -2.413) (end 18.796 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.796 -2.413) (end 18.796 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 -2.413) (end -1.27 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 -2.413) (end -1.27 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 2.286) (end 20.066 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 9.271) (end 20.066 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 9.271) (end -2.54 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 2.286) (end -2.54 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.066 2.286) (end 20.066 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.066 9.271) (end 20.066 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.891 9.271) (end 16.891 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.891 5.715) (end 18.161 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.161 5.715) (end 18.161 9.271) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.508 9.271) (end -0.508 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.508 5.715) (end 0.635 5.715) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.635 5.715) (end 0.635 9.144) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.986 2.286) (end 14.986 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.573 2.286) (end 12.573 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 9.906 2.286) (end 9.906 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.493 2.286) (end 7.493 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.953 2.286) (end 4.953 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 2.286) (end 2.54 1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start 0 2.286) (end 0 1.397) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.513 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 5.013 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 7.513 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 10.013 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 12.513 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 15.013 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 17.513 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/Wafer_Horizontal22.5x5.8x7RM2.5-8.wrl + (at (xyz 0 0 0)) + (scale (xyz 4 4 4)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/Wafer_Horizontal22.5x5.8x7RM2.5-8.kicad_mod.REMOVED.git-id b/PCB/.pretty/Wafer_Horizontal22.5x5.8x7RM2.5-8.kicad_mod.REMOVED.git-id deleted file mode 100644 index 6ec6bdae..00000000 --- a/PCB/.pretty/Wafer_Horizontal22.5x5.8x7RM2.5-8.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b9c4460eccb60ecaa8d36af4455fa07acd777797 \ No newline at end of file diff --git a/PCB/.pretty/Wafer_Vertical10x5.8x7RM2.5-3.kicad_mod b/PCB/.pretty/Wafer_Vertical10x5.8x7RM2.5-3.kicad_mod new file mode 100644 index 00000000..5f108816 --- /dev/null +++ b/PCB/.pretty/Wafer_Vertical10x5.8x7RM2.5-3.kicad_mod @@ -0,0 +1,26 @@ +(module Wafer_Vertical10x5.8x7RM2.5-3 (layer F.Cu) (tedit 556C2A89) + (descr "Gold-Tek vertical wafer connector with 2.5mm pitch") + (tags "wafer connector vertical") + (fp_text reference REF** (at 2.54 -3.81) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Wafer_Vertical10x5.8x7RM2.5-3 (at 2.54 5.08) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.75 -2.75) (end 7.85 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 7.85 -2.75) (end 7.85 3.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 7.85 3.8) (end -2.75 3.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.75 3.8) (end -2.75 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 7.62 3.429) (end -2.54 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 -2.413) (end 7.62 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 -2.413) (end 7.62 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 -2.413) (end -2.54 3.429) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.54 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 5.04 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/Wafer_Vertical10x5.8x7RM2.5-3.wrl + (at (xyz 0 0 0)) + (scale (xyz 4 4 4)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/Wafer_Vertical10x5.8x7RM2.5-3.kicad_mod.REMOVED.git-id b/PCB/.pretty/Wafer_Vertical10x5.8x7RM2.5-3.kicad_mod.REMOVED.git-id deleted file mode 100644 index e1653b88..00000000 --- a/PCB/.pretty/Wafer_Vertical10x5.8x7RM2.5-3.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5f1088169aa79e998f799701492565eff0c0001b \ No newline at end of file diff --git a/PCB/.pretty/Wafer_Vertical15x5.8x7RM2.5-5.kicad_mod b/PCB/.pretty/Wafer_Vertical15x5.8x7RM2.5-5.kicad_mod new file mode 100644 index 00000000..7787720a --- /dev/null +++ b/PCB/.pretty/Wafer_Vertical15x5.8x7RM2.5-5.kicad_mod @@ -0,0 +1,28 @@ +(module Wafer_Vertical15x5.8x7RM2.5-5 (layer F.Cu) (tedit 556C2A98) + (descr "Gold-Tek vertical wafer connector with 2.5mm pitch") + (tags "wafer connector vertical") + (fp_text reference REF** (at 5.0165 -3.81) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Wafer_Vertical15x5.8x7RM2.5-5 (at 5.0165 5.08) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -3 -2.75) (end 12.95 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 12.95 -2.75) (end 12.95 3.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 12.95 3.8) (end -3 3.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3 3.8) (end -3 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 12.6365 3.429) (end -2.6035 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.6035 -2.413) (end 12.6365 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.6365 -2.413) (end 12.6365 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.6035 -2.413) (end -2.6035 3.429) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.5165 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 5.0165 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 7.5165 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 10.0165 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/Wafer_Vertical15x5.8x7RM2.5-5.wrl + (at (xyz 0 0 0)) + (scale (xyz 4 4 4)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/Wafer_Vertical15x5.8x7RM2.5-5.kicad_mod.REMOVED.git-id b/PCB/.pretty/Wafer_Vertical15x5.8x7RM2.5-5.kicad_mod.REMOVED.git-id deleted file mode 100644 index ee678a6a..00000000 --- a/PCB/.pretty/Wafer_Vertical15x5.8x7RM2.5-5.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7787720af72e370f60e415e2e125407f9304b313 \ No newline at end of file diff --git a/PCB/.pretty/Wafer_Vertical17.5x5.8x7RM2.5-6.kicad_mod b/PCB/.pretty/Wafer_Vertical17.5x5.8x7RM2.5-6.kicad_mod new file mode 100644 index 00000000..786c93dc --- /dev/null +++ b/PCB/.pretty/Wafer_Vertical17.5x5.8x7RM2.5-6.kicad_mod @@ -0,0 +1,29 @@ +(module Wafer_Vertical17.5x5.8x7RM2.5-6 (layer F.Cu) (tedit 556C2AA9) + (descr "Gold-Tek vertical wafer connector with 2.5mm pitch") + (tags "wafer connector vertical") + (fp_text reference REF** (at 6.2865 -3.81) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Wafer_Vertical17.5x5.8x7RM2.5-6 (at 6.2865 5.08) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.75 -2.75) (end 15.2 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 15.2 -2.75) (end 15.2 3.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 15.2 3.8) (end -2.75 3.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.75 3.8) (end -2.75 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 15.0495 3.429) (end -2.4765 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.4765 -2.413) (end 15.0495 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.0495 -2.413) (end 15.0495 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.4765 -2.413) (end -2.4765 3.429) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.5365 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 5.0365 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 7.5365 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 10.0365 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 12.5365 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/Wafer_Vertical17.5x5.8x7RM2.5-6.wrl + (at (xyz 0 0 0)) + (scale (xyz 4 4 4)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/Wafer_Vertical17.5x5.8x7RM2.5-6.kicad_mod.REMOVED.git-id b/PCB/.pretty/Wafer_Vertical17.5x5.8x7RM2.5-6.kicad_mod.REMOVED.git-id deleted file mode 100644 index acbc5e72..00000000 --- a/PCB/.pretty/Wafer_Vertical17.5x5.8x7RM2.5-6.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -786c93dc6094a0e3ca9d14eb8732fb417555db6e \ No newline at end of file diff --git a/PCB/.pretty/Wafer_Vertical20x5.8x7RM2.5-7.kicad_mod b/PCB/.pretty/Wafer_Vertical20x5.8x7RM2.5-7.kicad_mod new file mode 100644 index 00000000..9978f869 --- /dev/null +++ b/PCB/.pretty/Wafer_Vertical20x5.8x7RM2.5-7.kicad_mod @@ -0,0 +1,30 @@ +(module Wafer_Vertical20x5.8x7RM2.5-7 (layer F.Cu) (tedit 556C2ABA) + (descr "Gold-Tek vertical wafer connector with 2.5mm pitch") + (tags "wafer connector vertical") + (fp_text reference REF** (at 7.493 -3.81) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Wafer_Vertical20x5.8x7RM2.5-7 (at 7.493 5.08) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.75 -2.75) (end 17.75 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 17.75 -2.75) (end 17.75 3.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 17.75 3.8) (end -2.75 3.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.75 3.8) (end -2.75 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.54 -2.413) (end -2.54 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 3.429) (end 17.526 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.526 3.429) (end 17.526 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.526 -2.413) (end -2.54 -2.413) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.493 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 4.993 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 7.493 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 9.993 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 12.493 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 14.993 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/Wafer_Vertical20x5.8x7RM2.5-7.wrl + (at (xyz 0 0 0)) + (scale (xyz 4 4 4)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/Wafer_Vertical20x5.8x7RM2.5-7.kicad_mod.REMOVED.git-id b/PCB/.pretty/Wafer_Vertical20x5.8x7RM2.5-7.kicad_mod.REMOVED.git-id deleted file mode 100644 index 75fcbe1e..00000000 --- a/PCB/.pretty/Wafer_Vertical20x5.8x7RM2.5-7.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9978f869179553d904b255aa1b41ce650ea80d25 \ No newline at end of file diff --git a/PCB/.pretty/Wafer_Vertical22.5x5.8x7RM2.5-8.kicad_mod b/PCB/.pretty/Wafer_Vertical22.5x5.8x7RM2.5-8.kicad_mod new file mode 100644 index 00000000..2d439de8 --- /dev/null +++ b/PCB/.pretty/Wafer_Vertical22.5x5.8x7RM2.5-8.kicad_mod @@ -0,0 +1,35 @@ +(module Wafer_Vertical22.5x5.8x7RM2.5-8 (layer F.Cu) (tedit 556C2AC9) + (descr "Gold-Tek vertical wafer connector with 2.5mm pitch") + (tags "wafer connector vertical") + (fp_text reference REF** (at 8.763 -3.81) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Wafer_Vertical22.5x5.8x7RM2.5-8 (at 8.763 5.08) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.75 -2.75) (end 20.3 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 20.3 -2.75) (end 20.3 3.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 20.3 3.8) (end -2.75 3.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.75 3.8) (end -2.75 -2.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 -2.413) (end -2.54 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 -2.413) (end -2.54 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 3.429) (end -1.27 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.796 -2.413) (end 20.066 -2.413) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.796 3.429) (end 20.066 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.066 -2.413) (end 20.066 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 3.429) (end 18.796 3.429) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.796 -2.413) (end -1.27 -2.413) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.513 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 5.013 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 7.513 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 10.013 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 12.513 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 15.013 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 17.513 0) (size 2 2) (drill 1.2) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/Wafer_Vertical22.5x5.8x7RM2.5-8.wrl + (at (xyz 0 0 0)) + (scale (xyz 4 4 4)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/Wafer_Vertical22.5x5.8x7RM2.5-8.kicad_mod.REMOVED.git-id b/PCB/.pretty/Wafer_Vertical22.5x5.8x7RM2.5-8.kicad_mod.REMOVED.git-id deleted file mode 100644 index 52f36149..00000000 --- a/PCB/.pretty/Wafer_Vertical22.5x5.8x7RM2.5-8.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2d439de809867f2d5bf1cef1a7e3119ea6760eae \ No newline at end of file diff --git a/PCB/.pretty/XLR3MC.kicad_mod b/PCB/.pretty/XLR3MC.kicad_mod new file mode 100644 index 00000000..5bc81e97 --- /dev/null +++ b/PCB/.pretty/XLR3MC.kicad_mod @@ -0,0 +1,32 @@ +(module XLR3MC (layer F.Cu) (tedit 0) + (fp_text reference REF** (at 0 10.16) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value XLR3MC (at 0 15.24) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -11.43 22.225) (end -11.43 24.13) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.43 24.13) (end -11.43 24.765) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.43 24.765) (end 11.43 24.765) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.43 24.765) (end 11.43 22.225) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 0) (end -1.27 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 -5.08) (end 1.27 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 -5.08) (end 1.27 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.335 20.32) (end -13.335 22.225) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.335 22.225) (end 13.335 22.225) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.335 22.225) (end 13.335 20.32) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.335 20.32) (end -13.335 20.32) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.43 0) (end -11.43 20.32) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.43 0) (end 11.43 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.43 0) (end 11.43 20.32) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole circle (at -4.064 0) (size 2.794 2.794) (drill 1.778) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 4.064 0) (size 2.794 2.794) (drill 1.778) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 0 -5.08) (size 2.54 2.54) (drill 1.27) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 0 0) (size 2.794 2.794) (drill 1.778) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 0 5.08) (size 3.81 3.81) (drill 3.2004) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/XLR3MC.wrl + (at (xyz 0 0 0)) + (scale (xyz 2 2 2)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/XLR3MC.kicad_mod.REMOVED.git-id b/PCB/.pretty/XLR3MC.kicad_mod.REMOVED.git-id deleted file mode 100644 index c03ce74a..00000000 --- a/PCB/.pretty/XLR3MC.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5bc81e97fb7452645b45e879709999cc2126e17d \ No newline at end of file diff --git a/PCB/.pretty/XLR5MC.kicad_mod b/PCB/.pretty/XLR5MC.kicad_mod new file mode 100644 index 00000000..969b532a --- /dev/null +++ b/PCB/.pretty/XLR5MC.kicad_mod @@ -0,0 +1,31 @@ +(module XLR5MC (layer F.Cu) (tedit 0) + (fp_text reference REF** (at -5.08 6.35) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value XLR5MC (at 5.08 20.32) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 11.43 25.4) (end 11.43 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.43 25.4) (end -11.43 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.335 27.305) (end -13.335 27.305) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.335 27.305) (end -13.335 25.4) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.335 25.4) (end 13.335 25.4) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.43 27.305) (end 11.43 29.845) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.43 29.845) (end -11.43 29.845) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.43 29.845) (end -11.43 27.305) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.335 27.305) (end 13.335 25.4) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.43 0) (end 11.43 0) (layer F.SilkS) (width 0.15)) + (pad 4 thru_hole circle (at 5.08 0) (size 2.54 2.54) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 10.16 0) (size 2.54 2.54) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 0 0) (size 2.54 2.54) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 0 12.7) (size 3.81 3.81) (drill 3.302) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -5.08 0) (size 2.54 2.54) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole circle (at -10.16 0) (size 2.54 2.54) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 5.08 5.08) (size 2.54 2.54) (drill 2.1082) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at -5.08 17.78) (size 2.54 2.54) (drill 2.1082) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/XLR5MC.wrl + (at (xyz 0 0 0)) + (scale (xyz 2 2 2)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/XLR5MC.kicad_mod.REMOVED.git-id b/PCB/.pretty/XLR5MC.kicad_mod.REMOVED.git-id deleted file mode 100644 index a71ebdfc..00000000 --- a/PCB/.pretty/XLR5MC.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -969b532a7c93eadab170c8be71addefe895ff4e0 \ No newline at end of file diff --git a/PCB/.pretty/bnc-ci.kicad_mod b/PCB/.pretty/bnc-ci.kicad_mod new file mode 100644 index 00000000..38375636 --- /dev/null +++ b/PCB/.pretty/bnc-ci.kicad_mod @@ -0,0 +1,19 @@ +(module bnc-ci (layer F.Cu) (tedit 0) + (fp_text reference REF** (at 0 -8.89) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value bnc-ci (at 0 8.89) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_circle (center 0 0) (end -6.985 0) (layer F.SilkS) (width 0.15)) + (pad 2 thru_hole circle (at -3.175 -3.175) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole circle (at 0 0) (size 3.556 3.556) (drill 1.27) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 3.175 -3.175) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -3.175 3.175) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 3.175 3.175) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/bnc-ci.wrl + (at (xyz 0 0 0)) + (scale (xyz 2 2 2)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/bnc-ci.kicad_mod.REMOVED.git-id b/PCB/.pretty/bnc-ci.kicad_mod.REMOVED.git-id deleted file mode 100644 index 0597aa82..00000000 --- a/PCB/.pretty/bnc-ci.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -383756361e5f6f2207763ef282275fe04474536b \ No newline at end of file diff --git a/PCB/.pretty/bnc.kicad_mod b/PCB/.pretty/bnc.kicad_mod new file mode 100644 index 00000000..acfb16d7 --- /dev/null +++ b/PCB/.pretty/bnc.kicad_mod @@ -0,0 +1,21 @@ +(module bnc (layer F.Cu) (tedit 0) + (fp_text reference REF** (at -2.54 -10.16) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value bnc (at -3.81 11.43) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 7.62 3.81) (end 13.97 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.97 3.81) (end 16.51 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.51 1.27) (end 16.51 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.51 -1.27) (end 13.97 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.97 -3.81) (end 7.62 -3.81) (layer F.SilkS) (width 0.15)) + (fp_circle (center 0 0) (end 7.62 3.81) (layer F.SilkS) (width 0.15)) + (pad 2 thru_hole circle (at 0 0) (size 15.24 15.24) (drill 9.652) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole circle (at 12.7 0) (size 5.08 5.08) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/bnc.wrl + (at (xyz 0 0 0)) + (scale (xyz 2 2 2)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/bnc.kicad_mod.REMOVED.git-id b/PCB/.pretty/bnc.kicad_mod.REMOVED.git-id deleted file mode 100644 index 88224555..00000000 --- a/PCB/.pretty/bnc.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -acfb16d7fa94a9004bcc4e784929ec5837ce489e \ No newline at end of file diff --git a/PCB/.pretty/bornier2.kicad_mod b/PCB/.pretty/bornier2.kicad_mod new file mode 100644 index 00000000..a0acef3f --- /dev/null +++ b/PCB/.pretty/bornier2.kicad_mod @@ -0,0 +1,22 @@ +(module bornier2 (layer F.Cu) (tedit 0) + (descr "Bornier d'alimentation 2 pins") + (tags DEV) + (fp_text reference REF** (at 0 -5.08) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value bornier2 (at 0 5.08) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 5.08 2.54) (end -5.08 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.08 3.81) (end 5.08 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.08 -3.81) (end -5.08 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.08 -3.81) (end -5.08 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.08 3.81) (end 5.08 3.81) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -2.54 0) (size 2.54 2.54) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 2.54 0) (size 2.54 2.54) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/bornier2.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/bornier2.kicad_mod.REMOVED.git-id b/PCB/.pretty/bornier2.kicad_mod.REMOVED.git-id deleted file mode 100644 index 75b563d3..00000000 --- a/PCB/.pretty/bornier2.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a0acef3f9e927e2d4668b065b3787c3faba2f7a3 \ No newline at end of file diff --git a/PCB/.pretty/bornier3.kicad_mod b/PCB/.pretty/bornier3.kicad_mod new file mode 100644 index 00000000..f9c4347a --- /dev/null +++ b/PCB/.pretty/bornier3.kicad_mod @@ -0,0 +1,23 @@ +(module bornier3 (layer F.Cu) (tedit 0) + (descr "Bornier d'alimentation 3 pins") + (tags DEV) + (fp_text reference REF** (at 0 -5.08) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value bornier3 (at 0 5.08) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -7.62 3.81) (end -7.62 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 3.81) (end 7.62 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 2.54) (end 7.62 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 -3.81) (end 7.62 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.62 3.81) (end 7.62 3.81) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -5.08 0) (size 2.54 2.54) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 0 0) (size 2.54 2.54) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 5.08 0) (size 2.54 2.54) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/bornier3.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/bornier3.kicad_mod.REMOVED.git-id b/PCB/.pretty/bornier3.kicad_mod.REMOVED.git-id deleted file mode 100644 index e39e10ab..00000000 --- a/PCB/.pretty/bornier3.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f9c4347a463d64de30da281757f346f933a4ad6a \ No newline at end of file diff --git a/PCB/.pretty/bornier4.kicad_mod b/PCB/.pretty/bornier4.kicad_mod new file mode 100644 index 00000000..fdb69a67 --- /dev/null +++ b/PCB/.pretty/bornier4.kicad_mod @@ -0,0 +1,24 @@ +(module bornier4 (layer F.Cu) (tedit 0) + (descr "Bornier d'alimentation 4 pins") + (tags DEV) + (fp_text reference REF** (at 0 -6.35) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value bornier4 (at 0 5.08) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -10.16 -3.81) (end -10.16 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 10.16 3.81) (end 10.16 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 10.16 2.54) (end -10.16 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.16 -3.81) (end 10.16 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.16 3.81) (end 10.16 3.81) (layer F.SilkS) (width 0.15)) + (pad 2 thru_hole circle (at -2.54 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 2.54 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -7.62 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 7.62 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/bornier4.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/bornier4.kicad_mod.REMOVED.git-id b/PCB/.pretty/bornier4.kicad_mod.REMOVED.git-id deleted file mode 100644 index 9c4fbb5a..00000000 --- a/PCB/.pretty/bornier4.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fdb69a6799fc2e31ab4b2275b67f453d4431907f \ No newline at end of file diff --git a/PCB/.pretty/bornier5.kicad_mod b/PCB/.pretty/bornier5.kicad_mod new file mode 100644 index 00000000..844956ab --- /dev/null +++ b/PCB/.pretty/bornier5.kicad_mod @@ -0,0 +1,25 @@ +(module bornier5 (layer F.Cu) (tedit 0) + (descr "Bornier d'alimentation 4 pins") + (tags DEV) + (fp_text reference REF** (at 0 -5.08) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value bornier5 (at 0 5.08) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -12.7 3.81) (end 12.7 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.7 2.54) (end 12.7 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.7 -3.81) (end 12.7 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.7 -3.81) (end 12.7 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.7 -3.81) (end -12.7 3.81) (layer F.SilkS) (width 0.15)) + (pad 2 thru_hole circle (at -5.08 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 0 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -10.16 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 5.08 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 10.16 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/bornier5.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/bornier5.kicad_mod.REMOVED.git-id b/PCB/.pretty/bornier5.kicad_mod.REMOVED.git-id deleted file mode 100644 index fd81767e..00000000 --- a/PCB/.pretty/bornier5.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -844956abd44a3b6967109dfd587620a9712191a4 \ No newline at end of file diff --git a/PCB/.pretty/bornier6.kicad_mod b/PCB/.pretty/bornier6.kicad_mod new file mode 100644 index 00000000..f338fdb1 --- /dev/null +++ b/PCB/.pretty/bornier6.kicad_mod @@ -0,0 +1,26 @@ +(module bornier6 (layer F.Cu) (tedit 0) + (descr "Bornier d'alimentation 4 pins") + (tags DEV) + (fp_text reference REF** (at 1.27 -7.62) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value bornier6 (at 0 7.62) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -15.24 -3.81) (end -15.24 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.24 3.81) (end 15.24 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.24 2.54) (end 15.24 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.24 -3.81) (end 15.24 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.24 3.81) (end 15.24 3.81) (layer F.SilkS) (width 0.15)) + (pad 2 thru_hole circle (at -7.62 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -2.54 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -12.7 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 2.54 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 7.62 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 12.7 0) (size 3.81 3.81) (drill 1.524) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/bornier6.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/bornier6.kicad_mod.REMOVED.git-id b/PCB/.pretty/bornier6.kicad_mod.REMOVED.git-id deleted file mode 100644 index 0c35fff5..00000000 --- a/PCB/.pretty/bornier6.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f338fdb12ea6f5a4f079c37f291576f3f2a7cbc3 \ No newline at end of file diff --git a/PCB/.pretty/c64abfd.kicad_mod b/PCB/.pretty/c64abfd.kicad_mod new file mode 100644 index 00000000..50ca5635 --- /dev/null +++ b/PCB/.pretty/c64abfd.kicad_mod @@ -0,0 +1,87 @@ +(module c64abfd (layer F.Cu) (tedit 0) + (descr "Connecteur DIN Europe 64 contatcts Femelle Droit") + (tags "CONN DIN") + (fp_text reference REF** (at -20.955 -5.715) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value c64abfd (at 24.13 -5.715) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -46.99 -3.81) (end 46.99 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 46.99 -3.81) (end 46.99 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 46.99 3.81) (end -46.99 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -46.99 3.81) (end -46.99 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -41.91 3.81) (end -41.91 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 41.91 3.81) (end 41.91 -3.81) (layer F.SilkS) (width 0.15)) + (pad A1 thru_hole rect (at -39.37 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A2 thru_hole circle (at -36.83 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A3 thru_hole circle (at -34.29 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A4 thru_hole circle (at -31.75 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A5 thru_hole circle (at -29.21 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A6 thru_hole circle (at -26.67 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A7 thru_hole circle (at -24.13 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A8 thru_hole circle (at -21.59 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A9 thru_hole circle (at -19.05 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A10 thru_hole circle (at -16.51 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A11 thru_hole circle (at -13.97 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A12 thru_hole circle (at -11.43 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A13 thru_hole circle (at -8.89 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A14 thru_hole circle (at -6.35 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A15 thru_hole circle (at -3.81 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A16 thru_hole circle (at -1.27 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A17 thru_hole circle (at 1.27 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A18 thru_hole circle (at 3.81 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A19 thru_hole circle (at 6.35 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A20 thru_hole circle (at 8.89 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A21 thru_hole circle (at 11.43 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A22 thru_hole circle (at 13.97 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A23 thru_hole circle (at 16.51 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A24 thru_hole circle (at 19.05 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A25 thru_hole circle (at 21.59 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A26 thru_hole circle (at 24.13 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A27 thru_hole circle (at 26.67 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A28 thru_hole circle (at 29.21 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A29 thru_hole circle (at 31.75 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A30 thru_hole circle (at 34.29 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A31 thru_hole circle (at 36.83 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A32 thru_hole circle (at 39.37 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B1 thru_hole circle (at -39.37 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B2 thru_hole circle (at -36.83 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B3 thru_hole circle (at -34.29 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B4 thru_hole circle (at -31.75 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B5 thru_hole circle (at -29.21 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B6 thru_hole circle (at -26.67 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B7 thru_hole circle (at -24.13 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B8 thru_hole circle (at -21.59 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B9 thru_hole circle (at -19.05 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B10 thru_hole circle (at -16.51 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B11 thru_hole circle (at -13.97 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B12 thru_hole circle (at -11.43 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B13 thru_hole circle (at -8.89 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B14 thru_hole circle (at -6.35 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B15 thru_hole circle (at -3.81 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B16 thru_hole circle (at -1.27 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B17 thru_hole circle (at 1.27 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B18 thru_hole circle (at 3.81 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B19 thru_hole circle (at 6.35 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B20 thru_hole circle (at 8.89 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B21 thru_hole circle (at 11.43 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B22 thru_hole circle (at 13.97 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B23 thru_hole circle (at 16.51 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B24 thru_hole circle (at 19.05 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B25 thru_hole circle (at 21.59 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B26 thru_hole circle (at 24.13 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B27 thru_hole circle (at 26.67 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B28 thru_hole circle (at 29.21 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B29 thru_hole circle (at 31.75 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B30 thru_hole circle (at 34.29 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B31 thru_hole circle (at 36.83 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B32 thru_hole circle (at 39.37 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 65 thru_hole circle (at -44.45 -1.27) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 66 thru_hole circle (at 44.45 -1.27) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/c64abfd.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/c64abfd.kicad_mod.REMOVED.git-id b/PCB/.pretty/c64abfd.kicad_mod.REMOVED.git-id deleted file mode 100644 index 9690bf3f..00000000 --- a/PCB/.pretty/c64abfd.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -50ca563523d5eadcda50a1631b16fe9f0835d65a \ No newline at end of file diff --git a/PCB/.pretty/c64abmd.kicad_mod b/PCB/.pretty/c64abmd.kicad_mod new file mode 100644 index 00000000..21bbd59d --- /dev/null +++ b/PCB/.pretty/c64abmd.kicad_mod @@ -0,0 +1,87 @@ +(module c64abmd (layer F.Cu) (tedit 0) + (descr "Connecteur DIN Europe 64 contacts Male Droit") + (tags "CONN DIN") + (fp_text reference REF** (at -21.59 -5.715) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value c64abmd (at 24.13 -5.715) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -46.99 -3.81) (end 46.99 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 46.99 -3.81) (end 46.99 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -46.99 3.81) (end -46.99 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -41.91 3.81) (end -41.91 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 41.91 3.81) (end 41.91 -3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -46.99 3.81) (end 46.99 3.81) (layer F.SilkS) (width 0.15)) + (pad 65 thru_hole circle (at -44.45 1.27) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 66 thru_hole circle (at 44.45 1.27) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad A3 thru_hole circle (at -34.29 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A4 thru_hole circle (at -31.75 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A5 thru_hole circle (at -29.21 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A6 thru_hole circle (at -26.67 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A7 thru_hole circle (at -24.13 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A8 thru_hole circle (at -21.59 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A9 thru_hole circle (at -19.05 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A10 thru_hole circle (at -16.51 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A11 thru_hole circle (at -13.97 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A12 thru_hole circle (at -11.43 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A13 thru_hole circle (at -8.89 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A14 thru_hole circle (at -6.35 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A15 thru_hole circle (at -3.81 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A16 thru_hole circle (at -1.27 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A17 thru_hole circle (at 1.27 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A18 thru_hole circle (at 3.81 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A19 thru_hole circle (at 6.35 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A20 thru_hole circle (at 8.89 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A21 thru_hole circle (at 11.43 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A22 thru_hole circle (at 13.97 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A23 thru_hole circle (at 16.51 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A24 thru_hole circle (at 19.05 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A25 thru_hole circle (at 21.59 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A26 thru_hole circle (at 24.13 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A27 thru_hole circle (at 26.67 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A28 thru_hole circle (at 29.21 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A29 thru_hole circle (at 31.75 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A30 thru_hole circle (at 34.29 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A31 thru_hole circle (at 36.83 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A32 thru_hole circle (at 39.37 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A2 thru_hole circle (at -36.83 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A1 thru_hole rect (at -39.37 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B1 thru_hole circle (at -39.37 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B2 thru_hole circle (at -36.83 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B3 thru_hole circle (at -34.29 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B4 thru_hole circle (at -31.75 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B5 thru_hole circle (at -29.21 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B6 thru_hole circle (at -26.67 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B7 thru_hole circle (at -24.13 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B8 thru_hole circle (at -21.59 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B9 thru_hole circle (at -19.05 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B10 thru_hole circle (at -16.51 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B11 thru_hole circle (at -13.97 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B12 thru_hole circle (at -11.43 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B13 thru_hole circle (at -8.89 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B14 thru_hole circle (at -6.35 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B15 thru_hole circle (at -3.81 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B16 thru_hole circle (at -1.27 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B17 thru_hole circle (at 1.27 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B18 thru_hole circle (at 3.81 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B19 thru_hole circle (at 6.35 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B20 thru_hole circle (at 8.89 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B21 thru_hole circle (at 11.43 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B22 thru_hole circle (at 13.97 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B23 thru_hole circle (at 16.51 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B24 thru_hole circle (at 19.05 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B25 thru_hole circle (at 21.59 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B26 thru_hole circle (at 24.13 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B27 thru_hole circle (at 26.67 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B28 thru_hole circle (at 29.21 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B29 thru_hole circle (at 31.75 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B30 thru_hole circle (at 34.29 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B31 thru_hole circle (at 36.83 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad B32 thru_hole circle (at 39.37 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/c64abmd.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/c64abmd.kicad_mod.REMOVED.git-id b/PCB/.pretty/c64abmd.kicad_mod.REMOVED.git-id deleted file mode 100644 index e9acdf27..00000000 --- a/PCB/.pretty/c64abmd.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -21bbd59deef3b30cfc1292b6a8f55e4090a2354e \ No newline at end of file diff --git a/PCB/.pretty/c64acfd.kicad_mod b/PCB/.pretty/c64acfd.kicad_mod new file mode 100644 index 00000000..8fb52aaa --- /dev/null +++ b/PCB/.pretty/c64acfd.kicad_mod @@ -0,0 +1,89 @@ +(module c64acfd (layer F.Cu) (tedit 0) + (descr "Connecteur DIN Europe 96 contacts AC femelle droit") + (tags "CONN DIN") + (fp_text reference REF** (at 20.955 6.985) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value c64acfd (at -24.765 6.985) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 46.99 5.08) (end -46.99 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 46.99 -2.54) (end 46.99 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 41.91 -2.54) (end 41.91 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 46.99 -2.54) (end 46.99 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 46.99 -5.08) (end -46.99 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start 41.91 -2.54) (end 41.91 -5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -41.91 -5.08) (end -41.91 5.08) (layer F.SilkS) (width 0.15)) + (fp_line (start -46.99 5.08) (end -46.99 -5.08) (layer F.SilkS) (width 0.15)) + (pad 65 thru_hole circle (at 44.45 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad 66 thru_hole circle (at -44.45 0) (size 3.81 3.81) (drill 3.048) (layers *.Cu *.Mask F.SilkS)) + (pad A1 thru_hole rect (at -39.37 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A2 thru_hole circle (at -36.83 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A3 thru_hole circle (at -34.29 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A4 thru_hole circle (at -31.75 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A5 thru_hole circle (at -29.21 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A6 thru_hole circle (at -26.67 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A7 thru_hole circle (at -24.13 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A8 thru_hole circle (at -21.59 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A9 thru_hole circle (at -19.05 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A10 thru_hole circle (at -16.51 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A11 thru_hole circle (at -13.97 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A12 thru_hole circle (at -11.43 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A13 thru_hole circle (at -8.89 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A14 thru_hole circle (at -6.35 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A15 thru_hole circle (at -3.81 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A16 thru_hole circle (at -1.27 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A17 thru_hole circle (at 1.27 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A18 thru_hole circle (at 3.81 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A19 thru_hole circle (at 6.35 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A20 thru_hole circle (at 8.89 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A21 thru_hole circle (at 11.43 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A22 thru_hole circle (at 13.97 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A23 thru_hole circle (at 16.51 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A24 thru_hole circle (at 19.05 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A25 thru_hole circle (at 21.59 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A26 thru_hole circle (at 24.13 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A27 thru_hole circle (at 26.67 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A28 thru_hole circle (at 29.21 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A29 thru_hole circle (at 31.75 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A30 thru_hole circle (at 34.29 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A31 thru_hole circle (at 36.83 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad A32 thru_hole circle (at 39.37 2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C1 thru_hole circle (at -39.37 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C2 thru_hole circle (at -36.83 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C3 thru_hole circle (at -34.29 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C4 thru_hole circle (at -31.75 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C5 thru_hole circle (at -29.21 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C6 thru_hole circle (at -26.67 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C7 thru_hole circle (at -24.13 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C8 thru_hole circle (at -21.59 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C9 thru_hole circle (at -19.05 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C10 thru_hole circle (at -16.51 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C11 thru_hole circle (at -13.97 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C12 thru_hole circle (at -11.43 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C13 thru_hole circle (at -8.89 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C14 thru_hole circle (at -6.35 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C15 thru_hole circle (at -3.81 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C16 thru_hole circle (at -1.27 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C17 thru_hole circle (at 1.27 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C18 thru_hole circle (at 3.81 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C19 thru_hole circle (at 6.35 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C20 thru_hole circle (at 8.89 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C21 thru_hole circle (at 11.43 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C22 thru_hole circle (at 13.97 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C23 thru_hole circle (at 16.51 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C24 thru_hole circle (at 19.05 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C25 thru_hole circle (at 21.59 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C26 thru_hole circle (at 24.13 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C27 thru_hole circle (at 26.67 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C28 thru_hole circle (at 29.21 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C29 thru_hole circle (at 31.75 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C30 thru_hole circle (at 34.29 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C31 thru_hole circle (at 36.83 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad C32 thru_hole circle (at 39.37 -2.54) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/c64acfd.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/c64acfd.kicad_mod.REMOVED.git-id b/PCB/.pretty/c64acfd.kicad_mod.REMOVED.git-id deleted file mode 100644 index 52b31911..00000000 --- a/PCB/.pretty/c64acfd.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8fb52aaa9fcabed03643da75bf7353e0149d899e \ No newline at end of file diff --git a/PCB/.pretty/he10-10d.kicad_mod b/PCB/.pretty/he10-10d.kicad_mod new file mode 100644 index 00000000..17f2c541 --- /dev/null +++ b/PCB/.pretty/he10-10d.kicad_mod @@ -0,0 +1,41 @@ +(module he10-10d (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 10 contacts droit") + (tags "CONN HE10") + (fp_text reference REF** (at -6.096 -5.842) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value he10-10d (at 6.096 5.842) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 16.002 -4.318) (end 16.002 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.002 4.318) (end -16.002 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -16.002 -4.318) (end 16.002 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.89 3.556) (end -8.89 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.89 3.556) (end 8.89 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 4.318) (end -2.54 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 3.556) (end -8.89 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.89 -3.556) (end 8.89 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.89 3.556) (end 2.54 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 3.556) (end 2.54 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -16.002 4.318) (end -16.002 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -6.604 1.27) (end -7.874 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.874 0.508) (end -7.874 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -7.874 2.032) (end -6.604 1.27) (layer F.SilkS) (width 0.15)) + (pad "" thru_hole circle (at -13.97 0) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) + (pad "" thru_hole circle (at 13.97 0) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -5.08 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -5.08 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -2.54 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -2.54 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 0 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 0 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 2.54 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 2.54 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 5.08 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at 5.08 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (model Connect.3dshapes/he10-10d.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/.pretty/he10-10d.kicad_mod.REMOVED.git-id b/PCB/.pretty/he10-10d.kicad_mod.REMOVED.git-id deleted file mode 100644 index 130a8fc7..00000000 --- a/PCB/.pretty/he10-10d.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -17f2c541822541ecf4667c6760cf4eb7f3116ddd \ No newline at end of file diff --git a/PCB/.pretty/he10-14c.kicad_mod b/PCB/.pretty/he10-14c.kicad_mod new file mode 100644 index 00000000..9797dbde --- /dev/null +++ b/PCB/.pretty/he10-14c.kicad_mod @@ -0,0 +1,48 @@ +(module he10-14c (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 14 contacts couche") + (tags "CONN HE10") + (fp_text reference REF** (at 0 3.81) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value he10-14c (at -2.54 7.62) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -11.176 -2.54) (end -11.176 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.176 2.032) (end -12.446 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.446 3.302) (end -14.478 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -14.478 3.302) (end -15.748 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.748 2.032) (end -15.748 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.446 3.302) (end 11.176 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.176 2.032) (end 11.176 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.748 -2.54) (end 15.748 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.748 2.032) (end 14.478 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.478 3.302) (end 12.446 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -17.78 -2.54) (end -17.78 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -17.78 4.445) (end -14.605 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -14.605 14.605) (end -10.795 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.795 14.605) (end -8.89 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start -17.78 -2.54) (end 18.415 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.24 14.605) (end 11.43 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.415 -2.54) (end 18.415 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.415 4.445) (end 15.24 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -8.89 10.16) (end 8.763 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.43 14.605) (end 8.763 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.112 10.16) (end 6.096 8.128) (layer F.SilkS) (width 0.15)) + (fp_line (start 6.096 8.128) (end 5.08 10.16) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -13.462 0.508) (size 3.048 3.048) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 13.462 0.508) (size 3.048 3.048) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 7.62 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 7.62 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 5.08 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 5.08 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 2.54 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 0 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 0 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 2.54 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -2.54 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -2.54 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -5.08 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -5.08 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -7.62 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -7.62 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/he10-14c.kicad_mod.REMOVED.git-id b/PCB/.pretty/he10-14c.kicad_mod.REMOVED.git-id deleted file mode 100644 index 2466697c..00000000 --- a/PCB/.pretty/he10-14c.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9797dbde136246f7200b221b3309a4f579fdf529 \ No newline at end of file diff --git a/PCB/.pretty/he10-14d.kicad_mod b/PCB/.pretty/he10-14d.kicad_mod new file mode 100644 index 00000000..97b787e0 --- /dev/null +++ b/PCB/.pretty/he10-14d.kicad_mod @@ -0,0 +1,40 @@ +(module he10-14d (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 14 contacts droit") + (tags "CONN HE10") + (fp_text reference REF** (at -7.874 -5.842) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value he10-14d (at 8.382 5.842) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -18.796 -4.318) (end 18.542 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.542 -4.318) (end 18.542 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.542 4.318) (end -18.796 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 4.318) (end -2.54 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 3.556) (end -11.43 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.43 3.556) (end -11.43 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.43 -3.556) (end 11.43 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.43 -3.556) (end 11.43 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.43 3.556) (end 2.54 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 3.556) (end 2.54 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -18.796 4.318) (end -18.796 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -9.144 1.27) (end -10.414 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.414 0.508) (end -10.414 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.414 2.032) (end -9.144 1.27) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -16.51 0) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 16.51 0) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -7.62 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -7.62 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -5.08 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -5.08 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -2.54 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -2.54 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 0 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 0 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 2.54 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at 2.54 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at 5.08 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at 5.08 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at 7.62 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at 7.62 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/he10-14d.kicad_mod.REMOVED.git-id b/PCB/.pretty/he10-14d.kicad_mod.REMOVED.git-id deleted file mode 100644 index b10dcdec..00000000 --- a/PCB/.pretty/he10-14d.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -97b787e017b58c9533d88a5eb25d004ad2540cd1 \ No newline at end of file diff --git a/PCB/.pretty/he10-16c.kicad_mod b/PCB/.pretty/he10-16c.kicad_mod new file mode 100644 index 00000000..1c2eac4d --- /dev/null +++ b/PCB/.pretty/he10-16c.kicad_mod @@ -0,0 +1,50 @@ +(module he10-16c (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 16 contacts couche") + (tags "CONN HE10") + (fp_text reference REF** (at 0 3.81) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value he10-16c (at -1.27 7.62) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -12.446 -2.54) (end -12.446 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.446 2.032) (end -13.716 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -13.716 3.302) (end -15.748 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.748 3.302) (end -17.018 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -17.018 2.032) (end -17.018 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.018 -2.54) (end 17.018 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start 17.018 2.032) (end 15.748 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.748 3.302) (end 13.716 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 13.716 3.302) (end 12.446 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.446 2.032) (end 12.446 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.05 -2.54) (end -19.05 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.05 4.445) (end -15.875 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -15.875 14.605) (end -12.065 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.065 14.605) (end -10.16 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.05 -2.54) (end 19.05 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.05 -2.54) (end 19.05 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.05 4.445) (end 15.875 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.875 14.605) (end 12.065 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.16 10.16) (end 9.906 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.065 14.605) (end 9.906 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start 8.636 10.16) (end 7.62 8.128) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 8.128) (end 6.604 10.16) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -14.732 0.508) (size 3.048 3.048) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 14.732 0.508) (size 3.048 3.048) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 8.89 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 8.89 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 6.35 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 6.35 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 3.81 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 3.81 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 1.27 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 1.27 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -1.27 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -1.27 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -3.81 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -3.81 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -6.35 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -6.35 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -8.89 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at -8.89 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/he10-16c.kicad_mod.REMOVED.git-id b/PCB/.pretty/he10-16c.kicad_mod.REMOVED.git-id deleted file mode 100644 index f66049f6..00000000 --- a/PCB/.pretty/he10-16c.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1c2eac4d45f3be981f8fab0aefaf9b0d3ec6addb \ No newline at end of file diff --git a/PCB/.pretty/he10-16d.kicad_mod b/PCB/.pretty/he10-16d.kicad_mod new file mode 100644 index 00000000..a52f4114 --- /dev/null +++ b/PCB/.pretty/he10-16d.kicad_mod @@ -0,0 +1,42 @@ +(module he10-16d (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 16 contacts droit") + (tags "CONN HE10") + (fp_text reference REF** (at -5.588 -6.096) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value he10-16d (at 12.7 6.096) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.54 4.318) (end -2.54 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.54 3.556) (end -12.7 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.7 3.556) (end -12.7 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.7 -3.556) (end 12.7 -3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.7 -3.556) (end 12.7 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 12.7 3.556) (end 2.54 3.556) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 3.556) (end 2.54 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.812 4.318) (end -19.812 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.812 -4.318) (end 19.812 -4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.812 -4.318) (end 19.812 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.812 4.318) (end -19.812 4.318) (layer F.SilkS) (width 0.15)) + (fp_line (start -10.414 1.27) (end -11.684 0.508) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.684 0.508) (end -11.684 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -11.684 2.032) (end -10.414 1.27) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -17.78 0) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 17.78 0) (size 5.461 5.461) (drill 2.6924) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -8.89 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -8.89 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -6.35 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -6.35 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -3.81 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -3.81 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -1.27 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -1.27 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 1.27 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at 1.27 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at 3.81 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at 3.81 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at 6.35 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at 6.35 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at 8.89 1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at 8.89 -1.27) (size 1.524 1.524) (drill 0.9144) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/he10-16d.kicad_mod.REMOVED.git-id b/PCB/.pretty/he10-16d.kicad_mod.REMOVED.git-id deleted file mode 100644 index a1f6b40d..00000000 --- a/PCB/.pretty/he10-16d.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a52f4114c9c09c686d5170a8919ca3b74699822f \ No newline at end of file diff --git a/PCB/.pretty/he10-20c.kicad_mod b/PCB/.pretty/he10-20c.kicad_mod new file mode 100644 index 00000000..3376b648 --- /dev/null +++ b/PCB/.pretty/he10-20c.kicad_mod @@ -0,0 +1,54 @@ +(module he10-20c (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 20 contacts couche") + (tags "CONN HE10") + (fp_text reference REF** (at 0 3.81) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value he10-20c (at -1.27 7.62) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -14.986 -2.54) (end -14.986 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -14.986 2.032) (end -16.256 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -16.256 3.302) (end -18.288 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -18.288 3.302) (end -19.558 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -19.558 2.032) (end -19.558 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.558 -2.54) (end 19.558 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start 19.558 2.032) (end 18.288 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.288 3.302) (end 16.256 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.256 3.302) (end 14.986 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.986 2.032) (end 14.986 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.59 -2.54) (end -21.59 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.59 4.445) (end -18.415 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -18.415 14.605) (end -14.605 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -14.605 14.605) (end -12.7 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.59 -2.54) (end 21.59 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 21.59 -2.54) (end 21.59 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 21.59 4.445) (end 18.415 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.415 14.605) (end 14.605 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -12.7 10.16) (end 12.573 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.605 14.605) (end 12.573 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start 11.43 10.16) (end 10.414 8.128) (layer F.SilkS) (width 0.15)) + (fp_line (start 10.414 8.128) (end 9.398 10.16) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -17.272 0.508) (size 3.048 3.048) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 17.272 0.508) (size 3.048 3.048) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 11.43 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.SilkS *.Mask)) + (pad 2 thru_hole circle (at 11.43 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 8.89 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 8.89 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 6.35 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 6.35 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 3.81 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 3.81 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 1.27 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at 1.27 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -1.27 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -1.27 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -3.81 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -3.81 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -6.35 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at -6.35 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at -8.89 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at -8.89 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at -11.43 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at -11.43 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/he10-20c.kicad_mod.REMOVED.git-id b/PCB/.pretty/he10-20c.kicad_mod.REMOVED.git-id deleted file mode 100644 index f2f23eeb..00000000 --- a/PCB/.pretty/he10-20c.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3376b648d2de8d6aa0e6ac55d44d0a59458c31f2 \ No newline at end of file diff --git a/PCB/.pretty/he10-26c.kicad_mod b/PCB/.pretty/he10-26c.kicad_mod new file mode 100644 index 00000000..7036b938 --- /dev/null +++ b/PCB/.pretty/he10-26c.kicad_mod @@ -0,0 +1,60 @@ +(module he10-26c (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 26 contacts couche") + (tags "CONN HE10") + (fp_text reference REF** (at -0.508 4.572) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value he10-26c (at -2.54 8.128) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -18.796 -2.54) (end -18.796 1.778) (layer F.SilkS) (width 0.15)) + (fp_line (start -18.796 1.778) (end -20.066 3.048) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.066 3.048) (end -22.098 3.048) (layer F.SilkS) (width 0.15)) + (fp_line (start -22.098 3.048) (end -23.368 1.778) (layer F.SilkS) (width 0.15)) + (fp_line (start -23.368 1.778) (end -23.368 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 23.368 -2.54) (end 23.368 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start 23.368 2.032) (end 22.098 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 22.098 3.302) (end 20.066 3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 20.066 3.302) (end 18.796 2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.796 2.032) (end 18.796 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -25.4 -2.54) (end -25.4 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -25.4 4.445) (end -22.225 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -22.225 14.605) (end -18.415 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -18.415 14.605) (end -16.51 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start -25.4 -2.54) (end 25.4 -2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 25.4 -2.54) (end 25.4 4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 25.4 4.445) (end 22.225 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start 22.225 14.605) (end 18.415 14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start 16.256 10.16) (end -16.51 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start 18.415 14.605) (end 16.256 10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start 15.113 10.16) (end 14.097 8.128) (layer F.SilkS) (width 0.15)) + (fp_line (start 14.097 8.128) (end 13.081 10.16) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -21.082 0.508) (size 3.048 3.048) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 21.082 0.508) (size 3.048 3.048) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at 15.24 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at 15.24 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at 12.7 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at 12.7 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at 10.16 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at 10.16 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at 7.62 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at 7.62 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at 5.08 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at 5.08 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at 2.54 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at 2.54 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at 0 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at 0 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -2.54 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at -2.54 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at -5.08 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at -5.08 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at -7.62 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at -7.62 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at -10.16 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at -10.16 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at -12.7 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at -12.7 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at -15.24 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 26 thru_hole circle (at -15.24 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/he10-26c.kicad_mod.REMOVED.git-id b/PCB/.pretty/he10-26c.kicad_mod.REMOVED.git-id deleted file mode 100644 index 5ef25a32..00000000 --- a/PCB/.pretty/he10-26c.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7036b938d34fe45ab2e9d281af8a5405c8b3f9a9 \ No newline at end of file diff --git a/PCB/.pretty/he10-34c.kicad_mod b/PCB/.pretty/he10-34c.kicad_mod new file mode 100644 index 00000000..947d5ed3 --- /dev/null +++ b/PCB/.pretty/he10-34c.kicad_mod @@ -0,0 +1,68 @@ +(module he10-34c (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 34 contacts couche") + (tags "CONN HE10") + (fp_text reference REF** (at -15.24 -5.08) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value he10-34c (at 12.7 -5.08) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 23.876 -2.032) (end 25.146 -3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 25.146 -3.302) (end 27.178 -3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 27.178 -3.302) (end 28.448 -2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -28.448 -2.032) (end -27.178 -3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -27.178 -3.302) (end -25.146 -3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -25.146 -3.302) (end -23.876 -2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -23.876 2.54) (end -23.876 -2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -31.115 2.54) (end 31.115 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 31.115 2.54) (end 31.115 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 31.115 -4.445) (end 28.575 -14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -31.115 -4.445) (end -31.115 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -28.575 -14.605) (end -31.115 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -28.448 2.54) (end -28.448 -2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start 23.876 2.54) (end 23.876 -2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start 28.448 -2.032) (end 28.448 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -21.59 -10.16) (end -20.32 -7.62) (layer F.SilkS) (width 0.15)) + (fp_line (start -20.32 -7.62) (end -19.05 -10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start -23.495 -10.16) (end 23.495 -10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start -28.575 -14.605) (end -24.765 -14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -24.765 -14.605) (end -23.495 -10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start 28.575 -14.605) (end 24.765 -14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start 24.765 -14.605) (end 23.495 -10.16) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -26.162 -0.508) (size 3.048 3.048) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 26.162 -0.508) (size 3.048 3.048) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -20.32 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -20.32 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -17.78 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -17.78 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -15.24 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -15.24 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -12.7 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -12.7 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -10.16 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -10.16 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -7.62 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -7.62 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -5.08 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -5.08 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -2.54 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at -2.54 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at 0 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at 0 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at 2.54 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at 2.54 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at 5.08 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at 5.08 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at 7.62 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at 7.62 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at 10.16 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 26 thru_hole circle (at 10.16 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 27 thru_hole circle (at 12.7 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 28 thru_hole circle (at 12.7 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 29 thru_hole circle (at 15.24 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 30 thru_hole circle (at 15.24 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 31 thru_hole circle (at 17.78 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 32 thru_hole circle (at 17.78 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 33 thru_hole circle (at 20.32 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 34 thru_hole circle (at 20.32 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/he10-34c.kicad_mod.REMOVED.git-id b/PCB/.pretty/he10-34c.kicad_mod.REMOVED.git-id deleted file mode 100644 index 2b3c4264..00000000 --- a/PCB/.pretty/he10-34c.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -947d5ed358d46658513df315aea505a4414c7f00 \ No newline at end of file diff --git a/PCB/.pretty/he10-40c.kicad_mod b/PCB/.pretty/he10-40c.kicad_mod new file mode 100644 index 00000000..af3407e6 --- /dev/null +++ b/PCB/.pretty/he10-40c.kicad_mod @@ -0,0 +1,74 @@ +(module he10-40c (layer F.Cu) (tedit 0) + (descr "Connecteur HE10 40 contacts couche") + (tags "CONN HE10") + (fp_text reference REF** (at -16.51 -5.08) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value he10-40c (at 15.24 -5.08) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 32.258 -2.032) (end 32.258 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 27.686 -2.032) (end 28.956 -3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 28.956 -3.302) (end 30.988 -3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start 30.988 -3.302) (end 32.258 -2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -32.258 -2.032) (end -30.988 -3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -30.988 -3.302) (end -28.956 -3.302) (layer F.SilkS) (width 0.15)) + (fp_line (start -28.956 -3.302) (end -27.686 -2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -34.925 2.54) (end 34.925 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 34.925 2.54) (end 34.925 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start 34.925 -4.445) (end 32.385 -14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -32.385 -14.605) (end -34.925 -4.445) (layer F.SilkS) (width 0.15)) + (fp_line (start -34.925 -4.445) (end -34.925 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start -32.258 2.54) (end -32.258 -2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -27.686 -2.032) (end -27.686 2.54) (layer F.SilkS) (width 0.15)) + (fp_line (start 27.686 2.54) (end 27.686 -2.032) (layer F.SilkS) (width 0.15)) + (fp_line (start -25.4 -10.16) (end -24.13 -7.62) (layer F.SilkS) (width 0.15)) + (fp_line (start -24.13 -7.62) (end -22.86 -10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start 27.305 -10.16) (end -27.305 -10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start -32.385 -14.605) (end -28.575 -14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start -28.575 -14.605) (end -27.305 -10.16) (layer F.SilkS) (width 0.15)) + (fp_line (start 32.385 -14.605) (end 28.575 -14.605) (layer F.SilkS) (width 0.15)) + (fp_line (start 28.575 -14.605) (end 27.305 -10.16) (layer F.SilkS) (width 0.15)) + (pad 0 thru_hole circle (at -29.972 -0.508) (size 3.048 3.048) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 0 thru_hole circle (at 29.972 -0.508) (size 3.048 3.048) (drill 2.54) (layers *.Cu *.Mask F.SilkS)) + (pad 1 thru_hole rect (at -24.13 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole circle (at -24.13 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 3 thru_hole circle (at -21.59 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 4 thru_hole circle (at -21.59 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 5 thru_hole circle (at -19.05 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 6 thru_hole circle (at -19.05 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 7 thru_hole circle (at -16.51 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 8 thru_hole circle (at -16.51 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 9 thru_hole circle (at -13.97 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 10 thru_hole circle (at -13.97 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 11 thru_hole circle (at -11.43 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 12 thru_hole circle (at -11.43 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 13 thru_hole circle (at -8.89 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 14 thru_hole circle (at -8.89 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 15 thru_hole circle (at -6.35 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 16 thru_hole circle (at -6.35 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 17 thru_hole circle (at -3.81 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 18 thru_hole circle (at -3.81 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 19 thru_hole circle (at -1.27 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 20 thru_hole circle (at -1.27 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 21 thru_hole circle (at 1.27 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 22 thru_hole circle (at 1.27 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 23 thru_hole circle (at 3.81 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 24 thru_hole circle (at 3.81 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 25 thru_hole circle (at 6.35 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 26 thru_hole circle (at 6.35 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 27 thru_hole circle (at 8.89 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 28 thru_hole circle (at 8.89 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 29 thru_hole circle (at 11.43 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 30 thru_hole circle (at 11.43 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 31 thru_hole circle (at 13.97 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 32 thru_hole circle (at 13.97 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 33 thru_hole circle (at 16.51 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 34 thru_hole circle (at 16.51 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 35 thru_hole circle (at 19.05 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 36 thru_hole circle (at 19.05 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 37 thru_hole circle (at 21.59 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 38 thru_hole circle (at 21.59 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 39 thru_hole circle (at 24.13 1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) + (pad 40 thru_hole circle (at 24.13 -1.27) (size 1.524 1.524) (drill 0.8128) (layers *.Cu *.Mask F.SilkS)) +) diff --git a/PCB/.pretty/he10-40c.kicad_mod.REMOVED.git-id b/PCB/.pretty/he10-40c.kicad_mod.REMOVED.git-id deleted file mode 100644 index a3ff97b7..00000000 --- a/PCB/.pretty/he10-40c.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -af3407e6d8412da09de31ec9a52a8c6e92109bb7 \ No newline at end of file diff --git a/PCB/BACKUP_OLD_PCB.REMOVED.git-id b/PCB/BACKUP_OLD_PCB.REMOVED.git-id deleted file mode 100644 index d37017a2..00000000 --- a/PCB/BACKUP_OLD_PCB.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5cc153bd1a32922b0b8ef2e2d90dbba8d46325d5 \ No newline at end of file diff --git a/PCB/ESCHEMA_OF_THAT_WAS_SENT_TO_PROTOTYPE_BACKERS.pdf.REMOVED.git-id b/PCB/ESCHEMA_OF_THAT_WAS_SENT_TO_PROTOTYPE_BACKERS.pdf.REMOVED.git-id deleted file mode 100644 index 476dee32..00000000 --- a/PCB/ESCHEMA_OF_THAT_WAS_SENT_TO_PROTOTYPE_BACKERS.pdf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b58784813023e57acea3c688a6911f4c94a8459b \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/BOM.csv.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/BOM.csv.REMOVED.git-id deleted file mode 100644 index c1c13c69..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/BOM.csv.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b9fc30efa701fc640af700f79f1c8035d3ca5791 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber.zip.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber.zip.REMOVED.git-id deleted file mode 100644 index 486310ff..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c7d73d27ce40c26fed4bde454f4a10cada1c1915 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id deleted file mode 100644 index fdf8bc81..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b08131545e4216f626ef755afbcd48b9c79dabf3 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id deleted file mode 100644 index 64fc2493..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ab03579487dc4839ca86e4f6fb14e1f37ebd0233 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id deleted file mode 100644 index 2ad85bf8..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -05e3a43ab34b6f6d668f3061921c8f3b13b181ad \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id deleted file mode 100644 index 4c63ca73..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -64cc8ef8c784f0b3319aa599500b35cce504bb9a \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id deleted file mode 100644 index f9875d45..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -403fb676623315eebcef27837316e3c3ee31a009 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id deleted file mode 100644 index a4f0679f..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c896e6682da0ccb47c856b25ca31a321bc9af2f7 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id deleted file mode 100644 index d2ca0232..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5cda148e0b0760fbab88e05e37dd0a3d00281a80 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1.drl.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index 1b478596..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a5930495bec2b4825e4d96e14b0e65e0fdf8b43e \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber_and_bom.zip.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber_and_bom.zip.REMOVED.git-id deleted file mode 100644 index 366fb9ee..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Gerber_and_bom.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cddba01a23510f09f7f2754e93fcb35b892abfdc \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Stocktake.csv.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Stocktake.csv.REMOVED.git-id deleted file mode 100644 index f9fa95ba..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Stocktake.csv.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3203c7bf975ae3713ff7a90f1760e295de3b38f9 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Stocktake.ods.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Stocktake.ods.REMOVED.git-id deleted file mode 100644 index 996e7341..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Stocktake.ods.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bfd4eec42252c19baa6ca198016f365317cb221a \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Stocktake.pdf.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Stocktake.pdf.REMOVED.git-id deleted file mode 100644 index 4bc832ed..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Stocktake.pdf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e5f96f1846949f825647a83c795817c299d2433d \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Thumbs.db.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Thumbs.db.REMOVED.git-id deleted file mode 100644 index dd6893f6..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Thumbs.db.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -77f95a70cbc044489a95a5c680a84b82fe6efd45 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id deleted file mode 100644 index 35a6d357..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e09dacf33ceb48d4c003412f3c0d3bd529c32419 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id deleted file mode 100644 index 042c73df..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -547cbe458acc4a449a7f52422b033032de9ba013 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id deleted file mode 100644 index beb9b672..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f06301d1e130f3d1006875cb63f50188e004c547 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id deleted file mode 100644 index df8de409..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8df49716c81c07f1619ebdbc10a0a36a1b97b1e4 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id deleted file mode 100644 index b0040f87..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -789865518a9005e67c159fa07c04167f8bfc70ae \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id deleted file mode 100644 index de4a69e1..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -90e691270bfacca88653726e6dd38b17101c3a20 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id deleted file mode 100644 index 09fac0dc..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_0/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4d016dc26b65d19dcb77e6b7725339d6bdc0a041 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/Design Files.zip.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/Design Files.zip.REMOVED.git-id deleted file mode 100644 index 2c0b52f8..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/Design Files.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a9ffa1e0768ba6180c4a9d45962c6addadf6c852 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/GERBER.zip.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/GERBER.zip.REMOVED.git-id deleted file mode 100644 index 1fb38ff4..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/GERBER.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cffc2395f8d06c6ee406bcdd6dcfc6fd58a680ef \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-B.Adhes.pdf.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-B.Adhes.pdf.REMOVED.git-id deleted file mode 100644 index aed4cd99..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-B.Adhes.pdf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c83874239ecefafb0251d52ba62b51d685bf5ffb \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-B.Cu.pdf.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-B.Cu.pdf.REMOVED.git-id deleted file mode 100644 index 5b87aaa0..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-B.Cu.pdf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8a1551f69875ca283bb4d288d5d8b99a8f21b5e9 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-B.SilkS.pdf.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-B.SilkS.pdf.REMOVED.git-id deleted file mode 100644 index 92d8861d..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-B.SilkS.pdf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -31970db214246a23a48f1997d4da69e770864d5d \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-Dwgs.User.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-Dwgs.User.gbr.REMOVED.git-id deleted file mode 100644 index 54c69469..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-Dwgs.User.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -436ea7db266df4b9c4b451b77b2cc3101b01f020 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-Dwgs.User.pdf.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-Dwgs.User.pdf.REMOVED.git-id deleted file mode 100644 index ff28eebe..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-Dwgs.User.pdf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -67d808ff1bebf80a6dcc66c234e4dcbaf1391ef4 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-Edge.Cuts.pdf.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-Edge.Cuts.pdf.REMOVED.git-id deleted file mode 100644 index c2342e34..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-Edge.Cuts.pdf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8c01d32bd63e926408a0945973d77a926d19105f \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-F.Adhes.pdf.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-F.Adhes.pdf.REMOVED.git-id deleted file mode 100644 index dcbdd153..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-F.Adhes.pdf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -61f7e7bedca378847a97c44616fe0224a6e2331c \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-F.Cu.pdf.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-F.Cu.pdf.REMOVED.git-id deleted file mode 100644 index 28f89a00..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-F.Cu.pdf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -94ce64c7098239de34471b0a1b2bb3e8e9ee29d8 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-F.SilkS.pdf.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-F.SilkS.pdf.REMOVED.git-id deleted file mode 100644 index ec57840d..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1-F.SilkS.pdf.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d1fbd13c31ec15e9cb7835d281e0a292f8745482 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1.drl.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index 3e7df5dc..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8681608a9255e3e222979ae19ed362602feb4b29 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id deleted file mode 100644 index df538c41..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -98104b3fe3de9b2a292e9b9f61b7ca74e0e48a56 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id deleted file mode 100644 index 3072e9a3..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b0ab2352ecf55f0968bfb99a0730fd4723c8afc7 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id deleted file mode 100644 index aa76b19e..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -113cf72feea801e311d65f81bb46a0a580246431 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id deleted file mode 100644 index ebae40ba..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b0e19b450e1085c12823d908b20d5c168cfddb39 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id deleted file mode 100644 index a3808dd5..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8316fc58ebf49e13e3f52e545539f4923f71db05 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id deleted file mode 100644 index 2b10ee1d..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -605e820aa7c41e971575160132099d15656ada66 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id deleted file mode 100644 index 282fb51b..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e9809d56ab7a454b85bb48b4614b4977b44afd7b \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1.drl.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index 23805b5c..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_1/gerber/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ec3521a3f8aecaed9eb1da887bf24f3137f03c62 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_2/Gerber.zip.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_2/Gerber.zip.REMOVED.git-id deleted file mode 100644 index 9af3c929..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_2/Gerber.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b629f4c97d60afba9308ef26b4198e08040318ac \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-B.Adhes.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-B.Adhes.gbr.REMOVED.git-id deleted file mode 100644 index 81646362..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-B.Adhes.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8c7fee3c7cc62333afad3f4f5ce42061cafad3e0 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id deleted file mode 100644 index 45dd77f2..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fbcaca1fe4074369d773d91cd16ea399273a1ba0 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id deleted file mode 100644 index 1ad533bb..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -445691536bddc8fa3c3c1919a8cf68b8bbf8b457 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id deleted file mode 100644 index 9aa66f08..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f46c607355eb91ee2d0fd7e34ce26087cc0689d8 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-F.Adhes.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-F.Adhes.gbr.REMOVED.git-id deleted file mode 100644 index f55cb869..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-F.Adhes.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4c76386dd907df1170e6c9b5897e1e5cd0387524 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id deleted file mode 100644 index 88b4dc71..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -308c0940f851af37885cde5241e6b59082753b8c \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id deleted file mode 100644 index c45e5785..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bb27bfef31359a9ff6674be71491f1ce2afa974a \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1.drl.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index f5d81560..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_2/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ecf5c4a3cfe4fa30648ab9637ad4b9e07f6ca24d \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_3/Labrador_Final_B3.zip.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_3/Labrador_Final_B3.zip.REMOVED.git-id deleted file mode 100644 index 7b6fa762..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_3/Labrador_Final_B3.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1e164ae0cfcbbcca659787cf1fd3aeb6f2aaf7da \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_3/Labrador_Final_B3_May8.zip.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_3/Labrador_Final_B3_May8.zip.REMOVED.git-id deleted file mode 100644 index ecd0fb8d..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_3/Labrador_Final_B3_May8.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a3e627bf54cadcfb06e46db2e378aaff4c69be01 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_3/Labrador_Final_B3_May9.zip.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_3/Labrador_Final_B3_May9.zip.REMOVED.git-id deleted file mode 100644 index 429672ea..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_3/Labrador_Final_B3_May9.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -eda66fa8f0af3b44120e440726a5089d9bc62366 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-B.Adhes.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-B.Adhes.gbr.REMOVED.git-id deleted file mode 100644 index 1990a101..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-B.Adhes.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a488ef027919795ddd231cd787a7912b40c46bdd \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id deleted file mode 100644 index 78be1ea4..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c70f40a3fd81b33c7b08e9a148a92174e8ef1aff \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id deleted file mode 100644 index c3794d04..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8ca7362471979f08defec5a6f38a06a121f97514 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id deleted file mode 100644 index c38ca58c..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-B.SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e372b436e5f8d5d469de01ea0487e9012301f757 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-Dwgs.User.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-Dwgs.User.gbr.REMOVED.git-id deleted file mode 100644 index 84bcc24e..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-Dwgs.User.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7160f38e0ef903a89b359587769f20347de9d892 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id deleted file mode 100644 index e9e1972e..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f26e40dd0fb1db1ba4b4845aec6a8ddc29ad4eb6 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-F.Adhes.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-F.Adhes.gbr.REMOVED.git-id deleted file mode 100644 index 87fd4936..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-F.Adhes.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4e5ef37097133e274a4128709df7db85d76b9739 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id deleted file mode 100644 index a35e1413..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d9c5aa17b6221f5918b44816cf949021205f26e3 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id deleted file mode 100644 index b5500fbf..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -18afc3acbadc2d87d3f7ccc99e2182b344e3cc54 \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id deleted file mode 100644 index d0c95c0b..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1835be6efc0b813b2cfbd90fd060557e4f4a9bcd \ No newline at end of file diff --git a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1.drl.REMOVED.git-id b/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index 1f2043e0..00000000 --- a/PCB/LABRADOR_BE_FILES_BATCH_3/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -85047c98917619f6210f500a736cc9f5db7646d8 \ No newline at end of file diff --git a/PCB/Labrador BE-0 with edgecuts.zip.REMOVED.git-id b/PCB/Labrador BE-0 with edgecuts.zip.REMOVED.git-id deleted file mode 100644 index 31534158..00000000 --- a/PCB/Labrador BE-0 with edgecuts.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f548e452f46ca067b89518e856880c29459a6c91 \ No newline at end of file diff --git a/PCB/OUTPUT/OUTPUT.zip.REMOVED.git-id b/PCB/OUTPUT/OUTPUT.zip.REMOVED.git-id deleted file mode 100644 index bc66cff6..00000000 --- a/PCB/OUTPUT/OUTPUT.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e6c8fbfd10af24120c1a375d7a4e8f93ea9626ba \ No newline at end of file diff --git a/PCB/OUTPUT/Tinylab_proto1-B_Cu.gbl.REMOVED.git-id b/PCB/OUTPUT/Tinylab_proto1-B_Cu.gbl.REMOVED.git-id deleted file mode 100644 index a2c975fb..00000000 --- a/PCB/OUTPUT/Tinylab_proto1-B_Cu.gbl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -15866d7591a1716f0dede40f6436e8ed74ce8712 \ No newline at end of file diff --git a/PCB/OUTPUT/Tinylab_proto1-B_Mask.gbs.REMOVED.git-id b/PCB/OUTPUT/Tinylab_proto1-B_Mask.gbs.REMOVED.git-id deleted file mode 100644 index f5516275..00000000 --- a/PCB/OUTPUT/Tinylab_proto1-B_Mask.gbs.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f613d718d77251f83a7d4bb60d17f9387bd5f36d \ No newline at end of file diff --git a/PCB/OUTPUT/Tinylab_proto1-B_SilkS.gbo.REMOVED.git-id b/PCB/OUTPUT/Tinylab_proto1-B_SilkS.gbo.REMOVED.git-id deleted file mode 100644 index 26655c8d..00000000 --- a/PCB/OUTPUT/Tinylab_proto1-B_SilkS.gbo.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8f3574b824a93831060e852cf9b4a810344dacbe \ No newline at end of file diff --git a/PCB/OUTPUT/Tinylab_proto1-Edge_Cuts.gm1.REMOVED.git-id b/PCB/OUTPUT/Tinylab_proto1-Edge_Cuts.gm1.REMOVED.git-id deleted file mode 100644 index 8a61f278..00000000 --- a/PCB/OUTPUT/Tinylab_proto1-Edge_Cuts.gm1.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ecb2ce90257bf421f763111eb63b21e7e59fdc0d \ No newline at end of file diff --git a/PCB/OUTPUT/Tinylab_proto1-F_Cu.gtl.REMOVED.git-id b/PCB/OUTPUT/Tinylab_proto1-F_Cu.gtl.REMOVED.git-id deleted file mode 100644 index cb4b789e..00000000 --- a/PCB/OUTPUT/Tinylab_proto1-F_Cu.gtl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2cc35b67393730e37142ee1fcc3ed23c4710b85a \ No newline at end of file diff --git a/PCB/OUTPUT/Tinylab_proto1-F_Mask.gts.REMOVED.git-id b/PCB/OUTPUT/Tinylab_proto1-F_Mask.gts.REMOVED.git-id deleted file mode 100644 index 4208a296..00000000 --- a/PCB/OUTPUT/Tinylab_proto1-F_Mask.gts.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fdb600b740b4dda6905dfe9e524133eb9e85aea7 \ No newline at end of file diff --git a/PCB/OUTPUT/Tinylab_proto1-F_SilkS.gto.REMOVED.git-id b/PCB/OUTPUT/Tinylab_proto1-F_SilkS.gto.REMOVED.git-id deleted file mode 100644 index e5fa5a3f..00000000 --- a/PCB/OUTPUT/Tinylab_proto1-F_SilkS.gto.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -dd95c16120640feef929829ab291f724138f9614 \ No newline at end of file diff --git a/PCB/OUTPUT/Tinylab_proto1.drl.REMOVED.git-id b/PCB/OUTPUT/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index 215a2711..00000000 --- a/PCB/OUTPUT/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -af50d9a7e039d948581aee2f6b819e10d51eca08 \ No newline at end of file diff --git a/PCB/OUTPUT_V2/OUTPUT.zip.REMOVED.git-id b/PCB/OUTPUT_V2/OUTPUT.zip.REMOVED.git-id deleted file mode 100644 index f0152381..00000000 --- a/PCB/OUTPUT_V2/OUTPUT.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6aa0399cdf9d1aa0a7f9da69c57e9cc5da560410 \ No newline at end of file diff --git a/PCB/OUTPUT_V2/Tinylab_proto1-B_Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V2/Tinylab_proto1-B_Cu.gbr.REMOVED.git-id deleted file mode 100644 index 28c328bc..00000000 --- a/PCB/OUTPUT_V2/Tinylab_proto1-B_Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c5f3e596124ca75d0e5411b2c160106ccaabb31d \ No newline at end of file diff --git a/PCB/OUTPUT_V2/Tinylab_proto1-B_Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V2/Tinylab_proto1-B_Mask.gbr.REMOVED.git-id deleted file mode 100644 index 3b548294..00000000 --- a/PCB/OUTPUT_V2/Tinylab_proto1-B_Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0d3b6ab2a9c2ad6dfabd4e476b82f88598cf8413 \ No newline at end of file diff --git a/PCB/OUTPUT_V2/Tinylab_proto1-B_SilkS.gbr.REMOVED.git-id b/PCB/OUTPUT_V2/Tinylab_proto1-B_SilkS.gbr.REMOVED.git-id deleted file mode 100644 index 79e5b334..00000000 --- a/PCB/OUTPUT_V2/Tinylab_proto1-B_SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -95dc0d04973816b4d386c713bed3839c033f7325 \ No newline at end of file diff --git a/PCB/OUTPUT_V2/Tinylab_proto1-Edge_Cuts.gbr.REMOVED.git-id b/PCB/OUTPUT_V2/Tinylab_proto1-Edge_Cuts.gbr.REMOVED.git-id deleted file mode 100644 index a77d4c93..00000000 --- a/PCB/OUTPUT_V2/Tinylab_proto1-Edge_Cuts.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e027d1e1466e7bd4069e2f483b1dd99f6c70b134 \ No newline at end of file diff --git a/PCB/OUTPUT_V2/Tinylab_proto1-F_Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V2/Tinylab_proto1-F_Cu.gbr.REMOVED.git-id deleted file mode 100644 index 5ce565bb..00000000 --- a/PCB/OUTPUT_V2/Tinylab_proto1-F_Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a7827f1b2047f87c4a745fa96002a4a1a1cb4d57 \ No newline at end of file diff --git a/PCB/OUTPUT_V2/Tinylab_proto1-F_Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V2/Tinylab_proto1-F_Mask.gbr.REMOVED.git-id deleted file mode 100644 index 710eeda3..00000000 --- a/PCB/OUTPUT_V2/Tinylab_proto1-F_Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -15cf453a6dd8bb452a54286e65f5c748ca0fe43d \ No newline at end of file diff --git a/PCB/OUTPUT_V2/Tinylab_proto1-F_SilkS.gbr.REMOVED.git-id b/PCB/OUTPUT_V2/Tinylab_proto1-F_SilkS.gbr.REMOVED.git-id deleted file mode 100644 index 3dcca071..00000000 --- a/PCB/OUTPUT_V2/Tinylab_proto1-F_SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -46c89ff2da7e215e72491aa5b1f2cec95396fafa \ No newline at end of file diff --git a/PCB/OUTPUT_V2/Tinylab_proto1.drl.REMOVED.git-id b/PCB/OUTPUT_V2/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index 1ada6c97..00000000 --- a/PCB/OUTPUT_V2/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -98655d266687708ccec673b3defece00c4fd4863 \ No newline at end of file diff --git a/PCB/OUTPUT_V2/Tinylab_proto1.net.REMOVED.git-id b/PCB/OUTPUT_V2/Tinylab_proto1.net.REMOVED.git-id deleted file mode 100644 index 85aece31..00000000 --- a/PCB/OUTPUT_V2/Tinylab_proto1.net.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d0c1a6c7ba14fd29b2097842349b5f99828b2ded \ No newline at end of file diff --git a/PCB/OUTPUT_V3/OUTPUT_V3.zip.REMOVED.git-id b/PCB/OUTPUT_V3/OUTPUT_V3.zip.REMOVED.git-id deleted file mode 100644 index f8bae037..00000000 --- a/PCB/OUTPUT_V3/OUTPUT_V3.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0979e69b8edd27abad4268964511047bc75212fe \ No newline at end of file diff --git a/PCB/OUTPUT_V3/Tinylab_proto1-B_Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V3/Tinylab_proto1-B_Cu.gbr.REMOVED.git-id deleted file mode 100644 index 8849f152..00000000 --- a/PCB/OUTPUT_V3/Tinylab_proto1-B_Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bd5d0fbde0635e052609ddc6292a3f21fecb883d \ No newline at end of file diff --git a/PCB/OUTPUT_V3/Tinylab_proto1-B_Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V3/Tinylab_proto1-B_Mask.gbr.REMOVED.git-id deleted file mode 100644 index 1c0ac5f8..00000000 --- a/PCB/OUTPUT_V3/Tinylab_proto1-B_Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -db03c737aec8da4805d8ed571e329faff4a83b22 \ No newline at end of file diff --git a/PCB/OUTPUT_V3/Tinylab_proto1-Edge_Cuts.gbr.REMOVED.git-id b/PCB/OUTPUT_V3/Tinylab_proto1-Edge_Cuts.gbr.REMOVED.git-id deleted file mode 100644 index af3a5b74..00000000 --- a/PCB/OUTPUT_V3/Tinylab_proto1-Edge_Cuts.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -25d22b74ead79eb22b1ad01e600920c42aca5b06 \ No newline at end of file diff --git a/PCB/OUTPUT_V3/Tinylab_proto1-F_Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V3/Tinylab_proto1-F_Cu.gbr.REMOVED.git-id deleted file mode 100644 index 89d6e6e7..00000000 --- a/PCB/OUTPUT_V3/Tinylab_proto1-F_Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -228f9d089aa50b17fe430bbd8643cbe035393a4f \ No newline at end of file diff --git a/PCB/OUTPUT_V3/Tinylab_proto1-F_Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V3/Tinylab_proto1-F_Mask.gbr.REMOVED.git-id deleted file mode 100644 index f42ee2a9..00000000 --- a/PCB/OUTPUT_V3/Tinylab_proto1-F_Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -011397c1810852c8cb93392c56b12f8fab156c67 \ No newline at end of file diff --git a/PCB/OUTPUT_V3/Tinylab_proto1.drl.REMOVED.git-id b/PCB/OUTPUT_V3/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index 5d53f039..00000000 --- a/PCB/OUTPUT_V3/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2c0f4e5644003bbb74f45e257035fc6d3dcacbef \ No newline at end of file diff --git a/PCB/OUTPUT_V35/Tinylab_proto1-B_Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V35/Tinylab_proto1-B_Cu.gbr.REMOVED.git-id deleted file mode 100644 index 214cefe9..00000000 --- a/PCB/OUTPUT_V35/Tinylab_proto1-B_Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d89619c356a8a18228262828dba400950207e5f1 \ No newline at end of file diff --git a/PCB/OUTPUT_V35/Tinylab_proto1-B_Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V35/Tinylab_proto1-B_Mask.gbr.REMOVED.git-id deleted file mode 100644 index 3658c21d..00000000 --- a/PCB/OUTPUT_V35/Tinylab_proto1-B_Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -dc8815dd4392551501bc4f6a70c16a7cd5649e53 \ No newline at end of file diff --git a/PCB/OUTPUT_V35/Tinylab_proto1-Edge_Cuts.gbr.REMOVED.git-id b/PCB/OUTPUT_V35/Tinylab_proto1-Edge_Cuts.gbr.REMOVED.git-id deleted file mode 100644 index d8a55f9a..00000000 --- a/PCB/OUTPUT_V35/Tinylab_proto1-Edge_Cuts.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -59d9d01d5c8391bb756e55ba903534be79be5542 \ No newline at end of file diff --git a/PCB/OUTPUT_V35/Tinylab_proto1-F_Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V35/Tinylab_proto1-F_Cu.gbr.REMOVED.git-id deleted file mode 100644 index 9e128a16..00000000 --- a/PCB/OUTPUT_V35/Tinylab_proto1-F_Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e07fb7e31b6b49b0b1322813bf247c8afcf2a1eb \ No newline at end of file diff --git a/PCB/OUTPUT_V35/Tinylab_proto1-F_Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V35/Tinylab_proto1-F_Mask.gbr.REMOVED.git-id deleted file mode 100644 index f40c0765..00000000 --- a/PCB/OUTPUT_V35/Tinylab_proto1-F_Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f88be37e025f686d31c5f1a9c84074217167a9a5 \ No newline at end of file diff --git a/PCB/OUTPUT_V35/Tinylab_proto1.kicad_pcb-bak.REMOVED.git-id b/PCB/OUTPUT_V35/Tinylab_proto1.kicad_pcb-bak.REMOVED.git-id deleted file mode 100644 index 453df3c7..00000000 --- a/PCB/OUTPUT_V35/Tinylab_proto1.kicad_pcb-bak.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -be9f547ddaddf1bc32e3f034f6dda88ac9d13831 \ No newline at end of file diff --git a/PCB/OUTPUT_V35/Tinylab_proto1.kicad_pcb.REMOVED.git-id b/PCB/OUTPUT_V35/Tinylab_proto1.kicad_pcb.REMOVED.git-id deleted file mode 100644 index 23703689..00000000 --- a/PCB/OUTPUT_V35/Tinylab_proto1.kicad_pcb.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -accffff3b289208ce314b8e62b3d9050fef6b24c \ No newline at end of file diff --git a/PCB/OUTPUT_V35/Tinylab_proto1.net.REMOVED.git-id b/PCB/OUTPUT_V35/Tinylab_proto1.net.REMOVED.git-id deleted file mode 100644 index d17deb7f..00000000 --- a/PCB/OUTPUT_V35/Tinylab_proto1.net.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4338050991688cfcdaed3efa6c6136254ed3bd05 \ No newline at end of file diff --git a/PCB/OUTPUT_V35/Tinylab_proto1.pro.REMOVED.git-id b/PCB/OUTPUT_V35/Tinylab_proto1.pro.REMOVED.git-id deleted file mode 100644 index 21c33553..00000000 --- a/PCB/OUTPUT_V35/Tinylab_proto1.pro.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -804cf83d727f34d041e3710ef0c94734008208ff \ No newline at end of file diff --git a/PCB/OUTPUT_V4/BOM/Tinylab_proto1.csv.REMOVED.git-id b/PCB/OUTPUT_V4/BOM/Tinylab_proto1.csv.REMOVED.git-id deleted file mode 100644 index 15e93a5a..00000000 --- a/PCB/OUTPUT_V4/BOM/Tinylab_proto1.csv.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -25b71349dd0f4ba8c7d10d67d955f143d59bdcf3 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/BOM/Tinylab_proto1_Elecrow.csv.REMOVED.git-id b/PCB/OUTPUT_V4/BOM/Tinylab_proto1_Elecrow.csv.REMOVED.git-id deleted file mode 100644 index 8d329c81..00000000 --- a/PCB/OUTPUT_V4/BOM/Tinylab_proto1_Elecrow.csv.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1b80aa2ea1437655e6188befaea1626da98510c6 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/Drill/Tinylab_proto1.drl.REMOVED.git-id b/PCB/OUTPUT_V4/Drill/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index 73c03630..00000000 --- a/PCB/OUTPUT_V4/Drill/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -dab9c8e95ff76ba6a9c189236890d5b57008898d \ No newline at end of file diff --git a/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id deleted file mode 100644 index d96bf392..00000000 --- a/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -81a7e9061057e2d0993e4ac8e8d88569e02e8c79 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id deleted file mode 100644 index ae12acdb..00000000 --- a/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3630af90032efd06143c4f5bc3094170188fc70e \ No newline at end of file diff --git a/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id deleted file mode 100644 index 545c3068..00000000 --- a/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6a8dc7fe585fd3c52edb7e228016672b34ed04d0 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id deleted file mode 100644 index bf36f341..00000000 --- a/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -741a10d6914c13d5bb1c68759cb0a976cccbba5d \ No newline at end of file diff --git a/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id deleted file mode 100644 index 3b6e16b7..00000000 --- a/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1c0c548306612af5529d83841933f540d231e6e4 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id deleted file mode 100644 index bae99f31..00000000 --- a/PCB/OUTPUT_V4/Gerber/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -307bf8804c76ba11680f2b96940c470393c91eec \ No newline at end of file diff --git a/PCB/OUTPUT_V4/OUTPUT_V4.zip.REMOVED.git-id b/PCB/OUTPUT_V4/OUTPUT_V4.zip.REMOVED.git-id deleted file mode 100644 index 56d257d4..00000000 --- a/PCB/OUTPUT_V4/OUTPUT_V4.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8e2a84d505057436e8b372599093a07c250e6700 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/Tinylab_proto1.net.REMOVED.git-id b/PCB/OUTPUT_V4/Tinylab_proto1.net.REMOVED.git-id deleted file mode 100644 index 52a538f2..00000000 --- a/PCB/OUTPUT_V4/Tinylab_proto1.net.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -be518cf1cccfde9283d29a8af72a97b2f4722885 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/itead/ITEAD.zip.REMOVED.git-id b/PCB/OUTPUT_V4/itead/ITEAD.zip.REMOVED.git-id deleted file mode 100644 index 4df244c1..00000000 --- a/PCB/OUTPUT_V4/itead/ITEAD.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -20d62a6b94230790fe8efa95849bd3bf8cb1834c \ No newline at end of file diff --git a/PCB/OUTPUT_V4/itead/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/itead/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id deleted file mode 100644 index 4876ea79..00000000 --- a/PCB/OUTPUT_V4/itead/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4db900d53edf566570002667ddcaa1d1ec54043c \ No newline at end of file diff --git a/PCB/OUTPUT_V4/itead/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/itead/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id deleted file mode 100644 index 00fc371f..00000000 --- a/PCB/OUTPUT_V4/itead/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e4bb5dcccdea9aea84958d3d124b094e8c924adf \ No newline at end of file diff --git a/PCB/OUTPUT_V4/itead/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/itead/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id deleted file mode 100644 index c8649eab..00000000 --- a/PCB/OUTPUT_V4/itead/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5f0024ea4fec6c26a8dfdfddbfbd6a16a079ab63 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/itead/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/itead/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id deleted file mode 100644 index 9f3d7f2b..00000000 --- a/PCB/OUTPUT_V4/itead/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cb3b5d51d8360693adf37edf65c649b758b05208 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/itead/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/itead/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id deleted file mode 100644 index 47eea826..00000000 --- a/PCB/OUTPUT_V4/itead/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aef2a73926cacf3573d13a280765a7615324448d \ No newline at end of file diff --git a/PCB/OUTPUT_V4/itead/Tinylab_proto1.drl.REMOVED.git-id b/PCB/OUTPUT_V4/itead/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index 20195270..00000000 --- a/PCB/OUTPUT_V4/itead/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aca0c51008a7395491d979fc44f3587547aac699 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/seeeed/BOM/Seeed BOM Format.ods.REMOVED.git-id b/PCB/OUTPUT_V4/seeeed/BOM/Seeed BOM Format.ods.REMOVED.git-id deleted file mode 100644 index 37898b82..00000000 --- a/PCB/OUTPUT_V4/seeeed/BOM/Seeed BOM Format.ods.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5cd5afc257be9204167304a13255cf7597101e28 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/seeeed/BOM/Seeed BOM Format.xls.REMOVED.git-id b/PCB/OUTPUT_V4/seeeed/BOM/Seeed BOM Format.xls.REMOVED.git-id deleted file mode 100644 index 0323ac55..00000000 --- a/PCB/OUTPUT_V4/seeeed/BOM/Seeed BOM Format.xls.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c76c5a6a2107f49b637168836d78cb7972f1ae59 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/seeeed/BOM/Thumbs.db.REMOVED.git-id b/PCB/OUTPUT_V4/seeeed/BOM/Thumbs.db.REMOVED.git-id deleted file mode 100644 index 2efb0f43..00000000 --- a/PCB/OUTPUT_V4/seeeed/BOM/Thumbs.db.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5c1834e0ab5546eed579477d6df93c873a95ec77 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id deleted file mode 100644 index 4876ea79..00000000 --- a/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4db900d53edf566570002667ddcaa1d1ec54043c \ No newline at end of file diff --git a/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id deleted file mode 100644 index 00fc371f..00000000 --- a/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e4bb5dcccdea9aea84958d3d124b094e8c924adf \ No newline at end of file diff --git a/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id deleted file mode 100644 index c8649eab..00000000 --- a/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5f0024ea4fec6c26a8dfdfddbfbd6a16a079ab63 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id deleted file mode 100644 index 9f3d7f2b..00000000 --- a/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cb3b5d51d8360693adf37edf65c649b758b05208 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id deleted file mode 100644 index 47eea826..00000000 --- a/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aef2a73926cacf3573d13a280765a7615324448d \ No newline at end of file diff --git a/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1.drl.REMOVED.git-id b/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index 20195270..00000000 --- a/PCB/OUTPUT_V4/seeeed/Gerber + Drill/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -aca0c51008a7395491d979fc44f3587547aac699 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/seeeed/Requirement/PCB Requirement Format.ods.REMOVED.git-id b/PCB/OUTPUT_V4/seeeed/Requirement/PCB Requirement Format.ods.REMOVED.git-id deleted file mode 100644 index d9ec7142..00000000 --- a/PCB/OUTPUT_V4/seeeed/Requirement/PCB Requirement Format.ods.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8f12549742465a5e7c71d383c8ac1d7b7a185ab8 \ No newline at end of file diff --git a/PCB/OUTPUT_V4/seeeed/Requirement/PCB Requirement Format.xls.REMOVED.git-id b/PCB/OUTPUT_V4/seeeed/Requirement/PCB Requirement Format.xls.REMOVED.git-id deleted file mode 100644 index 65acdb57..00000000 --- a/PCB/OUTPUT_V4/seeeed/Requirement/PCB Requirement Format.xls.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cd7b955d903bbf729ca7705a3235b5f59a9a8a8d \ No newline at end of file diff --git a/PCB/OUTPUT_V4/seeeed/seeed.zip.REMOVED.git-id b/PCB/OUTPUT_V4/seeeed/seeed.zip.REMOVED.git-id deleted file mode 100644 index d597d07b..00000000 --- a/PCB/OUTPUT_V4/seeeed/seeed.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9ab9a33e57db4c1304abf0777756d6dac9fd89ba \ No newline at end of file diff --git a/PCB/OUTPUT_V5/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V5/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id deleted file mode 100644 index 81214eab..00000000 --- a/PCB/OUTPUT_V5/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d3a5e0d87759cebcfbb4a181a4873e894954824d \ No newline at end of file diff --git a/PCB/OUTPUT_V5/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V5/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id deleted file mode 100644 index cb8bd92e..00000000 --- a/PCB/OUTPUT_V5/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -eff69fdb02f0ec7d95c0d32dbacd00c44891708d \ No newline at end of file diff --git a/PCB/OUTPUT_V5/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id b/PCB/OUTPUT_V5/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id deleted file mode 100644 index 47fb03a2..00000000 --- a/PCB/OUTPUT_V5/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4f2217b9b3ce91ebd669e8431ff30aeee8684e3c \ No newline at end of file diff --git a/PCB/OUTPUT_V5/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V5/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id deleted file mode 100644 index 198805de..00000000 --- a/PCB/OUTPUT_V5/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -205e1d87e2d9d6bf35a89f9240c33b5a65bbd8cf \ No newline at end of file diff --git a/PCB/OUTPUT_V5/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V5/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id deleted file mode 100644 index 1e274c3a..00000000 --- a/PCB/OUTPUT_V5/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -36c5d2205ab3d7e02c9f41faa06cac84ad2cfda8 \ No newline at end of file diff --git a/PCB/OUTPUT_V5/Tinylab_proto1.drl.REMOVED.git-id b/PCB/OUTPUT_V5/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index fbf21114..00000000 --- a/PCB/OUTPUT_V5/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2f07979546d188a4a3d4be9c4b5b11f8d45bf02c \ No newline at end of file diff --git a/PCB/OUTPUT_V6/OUTPUT_V6.zip.REMOVED.git-id b/PCB/OUTPUT_V6/OUTPUT_V6.zip.REMOVED.git-id deleted file mode 100644 index fedb289a..00000000 --- a/PCB/OUTPUT_V6/OUTPUT_V6.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b523e66a36b429ed290da947c9b849e9943b6214 \ No newline at end of file diff --git a/PCB/OUTPUT_V6/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V6/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id deleted file mode 100644 index 1c4164bc..00000000 --- a/PCB/OUTPUT_V6/Tinylab_proto1-B.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bed2332c4dc37cdb9eec37974a73f71e77bef459 \ No newline at end of file diff --git a/PCB/OUTPUT_V6/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V6/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id deleted file mode 100644 index a3e75480..00000000 --- a/PCB/OUTPUT_V6/Tinylab_proto1-B.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -73d76489262c0e4c8b3b7406e439d0011da20e12 \ No newline at end of file diff --git a/PCB/OUTPUT_V6/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id b/PCB/OUTPUT_V6/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id deleted file mode 100644 index 152787c5..00000000 --- a/PCB/OUTPUT_V6/Tinylab_proto1-Edge.Cuts.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -38b6afcdb360d351d247ccafdda12272aeb9433d \ No newline at end of file diff --git a/PCB/OUTPUT_V6/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id b/PCB/OUTPUT_V6/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id deleted file mode 100644 index 8b7f36a7..00000000 --- a/PCB/OUTPUT_V6/Tinylab_proto1-F.Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -883cc6c73d796e1acc4d7094c0538d145ec7eaa8 \ No newline at end of file diff --git a/PCB/OUTPUT_V6/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id b/PCB/OUTPUT_V6/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id deleted file mode 100644 index 32e9f5fb..00000000 --- a/PCB/OUTPUT_V6/Tinylab_proto1-F.Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -dda7c769a77ac0aa2bc9bdf46ad2865ea8af5e4e \ No newline at end of file diff --git a/PCB/OUTPUT_V6/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id b/PCB/OUTPUT_V6/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id deleted file mode 100644 index 30c23a2f..00000000 --- a/PCB/OUTPUT_V6/Tinylab_proto1-F.SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -454ead64354443364ec0554eb0afc4a7d39cf6df \ No newline at end of file diff --git a/PCB/OUTPUT_V6/Tinylab_proto1.drl.REMOVED.git-id b/PCB/OUTPUT_V6/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index a284b7b1..00000000 --- a/PCB/OUTPUT_V6/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -efcda5cc8f28e45949868229459e512b6d50ba7c \ No newline at end of file diff --git a/PCB/PinNames.PNG.REMOVED.git-id b/PCB/PinNames.PNG.REMOVED.git-id deleted file mode 100644 index 0e1051f9..00000000 --- a/PCB/PinNames.PNG.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cd5980d0d214e2bb7aa2a24fee1b153be9ea248e \ No newline at end of file diff --git a/PCB/Special_inductor.pretty/SELF-WE-PD-XXL.kicad_mod b/PCB/Special_inductor.pretty/SELF-WE-PD-XXL.kicad_mod new file mode 100644 index 00000000..2162333d --- /dev/null +++ b/PCB/Special_inductor.pretty/SELF-WE-PD-XXL.kicad_mod @@ -0,0 +1,33 @@ +(module Inductors:SELF-WE-PD-XXL (layer F.Cu) (tedit 58801755) + (descr "SELF- WE-PD-XXL") + (attr smd) + (fp_text reference L1 (at -1.69926 0.09906 90) (layer Dwgs.User) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value INDUCTOR (at 1.80086 0 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_circle (center 0 0) (end 0 -5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.99948 0) (end -5.99948 -5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.99948 -5.00126) (end -5.00126 -5.99948) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.00126 -5.99948) (end 5.00126 -5.99948) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.00126 -5.99948) (end 5.99948 -5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.99948 -5.00126) (end 5.99948 5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.99948 5.00126) (end 5.00126 5.99948) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.00126 5.99948) (end -5.00126 5.99948) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.00126 5.99948) (end -5.99948 5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.99948 5.00126) (end -5.99948 0) (layer Dwgs.User) (width 0.15)) + (fp_text user "" (at 0 0) (layer Dwgs.User) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text user "" (at 0 0) (layer Dwgs.User) + (effects (font (size 1 1) (thickness 0.15))) + ) + (pad 1 smd rect (at -5.00126 0) (size 2.90068 5.40004) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at 2.500126 0) (size 7.90068 5.40004) (layers F.Cu F.Paste F.Mask)) + (model Inductors.3dshapes/SELF-WE-PD-XXL.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/Special_inductor.pretty/SELF-WE-PD-XXL.kicad_mod.REMOVED.git-id b/PCB/Special_inductor.pretty/SELF-WE-PD-XXL.kicad_mod.REMOVED.git-id deleted file mode 100644 index 1519e8fd..00000000 --- a/PCB/Special_inductor.pretty/SELF-WE-PD-XXL.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2162333d7cab7c1448ef23bc1f5f84d5691f165e \ No newline at end of file diff --git a/PCB/Special_inductor.pretty/SMALL_INDUCTOR.kicad_mod b/PCB/Special_inductor.pretty/SMALL_INDUCTOR.kicad_mod new file mode 100644 index 00000000..716ded11 --- /dev/null +++ b/PCB/Special_inductor.pretty/SMALL_INDUCTOR.kicad_mod @@ -0,0 +1,33 @@ +(module SMALL_INDUCTOR (layer F.Cu) (tedit 58F57C0A) + (descr "SELF- WE-PD-XXL") + (attr smd) + (fp_text reference L1 (at -0.0127 -0.2032 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value INDUCTOR (at 1.80086 0 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_circle (center 0 0) (end 0 -5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.99948 0) (end -5.99948 -5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.99948 -5.00126) (end -5.00126 -5.99948) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.00126 -5.99948) (end 5.00126 -5.99948) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.00126 -5.99948) (end 5.99948 -5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.99948 -5.00126) (end 5.99948 5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.99948 5.00126) (end 5.00126 5.99948) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.00126 5.99948) (end -5.00126 5.99948) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.00126 5.99948) (end -5.99948 5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.99948 5.00126) (end -5.99948 0) (layer Dwgs.User) (width 0.15)) + (fp_text user "" (at 0 0) (layer Dwgs.User) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text user "" (at 0 0) (layer Dwgs.User) + (effects (font (size 1 1) (thickness 0.15))) + ) + (pad 1 smd rect (at -5.00126 0) (size 2.90068 5.40004) (layers F.Cu F.Paste F.Mask)) + (pad 2 smd rect (at 0.08 0) (size 2.9 5.40004) (layers F.Cu F.Paste F.Mask)) + (model Inductors.3dshapes/SELF-WE-PD-XXL.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) +) diff --git a/PCB/Special_inductor.pretty/SMALL_INDUCTOR.kicad_mod.REMOVED.git-id b/PCB/Special_inductor.pretty/SMALL_INDUCTOR.kicad_mod.REMOVED.git-id deleted file mode 100644 index d6836119..00000000 --- a/PCB/Special_inductor.pretty/SMALL_INDUCTOR.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -716ded118c0c4ccf178cabdfb6281b6fc4d4caea \ No newline at end of file diff --git a/PCB/Thumbs.db b/PCB/Thumbs.db new file mode 100644 index 00000000..a28c52a3 Binary files /dev/null and b/PCB/Thumbs.db differ diff --git a/PCB/Thumbs.db.REMOVED.git-id b/PCB/Thumbs.db.REMOVED.git-id deleted file mode 100644 index 73917863..00000000 --- a/PCB/Thumbs.db.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -a28c52a31065db90f62b16efbe1aa8b330c62f41 \ No newline at end of file diff --git a/PCB/Tinylab_proto1-cache.lib b/PCB/Tinylab_proto1-cache.lib new file mode 100644 index 00000000..58805470 --- /dev/null +++ b/PCB/Tinylab_proto1-cache.lib @@ -0,0 +1,474 @@ +EESchema-LIBRARY Version 2.3 +#encoding utf-8 +# +# +5V +# +DEF +5V #PWR 0 0 Y Y 1 F P +F0 "#PWR" 0 -150 50 H I C CNN +F1 "+5V" 0 140 50 H V C CNN +F2 "" 0 0 50 H V C CNN +F3 "" 0 0 50 H V C CNN +DRAW +P 2 0 1 0 -30 50 0 100 N +P 2 0 1 0 0 0 0 100 N +P 2 0 1 0 0 100 30 50 N +X +5V 1 0 0 0 U 50 50 1 1 W N +ENDDRAW +ENDDEF +# +# 78L05-RESCUE-Tinylab_proto1 +# +DEF 78L05-RESCUE-Tinylab_proto1 U 0 30 N Y 1 F N +F0 "U" 150 -196 60 H V C CNN +F1 "78L05-RESCUE-Tinylab_proto1" 0 200 60 H V C CNN +F2 "" 0 0 60 H V C CNN +F3 "" 0 0 60 H V C CNN +DRAW +S -200 -150 200 150 0 1 0 N +X GND 1 0 -250 100 U 40 40 1 1 I +X VO 2 400 50 200 L 40 40 1 1 w +X VI 3 -400 50 200 R 40 40 1 1 I +ENDDRAW +ENDDEF +# +# ATXMEGA16A4U-A +# +DEF ATXMEGA16A4U-A IC 0 40 Y Y 1 F N +F0 "IC" -750 1200 50 H V L BNN +F1 "ATXMEGA16A4U-A" 350 -1250 50 H V L BNN +F2 "TQFP44" 0 0 50 H V C CIN +F3 "" 0 0 50 H V C CNN +ALIAS ATXMEGA32A4U-A ATXMEGA64A4U-A ATXMEGA128A4U-A +DRAW +S -750 1150 750 -1150 0 1 10 f +X AC5/ADC5/PA5 1 900 500 150 L 40 35 1 1 B +X AC1OUT/AC6/ADC6/PA6 2 900 400 150 L 40 35 1 1 B +X AC0OUT/AC7/ADC7/PA7 3 900 300 150 L 40 35 1 1 B +X AREFB/ADC8/PB0 4 900 150 150 L 40 35 1 1 B +X ADC9/PB1 5 900 50 150 L 40 35 1 1 B +X DAC0/ADC10/PB2 6 900 -50 150 L 40 35 1 1 B +X DAC1/ACD11/PB3 7 900 -150 150 L 40 35 1 1 B +X GND 8 -150 -1300 150 U 40 35 1 1 W +X VCC 9 -100 1300 150 D 40 35 1 1 W +X SDAIN/SDA/~OC0ALS~/OC0A/PC0 10 900 -300 150 L 40 35 1 1 B +X PD0/OC0A 20 -900 -300 150 R 40 35 1 1 B +X GND 30 50 -1300 150 U 40 35 1 1 W +X AREFA/AC0/ADC0/PA0 40 900 1000 150 L 40 35 1 1 B +X SCLIN/SCL/XCK0/OC0AHS/OC0B/PC1 11 900 -400 150 L 40 35 1 1 B +X PD1/OC0B/XCK0 21 -900 -400 150 R 40 35 1 1 B +X VCC 31 100 1300 150 D 40 35 1 1 W +X AC1/ADC1/PA1 41 900 900 150 L 40 35 1 1 B +X SDAOUT/RXD0/~OC0BLS~/OC0C/PC2 12 900 -500 150 L 40 35 1 1 B +X PD2/OC0C/RXD0 22 -900 -500 150 R 40 35 1 1 B +X PE2/OC0C/RXD0 32 -900 -50 150 R 40 35 1 1 B +X AC2/ADC2/PA2 42 900 800 150 L 40 35 1 1 B +X SCLOUT/TXD0/OC0BHS/OC0D/PC3 13 900 -600 150 L 40 35 1 1 B +X PD3/OC0D/TXD0 23 -900 -600 150 R 40 35 1 1 B +X PE3/OC0D/TXD0 33 -900 -150 150 R 40 35 1 1 B +X AC3/ADC3/PA3 43 900 700 150 L 40 35 1 1 B +X ~SS~/~OC0CLS~/OC1A/PC4 14 900 -700 150 L 40 35 1 1 B +X PD4/OC1A/~SS~ 24 -900 -700 150 R 40 35 1 1 B +X PDI_DATA 34 -900 900 150 R 40 35 1 1 I +X AC4/ADC4/PA4 44 900 600 150 L 40 35 1 1 B +X MOSI/XCK1/OC0CHS/OC1B/PC5 15 900 -800 150 L 40 35 1 1 B +X PD5/OC1B/XCK1/MOSI 25 -900 -800 150 R 40 35 1 1 B +X ~RESET~/PDI_CLK 35 -900 1000 150 R 40 35 1 1 I +X CLKRTC/MISO/RXD1/~OC0DLS~/PC6 16 900 -900 150 L 40 35 1 1 B +X PD6/D-/RXD1/MISO 26 -900 -900 150 R 40 35 1 1 B +X PR0/XTAL2/TOSC2 36 -900 400 150 R 40 35 1 1 B +X EVOUT/CLKOUT/SCK/TXD1/OC0DHS/PC7 17 900 -1000 150 L 40 35 1 1 B +X PD7/D+/TXD1/SCK/CLKOUT/EVOUT 27 -900 -1000 150 R 40 35 1 1 B +X PR1/XTAL1/TOSC1 37 -900 300 150 R 40 35 1 1 B +X GND 18 -50 -1300 150 U 40 35 1 1 W +X PE0/OC0A/SDA 28 -900 150 150 R 40 35 1 1 B +X GND 38 150 -1300 150 U 40 35 1 1 W +X VCC 19 0 1300 150 D 40 35 1 1 W +X PE1/OC0B/XCK0/SCL 29 -900 50 150 R 40 35 1 1 B +X AVCC 39 300 1300 150 D 40 35 1 1 W +ENDDRAW +ENDDEF +# +# C +# +DEF C C 0 10 N Y 1 F N +F0 "C" 25 100 50 H V L CNN +F1 "C" 25 -100 50 H V L CNN +F2 "" 38 -150 50 H V C CNN +F3 "" 0 0 50 H V C CNN +$FPLIST + C? + C_????_* + C_???? + SMD*_c + Capacitor* +$ENDFPLIST +DRAW +P 2 0 1 20 -80 -30 80 -30 N +P 2 0 1 20 -80 30 80 30 N +X ~ 1 0 150 110 D 40 40 1 1 P +X ~ 2 0 -150 110 U 40 40 1 1 P +ENDDRAW +ENDDEF +# +# CONN_01X02 +# +DEF CONN_01X02 P 0 40 Y N 1 F N +F0 "P" 0 150 50 H V C CNN +F1 "CONN_01X02" 100 0 50 V V C CNN +F2 "" 0 0 50 H V C CNN +F3 "" 0 0 50 H V C CNN +$FPLIST + Pin_Header_Straight_1X02 + Pin_Header_Angled_1X02 + Socket_Strip_Straight_1X02 + Socket_Strip_Angled_1X02 +$ENDFPLIST +DRAW +S -50 -45 10 -55 0 1 0 N +S -50 55 10 45 0 1 0 N +S -50 100 50 -100 0 1 0 N +X P1 1 -200 50 150 R 50 50 1 1 P +X P2 2 -200 -50 150 R 50 50 1 1 P +ENDDRAW +ENDDEF +# +# CONN_01X03 +# +DEF CONN_01X03 P 0 40 Y N 1 F N +F0 "P" 0 200 50 H V C CNN +F1 "CONN_01X03" 100 0 50 V V C CNN +F2 "" 0 0 50 H V C CNN +F3 "" 0 0 50 H V C CNN +$FPLIST + Pin_Header_Straight_1X03 + Pin_Header_Angled_1X03 + Socket_Strip_Straight_1X03 + Socket_Strip_Angled_1X03 +$ENDFPLIST +DRAW +S -50 -95 10 -105 0 1 0 N +S -50 5 10 -5 0 1 0 N +S -50 105 10 95 0 1 0 N +S -50 150 50 -150 0 1 0 N +X P1 1 -200 100 150 R 50 50 1 1 P +X P2 2 -200 0 150 R 50 50 1 1 P +X P3 3 -200 -100 150 R 50 50 1 1 P +ENDDRAW +ENDDEF +# +# CONN_01X04 +# +DEF CONN_01X04 P 0 40 Y N 1 F N +F0 "P" 0 250 50 H V C CNN +F1 "CONN_01X04" 100 0 50 V V C CNN +F2 "" 0 0 50 H V C CNN +F3 "" 0 0 50 H V C CNN +$FPLIST + Pin_Header_Straight_1X04 + Pin_Header_Angled_1X04 + Socket_Strip_Straight_1X04 + Socket_Strip_Angled_1X04 +$ENDFPLIST +DRAW +S -50 -145 10 -155 0 1 0 N +S -50 -45 10 -55 0 1 0 N +S -50 55 10 45 0 1 0 N +S -50 155 10 145 0 1 0 N +S -50 200 50 -200 0 1 0 N +X P1 1 -200 150 150 R 50 50 1 1 P +X P2 2 -200 50 150 R 50 50 1 1 P +X P3 3 -200 -50 150 R 50 50 1 1 P +X P4 4 -200 -150 150 R 50 50 1 1 P +ENDDRAW +ENDDEF +# +# CONN_02X02 +# +DEF CONN_02X02 P 0 1 Y N 1 F N +F0 "P" 0 150 50 H V C CNN +F1 "CONN_02X02" 0 -150 50 H V C CNN +F2 "" 0 -1200 50 H V C CNN +F3 "" 0 -1200 50 H V C CNN +$FPLIST + Pin_Header_Straight_2X02 + Pin_Header_Angled_2X02 + Socket_Strip_Straight_2X02 + Socket_Strip_Angled_2X02 +$ENDFPLIST +DRAW +S -100 -45 -50 -55 0 1 0 N +S -100 55 -50 45 0 1 0 N +S -100 100 100 -100 0 1 0 N +S 50 -45 100 -55 0 1 0 N +S 50 55 100 45 0 1 0 N +X P1 1 -250 50 150 R 50 50 1 1 P +X P2 2 250 50 150 L 50 50 1 1 P +X P3 3 -250 -50 150 R 50 50 1 1 P +X P4 4 250 -50 150 L 50 50 1 1 P +ENDDRAW +ENDDEF +# +# CP1 +# +DEF CP1 C 0 10 N N 1 F N +F0 "C" 25 100 50 H V L CNN +F1 "CP1" 25 -100 50 H V L CNN +F2 "" 0 0 50 H V C CNN +F3 "" 0 0 50 H V C CNN +$FPLIST + SMD*_Pol + C_Axial* + C_Radial* + c_elec* + C*elec + TantalC* + CP* +$ENDFPLIST +DRAW +A 0 -150 128 1287 513 0 1 20 N -80 -50 80 -50 +P 2 0 1 20 -80 30 80 30 N +P 2 0 1 0 -70 90 -30 90 N +P 2 0 1 0 -50 70 -50 110 N +X ~ 1 0 150 110 D 40 40 1 1 P +X ~ 2 0 -150 130 U 40 40 1 1 P +ENDDRAW +ENDDEF +# +# C_Small +# +DEF C_Small C 0 10 N N 1 F N +F0 "C" 10 70 50 H V L CNN +F1 "C_Small" 10 -80 50 H V L CNN +F2 "" 0 0 50 H V C CNN +F3 "" 0 0 50 H V C CNN +$FPLIST + C? + C_????_* + C_???? + SMD*_c + Capacitor* +$ENDFPLIST +DRAW +P 2 0 1 13 -60 -20 60 -20 N +P 2 0 1 12 -60 20 60 20 N +X ~ 1 0 100 75 D 40 40 1 1 P +X ~ 2 0 -100 80 U 40 40 1 1 P +ENDDRAW +ENDDEF +# +# DMN63D8LDW +# +DEF DMN63D8LDW U 0 40 Y Y 1 F N +F0 "U" 0 -300 60 H V C CNN +F1 "DMN63D8LDW" 0 350 60 H V C CNN +F2 "" 0 -300 60 H V C CNN +F3 "" 0 -300 60 H V C CNN +DRAW +S -250 300 250 -350 0 1 0 f +X S1 1 450 -150 200 L 50 50 1 1 I +X G1 2 450 0 200 L 50 50 1 1 I +X D2 3 450 150 200 L 50 50 1 1 I +X S2 4 -450 150 200 R 50 50 1 1 I +X G2 5 -450 0 200 R 50 50 1 1 I +X D1 6 -450 -150 200 R 50 50 1 1 I +ENDDRAW +ENDDEF +# +# D_Schottky +# +DEF D_Schottky D 0 40 N N 1 F N +F0 "D" 0 100 50 H V C CNN +F1 "D_Schottky" 0 -100 50 H V C CNN +F2 "" 0 0 50 H V C CNN +F3 "" 0 0 50 H V C CNN +$FPLIST + D-Pak_TO252AA + Diode_* + *SingleDiode + *SingleDiode* + *_Diode_* +$ENDFPLIST +DRAW +P 3 0 1 0 50 50 -50 0 50 -50 F +P 6 0 1 8 -75 25 -75 50 -50 50 -50 -50 -25 -50 -25 -25 N +X K 1 -150 0 100 R 50 50 1 1 P +X A 2 150 0 100 L 50 50 1 1 P +ENDDRAW +ENDDEF +# +# F_Small +# +DEF F_Small F 0 10 N N 1 F N +F0 "F" -40 60 50 H V L CNN +F1 "F_Small" -120 -60 50 H V L CNN +F2 "" 0 0 50 H V C CNN +F3 "" 0 0 50 H V C CNN +$FPLIST + CP* + SM* +$ENDFPLIST +DRAW +S -50 20 50 -20 0 1 0 N +P 2 0 1 0 -50 0 50 0 N +X ~ 1 -100 0 50 R 40 40 1 1 P +X ~ 2 100 0 50 L 40 40 1 1 P +ENDDRAW +ENDDEF +# +# INDUCTOR +# +DEF INDUCTOR L 0 40 N N 1 F N +F0 "L" -50 0 50 V V C CNN +F1 "INDUCTOR" 100 0 50 V V C CNN +F2 "" 0 0 50 H V C CNN +F3 "" 0 0 50 H V C CNN +$FPLIST + Choke_* + *Coil* +$ENDFPLIST +DRAW +A 0 -150 50 -889 889 0 1 0 N 1 -199 1 -100 +A 0 -49 51 -889 889 0 1 0 N 1 -99 1 2 +A 0 51 51 -889 889 0 1 0 N 1 1 1 102 +A 0 148 48 -889 889 0 1 0 N 1 101 1 196 +X 1 1 0 300 100 D 50 50 1 1 P +X 2 2 0 -300 100 U 50 50 1 1 P +ENDDRAW +ENDDEF +# +# LED +# +DEF LED D 0 40 Y N 1 F N +F0 "D" 0 100 50 H V C CNN +F1 "LED" 0 -100 50 H V C CNN +F2 "" 0 0 50 H V C CNN +F3 "" 0 0 50 H V C CNN +$FPLIST + LED-* + LED_* +$ENDFPLIST +DRAW +P 2 0 1 0 -50 50 -50 -50 N +P 3 0 1 0 -80 -25 -125 -65 -120 -40 N +P 3 0 1 0 -65 -40 -110 -80 -105 -55 N +P 3 0 1 0 50 50 -50 0 50 -50 F +X K 1 -200 0 150 R 40 40 1 1 P +X A 2 200 0 150 L 40 40 1 1 P +ENDDRAW +ENDDEF +# +# LM324-RESCUE-Tinylab_proto1 +# +DEF LM324-RESCUE-Tinylab_proto1 U 0 20 Y Y 4 F N +F0 "U" 50 200 60 H V C CNN +F1 "LM324-RESCUE-Tinylab_proto1" 150 -200 50 H V C CNN +F2 "" 0 0 60 H V C CNN +F3 "" 0 0 60 H V C CNN +DRAW +P 4 0 1 6 -200 200 200 0 -200 -200 -200 200 f +X V+ 4 -100 400 250 D 40 40 0 1 W +X V- 11 -100 -400 250 U 40 40 0 1 W +X ~ 1 500 0 300 L 40 40 1 1 O +X - 2 -500 -100 300 R 40 40 1 1 I +X + 3 -500 100 300 R 40 40 1 1 I +X + 5 -500 100 300 R 40 40 2 1 I +X - 6 -500 -100 300 R 40 40 2 1 I +X ~ 7 500 0 300 L 40 40 2 1 O +X ~ 8 500 0 300 L 40 40 3 1 O +X - 9 -500 -100 300 R 40 40 3 1 I +X + 10 -500 100 300 R 40 40 3 1 I +X + 12 -500 100 300 R 40 40 4 1 I +X - 13 -500 -100 300 R 40 40 4 1 I +X ~ 14 500 0 300 L 40 40 4 1 O +ENDDRAW +ENDDEF +# +# Q_NMOS_GSD +# +DEF Q_NMOS_GSD Q 0 0 Y N 1 F N +F0 "Q" 300 50 50 H V R CNN +F1 "Q_NMOS_GSD" 650 -50 50 H V R CNN +F2 "" 200 100 50 H V C CNN +F3 "" 0 0 50 H V C CNN +DRAW +C 50 0 111 0 1 10 N +P 2 0 1 0 30 -70 100 -70 N +P 2 0 1 10 30 -50 30 -90 N +P 2 0 1 0 30 0 100 0 N +P 2 0 1 10 30 20 30 -20 N +P 2 0 1 0 30 70 100 70 N +P 2 0 1 10 30 90 30 50 N +P 2 0 1 0 100 -70 100 -100 N +P 2 0 1 0 100 -70 100 0 N +P 2 0 1 0 100 100 100 70 N +P 3 0 1 10 10 75 10 -75 10 -75 N +P 4 0 1 0 40 0 80 15 80 -15 40 0 F +X G 1 -200 0 210 R 50 50 1 1 I +X S 2 100 -200 100 U 50 50 1 1 P +X D 3 100 200 100 D 50 50 1 1 P +ENDDRAW +ENDDEF +# +# R +# +DEF R R 0 0 N Y 1 F N +F0 "R" 80 0 50 V V C CNN +F1 "R" 0 0 50 V V C CNN +F2 "" -70 0 50 V V C CNN +F3 "" 0 0 50 H V C CNN +$FPLIST + R_* + Resistor_* +$ENDFPLIST +DRAW +S -40 -100 40 100 0 1 10 N +X ~ 1 0 150 50 D 50 50 1 1 P +X ~ 2 0 -150 50 U 50 50 1 1 P +ENDDRAW +ENDDEF +# +# R_Small +# +DEF R_Small R 0 10 N N 1 F N +F0 "R" 30 20 50 H V L CNN +F1 "R_Small" 30 -40 50 H V L CNN +F2 "" 0 0 50 H V C CNN +F3 "" 0 0 50 H V C CNN +$FPLIST + Resistor_* + R_* +$ENDFPLIST +DRAW +S -30 70 30 -70 0 1 8 N +X ~ 1 0 100 30 D 40 40 1 1 P +X ~ 2 0 -100 30 U 40 40 1 1 P +ENDDRAW +ENDDEF +# +# USB_OTG +# +DEF USB_OTG P 0 40 Y Y 1 F N +F0 "P" 325 -125 50 H V C CNN +F1 "USB_OTG" 0 200 50 H V C CNN +F2 "" -50 -100 50 V V C CNN +F3 "" -50 -100 50 V V C CNN +$FPLIST + USB* +$ENDFPLIST +DRAW +S -250 -150 250 150 0 1 0 N +S -205 -150 -195 -120 0 1 0 N +S -105 -150 -95 -120 0 1 0 N +S -5 -150 5 -120 0 1 0 N +S 95 -150 105 -120 0 1 0 N +S 195 -150 205 -120 0 1 0 N +X VCC 1 -200 -300 150 U 50 50 1 1 w +X D- 2 -100 -300 150 U 50 50 1 1 P +X D+ 3 0 -300 150 U 50 50 1 1 P +X ID 4 100 -300 150 U 50 50 1 1 W +X GND 5 200 -300 150 U 50 50 1 1 W +X shield 6 400 100 150 L 50 50 1 1 P +ENDDRAW +ENDDEF +# +#End Library diff --git a/PCB/Tinylab_proto1-cache.lib.REMOVED.git-id b/PCB/Tinylab_proto1-cache.lib.REMOVED.git-id deleted file mode 100644 index 6fce85fa..00000000 --- a/PCB/Tinylab_proto1-cache.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -588054700d47c625c99e33a4db4fbb8d7c408d6a \ No newline at end of file diff --git a/PCB/Tinylab_proto1-rescue.lib b/PCB/Tinylab_proto1-rescue.lib new file mode 100644 index 00000000..96ebf965 --- /dev/null +++ b/PCB/Tinylab_proto1-rescue.lib @@ -0,0 +1,45 @@ +EESchema-LIBRARY Version 2.3 +#encoding utf-8 +# +# 78L05-RESCUE-Tinylab_proto1 +# +DEF 78L05-RESCUE-Tinylab_proto1 U 0 30 N Y 1 F N +F0 "U" 150 -196 60 H V C CNN +F1 "78L05-RESCUE-Tinylab_proto1" 0 200 60 H V C CNN +F2 "" 0 0 60 H V C CNN +F3 "" 0 0 60 H V C CNN +DRAW +S -200 -150 200 150 0 1 0 N +X GND 1 0 -250 100 U 40 40 1 1 I +X VO 2 400 50 200 L 40 40 1 1 w +X VI 3 -400 50 200 R 40 40 1 1 I +ENDDRAW +ENDDEF +# +# LM324-RESCUE-Tinylab_proto1 +# +DEF LM324-RESCUE-Tinylab_proto1 U 0 20 Y Y 4 F N +F0 "U" 50 200 60 H V C CNN +F1 "LM324-RESCUE-Tinylab_proto1" 150 -200 50 H V C CNN +F2 "" 0 0 60 H V C CNN +F3 "" 0 0 60 H V C CNN +DRAW +P 4 0 1 6 -200 200 200 0 -200 -200 -200 200 f +X V+ 4 -100 400 250 D 40 40 0 1 W +X V- 11 -100 -400 250 U 40 40 0 1 W +X ~ 1 500 0 300 L 40 40 1 1 O +X - 2 -500 -100 300 R 40 40 1 1 I +X + 3 -500 100 300 R 40 40 1 1 I +X + 5 -500 100 300 R 40 40 2 1 I +X - 6 -500 -100 300 R 40 40 2 1 I +X ~ 7 500 0 300 L 40 40 2 1 O +X ~ 8 500 0 300 L 40 40 3 1 O +X - 9 -500 -100 300 R 40 40 3 1 I +X + 10 -500 100 300 R 40 40 3 1 I +X + 12 -500 100 300 R 40 40 4 1 I +X - 13 -500 -100 300 R 40 40 4 1 I +X ~ 14 500 0 300 L 40 40 4 1 O +ENDDRAW +ENDDEF +# +#End Library diff --git a/PCB/Tinylab_proto1-rescue.lib.REMOVED.git-id b/PCB/Tinylab_proto1-rescue.lib.REMOVED.git-id deleted file mode 100644 index 18d02250..00000000 --- a/PCB/Tinylab_proto1-rescue.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -96ebf965f8800a4d497869db15bc04d1a736f0e2 \ No newline at end of file diff --git a/PCB/Tinylab_proto1.bak b/PCB/Tinylab_proto1.bak new file mode 100644 index 00000000..740b0f8c --- /dev/null +++ b/PCB/Tinylab_proto1.bak @@ -0,0 +1,1600 @@ +EESchema Schematic File Version 2 +LIBS:Tinylab_proto1-rescue +LIBS:power +LIBS:device +LIBS:transistors +LIBS:conn +LIBS:linear +LIBS:regul +LIBS:74xx +LIBS:cmos4000 +LIBS:adc-dac +LIBS:memory +LIBS:xilinx +LIBS:microcontrollers +LIBS:dsp +LIBS:microchip +LIBS:analog_switches +LIBS:motorola +LIBS:texas +LIBS:intel +LIBS:audio +LIBS:interface +LIBS:digital-audio +LIBS:philips +LIBS:display +LIBS:cypress +LIBS:siliconi +LIBS:opto +LIBS:atmel +LIBS:contrib +LIBS:valves +LIBS:ESPO_PART +LIBS:Tinylab_proto1-cache +EELAYER 25 0 +EELAYER END +$Descr A2 23386 16535 +encoding utf-8 +Sheet 1 1 +Title "" +Date "" +Rev "" +Comp "" +Comment1 "" +Comment2 "" +Comment3 "" +Comment4 "" +$EndDescr +$Comp +L LM324-RESCUE-Tinylab_proto1 U2 +U 1 1 55CA87E2 +P 4200 8750 +F 0 "U2" H 4250 8950 60 0000 C CNN +F 1 "LM324" H 4350 8550 50 0000 C CNN +F 2 "Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm" H 4200 8750 60 0001 C CNN +F 3 "" H 4200 8750 60 0000 C CNN + 1 4200 8750 + 1 0 0 -1 +$EndComp +$Comp +L LM324-RESCUE-Tinylab_proto1 U2 +U 2 1 55CA88A1 +P 4200 10550 +F 0 "U2" H 4250 10750 60 0000 C CNN +F 1 "LM324" H 4350 10350 50 0000 C CNN +F 2 "Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm" H 4200 10550 60 0001 C CNN +F 3 "" H 4200 10550 60 0000 C CNN + 2 4200 10550 + 1 0 0 -1 +$EndComp +$Comp +L LM324-RESCUE-Tinylab_proto1 U2 +U 3 1 55CA8924 +P 8450 9250 +F 0 "U2" H 8500 9450 60 0000 C CNN +F 1 "LM324" H 8600 9050 50 0000 C CNN +F 2 "Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm" H 8450 9250 60 0001 C CNN +F 3 "" H 8450 9250 60 0000 C CNN + 3 8450 9250 + 1 0 0 -1 +$EndComp +$Comp +L LM324-RESCUE-Tinylab_proto1 U2 +U 4 1 55CA89A3 +P 8400 11550 +F 0 "U2" H 8450 11750 60 0000 C CNN +F 1 "LM324" H 8550 11350 50 0000 C CNN +F 2 "Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm" H 8400 11550 60 0001 C CNN +F 3 "" H 8400 11550 60 0000 C CNN + 4 8400 11550 + 1 0 0 -1 +$EndComp +$Comp +L ATXMEGA16A4U-A IC1 +U 1 1 55CA8F25 +P 6150 5300 +F 0 "IC1" H 5400 6500 40 0000 L BNN +F 1 "ATXMEGA32A4U-AU" H 6500 4050 40 0000 L BNN +F 2 "Housings_QFP:LQFP-44_10x10mm_Pitch0.8mm" H 6150 5300 35 0000 C CIN +F 3 "" H 6150 5300 60 0000 C CNN + 1 6150 5300 + 1 0 0 -1 +$EndComp +$Comp +L USB_OTG P2 +U 1 1 55CA90D2 +P 1650 6850 +F 0 "P2" H 1975 6725 50 0000 C CNN +F 1 "USB_OTG" H 1650 7050 50 0000 C CNN +F 2 "Connect:USB_Micro-B_WIDE" V 1600 6750 60 0001 C CNN +F 3 "" V 1600 6750 60 0000 C CNN + 1 1650 6850 + 0 -1 1 0 +$EndComp +$Comp +L 78L05-RESCUE-Tinylab_proto1 U1 +U 1 1 55CA99FA +P 3100 6700 +F 0 "U1" H 3250 6504 60 0000 C CNN +F 1 "78L05" H 3100 6900 60 0000 C CNN +F 2 "SMD:SOT-23-3" H 3100 6700 60 0001 C CNN +F 3 "" H 3100 6700 60 0000 C CNN + 1 3100 6700 + 1 0 0 -1 +$EndComp +$Comp +L R R1 +U 1 1 55CAAB95 +P 2000 9250 +F 0 "R1" V 2080 9250 50 0000 C CNN +F 1 "1M" V 2000 9250 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 1930 9250 30 0001 C CNN +F 3 "" H 2000 9250 30 0000 C CNN + 1 2000 9250 + 0 1 1 0 +$EndComp +$Comp +L R R3 +U 1 1 55CAABF4 +P 2350 9400 +F 0 "R3" V 2430 9400 50 0000 C CNN +F 1 "75K" V 2350 9400 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 2280 9400 30 0001 C CNN +F 3 "" H 2350 9400 30 0000 C CNN + 1 2350 9400 + 1 0 0 -1 +$EndComp +$Comp +L R R5 +U 1 1 55CAAC5F +P 3000 9500 +F 0 "R5" V 3080 9500 50 0000 C CNN +F 1 "1K" V 3000 9500 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 2930 9500 30 0001 C CNN +F 3 "" H 3000 9500 30 0000 C CNN + 1 3000 9500 + 0 1 1 0 +$EndComp +$Comp +L R R6 +U 1 1 55CAACD2 +P 3000 9700 +F 0 "R6" V 3080 9700 50 0000 C CNN +F 1 "1K" V 3000 9700 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 2930 9700 30 0001 C CNN +F 3 "" H 3000 9700 30 0000 C CNN + 1 3000 9700 + 0 1 1 0 +$EndComp +$Comp +L R R4 +U 1 1 55CAAD11 +P 2350 9800 +F 0 "R4" V 2430 9800 50 0000 C CNN +F 1 "75K" V 2350 9800 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 2280 9800 30 0001 C CNN +F 3 "" H 2350 9800 30 0000 C CNN + 1 2350 9800 + 1 0 0 -1 +$EndComp +$Comp +L R R2 +U 1 1 55CAAD4C +P 2000 9950 +F 0 "R2" V 2080 9950 50 0000 C CNN +F 1 "1M" V 2000 9950 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 1930 9950 30 0001 C CNN +F 3 "" H 2000 9950 30 0000 C CNN + 1 2000 9950 + 0 1 1 0 +$EndComp +$Comp +L C_Small C2 +U 1 1 55CAB4DE +P 1550 9950 +F 0 "C2" H 1560 10020 50 0000 L CNN +F 1 "C" H 1560 9870 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 1550 9950 60 0001 C CNN +F 3 "" H 1550 9950 60 0000 C CNN + 1 1550 9950 + 0 1 1 0 +$EndComp +$Comp +L C_Small C1 +U 1 1 55CAB611 +P 1450 9300 +F 0 "C1" H 1460 9370 50 0000 L CNN +F 1 "C" H 1460 9220 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 1450 9300 60 0001 C CNN +F 3 "" H 1450 9300 60 0000 C CNN + 1 1450 9300 + 0 1 1 0 +$EndComp +Text Label 3150 9500 0 60 ~ 0 +AVCC +Text Label 4700 8750 0 60 ~ 0 +CH1 +Text Label 4700 10550 0 60 ~ 0 +CH2 +Text Label 7050 4500 0 60 ~ 0 +CH1 +Text Label 7050 4300 0 60 ~ 0 +CH2 +Text Label 2350 9600 0 60 ~ 0 +AVCC_ON_2 +Text Label 7050 4700 0 60 ~ 0 +AVCC_ON_2 +$Comp +L C_Small C3 +U 1 1 55CB13E1 +P 2700 6950 +F 0 "C3" H 2710 7020 50 0000 L CNN +F 1 "C_Small" H 2710 6870 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 2700 6950 60 0001 C CNN +F 3 "" H 2700 6950 60 0000 C CNN + 1 2700 6950 + 1 0 0 -1 +$EndComp +$Comp +L C_Small C4 +U 1 1 55CB147C +P 3500 6950 +F 0 "C4" H 3510 7020 50 0000 L CNN +F 1 "C_Small" H 3510 6870 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 3500 6950 60 0001 C CNN +F 3 "" H 3500 6950 60 0000 C CNN + 1 3500 6950 + 1 0 0 -1 +$EndComp +Text Notes 1450 8500 0 60 ~ 0 +Analog Front End for Scope\n +Text Notes 8950 8600 0 60 ~ 0 +DAC stuff\n +$Comp +L R R22 +U 1 1 55CB4680 +P 10650 9250 +F 0 "R22" V 10730 9250 50 0000 C CNN +F 1 "28R" V 10650 9250 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 10580 9250 30 0001 C CNN +F 3 "" H 10650 9250 30 0000 C CNN + 1 10650 9250 + 0 1 1 0 +$EndComp +$Comp +L C_Small C13 +U 1 1 55CB630B +P 11250 9350 +F 0 "C13" H 11260 9420 50 0000 L CNN +F 1 "C" H 11260 9270 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 11250 9350 60 0001 C CNN +F 3 "" H 11250 9350 60 0000 C CNN + 1 11250 9350 + 0 1 1 0 +$EndComp +Text Label 7400 9150 0 60 ~ 0 +DAC_OUT +Text Label 7050 5350 0 60 ~ 0 +DAC_OUT +$Comp +L R R24 +U 1 1 55CB9020 +P 11000 9250 +F 0 "R24" V 11080 9250 50 0000 C CNN +F 1 "28R" V 11000 9250 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 10930 9250 30 0001 C CNN +F 3 "" H 11000 9250 30 0000 C CNN + 1 11000 9250 + 0 1 1 0 +$EndComp +$Comp +L R R11 +U 1 1 55CBCD2A +P 4700 5000 +F 0 "R11" V 4780 5000 50 0000 C CNN +F 1 "28R" V 4700 5000 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4630 5000 30 0001 C CNN +F 3 "" H 4700 5000 30 0000 C CNN + 1 4700 5000 + 0 1 1 0 +$EndComp +$Comp +L R R7 +U 1 1 55CBCDA5 +P 4350 5000 +F 0 "R7" V 4430 5000 50 0000 C CNN +F 1 "28R" V 4350 5000 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4280 5000 30 0001 C CNN +F 3 "" H 4350 5000 30 0000 C CNN + 1 4350 5000 + 0 1 1 0 +$EndComp +$Comp +L R R13 +U 1 1 55CBE0F4 +P 4700 5400 +F 0 "R13" V 4780 5400 50 0000 C CNN +F 1 "28R" V 4700 5400 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4630 5400 30 0001 C CNN +F 3 "" H 4700 5400 30 0000 C CNN + 1 4700 5400 + 0 1 1 0 +$EndComp +$Comp +L R R9 +U 1 1 55CBE16B +P 4350 5400 +F 0 "R9" V 4430 5400 50 0000 C CNN +F 1 "28R" V 4350 5400 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4280 5400 30 0001 C CNN +F 3 "" H 4350 5400 30 0000 C CNN + 1 4350 5400 + 0 1 1 0 +$EndComp +$Comp +L R R14 +U 1 1 55CBE21C +P 4700 5600 +F 0 "R14" V 4780 5600 50 0000 C CNN +F 1 "28R" V 4700 5600 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4630 5600 30 0001 C CNN +F 3 "" H 4700 5600 30 0000 C CNN + 1 4700 5600 + 0 1 1 0 +$EndComp +$Comp +L R R10 +U 1 1 55CBE2C7 +P 4350 5600 +F 0 "R10" V 4430 5600 50 0000 C CNN +F 1 "28R" V 4350 5600 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4280 5600 30 0001 C CNN +F 3 "" H 4350 5600 30 0000 C CNN + 1 4350 5600 + 0 1 1 0 +$EndComp +$Comp +L R R12 +U 1 1 55CBE362 +P 4700 5200 +F 0 "R12" V 4780 5200 50 0000 C CNN +F 1 "28R" V 4700 5200 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4630 5200 30 0001 C CNN +F 3 "" H 4700 5200 30 0000 C CNN + 1 4700 5200 + 0 1 1 0 +$EndComp +$Comp +L R R8 +U 1 1 55CBE401 +P 4350 5200 +F 0 "R8" V 4430 5200 50 0000 C CNN +F 1 "28R" V 4350 5200 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4280 5200 30 0001 C CNN +F 3 "" H 4350 5200 30 0000 C CNN + 1 4350 5200 + 0 1 1 0 +$EndComp +$Comp +L CONN_01X04 P3 +U 1 1 55CBF4D5 +P 3550 5300 +F 0 "P3" H 3550 5550 50 0000 C CNN +F 1 "DIG_OUT" V 3650 5300 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x04" H 3550 5300 60 0001 C CNN +F 3 "" H 3550 5300 60 0000 C CNN + 1 3550 5300 + -1 0 0 1 +$EndComp +Text Notes 4250 4850 0 60 ~ 0 +Dig Output\n +Text Notes 10050 4650 0 60 ~ 0 +PSU\n +$Comp +L +5V #PWR01 +U 1 1 55CD51C0 +P 2700 6650 +F 0 "#PWR01" H 2700 6500 50 0001 C CNN +F 1 "+5V" H 2700 6790 50 0000 C CNN +F 2 "" H 2700 6650 60 0000 C CNN +F 3 "" H 2700 6650 60 0000 C CNN + 1 2700 6650 + 1 0 0 -1 +$EndComp +Text Label 1950 6850 0 60 ~ 0 +D+ +Text Label 1950 6750 0 60 ~ 0 +D- +Text Label 5100 6200 0 60 ~ 0 +D- +Text Label 5100 6300 0 60 ~ 0 +D+ +NoConn ~ 1950 6950 +$Comp +L C_Small C5 +U 1 1 55D60181 +P 3600 9600 +F 0 "C5" H 3610 9670 50 0000 L CNN +F 1 "C_Small" H 3610 9520 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 3600 9600 60 0001 C CNN +F 3 "" H 3600 9600 60 0000 C CNN + 1 3600 9600 + 1 0 0 -1 +$EndComp +Text Label 6450 4000 0 60 ~ 0 +AVCC +$Comp +L DMN63D8LDW U4 +U 1 1 55D6ACFD +P 14400 3450 +F 0 "U4" H 14400 3150 60 0000 C CNN +F 1 "DMN63D8LDW" H 14400 3800 60 0000 C CNN +F 2 "TO_SOT_Packages_SMD:SOT-363" H 14400 3150 60 0001 C CNN +F 3 "" H 14400 3150 60 0000 C CNN + 1 14400 3450 + 1 0 0 -1 +$EndComp +Text Notes 14250 2450 0 60 ~ 0 +DIG IN +$Comp +L CONN_01X02 P8 +U 1 1 55D6DB77 +P 14400 2750 +F 0 "P8" H 14400 2900 50 0000 C CNN +F 1 "DIG_IN" V 14500 2750 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x02" H 14400 2750 60 0001 C CNN +F 3 "" H 14400 2750 60 0000 C CNN + 1 14400 2750 + 0 -1 -1 0 +$EndComp +Text Label 14850 3300 0 60 ~ 0 +DIG_CH2 +Text Label 13550 3600 0 60 ~ 0 +DIG_CH1 +$Comp +L F_Small F1 +U 1 1 55D739F3 +P 3350 4300 +F 0 "F1" H 3310 4360 50 0000 L CNN +F 1 "F_Small" H 3230 4240 50 0000 L CNN +F 2 "Capacitors_SMD:C_1210" H 3350 4300 60 0001 C CNN +F 3 "" H 3350 4300 60 0000 C CNN + 1 3350 4300 + -1 0 0 1 +$EndComp +Text Label 2500 7250 0 60 ~ 0 +VGND +Text Label 3500 6650 0 60 ~ 0 +VCC_3V3 +NoConn ~ 7050 5000 +NoConn ~ 7050 5600 +NoConn ~ 7050 5900 +Text Label 7050 5700 0 60 ~ 0 +XCK +Text Label 7050 5800 0 60 ~ 0 +DIG_CH2 +Text Label 7050 6100 0 60 ~ 0 +DIG_CH1 +Text Label 7050 6300 0 60 ~ 0 +XCK +NoConn ~ 7050 6200 +NoConn ~ 5250 5600 +Text Label 4750 6000 0 60 ~ 0 +PSU_PWM +NoConn ~ 5250 6100 +NoConn ~ 5250 5000 +NoConn ~ 5250 4900 +NoConn ~ 5250 5800 +NoConn ~ 5250 5700 +Text Label 6150 3800 0 60 ~ 0 +VCC_3V3 +$Comp +L INDUCTOR L1 +U 1 1 5606EE9E +P 10350 5050 +F 0 "L1" V 10300 5050 50 0000 C CNN +F 1 "INDUCTOR" V 10450 5050 50 0000 C CNN +F 2 "Special_inductor:SMALL_INDUCTOR" H 10350 5050 60 0001 C CNN +F 3 "" H 10350 5050 60 0000 C CNN + 1 10350 5050 + 0 1 1 0 +$EndComp +$Comp +L D_Schottky D1 +U 1 1 5606FDB4 +P 11100 5050 +F 0 "D1" H 11100 5150 50 0000 C CNN +F 1 "D_Schottky" H 11100 4950 50 0000 C CNN +F 2 "Diodes_SMD:SMA_Standard" H 11100 5050 60 0001 C CNN +F 3 "" H 11100 5050 60 0000 C CNN + 1 11100 5050 + -1 0 0 1 +$EndComp +$Comp +L CP1 C9 +U 1 1 560719D9 +P 9300 5350 +F 0 "C9" H 9325 5450 50 0000 L CNN +F 1 "CP1" H 9325 5250 50 0000 L CNN +F 2 "Capacitors_SMD:c_elec_4x5.3" H 9300 5350 60 0001 C CNN +F 3 "" H 9300 5350 60 0000 C CNN + 1 9300 5350 + 1 0 0 -1 +$EndComp +$Comp +L C C10 +U 1 1 56071A50 +P 9600 5350 +F 0 "C10" H 9625 5450 50 0000 L CNN +F 1 "C" H 9625 5250 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 9638 5200 30 0001 C CNN +F 3 "" H 9600 5350 60 0000 C CNN + 1 9600 5350 + 1 0 0 -1 +$EndComp +$Comp +L C C16 +U 1 1 5607355F +P 16600 5350 +F 0 "C16" H 16625 5450 50 0000 L CNN +F 1 "C" H 16625 5250 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 16638 5200 30 0001 C CNN +F 3 "" H 16600 5350 60 0000 C CNN + 1 16600 5350 + 1 0 0 -1 +$EndComp +$Comp +L CP1 C15 +U 1 1 560735FE +P 11500 5400 +F 0 "C15" H 11525 5500 50 0000 L CNN +F 1 "CP1" H 11525 5300 50 0000 L CNN +F 2 "Capacitors_SMD:c_elec_4x5.3" H 11500 5400 60 0001 C CNN +F 3 "" H 11500 5400 60 0000 C CNN + 1 11500 5400 + 1 0 0 -1 +$EndComp +NoConn ~ 7050 4400 +NoConn ~ 7050 4600 +Text Label 7050 4900 0 60 ~ 0 +CH2 +$Comp +L CONN_02X02 P4 +U 1 1 56069A87 +P 4600 4350 +F 0 "P4" H 4600 4500 50 0000 C CNN +F 1 "PDI/3V3" H 4600 4200 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_2x02" H 4600 3150 60 0001 C CNN +F 3 "" H 4600 3150 60 0000 C CNN + 1 4600 4350 + 1 0 0 -1 +$EndComp +Text Label 2700 4300 0 60 ~ 0 +VCC_3V3 +NoConn ~ 6050 4000 +Text Label 8900 5650 0 60 ~ 0 +VGND +Text Label 7050 5450 0 60 ~ 0 +DAC_OUT2 +Text Label 7350 11450 0 60 ~ 0 +DAC_OUT2 +$Comp +L R R23 +U 1 1 566DE721 +P 10850 11550 +F 0 "R23" V 10930 11550 50 0000 C CNN +F 1 "28R" V 10850 11550 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 10780 11550 30 0001 C CNN +F 3 "" H 10850 11550 30 0000 C CNN + 1 10850 11550 + 0 1 1 0 +$EndComp +$Comp +L R R25 +U 1 1 566DE7E8 +P 11150 11550 +F 0 "R25" V 11230 11550 50 0000 C CNN +F 1 "28R" V 11150 11550 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 11080 11550 30 0001 C CNN +F 3 "" H 11150 11550 30 0000 C CNN + 1 11150 11550 + 0 1 1 0 +$EndComp +$Comp +L C_Small C14 +U 1 1 566DF655 +P 11400 11650 +F 0 "C14" H 11410 11720 50 0000 L CNN +F 1 "C" H 11410 11570 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 11400 11650 60 0001 C CNN +F 3 "" H 11400 11650 60 0000 C CNN + 1 11400 11650 + 0 1 1 0 +$EndComp +$Comp +L CONN_01X04 P6 +U 1 1 566DF832 +P 12450 10750 +F 0 "P6" H 12450 11000 50 0000 C CNN +F 1 "DAC_OUT" V 12550 10750 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x04" H 12450 10750 60 0001 C CNN +F 3 "" H 12450 10750 60 0000 C CNN + 1 12450 10750 + 1 0 0 -1 +$EndComp +$Comp +L R R26 +U 1 1 566E5C29 +P 12100 5200 +F 0 "R26" V 12180 5200 50 0000 C CNN +F 1 "1K" V 12100 5200 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 12030 5200 30 0001 C CNN +F 3 "" H 12100 5200 30 0000 C CNN + 1 12100 5200 + 1 0 0 -1 +$EndComp +$Comp +L R R27 +U 1 1 566E5CBE +P 12100 5500 +F 0 "R27" V 12180 5500 50 0000 C CNN +F 1 "100R" V 12100 5500 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 12030 5500 30 0001 C CNN +F 3 "" H 12100 5500 30 0000 C CNN + 1 12100 5500 + 1 0 0 -1 +$EndComp +Text Label 7050 4800 0 60 ~ 0 +PSU_FDBK +Text Label 12350 5350 0 60 ~ 0 +PSU_FDBK +$Comp +L CP1 C6 +U 1 1 566F5A75 +P 4050 6900 +F 0 "C6" H 4075 7000 50 0000 L CNN +F 1 "CP1" H 4075 6800 50 0000 L CNN +F 2 "Capacitors_SMD:c_elec_4x5.3" H 4050 6900 60 0001 C CNN +F 3 "" H 4050 6900 60 0000 C CNN + 1 4050 6900 + 1 0 0 -1 +$EndComp +Text Label 6250 3900 0 60 ~ 0 +VCC_3V3 +$Comp +L R R19 +U 1 1 56AECD86 +P 8700 9750 +F 0 "R19" V 8780 9750 50 0000 C CNN +F 1 "1K" V 8700 9750 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 8630 9750 30 0001 C CNN +F 3 "" H 8700 9750 30 0000 C CNN + 1 8700 9750 + 0 1 1 0 +$EndComp +Text Label 10400 3600 0 60 ~ 0 +VCC_3V3 +Text Label 9150 3600 0 60 ~ 0 +AVCC +$Comp +L C C11 +U 1 1 5608B4BE +P 10150 3750 +F 0 "C11" H 10175 3850 50 0000 L CNN +F 1 "C" H 10175 3650 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 10188 3600 30 0001 C CNN +F 3 "" H 10150 3750 60 0000 C CNN + 1 10150 3750 + 1 0 0 -1 +$EndComp +$Comp +L C C8 +U 1 1 56AF91A3 +P 9200 3750 +F 0 "C8" H 9225 3850 50 0000 L CNN +F 1 "C" H 9225 3650 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 9238 3600 30 0001 C CNN +F 3 "" H 9200 3750 60 0000 C CNN + 1 9200 3750 + 1 0 0 -1 +$EndComp +$Comp +L R R17 +U 1 1 56AFE83E +P 7950 9900 +F 0 "R17" V 8030 9900 50 0000 C CNN +F 1 "1K" V 7950 9900 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 7880 9900 30 0001 C CNN +F 3 "" H 7950 9900 30 0000 C CNN + 1 7950 9900 + 1 0 0 -1 +$EndComp +$Comp +L R R18 +U 1 1 56AFE8F3 +P 8150 9900 +F 0 "R18" V 8230 9900 50 0000 C CNN +F 1 "1K" V 8150 9900 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 8080 9900 30 0001 C CNN +F 3 "" H 8150 9900 30 0000 C CNN + 1 8150 9900 + 1 0 0 -1 +$EndComp +$Comp +L DMN63D8LDW U3 +U 1 1 56B012DD +P 9250 10750 +F 0 "U3" H 9250 10450 60 0000 C CNN +F 1 "DMN63D8LDW" H 9250 11100 60 0000 C CNN +F 2 "TO_SOT_Packages_SMD:SOT-363" H 9250 10450 60 0001 C CNN +F 3 "" H 9250 10450 60 0000 C CNN + 1 9250 10750 + 1 0 0 -1 +$EndComp +Text Label 9800 10750 0 60 ~ 0 +TO_B0 +Text Label 7050 5150 0 60 ~ 0 +TO_B0 +Text Label 13950 5050 0 60 ~ 0 +PSU_OUT +$Comp +L R R20 +U 1 1 56B0C682 +P 8700 12050 +F 0 "R20" V 8780 12050 50 0000 C CNN +F 1 "1K" V 8700 12050 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 8630 12050 30 0001 C CNN +F 3 "" H 8700 12050 30 0000 C CNN + 1 8700 12050 + 0 1 1 0 +$EndComp +$Comp +L R R15 +U 1 1 56B0C779 +P 7900 12200 +F 0 "R15" V 7980 12200 50 0000 C CNN +F 1 "1K" V 7900 12200 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 7830 12200 30 0001 C CNN +F 3 "" H 7900 12200 30 0000 C CNN + 1 7900 12200 + 1 0 0 -1 +$EndComp +$Comp +L R R16 +U 1 1 56B0C86E +P 8100 12200 +F 0 "R16" V 8180 12200 50 0000 C CNN +F 1 "1K" V 8100 12200 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 8030 12200 30 0001 C CNN +F 3 "" H 8100 12200 30 0000 C CNN + 1 8100 12200 + 1 0 0 -1 +$EndComp +Text Label 8100 10750 0 60 ~ 0 +TO_B1 +Text Label 7050 5250 0 60 ~ 0 +TO_B1 +$Comp +L +5V #PWR02 +U 1 1 56E7FFFF +P 8900 5050 +F 0 "#PWR02" H 8900 4900 50 0001 C CNN +F 1 "+5V" H 8900 5190 50 0000 C CNN +F 2 "" H 8900 5050 60 0000 C CNN +F 3 "" H 8900 5050 60 0000 C CNN + 1 8900 5050 + 1 0 0 -1 +$EndComp +$Comp +L INDUCTOR L2 +U 1 1 56E88440 +P 9700 3600 +F 0 "L2" V 9650 3600 50 0000 C CNN +F 1 "INDUCTOR" V 9800 3600 50 0000 C CNN +F 2 "Resistors_SMD:R_1206" H 9700 3600 60 0001 C CNN +F 3 "" H 9700 3600 60 0000 C CNN + 1 9700 3600 + 0 1 1 0 +$EndComp +Text Label 4100 8350 0 60 ~ 0 +OPAMP_VCC +Text Label 4100 10150 0 60 ~ 0 +OPAMP_VCC +Text Label 8350 8850 0 60 ~ 0 +OPAMP_VCC +Text Label 8300 11150 0 60 ~ 0 +OPAMP_VCC +$Comp +L INDUCTOR L3 +U 1 1 56E8DA35 +P 15300 5050 +F 0 "L3" V 15250 5050 50 0000 C CNN +F 1 "INDUCTOR" V 15400 5050 50 0000 C CNN +F 2 "Resistors_SMD:R_1206" H 15300 5050 60 0001 C CNN +F 3 "" H 15300 5050 60 0000 C CNN + 1 15300 5050 + 0 1 1 0 +$EndComp +$Comp +L C C7 +U 1 1 56E8E263 +P 15000 5350 +F 0 "C7" H 15025 5450 50 0000 L CNN +F 1 "C" H 15025 5250 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 15038 5200 30 0001 C CNN +F 3 "" H 15000 5350 60 0000 C CNN + 1 15000 5350 + 1 0 0 -1 +$EndComp +Text Label 16250 5050 0 60 ~ 0 +OPAMP_VCC +$Comp +L R R21 +U 1 1 56E9851A +P 4900 8900 +F 0 "R21" V 4980 8900 50 0000 C CNN +F 1 "1K" V 4900 8900 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4830 8900 30 0001 C CNN +F 3 "" H 4900 8900 30 0000 C CNN + 1 4900 8900 + 1 0 0 -1 +$EndComp +$Comp +L R R28 +U 1 1 56E985EF +P 4950 10400 +F 0 "R28" V 5030 10400 50 0000 C CNN +F 1 "1K" V 4950 10400 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4880 10400 30 0001 C CNN +F 3 "" H 4950 10400 30 0000 C CNN + 1 4950 10400 + 1 0 0 -1 +$EndComp +$Comp +L R R29 +U 1 1 56E9888A +P 9600 9400 +F 0 "R29" V 9680 9400 50 0000 C CNN +F 1 "1K" V 9600 9400 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 9530 9400 30 0001 C CNN +F 3 "" H 9600 9400 30 0000 C CNN + 1 9600 9400 + 1 0 0 -1 +$EndComp +$Comp +L R R30 +U 1 1 56E98921 +P 10000 11400 +F 0 "R30" V 10080 11400 50 0000 C CNN +F 1 "1K" V 10000 11400 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 9930 11400 30 0001 C CNN +F 3 "" H 10000 11400 30 0000 C CNN + 1 10000 11400 + 1 0 0 -1 +$EndComp +$Comp +L CONN_01X02 P7 +U 1 1 56F2A93D +P 14150 5350 +F 0 "P7" H 14150 5500 50 0000 C CNN +F 1 "PSU" V 14250 5350 50 0000 C CIN +F 2 "Pin_Headers:Pin_Header_Straight_1x02" H 14150 5350 50 0001 C CNN +F 3 "" H 14150 5350 50 0000 C CNN + 1 14150 5350 + 1 0 0 -1 +$EndComp +Text Label 6300 6700 0 60 ~ 0 +VGND +Text Label 6200 6950 0 60 ~ 0 +VGND +Text Label 6100 6800 0 60 ~ 0 +VGND +Text Label 6000 7100 0 60 ~ 0 +VGND +Text Label 7600 6000 0 60 ~ 0 +VGND +Text Label 4750 9750 0 60 ~ 0 +VGND +Text Label 4100 9150 0 60 ~ 0 +VGND +Text Label 4100 10950 0 60 ~ 0 +VGND +Text Label 7900 3900 0 60 ~ 0 +VGND +Text Label 10800 3900 0 60 ~ 0 +VGND +Text Label 10300 10900 0 60 ~ 0 +VGND +Text Label 8500 10600 0 60 ~ 0 +VGND +Text Label 8350 9650 0 60 ~ 0 +VGND +Text Label 8300 11950 0 60 ~ 0 +VGND +$Comp +L INDUCTOR L4 +U 1 1 573254B0 +P 15950 5050 +F 0 "L4" V 15900 5050 50 0000 C CNN +F 1 "INDUCTOR" V 16050 5050 50 0000 C CNN +F 2 "Resistors_SMD:R_1206" H 15950 5050 60 0001 C CNN +F 3 "" H 15950 5050 60 0000 C CNN + 1 15950 5050 + 0 1 1 0 +$EndComp +Text Label 13700 3300 0 60 ~ 0 +VGND +Text Label 14850 3600 0 60 ~ 0 +VGND +Text Label 3900 4400 0 60 ~ 0 +VGND +$Comp +L C C18 +U 1 1 57564580 +P 8700 3750 +F 0 "C18" H 8725 3850 50 0000 L CNN +F 1 "C" H 8725 3650 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 8738 3600 50 0001 C CNN +F 3 "" H 8700 3750 50 0000 C CNN + 1 8700 3750 + 1 0 0 -1 +$EndComp +$Comp +L C C17 +U 1 1 57564635 +P 8450 3750 +F 0 "C17" H 8475 3850 50 0000 L CNN +F 1 "C" H 8475 3650 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 8488 3600 50 0001 C CNN +F 3 "" H 8450 3750 50 0000 C CNN + 1 8450 3750 + 1 0 0 -1 +$EndComp +$Comp +L R R31 +U 1 1 5804605C +P 10300 5500 +F 0 "R31" V 10380 5500 50 0000 C CNN +F 1 "1K" V 10300 5500 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 10230 5500 50 0001 C CNN +F 3 "" H 10300 5500 50 0000 C CNN + 1 10300 5500 + 1 0 0 -1 +$EndComp +Text Label 10150 5350 0 60 ~ 0 +PSU_PWM +$Comp +L Q_NMOS_GSD Q1 +U 1 1 583120F2 +P 10650 5350 +F 0 "Q1" H 10950 5400 50 0000 R CNN +F 1 "Q_NMOS_GSD" H 11300 5300 50 0000 R CNN +F 2 "SMD:SOT-23-3" H 10850 5450 50 0001 C CNN +F 3 "" H 10650 5350 50 0000 C CNN + 1 10650 5350 + 1 0 0 -1 +$EndComp +NoConn ~ 5250 5900 +$Comp +L LED D2 +U 1 1 5833E159 +P 14450 5450 +F 0 "D2" H 14450 5550 50 0000 C CNN +F 1 "LED" H 14450 5350 50 0000 C CNN +F 2 "LEDs:LED_0603" H 14450 5450 50 0001 C CNN +F 3 "" H 14450 5450 50 0000 C CNN + 1 14450 5450 + 0 -1 -1 0 +$EndComp +$Comp +L R_Small R32 +U 1 1 5833E34C +P 14450 5150 +F 0 "R32" H 14480 5170 50 0000 L CNN +F 1 "1K" H 14480 5110 50 0000 L CNN +F 2 "Resistors_SMD:R_0603" H 14450 5150 50 0001 C CNN +F 3 "" H 14450 5150 50 0000 C CNN + 1 14450 5150 + 1 0 0 -1 +$EndComp +$Comp +L CONN_01X03 P10 +U 1 1 5837847B +P 12800 4950 +F 0 "P10" H 12800 5150 50 0000 C CNN +F 1 "EXPANSION" V 12900 4950 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x03" H 12800 4950 50 0001 C CNN +F 3 "" H 12800 4950 50 0000 C CNN + 1 12800 4950 + 1 0 0 -1 +$EndComp +$Comp +L CONN_01X03 P11 +U 1 1 58378536 +P 13400 4950 +F 0 "P11" H 13400 5150 50 0000 C CNN +F 1 "SWITCH" V 13500 4950 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x03" H 13400 4950 50 0001 C CNN +F 3 "" H 13400 4950 50 0000 C CNN + 1 13400 4950 + 1 0 0 -1 +$EndComp +NoConn ~ 13200 4850 +$Comp +L CONN_01X04 P1 +U 1 1 5832064B +P 1050 9250 +F 0 "P1" H 1050 9500 50 0000 C CNN +F 1 "SCOPE_OUT" V 1150 9250 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x04" H 1050 9250 50 0001 C CNN +F 3 "" H 1050 9250 50 0000 C CNN + 1 1050 9250 + -1 0 0 1 +$EndComp +$Comp +L CONN_01X04 P5 +U 1 1 58320706 +P 1050 9900 +F 0 "P5" H 1050 10150 50 0000 C CNN +F 1 "SCOPE_OUT" V 1150 9900 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x04" H 1050 9900 50 0001 C CNN +F 3 "" H 1050 9900 50 0000 C CNN + 1 1050 9900 + -1 0 0 1 +$EndComp +Text Label 10650 5050 0 60 ~ 0 +QTop +Text Label 1300 9100 0 60 ~ 0 +Scope_CH1_DC +Text Label 1300 9300 0 60 ~ 0 +Scoe_CH1_AC +Text Label 1300 9750 0 60 ~ 0 +Scope_CH2_DC +Text Label 1300 9950 0 60 ~ 0 +Scope_CH2_AC +Text Label 12250 10400 0 60 ~ 0 +S-Gen_CH1_DC +Text Label 12150 10050 0 60 ~ 0 +S-Gen_CH1_AC +Text Label 11950 11100 0 60 ~ 0 +S-Gen_CH2_DC +Text Label 12100 11350 0 60 ~ 0 +S-Gen_CH2_AC +Text Label 7950 9650 0 60 ~ 0 +V_minus_dac_out +Text Label 7900 11900 0 60 ~ 0 +V_minus_dac_out2 +Text Label 9300 9250 0 60 ~ 0 +Buffered_DAC_CH1 +Text Label 9050 11550 0 60 ~ 0 +Buffered_DAC_CH2 +Text Label 8150 10350 0 60 ~ 0 +S-Gen_Drain_Top_CH1 +Text Label 7150 12350 0 60 ~ 0 +S-Gen_Drain_Top_CH2 +Text Label 2650 8650 0 60 ~ 0 +Scope_Buffer_Input_CH1 +Text Label 2500 10450 0 60 ~ 0 +Scope_Buffer_Input_CH2 +Text Label 3800 5150 0 60 ~ 0 +D0_OUT +Text Label 3800 5250 0 60 ~ 0 +D1_OUT +Text Label 3800 5350 0 60 ~ 0 +D2-OUT +Text Label 3800 5450 0 60 ~ 0 +D3-OUT +Text Label 4950 5000 0 60 ~ 0 +D0-prefuse +Text Label 4900 5200 0 60 ~ 0 +D1-prefuse +Text Label 4900 5400 0 60 ~ 0 +D2-prefuse +Text Label 4900 5600 0 60 ~ 0 +D3-prefuse +Text Label 4300 4000 0 60 ~ 0 +PDI_CLK +Text Label 4950 4400 0 60 ~ 0 +PDI_DATA +Text Label 3750 4300 0 60 ~ 0 +3V3_OUT +Text Label 13200 4850 0 60 ~ 0 +Switch_OC +Text Label 1950 6950 0 60 ~ 0 +Disconnected_USB +Text Label 4500 5000 0 60 ~ 0 +D0_MID +Text Label 4550 5200 0 60 ~ 0 +D1_MID +Text Label 4500 5400 0 60 ~ 0 +D2_MID +Text Label 4550 5600 0 60 ~ 0 +D3_MID +Text Label 12250 4600 0 60 ~ 0 +PSU_Unfiltered_Raw +Text Label 13650 2950 0 60 ~ 0 +L-Ana_IN_CH1 +Text Label 14950 2950 0 60 ~ 0 +L-Ana_IN_CH2 +Text Label 10800 9250 0 60 ~ 0 +R22-R24 +Text Label 11000 11550 0 60 ~ 0 +R23-R25 +$Comp +L C C12 +U 1 1 588029E7 +P 10100 5500 +F 0 "C12" H 10125 5600 50 0000 L CNN +F 1 "C" H 10125 5400 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 10138 5350 50 0001 C CNN +F 3 "" H 10100 5500 50 0000 C CNN + 1 10100 5500 + 1 0 0 -1 +$EndComp +Connection ~ 13950 5050 +Connection ~ 14450 5650 +Wire Wire Line + 13200 5050 14450 5050 +Wire Wire Line + 8900 5650 16400 5650 +Connection ~ 16350 5050 +Connection ~ 13950 5650 +Wire Wire Line + 15600 5050 15650 5050 +Wire Wire Line + 11900 5050 11250 5050 +Wire Wire Line + 16600 5650 16600 5500 +Wire Wire Line + 16600 5050 16600 5200 +Wire Wire Line + 12100 5350 12350 5350 +Connection ~ 10300 5350 +Connection ~ 10300 5650 +Wire Wire Line + 10100 5350 10450 5350 +Wire Wire Line + 10750 5650 10750 5550 +Wire Wire Line + 10750 5150 10750 5050 +Wire Wire Line + 13950 5650 13950 5400 +Wire Wire Line + 8450 3600 8950 3600 +Connection ~ 8450 3600 +Connection ~ 8700 3600 +Connection ~ 8950 3600 +Connection ~ 8950 3900 +Connection ~ 8700 3900 +Connection ~ 8450 3900 +Connection ~ 8200 3900 +Wire Wire Line + 2550 4000 4850 4000 +Wire Wire Line + 2550 4600 2550 4000 +Wire Wire Line + 5200 4600 2550 4600 +Wire Wire Line + 5200 4400 5200 4600 +Wire Wire Line + 5200 4400 5250 4400 +Wire Wire Line + 3250 4300 2700 4300 +Wire Wire Line + 8200 3900 8950 3900 +Wire Wire Line + 3100 6950 3100 7050 +Connection ~ 2500 7050 +Wire Wire Line + 2500 7250 2500 7050 +Wire Wire Line + 1950 7050 4050 7050 +Connection ~ 9600 9250 +Connection ~ 10000 11550 +Wire Wire Line + 6000 6600 6000 7100 +Wire Wire Line + 6300 6700 6300 6600 +Connection ~ 10000 10900 +Wire Wire Line + 10000 11250 10000 10900 +Connection ~ 10150 10900 +Wire Wire Line + 10150 11100 10150 10900 +Wire Wire Line + 10950 11100 10150 11100 +Wire Wire Line + 10950 10150 10950 11100 +Wire Wire Line + 9600 10150 10950 10150 +Wire Wire Line + 9600 9550 9600 10150 +Connection ~ 4400 9750 +Wire Wire Line + 4400 9950 4400 9750 +Wire Wire Line + 4950 9950 4400 9950 +Wire Wire Line + 4950 10250 4950 9950 +Wire Wire Line + 4700 10550 4950 10550 +Wire Wire Line + 4150 9250 4150 9750 +Wire Wire Line + 4150 9250 4900 9250 +Wire Wire Line + 4900 9250 4900 9050 +Wire Wire Line + 4700 8750 4900 8750 +Connection ~ 8100 12050 +Wire Wire Line + 8100 12050 8600 12050 +Connection ~ 7900 12350 +Wire Wire Line + 7150 12350 7150 10900 +Wire Wire Line + 7150 12350 8100 12350 +Connection ~ 8150 9750 +Wire Wire Line + 7950 10050 7950 10350 +Wire Wire Line + 8150 10050 7950 10050 +Wire Wire Line + 12100 10900 12250 10900 +Wire Wire Line + 12100 11650 12100 10900 +Wire Wire Line + 11500 11650 12100 11650 +Wire Wire Line + 11950 10800 12250 10800 +Wire Wire Line + 11950 11550 11950 10800 +Wire Wire Line + 12150 10700 12250 10700 +Wire Wire Line + 12150 9350 12150 10700 +Wire Wire Line + 12250 9250 12250 10600 +Wire Wire Line + 11150 9250 12250 9250 +Wire Wire Line + 8950 9250 10500 9250 +Wire Wire Line + 8900 11550 10700 11550 +Wire Wire Line + 8800 10600 8500 10600 +Wire Wire Line + 8800 10750 8100 10750 +Wire Wire Line + 7150 10900 8800 10900 +Wire Wire Line + 8550 12050 7900 12050 +Wire Wire Line + 8900 12050 8900 11550 +Wire Wire Line + 8850 12050 8900 12050 +Wire Wire Line + 7900 12050 7900 11650 +Wire Wire Line + 9700 10750 10350 10750 +Wire Wire Line + 9700 10900 10300 10900 +Wire Wire Line + 9700 10350 9700 10600 +Wire Wire Line + 7950 10350 9700 10350 +Wire Wire Line + 8950 9750 8950 9250 +Wire Wire Line + 8850 9750 8950 9750 +Wire Wire Line + 7950 9750 8550 9750 +Wire Wire Line + 7950 9350 7950 9750 +Wire Wire Line + 7900 3900 9200 3900 +Connection ~ 9200 3600 +Connection ~ 10150 3600 +Wire Wire Line + 10000 3600 10400 3600 +Wire Wire Line + 9150 3600 9400 3600 +Wire Wire Line + 6250 4000 6250 3900 +Wire Wire Line + 6200 6600 6200 6950 +Wire Wire Line + 4050 6650 3500 6650 +Wire Wire Line + 4050 6750 4050 6650 +Connection ~ 3500 7050 +Connection ~ 4150 9750 +Wire Wire Line + 11300 11550 11950 11550 +Wire Wire Line + 11300 11650 11300 11550 +Wire Wire Line + 7900 11450 7350 11450 +Wire Wire Line + 3600 9750 4750 9750 +Wire Wire Line + 3600 9700 3600 9750 +Wire Wire Line + 4850 4000 4850 4300 +Wire Wire Line + 5050 4400 4850 4400 +Wire Wire Line + 5050 4300 5050 4400 +Wire Wire Line + 5250 4300 5050 4300 +Wire Wire Line + 10150 3900 10800 3900 +Wire Wire Line + 4350 4400 3900 4400 +Wire Wire Line + 3450 4300 4350 4300 +Connection ~ 10750 5650 +Connection ~ 9600 5650 +Wire Wire Line + 9600 5500 9600 5650 +Connection ~ 9300 5650 +Wire Wire Line + 9300 5500 9300 5650 +Connection ~ 9300 5050 +Wire Wire Line + 9300 5200 9300 5050 +Connection ~ 9600 5050 +Wire Wire Line + 9600 4850 9600 5200 +Connection ~ 10750 5050 +Wire Wire Line + 9650 5050 8900 5050 +Wire Wire Line + 1950 7250 1950 7050 +Wire Wire Line + 1550 7250 1950 7250 +Wire Wire Line + 5250 6000 4750 6000 +Wire Wire Line + 7050 6000 7600 6000 +Wire Wire Line + 15250 3450 14850 3450 +Wire Wire Line + 15250 2950 15250 3450 +Wire Wire Line + 14450 2950 15250 2950 +Wire Wire Line + 13550 2950 14350 2950 +Wire Wire Line + 13550 3450 13550 2950 +Wire Wire Line + 13950 3450 13550 3450 +Wire Wire Line + 13950 3600 13550 3600 +Wire Wire Line + 13950 3300 13700 3300 +Wire Wire Line + 6150 4000 6150 3800 +Wire Wire Line + 6100 6600 6100 6800 +Wire Wire Line + 3600 9500 3150 9500 +Wire Wire Line + 3600 9700 3150 9700 +Wire Wire Line + 5250 6200 5100 6200 +Wire Wire Line + 5250 6300 5100 6300 +Wire Wire Line + 4000 5600 4200 5600 +Wire Wire Line + 4000 5450 4000 5600 +Wire Wire Line + 3750 5450 4000 5450 +Wire Wire Line + 4000 5400 4200 5400 +Wire Wire Line + 4000 5350 4000 5400 +Wire Wire Line + 3750 5350 4000 5350 +Wire Wire Line + 4000 5250 3750 5250 +Wire Wire Line + 4000 5200 4000 5250 +Wire Wire Line + 4200 5200 4000 5200 +Wire Wire Line + 4000 5000 4200 5000 +Wire Wire Line + 4000 5150 4000 5000 +Wire Wire Line + 3750 5150 4000 5150 +Wire Wire Line + 5050 5450 5250 5450 +Wire Wire Line + 5050 5600 5050 5450 +Wire Wire Line + 4850 5600 5050 5600 +Wire Wire Line + 5050 5350 5250 5350 +Wire Wire Line + 5050 5400 5050 5350 +Wire Wire Line + 4850 5400 5050 5400 +Wire Wire Line + 5050 5250 5250 5250 +Wire Wire Line + 5050 5200 5050 5250 +Wire Wire Line + 4850 5200 5050 5200 +Wire Wire Line + 5050 5150 5250 5150 +Wire Wire Line + 5050 5000 5050 5150 +Wire Wire Line + 4850 5000 5050 5000 +Wire Wire Line + 4500 5600 4550 5600 +Wire Wire Line + 4500 5400 4550 5400 +Wire Wire Line + 4500 5200 4550 5200 +Wire Wire Line + 4500 5000 4550 5000 +Wire Wire Line + 10800 9250 10850 9250 +Wire Wire Line + 1950 6650 2700 6650 +Wire Wire Line + 2700 6650 2700 6850 +Connection ~ 2700 7050 +Connection ~ 3100 7050 +Wire Wire Line + 3500 6650 3500 6850 +Wire Wire Line + 2150 9250 2350 9250 +Wire Wire Line + 2850 9500 2850 9700 +Wire Wire Line + 2350 9550 2350 9650 +Wire Wire Line + 2350 9600 2850 9600 +Connection ~ 2850 9600 +Connection ~ 2350 9600 +Wire Wire Line + 3700 8850 3700 9000 +Wire Wire Line + 3700 9000 4700 9000 +Wire Wire Line + 4700 9000 4700 8750 +Wire Wire Line + 2350 9250 2350 8650 +Wire Wire Line + 2350 8650 3700 8650 +Wire Wire Line + 3700 10650 3700 10800 +Wire Wire Line + 3700 10800 4700 10800 +Wire Wire Line + 4700 10800 4700 10550 +Wire Wire Line + 2350 10450 3700 10450 +Wire Wire Line + 2350 9950 2350 10450 +Wire Wire Line + 2150 9950 2350 9950 +Wire Wire Line + 11350 9350 12150 9350 +Wire Wire Line + 7950 9150 7400 9150 +Wire Wire Line + 11150 9250 11150 9350 +Wire Wire Line + 11500 5050 11500 5250 +Wire Wire Line + 11500 5650 11500 5550 +Connection ~ 11500 5650 +Connection ~ 11500 5050 +Connection ~ 16350 5650 +Wire Wire Line + 16600 5050 16250 5050 +Connection ~ 12100 5650 +Wire Wire Line + 12600 5050 12600 5650 +Connection ~ 12600 5650 +Wire Wire Line + 11900 5050 11900 4850 +Wire Wire Line + 13050 4600 13050 4950 +Wire Wire Line + 12100 4600 15000 4600 +Wire Wire Line + 15000 4600 15000 5200 +Wire Wire Line + 12100 4600 12100 5050 +Wire Wire Line + 11900 4850 12600 4850 +Connection ~ 12100 4850 +Wire Wire Line + 12350 5350 12350 4950 +Wire Wire Line + 12350 4950 12600 4950 +Connection ~ 13050 4600 +Wire Wire Line + 13950 5300 13950 5050 +Wire Wire Line + 13050 4950 13200 4950 +Wire Wire Line + 1850 9100 1850 9400 +Wire Wire Line + 1850 9100 1250 9100 +Wire Wire Line + 1250 9200 1850 9200 +Connection ~ 1850 9200 +Wire Wire Line + 1850 9400 1250 9400 +Connection ~ 1850 9250 +Wire Wire Line + 1250 9300 1350 9300 +Wire Wire Line + 1550 9300 1850 9300 +Connection ~ 1850 9300 +Wire Wire Line + 1850 9950 1650 9950 +Wire Wire Line + 1450 9950 1250 9950 +Wire Wire Line + 1850 9750 1850 10050 +Wire Wire Line + 1850 10050 1250 10050 +Wire Wire Line + 1250 9850 1850 9850 +Connection ~ 1850 9950 +Wire Wire Line + 1250 9750 1850 9750 +Connection ~ 1850 9850 +Connection ~ 15000 5050 +Wire Wire Line + 15000 5500 15000 5650 +Connection ~ 15000 5650 +Wire Wire Line + 16350 5200 16350 5050 +Wire Wire Line + 16350 5500 16350 5650 +Wire Wire Line + 8200 3600 9200 3600 +Connection ~ 10100 5650 +Wire Wire Line + 10950 5050 10650 5050 +$Comp +L F_Small F2 +U 1 1 58F5AF9C +P 9750 5050 +F 0 "F2" H 9710 5110 50 0000 L CNN +F 1 "F_Small" H 9630 4990 50 0000 L CNN +F 2 "Capacitors_SMD:C_1210" H 9750 5050 50 0001 C CNN +F 3 "" H 9750 5050 50 0000 C CNN + 1 9750 5050 + 1 0 0 -1 +$EndComp +Wire Wire Line + 9850 5050 10050 5050 +$Comp +L CONN_01X02 P9 +U 1 1 58FEDB8C +P 9750 4650 +F 0 "P9" H 9750 4800 50 0000 C CNN +F 1 "FUSE_BYPASS" V 9850 4650 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x02" H 9750 4650 60 0001 C CNN +F 3 "" H 9750 4650 60 0000 C CNN + 1 9750 4650 + 0 -1 -1 0 +$EndComp +Wire Wire Line + 9700 4850 9600 4850 +Wire Wire Line + 9800 4850 9950 4850 +Wire Wire Line + 9950 4850 9950 5050 +Connection ~ 9950 5050 +$EndSCHEMATC diff --git a/PCB/Tinylab_proto1.bak.REMOVED.git-id b/PCB/Tinylab_proto1.bak.REMOVED.git-id deleted file mode 100644 index 400de5b5..00000000 --- a/PCB/Tinylab_proto1.bak.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -740b0f8ce0476851f991b01137d7cde9b9690082 \ No newline at end of file diff --git a/PCB/Tinylab_proto1.csv b/PCB/Tinylab_proto1.csv new file mode 100644 index 00000000..713d1a0c --- /dev/null +++ b/PCB/Tinylab_proto1.csv @@ -0,0 +1,67 @@ +Reference; Value; Footprint; Datasheet +C1;SMD MLCC 1uF 16V 0603;Capacitors_SMD:C_0603; +C2;SMD MLCC 1uF 16V 0603;Capacitors_SMD:C_0603; +C3;SMD MLCC 1uF 16V 0603;Capacitors_SMD:C_0603; +C4;SMD MLCC 1uF 16V 0603;Capacitors_SMD:C_0603; +C5;SMD MLCC 1uF 16V 0603;Capacitors_SMD:C_0603; +C6;SMD 4mm 33uF;Capacitors_SMD:c_elec_5x5.3; +C7;SMD MLCC 1uF 16V 0603;Capacitors_SMD:C_0603; +C8;SMD MLCC 1uF 16V 0603;Capacitors_SMD:C_0603; +C9;SMD 4mm 33uF;Capacitors_SMD:c_elec_4x5.3; +C10;SMD MLCC 1uF 16V 0603;Capacitors_SMD:C_0603; +C11;SMD MLCC 1uF 16V 0603;Capacitors_SMD:C_0603; +C13;SMD MLCC 1uF 16V 0603;Capacitors_SMD:C_0603; +C14;SMD MLCC 1uF 16V 0603;Capacitors_SMD:C_0603; +C15;Thru Hole 6.3mm 220uF;Capacitors_ThroughHole:C_Radial_D6.3_L11.2_P2.5; +C16;SMD MLCC 1uF 16V 0603;Capacitors_SMD:C_0603; +D1;Thru Hole Schottky 1A;Diodes_ThroughHole:Diode_DO-41_SOD81_Horizontal_RM10; +F1;SMD PTC 400mA;Capacitors_SMD:C_1206; +IC1;QFN ATXMEGA16A4U-A;Housings_QFP:LQFP-44_10x10mm_Pitch0.8mm; +L1;Thru Hole Radial 220uH;Inductors:INDUCTOR_V; +L2;SMD 10uH 1210;Resistors_SMD:R_1210; +L3;SMD 10uH 1210;Resistors_SMD:R_1210; +P1;Female Header 1x2;Pin_Headers:Pin_Header_Straight_1x02; +P2;Micro USB-B Connector (F);Connect:USB_Micro-B_WIDE; +P3;Male header 1x4;Pin_Headers:Pin_Header_Straight_1x04; +P4;Male header 2x2;Pin_Headers:Pin_Header_Straight_2x02; +P5;Female Header 1x2;Pin_Headers:Pin_Header_Straight_1x02; +P6;Male header 1x4;Pin_Headers:Pin_Header_Straight_1x04; +P7;Male header 1x2;Pin_Headers:Pin_Header_Straight_2x02; +P8;Feamle Header 1x2;Pin_Headers:Pin_Header_Straight_1x02; +P9;Female Header 1x2;Pin_Headers:Pin_Header_Straight_1x02; +P10;Female Header 1x2;Pin_Headers:Pin_Header_Straight_1x02; +Q1;SMD nMOS Transistor TSM2302CX ;SMD:SOT-23-3; +R1;SMD 1M? 20V 0603;Resistors_SMD:R_0603; +R2;SMD 1M? 20V 0603;Resistors_SMD:R_0603; +R3;SMD 75k? 6.3V 0603;Resistors_SMD:R_0603; +R4;SMD 75k? 6.3V 0603;Resistors_SMD:R_0603; +R5;SMD 1k? 16V 0603;Resistors_SMD:R_0603; +R6;SMD 1k? 16V 0603;Resistors_SMD:R_0603; +R7;SMD 28? 6.3V 0603;Resistors_SMD:R_0603; +R8;SMD 28? 6.3V 0603;Resistors_SMD:R_0603; +R9;SMD 28? 6.3V 0603;Resistors_SMD:R_0603; +R10;SMD 28? 6.3V 0603;Resistors_SMD:R_0603; +R11;SMD 28? 6.3V 0603;Resistors_SMD:R_0603; +R12;SMD 28? 6.3V 0603;Resistors_SMD:R_0603; +R13;SMD 28? 6.3V 0603;Resistors_SMD:R_0603; +R14;SMD 28? 6.3V 0603;Resistors_SMD:R_0603; +R15;SMD 1k? 16V 0603;Resistors_SMD:R_0603; +R16;SMD 1k? 16V 0603;Resistors_SMD:R_0603; +R17;SMD 1k? 16V 0603;Resistors_SMD:R_0603; +R18;SMD 1k? 16V 0603;Resistors_SMD:R_0603; +R19;SMD 1k? 16V 0603;Resistors_SMD:R_0603; +R20;SMD 1k? 16V 0603;Resistors_SMD:R_0603; +R21;SMD 100? 16V 0603;Resistors_SMD:R_0603; +R22;SMD 28? 6.3V 0603;Resistors_SMD:R_0603; +R23;SMD 28? 6.3V 0603;Resistors_SMD:R_0603; +R24;SMD 28? 6.3V 0603;Resistors_SMD:R_0603; +R25;SMD 28? 6.3V 0603;Resistors_SMD:R_0603; +R26;SMD 1k? 16V 0603;Resistors_SMD:R_0603; +R27;SMD 100? 16V 0603;Resistors_SMD:R_0603; +R28;SMD 100? 16V 0603;Resistors_SMD:R_0603; +R29;SMD 100? 16V 0603;Resistors_SMD:R_0603; +R30;SMD 100? 16V 0603;Resistors_SMD:R_0603; +U1;SMD 3.3V Reg RT9161A-33GV;SMD:SOT-23-3; +U2;SMD LM324;Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm; +U3;SMD DMN63D8LDW;TO_SOT_Packages_SMD:SOT-363; +U4;SMD DMN63D8LDW;TO_SOT_Packages_SMD:SOT-363; diff --git a/PCB/Tinylab_proto1.csv.REMOVED.git-id b/PCB/Tinylab_proto1.csv.REMOVED.git-id deleted file mode 100644 index b3511137..00000000 --- a/PCB/Tinylab_proto1.csv.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -713d1a0c67f1d7c1271c6fcc7f6aef008d2141f6 \ No newline at end of file diff --git a/PCB/Tinylab_proto1.drl b/PCB/Tinylab_proto1.drl new file mode 100644 index 00000000..cbbd039a --- /dev/null +++ b/PCB/Tinylab_proto1.drl @@ -0,0 +1,130 @@ +M48 +;DRILL file {KiCad 4.0.4-stable} date 11/23/16 11:35:24 +;FORMAT={-:-/ absolute / inch / decimal} +FMAT,2 +INCH,TZ +T1C0.016 +T2C0.022 +T3C0.028 +T4C0.040 +% +G90 +G05 +M72 +T1 +X2.854Y-4.442 +X2.973Y-4.31 +X2.98Y-4.5475 +X2.9825Y-4.6475 +X2.9825Y-4.73 +X3.005Y-5.158 +X3.025Y-4.8275 +X3.032Y-5.014 +X3.05Y-4.12 +X3.055Y-4.937 +X3.079Y-5.17 +X3.0875Y-5.015 +X3.1175Y-5.1025 +X3.119Y-5.03 +X3.145Y-4.875 +X3.1475Y-4.49 +X3.15Y-4.775 +X3.152Y-4.816 +X3.161Y-4.976 +X3.21Y-4.255 +X3.214Y-5.246 +X3.226Y-4.804 +X3.25Y-5.0075 +X3.26Y-4.846 +X3.267Y-4.748 +X3.295Y-4.39 +X3.304Y-5.114 +X3.304Y-5.198 +X3.376Y-5.156 +X3.39Y-4.915 +X3.418Y-5.071 +X3.426Y-4.491 +X3.43Y-4.97 +X3.498Y-5.014 +X3.51Y-4.75 +X3.5175Y-4.79 +X3.5175Y-4.88 +X3.5225Y-4.6125 +X3.554Y-4.797 +X3.5675Y-4.87 +X3.621Y-5.014 +X3.635Y-4.8825 +X3.6575Y-4.5925 +X3.662Y-4.097 +X3.6875Y-4.9225 +X3.694Y-4.829 +X3.721Y-4.871 +X3.736Y-4.162 +X3.748Y-4.82 +X3.753Y-5.175 +X3.76Y-4.29 +X3.7625Y-4.4325 +X3.7725Y-4.58 +X3.775Y-4.917 +X3.7775Y-4.7475 +X3.782Y-5.219 +X3.7825Y-4.785 +X3.785Y-4.6275 +X3.814Y-4.851 +X3.8175Y-4.6575 +X3.864Y-4.81 +X3.864Y-5.174 +X3.865Y-4.778 +X3.871Y-5.255 +X3.885Y-4.535 +X3.9025Y-4.42 +X3.978Y-4.334 +X4.047Y-4.413 +X4.067Y-4.081 +X4.078Y-4.15 +X4.123Y-4.851 +T4 +X2.8Y-4. +X2.8Y-4.1 +X2.8Y-4.2 +X2.8Y-4.3 +X2.8Y-4.4 +X2.8Y-4.5 +X2.8Y-4.6 +X2.8Y-4.7 +X2.8Y-4.8 +X2.8Y-4.9 +X2.8Y-5. +X2.8Y-5.1 +X2.8Y-5.2 +X2.9Y-4. +X2.9Y-4.1 +X2.9Y-4.2 +X2.9Y-4.3 +X2.9Y-4.4 +X3.05Y-4.35 +X3.15Y-4.35 +X3.3775Y-5.2175 +X3.4775Y-5.0925 +X3.4775Y-5.2175 +X3.5775Y-5.0925 +X3.5775Y-5.2175 +X3.6775Y-5.0925 +X3.6775Y-5.2175 +X3.7775Y-5.0925 +X4.113Y-5.103 +X4.113Y-5.203 +X4.118Y-4.543 +X4.118Y-4.643 +T2 +X4.021Y-3.993G85X4.021Y-3.9753 +G05 +X4.021Y-4.1898G85X4.021Y-4.1721 +G05 +T3 +X4.1361Y-3.9447G85X4.1184Y-3.9447 +G05 +X4.1361Y-4.2203G85X4.1184Y-4.2203 +G05 +T0 +M30 diff --git a/PCB/Tinylab_proto1.drl.REMOVED.git-id b/PCB/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index b011a9c5..00000000 --- a/PCB/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -cbbd039afd661cda85fd260a13cb877087ecb952 \ No newline at end of file diff --git a/PCB/Tinylab_proto1.dsn b/PCB/Tinylab_proto1.dsn new file mode 100644 index 00000000..c4122e91 --- /dev/null +++ b/PCB/Tinylab_proto1.dsn @@ -0,0 +1,763 @@ +(pcb C:\Users\Esposch\Documents\KiCAD\Tinylab_proto1\Tinylab_proto1.dsn + (parser + (string_quote ") + (space_in_quoted_tokens on) + (host_cad "KiCad's Pcbnew") + (host_version "(2015-08-05 BZR 6055, Git fa29c62)-product") + ) + (resolution um 10) + (unit um) + (structure + (layer F.Cu + (type signal) + (property + (index 0) + ) + ) + (layer B.Cu + (type signal) + (property + (index 1) + ) + ) + (boundary + (path pcb 0 81280 -53340 240030 -53340 240030 -147320 81280 -147320 + 81280 -53340 81280 -53340) + ) + (via "Via[0-1]_600:400_um") + (rule + (width 250) + (clearance 200.1) + (clearance 200.1 (type default_smd)) + (clearance 50 (type smd_smd)) + ) + ) + (placement + (component Capacitors_SMD:C_1812_HandSoldering + (place C1 208215 -100175 front 0 (PN C)) + (place C3 184915 -123725 front 0 (PN C_Small)) + (place C4 192075 -115425 front 0 (PN C_Small)) + (place C5 203015 -123525 front 0 (PN C_Small)) + (place C6 210175 -108275 front 0 (PN C_Small)) + (place C7 193965 -123525 front 0 (PN C)) + (place C8 201125 -115425 front 0 (PN C_Small)) + ) + (component Capacitors_SMD:C_1812 + (place C2 210865 -116375 front 0 (PN C)) + ) + (component Capacitors_Elko_ThroughHole:Elko_vert_11.2x6.3mm_RM2.5_CopperClear + (place C9 124855 -107555 front 0 (PN CP1)) + ) + (component Resistors_SMD:R_2512_HandSoldering + (place F1 174565 -88175 front 0 (PN F_Small)) + (place R1 162915 -88175 front 0 (PN R)) + (place R2 151265 -88175 front 0 (PN R)) + (place R3 139615 -102775 front 0 (PN R)) + (place R4 127965 -118875 front 0 (PN R)) + (place R5 174565 -121375 front 0 (PN R)) + (place R6 116315 -118875 front 0 (PN R)) + (place R7 186215 -96475 front 0 (PN R)) + (place R8 151265 -104775 front 0 (PN R)) + (place R9 162915 -104775 front 0 (PN R)) + (place R10 174565 -104775 front 0 (PN R)) + (place R11 186215 -104775 front 0 (PN R)) + (place R12 139615 -113075 front 0 (PN R)) + (place R13 151265 -113075 front 0 (PN R)) + (place R14 162915 -113075 front 0 (PN R)) + (place R15 174565 -113075 front 0 (PN R)) + (place R16 139615 -121375 front 0 (PN R)) + (place R17 174565 -96475 front 0 (PN R)) + (place R18 197865 -96475 front 0 (PN R)) + (place R19 162915 -121375 front 0 (PN R)) + (place R20 162915 -96475 front 0 (PN R)) + (place R21 151265 -121375 front 0 (PN R)) + (place R22 151265 -96475 front 0 (PN R)) + (place R23 197865 -88175 front 0 (PN R)) + (place R24 186215 -88175 front 0 (PN R)) + ) + (component "Housings_QFP:LQFP-44_10x10mm_Pitch0.8mm" + (place IC1 117615 -92725 front 0 (PN "ATXMEGA16A4U-A")) + ) + (component Pin_Headers:Pin_Header_Straight_1x04 + (place P1 128610 -90175 front 0 (PN SCOPE_IN)) + (place P3 208343 -76075 front 0 (PN DIG_OUT)) + ) + (component "Connect:USB_Micro-B" + (place P2 208515 -90275 front 0 (PN USB_OTG)) + ) + (component Pin_Headers:Pin_Header_Straight_1x03 + (place P4 116598 -107575 front 0 (PN OPAMP_JUMPER)) + ) + (component Pin_Headers:Pin_Header_Straight_1x02 + (place P5 213635 -76075 front 0 (PN HVI)) + (place P6 183975 -115075 front 0 (PN AWG_OUT)) + (place P7 131515 -106025 front 0 (PN HVO)) + (place P8 194696 -106775 front 0 (PN DIG_IN)) + ) + (component Connect:C96ABCFD + (place T1 157755 -78595 front 0 (PN TIP29A)) + ) + (component "SMD:SOT-23-3" + (place U1 120685 -125535 front 0 (PN 78L05)) + ) + (component "Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm" + (place U2 136405 -92200 front 0 (PN LM324)) + ) + (component Footprints:SOT363 + (place U3 113928 -125375 front 0 (PN DMN63D8LDW)) + ) + ) + (library + (image Capacitors_SMD:C_1812_HandSoldering + (outline (path signal 50 -4300 1850 4300 1850)) + (outline (path signal 50 -4300 -1850 4300 -1850)) + (outline (path signal 50 -4300 1850 -4300 -1850)) + (outline (path signal 50 4300 1850 4300 -1850)) + (outline (path signal 150 1800 1725 -1800 1725)) + (outline (path signal 150 -1800 -1725 1800 -1725)) + (pin Rect[T]Pad_2200x3000_um 1 -2900 0) + (pin Rect[T]Pad_2200x3000_um 2 2900 0) + ) + (image Capacitors_SMD:C_1812 + (outline (path signal 50 -3100 1850 3100 1850)) + (outline (path signal 50 -3100 -1850 3100 -1850)) + (outline (path signal 50 -3100 1850 -3100 -1850)) + (outline (path signal 50 3100 1850 3100 -1850)) + (outline (path signal 150 1800 1725 -1800 1725)) + (outline (path signal 150 -1800 -1725 1800 -1725)) + (pin Rect[T]Pad_1000x3000_um 1 -2300 0) + (pin Rect[T]Pad_1000x3000_um 2 2300 0) + ) + (image Capacitors_Elko_ThroughHole:Elko_vert_11.2x6.3mm_RM2.5_CopperClear + (outline (path signal 150 269.24 1699.26 769.62 1699.26)) + (outline (path signal 150 269.24 1699.26 269.24 2199.64)) + (outline (path signal 150 -231.14 1699.26 269.24 1699.26)) + (outline (path signal 150 269.24 1699.26 269.24 1300.48)) + (outline (path signal 150 269.24 1300.48 269.24 1198.88)) + (outline (path signal 150 4419.6 0 4265.45 -973.28 3818.08 -1851.29 3121.29 -2548.08 + 2243.28 -2995.45 1270 -3149.6 296.72 -2995.45 -581.288 -2548.08 + -1278.08 -1851.29 -1725.45 -973.28 -1879.6 0 -1725.45 973.28 + -1278.08 1851.29 -581.288 2548.08 296.72 2995.45 1270 3149.6 + 2243.28 2995.45 3121.29 2548.08 3818.08 1851.29 4265.45 973.28)) + (pin Round[A]Pad_1501.14_um 2 2540 0) + (pin Round[A]Pad_1501.14_um 1 0 0) + ) + (image Resistors_SMD:R_2512_HandSoldering + (outline (path signal 50 -5600 1950 5600 1950)) + (outline (path signal 50 -5600 -1950 5600 -1950)) + (outline (path signal 50 -5600 1950 -5600 -1950)) + (outline (path signal 50 5600 1950 5600 -1950)) + (outline (path signal 150 2600 -1825 -2600 -1825)) + (outline (path signal 150 -2600 1825 2600 1825)) + (pin Rect[T]Pad_2700x3200_um 1 -3950 0) + (pin Rect[T]Pad_2700x3200_um 2 3950 0) + ) + (image "Housings_QFP:LQFP-44_10x10mm_Pitch0.8mm" + (outline (path signal 50 -6900 6900 -6900 -6900)) + (outline (path signal 50 6900 6900 6900 -6900)) + (outline (path signal 50 -6900 6900 6900 6900)) + (outline (path signal 50 -6900 -6900 6900 -6900)) + (outline (path signal 150 -5175 5175 -5175 4505)) + (outline (path signal 150 5175 5175 5175 4505)) + (outline (path signal 150 5175 -5175 5175 -4505)) + (outline (path signal 150 -5175 -5175 -5175 -4505)) + (outline (path signal 150 -5175 5175 -4505 5175)) + (outline (path signal 150 -5175 -5175 -4505 -5175)) + (outline (path signal 150 5175 -5175 4505 -5175)) + (outline (path signal 150 5175 5175 4505 5175)) + (outline (path signal 150 -5175 4505 -6650 4505)) + (pin Rect[T]Pad_1600x560_um 1 -5850 4000) + (pin Rect[T]Pad_1600x560_um 2 -5850 3200) + (pin Rect[T]Pad_1600x560_um 3 -5850 2400) + (pin Rect[T]Pad_1600x560_um 4 -5850 1600) + (pin Rect[T]Pad_1600x560_um 5 -5850 800) + (pin Rect[T]Pad_1600x560_um 6 -5850 0) + (pin Rect[T]Pad_1600x560_um 7 -5850 -800) + (pin Rect[T]Pad_1600x560_um 8 -5850 -1600) + (pin Rect[T]Pad_1600x560_um 9 -5850 -2400) + (pin Rect[T]Pad_1600x560_um 10 -5850 -3200) + (pin Rect[T]Pad_1600x560_um 11 -5850 -4000) + (pin Rect[T]Pad_1600x560_um (rotate 90) 12 -4000 -5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 13 -3200 -5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 14 -2400 -5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 15 -1600 -5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 16 -800 -5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 17 0 -5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 18 800 -5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 19 1600 -5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 20 2400 -5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 21 3200 -5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 22 4000 -5850) + (pin Rect[T]Pad_1600x560_um 23 5850 -4000) + (pin Rect[T]Pad_1600x560_um 24 5850 -3200) + (pin Rect[T]Pad_1600x560_um 25 5850 -2400) + (pin Rect[T]Pad_1600x560_um 26 5850 -1600) + (pin Rect[T]Pad_1600x560_um 27 5850 -800) + (pin Rect[T]Pad_1600x560_um 28 5850 0) + (pin Rect[T]Pad_1600x560_um 29 5850 800) + (pin Rect[T]Pad_1600x560_um 30 5850 1600) + (pin Rect[T]Pad_1600x560_um 31 5850 2400) + (pin Rect[T]Pad_1600x560_um 32 5850 3200) + (pin Rect[T]Pad_1600x560_um 33 5850 4000) + (pin Rect[T]Pad_1600x560_um (rotate 90) 34 4000 5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 35 3200 5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 36 2400 5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 37 1600 5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 38 800 5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 39 0 5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 40 -800 5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 41 -1600 5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 42 -2400 5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 43 -3200 5850) + (pin Rect[T]Pad_1600x560_um (rotate 90) 44 -4000 5850) + ) + (image Pin_Headers:Pin_Header_Straight_1x04 + (outline (path signal 50 -1750 1750 -1750 -9400)) + (outline (path signal 50 1750 1750 1750 -9400)) + (outline (path signal 50 -1750 1750 1750 1750)) + (outline (path signal 50 -1750 -9400 1750 -9400)) + (outline (path signal 150 -1270 -1270 -1270 -8890)) + (outline (path signal 150 1270 -1270 1270 -8890)) + (outline (path signal 150 1550 1550 1550 0)) + (outline (path signal 150 -1270 -8890 1270 -8890)) + (outline (path signal 150 1270 -1270 -1270 -1270)) + (outline (path signal 150 -1550 0 -1550 1550)) + (outline (path signal 150 -1550 1550 1550 1550)) + (pin Rect[A]Pad_2032x1727.2_um 1 0 0) + (pin Oval[A]Pad_2032x1727.2_um 2 0 -2540) + (pin Oval[A]Pad_2032x1727.2_um 3 0 -5080) + (pin Oval[A]Pad_2032x1727.2_um 4 0 -7620) + ) + (image "Connect:USB_Micro-B" + (outline (path signal 50 -4600 2800 4600 2800)) + (outline (path signal 50 4600 2800 4600 -4050)) + (outline (path signal 50 4600 -4050 -4600 -4050)) + (outline (path signal 50 -4600 -4050 -4600 2800)) + (outline (path signal 150 -4350.9 -3817.46 4349.1 -3817.46)) + (outline (path signal 150 -4350.9 2587.54 4349.1 2587.54)) + (outline (path signal 150 4349.1 2587.54 4349.1 -3817.46)) + (outline (path signal 150 4349.1 -2587.46 -4350.9 -2587.46)) + (outline (path signal 150 -4350.9 -3817.46 -4350.9 2587.54)) + (pin Rect[T]Pad_1350x400_um (rotate 90) 1 -1300.9 1562.54) + (pin Rect[T]Pad_1350x400_um (rotate 90) 2 -650.9 1562.54) + (pin Rect[T]Pad_1350x400_um (rotate 90) 3 -0.9 1562.54) + (pin Rect[T]Pad_1350x400_um (rotate 90) 4 649.1 1562.54) + (pin Rect[T]Pad_1350x400_um (rotate 90) 5 1299.1 1562.54) + (pin Oval[A]Pad_950x1250_um (rotate 90) 6 -2500.9 1562.54) + (pin Oval[A]Pad_950x1250_um (rotate 90) 6@1 2499.1 1562.54) + (pin Oval[A]Pad_1550x1000_um (rotate 90) 6@2 -3500.9 -1137.46) + (pin Oval[A]Pad_1550x1000_um (rotate 90) 6@3 3499.1 -1137.46) + ) + (image Pin_Headers:Pin_Header_Straight_1x03 + (outline (path signal 50 -1750 1750 -1750 -6850)) + (outline (path signal 50 1750 1750 1750 -6850)) + (outline (path signal 50 -1750 1750 1750 1750)) + (outline (path signal 50 -1750 -6850 1750 -6850)) + (outline (path signal 150 -1270 -1270 -1270 -6350)) + (outline (path signal 150 -1270 -6350 1270 -6350)) + (outline (path signal 150 1270 -6350 1270 -1270)) + (outline (path signal 150 1550 1550 1550 0)) + (outline (path signal 150 1270 -1270 -1270 -1270)) + (outline (path signal 150 -1550 0 -1550 1550)) + (outline (path signal 150 -1550 1550 1550 1550)) + (pin Rect[A]Pad_2032x1727.2_um 1 0 0) + (pin Oval[A]Pad_2032x1727.2_um 2 0 -2540) + (pin Oval[A]Pad_2032x1727.2_um 3 0 -5080) + ) + (image Pin_Headers:Pin_Header_Straight_1x02 + (outline (path signal 150 1270 -1270 1270 -3810)) + (outline (path signal 150 1550 1550 1550 0)) + (outline (path signal 50 -1750 1750 -1750 -4300)) + (outline (path signal 50 1750 1750 1750 -4300)) + (outline (path signal 50 -1750 1750 1750 1750)) + (outline (path signal 50 -1750 -4300 1750 -4300)) + (outline (path signal 150 1270 -1270 -1270 -1270)) + (outline (path signal 150 -1550 0 -1550 1550)) + (outline (path signal 150 -1550 1550 1550 1550)) + (outline (path signal 150 -1270 -1270 -1270 -3810)) + (outline (path signal 150 -1270 -3810 1270 -3810)) + (pin Rect[A]Pad_2032x2032_um 1 0 0) + (pin Oval[A]Pad_2032x2032_um 2 0 -2540) + ) + (image Connect:C96ABCFD + (outline (path signal 150 -46990 -5080 46990 -5080)) + (outline (path signal 150 46990 -5080 46990 2540)) + (outline (path signal 150 -46990 2540 -46990 -5080)) + (outline (path signal 150 -41910 2540 -41910 -5080)) + (outline (path signal 150 41910 2540 41910 -5080)) + (outline (path signal 150 -46990 2540 -46990 5080)) + (outline (path signal 150 -46990 5080 46990 5080)) + (outline (path signal 150 46990 5080 46990 2540)) + (outline (path signal 150 41910 5080 41910 2540)) + (outline (path signal 150 -41910 2540 -41910 5080)) + (pin Round[A]Pad_3810_um 65 -44450 0) + (pin Round[A]Pad_3810_um 66 44450 0) + (pin Round[A]Pad_1524_um A3 -34290 -2540) + (pin Round[A]Pad_1524_um A4 -31750 -2540) + (pin Round[A]Pad_1524_um A5 -29210 -2540) + (pin Round[A]Pad_1524_um A6 -26670 -2540) + (pin Round[A]Pad_1524_um A7 -24130 -2540) + (pin Round[A]Pad_1524_um A8 -21590 -2540) + (pin Round[A]Pad_1524_um A9 -19050 -2540) + (pin Round[A]Pad_1524_um A10 -16510 -2540) + (pin Round[A]Pad_1524_um A11 -13970 -2540) + (pin Round[A]Pad_1524_um A12 -11430 -2540) + (pin Round[A]Pad_1524_um A13 -8890 -2540) + (pin Round[A]Pad_1524_um A14 -6350 -2540) + (pin Round[A]Pad_1524_um A15 -3810 -2540) + (pin Round[A]Pad_1524_um A16 -1270 -2540) + (pin Round[A]Pad_1524_um A17 1270 -2540) + (pin Round[A]Pad_1524_um A18 3810 -2540) + (pin Round[A]Pad_1524_um A19 6350 -2540) + (pin Round[A]Pad_1524_um A20 8890 -2540) + (pin Round[A]Pad_1524_um A21 11430 -2540) + (pin Round[A]Pad_1524_um A22 13970 -2540) + (pin Round[A]Pad_1524_um A23 16510 -2540) + (pin Round[A]Pad_1524_um A24 19050 -2540) + (pin Round[A]Pad_1524_um A25 21590 -2540) + (pin Round[A]Pad_1524_um A26 24130 -2540) + (pin Round[A]Pad_1524_um A27 26670 -2540) + (pin Round[A]Pad_1524_um A28 29210 -2540) + (pin Round[A]Pad_1524_um A29 31750 -2540) + (pin Round[A]Pad_1524_um A30 34290 -2540) + (pin Round[A]Pad_1524_um A31 36830 -2540) + (pin Round[A]Pad_1524_um A32 39370 -2540) + (pin Round[A]Pad_1524_um A2 -36830 -2540) + (pin Rect[A]Pad_1524x1524_um A1 -39370 -2540) + (pin Round[A]Pad_1524_um B1 -39370 0) + (pin Round[A]Pad_1524_um B2 -36830 0) + (pin Round[A]Pad_1524_um B3 -34290 0) + (pin Round[A]Pad_1524_um B4 -31750 0) + (pin Round[A]Pad_1524_um B5 -29210 0) + (pin Round[A]Pad_1524_um B6 -26670 0) + (pin Round[A]Pad_1524_um B7 -24130 0) + (pin Round[A]Pad_1524_um B8 -21590 0) + (pin Round[A]Pad_1524_um B9 -19050 0) + (pin Round[A]Pad_1524_um B10 -16510 0) + (pin Round[A]Pad_1524_um B11 -13970 0) + (pin Round[A]Pad_1524_um B12 -11430 0) + (pin Round[A]Pad_1524_um B13 -8890 0) + (pin Round[A]Pad_1524_um B14 -6350 0) + (pin Round[A]Pad_1524_um B15 -3810 0) + (pin Round[A]Pad_1524_um B16 -1270 0) + (pin Round[A]Pad_1524_um B17 1270 0) + (pin Round[A]Pad_1524_um B18 3810 0) + (pin Round[A]Pad_1524_um B19 6350 0) + (pin Round[A]Pad_1524_um B20 8890 0) + (pin Round[A]Pad_1524_um B21 11430 0) + (pin Round[A]Pad_1524_um B22 13970 0) + (pin Round[A]Pad_1524_um B23 16510 0) + (pin Round[A]Pad_1524_um B24 19050 0) + (pin Round[A]Pad_1524_um B25 21590 0) + (pin Round[A]Pad_1524_um B26 24130 0) + (pin Round[A]Pad_1524_um B27 26670 0) + (pin Round[A]Pad_1524_um B28 29210 0) + (pin Round[A]Pad_1524_um B29 31750 0) + (pin Round[A]Pad_1524_um B30 34290 0) + (pin Round[A]Pad_1524_um B31 36830 0) + (pin Round[A]Pad_1524_um B32 39370 0) + (pin Round[A]Pad_1524_um C1 -39370 2540) + (pin Round[A]Pad_1524_um C2 -36830 2540) + (pin Round[A]Pad_1524_um C3 -34290 2540) + (pin Round[A]Pad_1524_um C4 -31750 2540) + (pin Round[A]Pad_1524_um C5 -29210 2540) + (pin Round[A]Pad_1524_um C6 -26670 2540) + (pin Round[A]Pad_1524_um C7 -24130 2540) + (pin Round[A]Pad_1524_um C8 -21590 2540) + (pin Round[A]Pad_1524_um C9 -19050 2540) + (pin Round[A]Pad_1524_um C10 -16510 2540) + (pin Round[A]Pad_1524_um C11 -13970 2540) + (pin Round[A]Pad_1524_um C12 -11430 2540) + (pin Round[A]Pad_1524_um C13 -8890 2540) + (pin Round[A]Pad_1524_um C14 -6350 2540) + (pin Round[A]Pad_1524_um C15 -3810 2540) + (pin Round[A]Pad_1524_um C16 -1270 2540) + (pin Round[A]Pad_1524_um C17 1270 2540) + (pin Round[A]Pad_1524_um C18 3810 2540) + (pin Round[A]Pad_1524_um C19 6350 2540) + (pin Round[A]Pad_1524_um C20 8890 2540) + (pin Round[A]Pad_1524_um C21 11430 2540) + (pin Round[A]Pad_1524_um C22 13970 2540) + (pin Round[A]Pad_1524_um C23 16510 2540) + (pin Round[A]Pad_1524_um C24 19050 2540) + (pin Round[A]Pad_1524_um C25 21590 2540) + (pin Round[A]Pad_1524_um C26 24130 2540) + (pin Round[A]Pad_1524_um C27 26670 2540) + (pin Round[A]Pad_1524_um C28 29210 2540) + (pin Round[A]Pad_1524_um C29 31750 2540) + (pin Round[A]Pad_1524_um C30 34290 2540) + (pin Round[A]Pad_1524_um C31 36830 2540) + (pin Round[A]Pad_1524_um C32 39370 2540) + ) + (image "SMD:SOT-23-3" + (outline (path signal 150 1141.42 400 1134.5 356.298 1114.41 316.875 1083.12 285.588 + 1043.7 265.5 1000 258.579 956.298 265.5 916.875 285.588 885.588 316.875 + 865.5 356.298 858.579 400 865.5 443.702 885.588 483.125 916.875 514.412 + 956.298 534.5 1000 541.421 1043.7 534.5 1083.12 514.412 1114.41 483.125 + 1134.5 443.702)) + (outline (path signal 150 -1500 800 -1500 -800)) + (outline (path signal 150 -1500 -800 1500 -800)) + (outline (path signal 150 1500 -800 1500 800)) + (outline (path signal 150 1500 800 -1500 800)) + (pin Rect[T]Pad_600x900_um 3 0 -1400) + (pin Rect[T]Pad_600x900_um 2 -950 1400) + (pin Rect[T]Pad_600x900_um 1 950 1400) + ) + (image "Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm" + (outline (path signal 50 -3700 4650 -3700 -4650)) + (outline (path signal 50 3700 4650 3700 -4650)) + (outline (path signal 50 -3700 4650 3700 4650)) + (outline (path signal 50 -3700 -4650 3700 -4650)) + (outline (path signal 150 -2075 4450 -2075 4335)) + (outline (path signal 150 2075 4450 2075 4335)) + (outline (path signal 150 2075 -4450 2075 -4335)) + (outline (path signal 150 -2075 -4450 -2075 -4335)) + (outline (path signal 150 -2075 4450 2075 4450)) + (outline (path signal 150 -2075 -4450 2075 -4450)) + (outline (path signal 150 -2075 4335 -3450 4335)) + (pin Rect[T]Pad_1500x600_um 1 -2700 3810) + (pin Rect[T]Pad_1500x600_um 2 -2700 2540) + (pin Rect[T]Pad_1500x600_um 3 -2700 1270) + (pin Rect[T]Pad_1500x600_um 4 -2700 0) + (pin Rect[T]Pad_1500x600_um 5 -2700 -1270) + (pin Rect[T]Pad_1500x600_um 6 -2700 -2540) + (pin Rect[T]Pad_1500x600_um 7 -2700 -3810) + (pin Rect[T]Pad_1500x600_um 8 2700 -3810) + (pin Rect[T]Pad_1500x600_um 9 2700 -2540) + (pin Rect[T]Pad_1500x600_um 10 2700 -1270) + (pin Rect[T]Pad_1500x600_um 11 2700 0) + (pin Rect[T]Pad_1500x600_um 12 2700 1270) + (pin Rect[T]Pad_1500x600_um 13 2700 2540) + (pin Rect[T]Pad_1500x600_um 14 2700 3810) + ) + (image Footprints:SOT363 + (outline (path signal 152.4 635 -1016 635 1016)) + (outline (path signal 152.4 635 1016 -635 1016)) + (outline (path signal 152.4 -635 1016 -635 -1016)) + (outline (path signal 152.4 -635 -1016 635 -1016)) + (pin Rect[T]Pad_508x304.8_um 1 -1016 635) + (pin Rect[T]Pad_508x304.8_um 3 -1016 -635) + (pin Rect[T]Pad_508x304.8_um 5 1016 0) + (pin Rect[T]Pad_508x304.8_um 2 -1016 0) + (pin Rect[T]Pad_508x304.8_um 4 1016 -635) + (pin Rect[T]Pad_508x304.8_um 6 1016 635) + ) + (padstack Round[A]Pad_1501.14_um + (shape (circle F.Cu 1501.14)) + (shape (circle B.Cu 1501.14)) + (attach off) + ) + (padstack Round[A]Pad_1524_um + (shape (circle F.Cu 1524)) + (shape (circle B.Cu 1524)) + (attach off) + ) + (padstack Round[A]Pad_3810_um + (shape (circle F.Cu 3810)) + (shape (circle B.Cu 3810)) + (attach off) + ) + (padstack Oval[A]Pad_1550x1000_um + (shape (path F.Cu 1000 -275 0 275 0)) + (shape (path B.Cu 1000 -275 0 275 0)) + (attach off) + ) + (padstack Oval[A]Pad_2032x1727.2_um + (shape (path F.Cu 1727.2 -152.4 0 152.4 0)) + (shape (path B.Cu 1727.2 -152.4 0 152.4 0)) + (attach off) + ) + (padstack Oval[A]Pad_2032x2032_um + (shape (path F.Cu 2032 0 0 0 0)) + (shape (path B.Cu 2032 0 0 0 0)) + (attach off) + ) + (padstack Oval[A]Pad_950x1250_um + (shape (path F.Cu 950 0 -150 0 150)) + (shape (path B.Cu 950 0 -150 0 150)) + (attach off) + ) + (padstack Rect[A]Pad_2032x2032_um + (shape (rect F.Cu -1016 -1016 1016 1016)) + (shape (rect B.Cu -1016 -1016 1016 1016)) + (attach off) + ) + (padstack Rect[A]Pad_2032x1727.2_um + (shape (rect F.Cu -1016 -863.6 1016 863.6)) + (shape (rect B.Cu -1016 -863.6 1016 863.6)) + (attach off) + ) + (padstack Rect[T]Pad_2200x3000_um + (shape (rect F.Cu -1100 -1500 1100 1500)) + (attach off) + ) + (padstack Rect[T]Pad_2700x3200_um + (shape (rect F.Cu -1350 -1600 1350 1600)) + (attach off) + ) + (padstack Rect[T]Pad_508x304.8_um + (shape (rect F.Cu -254 -152.4 254 152.4)) + (attach off) + ) + (padstack Rect[T]Pad_600x900_um + (shape (rect F.Cu -300 -450 300 450)) + (attach off) + ) + (padstack Rect[T]Pad_1000x3000_um + (shape (rect F.Cu -500 -1500 500 1500)) + (attach off) + ) + (padstack Rect[T]Pad_1350x400_um + (shape (rect F.Cu -675 -200 675 200)) + (attach off) + ) + (padstack Rect[T]Pad_1500x600_um + (shape (rect F.Cu -750 -300 750 300)) + (attach off) + ) + (padstack Rect[A]Pad_1524x1524_um + (shape (rect F.Cu -762 -762 762 762)) + (shape (rect B.Cu -762 -762 762 762)) + (attach off) + ) + (padstack Rect[T]Pad_1600x560_um + (shape (rect F.Cu -800 -280 800 280)) + (attach off) + ) + (padstack "Via[0-1]_600:400_um" + (shape (circle F.Cu 600)) + (shape (circle B.Cu 600)) + (attach off) + ) + ) + (network + (net "Net-(C1-Pad1)" + (pins C1-1 P1-4 R1-2) + ) + (net "Net-(C1-Pad2)" + (pins C1-2 P1-3) + ) + (net "Net-(C2-Pad1)" + (pins C2-1 P1-1 R2-2) + ) + (net "Net-(C2-Pad2)" + (pins C2-2 P1-2) + ) + (net +5V + (pins C3-1 P2-5 P2-6 P2-6@1 P2-6@2 P2-6@3 R16-2) + ) + (net GND + (pins C3-2 C4-2 C6-2 F1-1 IC1-8 IC1-14 IC1-18 IC1-30 P2-1 R15-2 R21-2 U3-1 U3-4) + ) + (net /VCC_3V3 + (pins C4-1 IC1-9 IC1-19 IC1-31) + ) + (net /AVCC + (pins C5-1 IC1-39 R5-1) + ) + (net /AGND + (pins C5-2 IC1-38 R6-1) + ) + (net "Net-(C6-Pad1)" + (pins C6-1 R19-1 U2-12) + ) + (net "Net-(C7-Pad1)" + (pins C7-1 P6-2) + ) + (net "Net-(C7-Pad2)" + (pins C7-2 P6-1 R20-1) + ) + (net /LM324_VCC + (pins C8-1 P4-2 U2-4) + ) + (net /VGND + (pins C8-2 F1-2 IC1-43 P5-2 R24-2 U2-11) + ) + (net /VSENSE_OCP + (pins C9-2 IC1-41 P7-2 R23-2 R24-1) + ) + (net "Net-(C9-Pad1)" + (pins C9-1 P7-1 R23-1) + ) + (net "Net-(IC1-Pad1)" + (pins IC1-1) + ) + (net "Net-(IC1-Pad2)" + (pins IC1-2) + ) + (net "Net-(IC1-Pad3)" + (pins IC1-3) + ) + (net "Net-(IC1-Pad4)" + (pins IC1-4) + ) + (net "Net-(IC1-Pad5)" + (pins IC1-5) + ) + (net /DAC_OUT + (pins IC1-6 U2-10) + ) + (net "Net-(IC1-Pad7)" + (pins IC1-7) + ) + (net "Net-(IC1-Pad10)" + (pins IC1-10) + ) + (net /XCK + (pins IC1-11 IC1-15) + ) + (net /DIG_CH2 + (pins IC1-12 U3-3) + ) + (net "Net-(IC1-Pad13)" + (pins IC1-13) + ) + (net "Net-(IC1-Pad16)" + (pins IC1-16) + ) + (net /DIG_CH1 + (pins IC1-17 U3-6) + ) + (net "Net-(IC1-Pad20)" + (pins IC1-20) + ) + (net "Net-(IC1-Pad21)" + (pins IC1-21) + ) + (net "Net-(IC1-Pad22)" + (pins IC1-22) + ) + (net "Net-(IC1-Pad23)" + (pins IC1-23) + ) + (net /PSU_PWM + (pins IC1-24 R19-2) + ) + (net "Net-(IC1-Pad25)" + (pins IC1-25) + ) + (net "/D-" + (pins IC1-26 P2-2) + ) + (net /D+ + (pins IC1-27 P2-3) + ) + (net "Net-(IC1-Pad28)" + (pins IC1-28 R11-1) + ) + (net "Net-(IC1-Pad29)" + (pins IC1-29 R12-1) + ) + (net "Net-(IC1-Pad32)" + (pins IC1-32 R13-1) + ) + (net "Net-(IC1-Pad33)" + (pins IC1-33 R14-1) + ) + (net "Net-(IC1-Pad34)" + (pins IC1-34) + ) + (net "Net-(IC1-Pad35)" + (pins IC1-35 R15-1) + ) + (net "Net-(IC1-Pad36)" + (pins IC1-36) + ) + (net "Net-(IC1-Pad37)" + (pins IC1-37) + ) + (net /CH1 + (pins IC1-40 U2-1 U2-2) + ) + (net /CH2 + (pins IC1-42 U2-6 U2-7) + ) + (net /AVCC_ON_2 + (pins IC1-44 R3-2 R4-1 R5-2 R6-2) + ) + (net "Net-(P2-Pad4)" + (pins P2-4) + ) + (net "Net-(P3-Pad1)" + (pins P3-1 R10-2) + ) + (net "Net-(P3-Pad2)" + (pins P3-2 R9-2) + ) + (net "Net-(P3-Pad3)" + (pins P3-3 R8-2) + ) + (net "Net-(P3-Pad4)" + (pins P3-4 R7-2) + ) + (net +12V + (pins P4-1 P5-1) + ) + (net "Net-(P4-Pad3)" + (pins P4-3 R17-1) + ) + (net "Net-(P8-Pad1)" + (pins P8-1 U3-5) + ) + (net "Net-(P8-Pad2)" + (pins P8-2 U3-2) + ) + (net "Net-(R1-Pad1)" + (pins R1-1 R3-1 U2-3) + ) + (net "Net-(R2-Pad1)" + (pins R2-1 R4-2 U2-5) + ) + (net "Net-(R11-Pad2)" + (pins R7-1 R11-2) + ) + (net "Net-(R12-Pad2)" + (pins R8-1 R12-2) + ) + (net "Net-(R13-Pad2)" + (pins R9-1 R13-2) + ) + (net "Net-(R10-Pad1)" + (pins R10-1 R14-2) + ) + (net "Net-(R16-Pad1)" + (pins R16-1 R17-2) + ) + (net "Net-(R18-Pad1)" + (pins R18-1 R20-2) + ) + (net "Net-(R18-Pad2)" + (pins R18-2 U2-8 U2-9) + ) + (net "Net-(R21-Pad1)" + (pins R21-1 R22-2 U2-13) + ) + (net "Net-(R22-Pad1)" + (pins R22-1 U2-14) + ) + (class kicad_default "" +12V +5V /AGND /AVCC /AVCC_ON_2 /CH1 /CH2 /D+ + "/D-" /DAC_OUT /DIG_CH1 /DIG_CH2 /LM324_VCC /PSU_PWM /VCC_3V3 /VGND + /VSENSE_OCP /XCK GND "Net-(C1-Pad1)" "Net-(C1-Pad2)" "Net-(C2-Pad1)" + "Net-(C2-Pad2)" "Net-(C6-Pad1)" "Net-(C7-Pad1)" "Net-(C7-Pad2)" "Net-(C9-Pad1)" + "Net-(IC1-Pad1)" "Net-(IC1-Pad10)" "Net-(IC1-Pad13)" "Net-(IC1-Pad16)" + "Net-(IC1-Pad2)" "Net-(IC1-Pad20)" "Net-(IC1-Pad21)" "Net-(IC1-Pad22)" + "Net-(IC1-Pad23)" "Net-(IC1-Pad25)" "Net-(IC1-Pad28)" "Net-(IC1-Pad29)" + "Net-(IC1-Pad3)" "Net-(IC1-Pad32)" "Net-(IC1-Pad33)" "Net-(IC1-Pad34)" + "Net-(IC1-Pad35)" "Net-(IC1-Pad36)" "Net-(IC1-Pad37)" "Net-(IC1-Pad4)" + "Net-(IC1-Pad5)" "Net-(IC1-Pad7)" "Net-(P2-Pad4)" "Net-(P3-Pad1)" "Net-(P3-Pad2)" + "Net-(P3-Pad3)" "Net-(P3-Pad4)" "Net-(P4-Pad3)" "Net-(P8-Pad1)" "Net-(P8-Pad2)" + "Net-(R1-Pad1)" "Net-(R10-Pad1)" "Net-(R11-Pad2)" "Net-(R12-Pad2)" "Net-(R13-Pad2)" + "Net-(R16-Pad1)" "Net-(R18-Pad1)" "Net-(R18-Pad2)" "Net-(R2-Pad1)" "Net-(R21-Pad1)" + "Net-(R22-Pad1)" + (circuit + (use_via Via[0-1]_600:400_um) + ) + (rule + (width 250) + (clearance 200.1) + ) + ) + ) + (wiring + ) +) diff --git a/PCB/Tinylab_proto1.dsn.REMOVED.git-id b/PCB/Tinylab_proto1.dsn.REMOVED.git-id deleted file mode 100644 index dc62aa68..00000000 --- a/PCB/Tinylab_proto1.dsn.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -c4122e91dc906eef70cd415239a561facc70cf75 \ No newline at end of file diff --git a/PCB/Tinylab_proto1.kicad_pcb b/PCB/Tinylab_proto1.kicad_pcb new file mode 100644 index 00000000..8a5607fe --- /dev/null +++ b/PCB/Tinylab_proto1.kicad_pcb @@ -0,0 +1,3829 @@ +(kicad_pcb (version 4) (host pcbnew 4.0.4-stable) + + (general + (links 157) + (no_connects 0) + (area 66.726343 96.542857 114.511487 136.986405) + (thickness 1.6) + (drawings 8) + (tracks 906) + (zones 0) + (modules 79) + (nets 77) + ) + + (page A4) + (layers + (0 F.Cu signal) + (31 B.Cu signal hide) + (32 B.Adhes user hide) + (33 F.Adhes user hide) + (34 B.Paste user hide) + (35 F.Paste user hide) + (36 B.SilkS user) + (37 F.SilkS user) + (38 B.Mask user hide) + (39 F.Mask user hide) + (40 Dwgs.User user hide) + (41 Cmts.User user hide) + (42 Eco1.User user hide) + (43 Eco2.User user hide) + (44 Edge.Cuts user hide) + (45 Margin user hide) + (46 B.CrtYd user hide) + (47 F.CrtYd user hide) + (48 B.Fab user hide) + (49 F.Fab user hide) + ) + + (setup + (last_trace_width 0.25) + (user_trace_width 0.4) + (user_trace_width 0.635) + (user_trace_width 0.8) + (user_trace_width 1.27) + (trace_clearance 0.2) + (zone_clearance 0.508) + (zone_45_only no) + (trace_min 0.2) + (segment_width 0.2) + (edge_width 0.1) + (via_size 0.6) + (via_drill 0.4) + (via_min_size 0.4) + (via_min_drill 0.3) + (uvia_size 0.3) + (uvia_drill 0.1) + (uvias_allowed no) + (uvia_min_size 0.2) + (uvia_min_drill 0.1) + (pcb_text_width 0.3) + (pcb_text_size 1.5 1.5) + (mod_edge_width 0.15) + (mod_text_size 0.6 0.6) + (mod_text_width 0.1) + (pad_size 1.5 1.5) + (pad_drill 0.6) + (pad_to_mask_clearance 0) + (aux_axis_origin 0 0) + (visible_elements 7FFEEFFF) + (pcbplotparams + (layerselection 0x01133_80000001) + (usegerberextensions false) + (excludeedgelayer true) + (linewidth 0.100000) + (plotframeref false) + (viasonmask false) + (mode 1) + (useauxorigin false) + (hpglpennumber 1) + (hpglpenspeed 20) + (hpglpendiameter 15) + (hpglpenoverlay 2) + (psnegative false) + (psa4output false) + (plotreference true) + (plotvalue true) + (plotinvisibletext false) + (padsonsilk false) + (subtractmaskfromsilk false) + (outputformat 1) + (mirror false) + (drillshape 0) + (scaleselection 1) + (outputdirectory LABRADOR_BE_FILES_BATCH_3/)) + ) + + (net 0 "") + (net 1 /Scope_CH1_DC) + (net 2 /Scoe_CH1_AC) + (net 3 /Scope_CH2_DC) + (net 4 /Scope_CH2_AC) + (net 5 +5V) + (net 6 /VGND) + (net 7 /VCC_3V3) + (net 8 /AVCC) + (net 9 /PSU_Unfiltered_Raw) + (net 10 /S-Gen_CH1_AC) + (net 11 /S-Gen_CH1_DC) + (net 12 /S-Gen_CH2_AC) + (net 13 /S-Gen_CH2_DC) + (net 14 /OPAMP_VCC) + (net 15 /QTop) + (net 16 "Net-(D2-Pad2)") + (net 17 /3V3_OUT) + (net 18 /PSU_FDBK) + (net 19 /CH2) + (net 20 "Net-(IC1-Pad3)") + (net 21 /TO_B0) + (net 22 /TO_B1) + (net 23 /DAC_OUT) + (net 24 /DAC_OUT2) + (net 25 "Net-(IC1-Pad9)") + (net 26 "Net-(IC1-Pad10)") + (net 27 /XCK) + (net 28 /DIG_CH2) + (net 29 "Net-(IC1-Pad13)") + (net 30 /DIG_CH1) + (net 31 "Net-(IC1-Pad16)") + (net 32 "Net-(IC1-Pad20)") + (net 33 "Net-(IC1-Pad21)") + (net 34 "Net-(IC1-Pad22)") + (net 35 "Net-(IC1-Pad23)") + (net 36 /PSU_PWM) + (net 37 "Net-(IC1-Pad25)") + (net 38 /D-) + (net 39 /D+) + (net 40 /D0-prefuse) + (net 41 /D1-prefuse) + (net 42 /D2-prefuse) + (net 43 /D3-prefuse) + (net 44 /PDI_CLK) + (net 45 /PDI_DATA) + (net 46 "Net-(IC1-Pad36)") + (net 47 "Net-(IC1-Pad37)") + (net 48 "Net-(IC1-Pad41)") + (net 49 /CH1) + (net 50 "Net-(IC1-Pad43)") + (net 51 /AVCC_ON_2) + (net 52 "Net-(L3-Pad1)") + (net 53 /Disconnected_USB) + (net 54 /D3-OUT) + (net 55 /D2-OUT) + (net 56 /D1_OUT) + (net 57 /D0_OUT) + (net 58 /PSU_OUT) + (net 59 /L-Ana_IN_CH1) + (net 60 /L-Ana_IN_CH2) + (net 61 /Switch_OC) + (net 62 /Scope_Buffer_Input_CH1) + (net 63 /Scope_Buffer_Input_CH2) + (net 64 /D0_MID) + (net 65 /D1_MID) + (net 66 /D2_MID) + (net 67 /D3_MID) + (net 68 /V_minus_dac_out2) + (net 69 /S-Gen_Drain_Top_CH2) + (net 70 /V_minus_dac_out) + (net 71 /S-Gen_Drain_Top_CH1) + (net 72 /Buffered_DAC_CH1) + (net 73 /Buffered_DAC_CH2) + (net 74 /R22-R24) + (net 75 /R23-R25) + (net 76 "Net-(F2-Pad2)") + + (net_class Default "This is the default net class." + (clearance 0.2) + (trace_width 0.25) + (via_dia 0.6) + (via_drill 0.4) + (uvia_dia 0.3) + (uvia_drill 0.1) + (add_net +5V) + (add_net /3V3_OUT) + (add_net /AVCC) + (add_net /AVCC_ON_2) + (add_net /Buffered_DAC_CH1) + (add_net /Buffered_DAC_CH2) + (add_net /CH1) + (add_net /CH2) + (add_net /D+) + (add_net /D-) + (add_net /D0-prefuse) + (add_net /D0_MID) + (add_net /D0_OUT) + (add_net /D1-prefuse) + (add_net /D1_MID) + (add_net /D1_OUT) + (add_net /D2-OUT) + (add_net /D2-prefuse) + (add_net /D2_MID) + (add_net /D3-OUT) + (add_net /D3-prefuse) + (add_net /D3_MID) + (add_net /DAC_OUT) + (add_net /DAC_OUT2) + (add_net /DIG_CH1) + (add_net /DIG_CH2) + (add_net /Disconnected_USB) + (add_net /L-Ana_IN_CH1) + (add_net /L-Ana_IN_CH2) + (add_net /OPAMP_VCC) + (add_net /PDI_CLK) + (add_net /PDI_DATA) + (add_net /PSU_FDBK) + (add_net /PSU_OUT) + (add_net /PSU_PWM) + (add_net /PSU_Unfiltered_Raw) + (add_net /QTop) + (add_net /R22-R24) + (add_net /R23-R25) + (add_net /S-Gen_CH1_AC) + (add_net /S-Gen_CH1_DC) + (add_net /S-Gen_CH2_AC) + (add_net /S-Gen_CH2_DC) + (add_net /S-Gen_Drain_Top_CH1) + (add_net /S-Gen_Drain_Top_CH2) + (add_net /Scoe_CH1_AC) + (add_net /Scope_Buffer_Input_CH1) + (add_net /Scope_Buffer_Input_CH2) + (add_net /Scope_CH1_DC) + (add_net /Scope_CH2_AC) + (add_net /Scope_CH2_DC) + (add_net /Switch_OC) + (add_net /TO_B0) + (add_net /TO_B1) + (add_net /VCC_3V3) + (add_net /VGND) + (add_net /V_minus_dac_out) + (add_net /V_minus_dac_out2) + (add_net /XCK) + (add_net "Net-(D2-Pad2)") + (add_net "Net-(F2-Pad2)") + (add_net "Net-(IC1-Pad10)") + (add_net "Net-(IC1-Pad13)") + (add_net "Net-(IC1-Pad16)") + (add_net "Net-(IC1-Pad20)") + (add_net "Net-(IC1-Pad21)") + (add_net "Net-(IC1-Pad22)") + (add_net "Net-(IC1-Pad23)") + (add_net "Net-(IC1-Pad25)") + (add_net "Net-(IC1-Pad3)") + (add_net "Net-(IC1-Pad36)") + (add_net "Net-(IC1-Pad37)") + (add_net "Net-(IC1-Pad41)") + (add_net "Net-(IC1-Pad43)") + (add_net "Net-(IC1-Pad9)") + (add_net "Net-(L3-Pad1)") + ) + + (module Capacitors_SMD:c_elec_4x5.3 (layer F.Cu) (tedit 58A7A899) (tstamp 5833820B) + (at 103.1875 124.0155 90) + (descr "SMT capacitor, aluminium electrolytic, 4x5.3") + (path /566F5A75) + (attr smd) + (fp_text reference C6 (at 0.0127 0.0381 180) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value CP1 (at 0 3.175 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -3.35 -2.65) (end 3.35 -2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.35 -2.65) (end 3.35 2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.35 2.65) (end -3.35 2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.35 2.65) (end -3.35 -2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.651 0) (end 0.889 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 -0.381) (end 1.27 0.381) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.524 2.286) (end -2.286 2.286) (layer Dwgs.User) (width 0.15)) + (fp_line (start 2.286 -1.524) (end 2.286 1.524) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.524 2.286) (end 2.286 1.524) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.524 -2.286) (end -2.286 -2.286) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.524 -2.286) (end 2.286 -1.524) (layer Dwgs.User) (width 0.15)) + (fp_line (start -2.032 0.127) (end -2.032 -0.127) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.905 -0.635) (end -1.905 0.635) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.778 0.889) (end -1.778 -0.889) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.651 1.143) (end -1.651 -1.143) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.524 -1.27) (end -1.524 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.397 1.397) (end -1.397 -1.397) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 -1.524) (end -1.27 1.524) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.143 -1.651) (end -1.143 1.651) (layer Dwgs.User) (width 0.15)) + (fp_line (start -2.286 -2.286) (end -2.286 2.286) (layer Dwgs.User) (width 0.15)) + (fp_circle (center 0 0) (end -2.032 0) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at 1.80086 0 90) (size 2.60096 1.6002) (layers F.Cu F.Paste F.Mask) + (net 7 /VCC_3V3)) + (pad 2 smd rect (at -1.80086 0 90) (size 2.60096 1.6002) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Capacitors_SMD.3dshapes/c_elec_4x5.3.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Housings_QFP:LQFP-44_10x10mm_Pitch0.8mm (layer F.Cu) (tedit 58A7A78E) (tstamp 58338295) + (at 93.5736 120.5738) + (descr "LQFP44 (see Appnote_PCB_Guidelines_TRINAMIC_packages.pdf)") + (tags "QFP 0.8") + (path /55CA8F25) + (attr smd) + (fp_text reference IC1 (at 0.0381 0.0635) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value ATXMEGA32A4U-AU (at 0 7.65) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -6.9 -6.9) (end -6.9 6.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start 6.9 -6.9) (end 6.9 6.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start -6.9 -6.9) (end 6.9 -6.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start -6.9 6.9) (end 6.9 6.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start -5.175 -5.175) (end -5.175 -4.505) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.175 -5.175) (end 5.175 -4.505) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.175 5.175) (end 5.175 4.505) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.175 5.175) (end -5.175 4.505) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.175 -5.175) (end -4.505 -5.175) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.175 5.175) (end -4.505 5.175) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.175 5.175) (end 4.505 5.175) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.175 -5.175) (end 4.505 -5.175) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.175 -4.505) (end -6.65 -4.505) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -5.85 -4) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 18 /PSU_FDBK)) + (pad 2 smd rect (at -5.85 -3.2) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 19 /CH2)) + (pad 3 smd rect (at -5.85 -2.4) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 20 "Net-(IC1-Pad3)")) + (pad 4 smd rect (at -5.85 -1.6) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 21 /TO_B0)) + (pad 5 smd rect (at -5.85 -0.8) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 22 /TO_B1)) + (pad 6 smd rect (at -5.85 0) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 23 /DAC_OUT)) + (pad 7 smd rect (at -5.85 0.8) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 24 /DAC_OUT2)) + (pad 8 smd rect (at -5.85 1.6) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 9 smd rect (at -5.85 2.4) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 25 "Net-(IC1-Pad9)")) + (pad 10 smd rect (at -5.85 3.2) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 26 "Net-(IC1-Pad10)")) + (pad 11 smd rect (at -5.85 4) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 27 /XCK)) + (pad 12 smd rect (at -4 5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 28 /DIG_CH2)) + (pad 13 smd rect (at -3.2 5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 29 "Net-(IC1-Pad13)")) + (pad 14 smd rect (at -2.4 5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 15 smd rect (at -1.6 5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 30 /DIG_CH1)) + (pad 16 smd rect (at -0.8 5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 31 "Net-(IC1-Pad16)")) + (pad 17 smd rect (at 0 5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 27 /XCK)) + (pad 18 smd rect (at 0.8 5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 19 smd rect (at 1.6 5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 7 /VCC_3V3)) + (pad 20 smd rect (at 2.4 5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 32 "Net-(IC1-Pad20)")) + (pad 21 smd rect (at 3.2 5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 33 "Net-(IC1-Pad21)")) + (pad 22 smd rect (at 4 5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 34 "Net-(IC1-Pad22)")) + (pad 23 smd rect (at 5.85 4) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 35 "Net-(IC1-Pad23)")) + (pad 24 smd rect (at 5.85 3.2) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 36 /PSU_PWM)) + (pad 25 smd rect (at 5.85 2.4) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 37 "Net-(IC1-Pad25)")) + (pad 26 smd rect (at 5.85 1.6) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 38 /D-)) + (pad 27 smd rect (at 5.85 0.8) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 39 /D+)) + (pad 28 smd rect (at 5.85 0) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 40 /D0-prefuse)) + (pad 29 smd rect (at 5.85 -0.8) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 41 /D1-prefuse)) + (pad 30 smd rect (at 5.85 -1.6) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 31 smd rect (at 5.85 -2.4) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 7 /VCC_3V3)) + (pad 32 smd rect (at 5.85 -3.2) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 42 /D2-prefuse)) + (pad 33 smd rect (at 5.85 -4) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 43 /D3-prefuse)) + (pad 34 smd rect (at 4 -5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 44 /PDI_CLK)) + (pad 35 smd rect (at 3.2 -5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 45 /PDI_DATA)) + (pad 36 smd rect (at 2.4 -5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 46 "Net-(IC1-Pad36)")) + (pad 37 smd rect (at 1.6 -5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 47 "Net-(IC1-Pad37)")) + (pad 38 smd rect (at 0.8 -5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 39 smd rect (at 0 -5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 8 /AVCC)) + (pad 40 smd rect (at -0.8 -5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 19 /CH2)) + (pad 41 smd rect (at -1.6 -5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 48 "Net-(IC1-Pad41)")) + (pad 42 smd rect (at -2.4 -5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 49 /CH1)) + (pad 43 smd rect (at -3.2 -5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 50 "Net-(IC1-Pad43)")) + (pad 44 smd rect (at -4 -5.85 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 51 /AVCC_ON_2)) + (model Housings_QFP.3dshapes/LQFP-44_10x10mm_Pitch0.8mm.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Connect:USB_Micro-B_WIDE (layer F.Cu) (tedit 58A7A6FD) (tstamp 583382C2) + (at 103.6955 103.6955 90) + (descr "Micro USB Type B Receptacle") + (tags "USB USB_B USB_micro USB_OTG") + (path /55CA90D2) + (attr smd) + (fp_text reference P2 (at -0.0508 0.0127 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value USB_OTG (at 0 4.8 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -4.6 -2.8) (end 4.6 -2.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.6 -2.8) (end 4.6 4.05) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.6 4.05) (end -4.6 4.05) (layer F.CrtYd) (width 0.05)) + (fp_line (start -4.6 4.05) (end -4.6 -2.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -4.3509 3.81746) (end 4.3491 3.81746) (layer Dwgs.User) (width 0.15)) + (fp_line (start -4.3509 -2.58754) (end 4.3491 -2.58754) (layer Dwgs.User) (width 0.15)) + (fp_line (start 4.3491 -2.58754) (end 4.3491 3.81746) (layer Dwgs.User) (width 0.15)) + (fp_line (start 4.3491 2.58746) (end -4.3509 2.58746) (layer Dwgs.User) (width 0.15)) + (fp_line (start -4.3509 3.81746) (end -4.3509 -2.58754) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -1.3009 -1.56254 180) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 5 +5V)) + (pad 2 smd rect (at -0.6509 -1.56254 180) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 38 /D-)) + (pad 3 smd rect (at -0.0009 -1.56254 180) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 39 /D+)) + (pad 4 smd rect (at 0.6491 -1.56254 180) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 53 /Disconnected_USB)) + (pad 5 smd rect (at 1.2991 -1.56254 180) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 6 thru_hole oval (at -2.5009 -1.56254 180) (size 0.95 1.4) (drill oval 0.55 1) (layers *.Cu *.Mask Dwgs.User) + (net 6 /VGND)) + (pad 6 thru_hole oval (at 2.4991 -1.56254 180) (size 0.95 1.4) (drill oval 0.55 1) (layers *.Cu *.Mask Dwgs.User) + (net 6 /VGND)) + (pad 6 thru_hole oval (at -3.5009 1.13746 180) (size 1.55 1.2) (drill oval 1.15 0.7) (layers *.Cu *.Mask Dwgs.User) + (net 6 /VGND)) + (pad 6 thru_hole oval (at 3.4991 1.13746 180) (size 1.55 1.2) (drill oval 1.15 0.7) (layers *.Cu *.Mask Dwgs.User) + (net 6 /VGND)) + ) + + (module Pin_Headers:Pin_Header_Straight_1x04 (layer F.Cu) (tedit 58A7A872) (tstamp 583382B5) + (at 88.3285 129.3495 90) + (descr "Through hole pin header") + (tags "pin header") + (path /5832064B) + (fp_text reference P1 (at 0.0127 0.0127 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value SCOPE_OUT (at 0 -3.1 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 9.4) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 1.27) (end -1.27 8.89) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 1.27) (end 1.27 8.89) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 8.89) (end 1.27 8.89) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 1 /Scope_CH1_DC)) + (pad 2 thru_hole oval (at 0 2.54 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 2 /Scoe_CH1_AC)) + (pad 3 thru_hole oval (at 0 5.08 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 1 /Scope_CH1_DC)) + (pad 4 thru_hole oval (at 0 7.62 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 1 /Scope_CH1_DC)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x04.wrl + (at (xyz 0 -0.15 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 58A7A89E) (tstamp 583381ED) + (at 98.3742 129.2098 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CAB611) + (attr smd) + (fp_text reference C1 (at 0.0254 0.0254 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 1 /Scope_CH1_DC)) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 2 /Scoe_CH1_AC)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 58A7A88B) (tstamp 583381F3) + (at 82.8802 133.2738 180) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CAB4DE) + (attr smd) + (fp_text reference C2 (at -0.0254 -0.0254 180) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C (at 0 1.9 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 180) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 3 /Scope_CH2_DC)) + (pad 2 smd rect (at 0.75 0 180) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 4 /Scope_CH2_AC)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 58A7A8D0) (tstamp 583381F9) + (at 102.1715 109.0295) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CB13E1) + (attr smd) + (fp_text reference C3 (at -0.0127 0.0381) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C_Small (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 5 +5V)) + (pad 2 smd rect (at 0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 583381FF) + (at 101.219 119.0625 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CB147C) + (attr smd) + (fp_text reference C4 (at -0.0127 0.0508 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C_Small (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 7 /VCC_3V3)) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 58A7A868) (tstamp 58338205) + (at 85.9155 128.5621 90) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55D60181) + (attr smd) + (fp_text reference C5 (at -0.0127 -0.0127 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C_Small (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 8 /AVCC)) + (pad 2 smd rect (at 0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 58A7A8AD) (tstamp 58338211) + (at 81.5975 116.205 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /56E8E263) + (attr smd) + (fp_text reference C7 (at 0.0254 -0.0381 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 9 /PSU_Unfiltered_Raw)) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 58A7A785) (tstamp 58338217) + (at 96.2025 112.2045 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /56AF91A3) + (attr smd) + (fp_text reference C8 (at -0.0127 -0.0127 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 8 /AVCC)) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:c_elec_4x5.3 (layer F.Cu) (tedit 556FDE77) (tstamp 5833821D) + (at 97.3455 108.077) + (descr "SMT capacitor, aluminium electrolytic, 4x5.3") + (path /560719D9) + (attr smd) + (fp_text reference C9 (at 0 -0.0127) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value CP1 (at 0 3.175) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -3.35 -2.65) (end 3.35 -2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.35 -2.65) (end 3.35 2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.35 2.65) (end -3.35 2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.35 2.65) (end -3.35 -2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.651 0) (end 0.889 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 -0.381) (end 1.27 0.381) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.524 2.286) (end -2.286 2.286) (layer Dwgs.User) (width 0.15)) + (fp_line (start 2.286 -1.524) (end 2.286 1.524) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.524 2.286) (end 2.286 1.524) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.524 -2.286) (end -2.286 -2.286) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.524 -2.286) (end 2.286 -1.524) (layer Dwgs.User) (width 0.15)) + (fp_line (start -2.032 0.127) (end -2.032 -0.127) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.905 -0.635) (end -1.905 0.635) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.778 0.889) (end -1.778 -0.889) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.651 1.143) (end -1.651 -1.143) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.524 -1.27) (end -1.524 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.397 1.397) (end -1.397 -1.397) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 -1.524) (end -1.27 1.524) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.143 -1.651) (end -1.143 1.651) (layer Dwgs.User) (width 0.15)) + (fp_line (start -2.286 -2.286) (end -2.286 2.286) (layer Dwgs.User) (width 0.15)) + (fp_circle (center 0 0) (end -2.032 0) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at 1.80086 0) (size 2.60096 1.6002) (layers F.Cu F.Paste F.Mask) + (net 5 +5V)) + (pad 2 smd rect (at -1.80086 0) (size 2.60096 1.6002) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Capacitors_SMD.3dshapes/c_elec_4x5.3.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 58A7A6F8) (tstamp 58338223) + (at 98.044 103.886 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /56071A50) + (attr smd) + (fp_text reference C10 (at -0.0127 -0.0762 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 5 +5V)) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 58338229) + (at 102.8065 110.8075) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /5608B4BE) + (attr smd) + (fp_text reference C11 (at 0 -0.0127) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 7 /VCC_3V3)) + (pad 2 smd rect (at 0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 58A7A81D) (tstamp 58338235) + (at 73.2155 125.095 90) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CB630B) + (attr smd) + (fp_text reference C13 (at -0.0254 0.0381 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 10 /S-Gen_CH1_AC)) + (pad 2 smd rect (at 0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 11 /S-Gen_CH1_DC)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 58A7A842) (tstamp 5833823B) + (at 73.152 130.8608 90) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /566DF655) + (attr smd) + (fp_text reference C14 (at -0.0508 0 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 12 /S-Gen_CH2_AC)) + (pad 2 smd rect (at 0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 13 /S-Gen_CH2_DC)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:c_elec_4x5.3 (layer F.Cu) (tedit 58A7A7F5) (tstamp 58338241) + (at 78.613 106.172 180) + (descr "SMT capacitor, aluminium electrolytic, 4x5.3") + (path /560735FE) + (attr smd) + (fp_text reference C15 (at -0.0127 0.0127 180) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value CP1 (at 0 3.175 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -3.35 -2.65) (end 3.35 -2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.35 -2.65) (end 3.35 2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.35 2.65) (end -3.35 2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.35 2.65) (end -3.35 -2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.651 0) (end 0.889 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 -0.381) (end 1.27 0.381) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.524 2.286) (end -2.286 2.286) (layer Dwgs.User) (width 0.15)) + (fp_line (start 2.286 -1.524) (end 2.286 1.524) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.524 2.286) (end 2.286 1.524) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.524 -2.286) (end -2.286 -2.286) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.524 -2.286) (end 2.286 -1.524) (layer Dwgs.User) (width 0.15)) + (fp_line (start -2.032 0.127) (end -2.032 -0.127) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.905 -0.635) (end -1.905 0.635) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.778 0.889) (end -1.778 -0.889) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.651 1.143) (end -1.651 -1.143) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.524 -1.27) (end -1.524 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.397 1.397) (end -1.397 -1.397) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 -1.524) (end -1.27 1.524) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.143 -1.651) (end -1.143 1.651) (layer Dwgs.User) (width 0.15)) + (fp_line (start -2.286 -2.286) (end -2.286 2.286) (layer Dwgs.User) (width 0.15)) + (fp_circle (center 0 0) (end -2.032 0) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at 1.80086 0 180) (size 2.60096 1.6002) (layers F.Cu F.Paste F.Mask) + (net 9 /PSU_Unfiltered_Raw)) + (pad 2 smd rect (at -1.80086 0 180) (size 2.60096 1.6002) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Capacitors_SMD.3dshapes/c_elec_4x5.3.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 58A7A8A3) (tstamp 58338247) + (at 85.852 122.428 90) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /5607355F) + (attr smd) + (fp_text reference C16 (at 0 -0.0508 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 14 /OPAMP_VCC)) + (pad 2 smd rect (at 0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 58A7A789) (tstamp 5833824D) + (at 94.8055 112.2045 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /57564635) + (attr smd) + (fp_text reference C17 (at -0.0127 -0.0127 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 8 /AVCC)) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 58A7A793) (tstamp 58338253) + (at 92.837 112.7125) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /57564580) + (attr smd) + (fp_text reference C18 (at 0.0127 -0.0127) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 8 /AVCC)) + (pad 2 smd rect (at 0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Diodes_SMD:SMA_Standard (layer F.Cu) (tedit 58A7A7F9) (tstamp 58338259) + (at 78.613 101.727) + (descr "Diode SMA") + (tags "Diode SMA") + (path /5606FDB4) + (attr smd) + (fp_text reference D1 (at 0.1397 -0.0127) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value D_Schottky (at 0 4.3) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -3.5 -2) (end 3.5 -2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.5 -2) (end 3.5 2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.5 2) (end -3.5 2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.5 2) (end -3.5 -2) (layer F.CrtYd) (width 0.05)) + (fp_text user K (at -2.9 2.95) (layer Dwgs.User) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text user A (at 2.9 2.9) (layer Dwgs.User) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_circle (center 0 0) (end 0.20066 -0.0508) (layer F.Adhes) (width 0.381)) + (fp_line (start -1.79914 1.75006) (end -1.79914 1.39954) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.79914 -1.75006) (end -1.79914 -1.39954) (layer Dwgs.User) (width 0.15)) + (fp_line (start 2.25044 1.75006) (end 2.25044 1.39954) (layer Dwgs.User) (width 0.15)) + (fp_line (start -2.25044 1.75006) (end -2.25044 1.39954) (layer Dwgs.User) (width 0.15)) + (fp_line (start -2.25044 -1.75006) (end -2.25044 -1.39954) (layer Dwgs.User) (width 0.15)) + (fp_line (start 2.25044 -1.75006) (end 2.25044 -1.39954) (layer Dwgs.User) (width 0.15)) + (fp_line (start -2.25044 1.75006) (end 2.25044 1.75006) (layer Dwgs.User) (width 0.15)) + (fp_line (start -2.25044 -1.75006) (end 2.25044 -1.75006) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -1.99898 0) (size 2.49936 1.80086) (layers F.Cu F.Paste F.Mask) + (net 9 /PSU_Unfiltered_Raw)) + (pad 2 smd rect (at 1.99898 0) (size 2.49936 1.80086) (layers F.Cu F.Paste F.Mask) + (net 15 /QTop)) + (model Diodes_SMD.3dshapes/SMA_Standard.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.3937 0.3937 0.3937)) + (rotate (xyz 0 0 180)) + ) + ) + + (module LEDs:LED_0603 (layer F.Cu) (tedit 58A7AA3B) (tstamp 5833825F) + (at 80.01 113.03 180) + (descr "LED 0603 smd package") + (tags "LED led 0603 SMD smd SMT smt smdled SMDLED smtled SMTLED") + (path /5833E159) + (attr smd) + (fp_text reference D2 (at -0.9652 -0.0508 180) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value LED (at 0 1.5 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -0.3 -0.2) (end -0.3 0.2) (layer F.Fab) (width 0.15)) + (fp_line (start -0.2 0) (end 0.1 -0.2) (layer F.Fab) (width 0.15)) + (fp_line (start 0.1 0.2) (end -0.2 0) (layer F.Fab) (width 0.15)) + (fp_line (start 0.1 -0.2) (end 0.1 0.2) (layer F.Fab) (width 0.15)) + (fp_line (start 0.8 0.4) (end -0.8 0.4) (layer F.Fab) (width 0.15)) + (fp_line (start 0.8 -0.4) (end 0.8 0.4) (layer F.Fab) (width 0.15)) + (fp_line (start -0.8 -0.4) (end 0.8 -0.4) (layer F.Fab) (width 0.15)) + (fp_line (start -0.8 0.4) (end -0.8 -0.4) (layer F.Fab) (width 0.15)) + (fp_line (start -1.1 0.55) (end 0.8 0.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.1 -0.55) (end 0.8 -0.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.2 0) (end 0.25 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.25 -0.25) (end -0.25 0.25) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.25 0) (end 0 -0.25) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0 -0.25) (end 0 0.25) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0 0.25) (end -0.25 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.4 -0.75) (end 1.4 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.4 0.75) (end -1.4 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.4 0.75) (end -1.4 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.4 -0.75) (end 1.4 -0.75) (layer F.CrtYd) (width 0.05)) + (pad 2 smd rect (at 0.7493 0) (size 0.79756 0.79756) (layers F.Cu F.Paste F.Mask) + (net 16 "Net-(D2-Pad2)")) + (pad 1 smd rect (at -0.7493 0) (size 0.79756 0.79756) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model LEDs.3dshapes/LED_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 180)) + ) + ) + + (module Capacitors_SMD:C_1210 (layer F.Cu) (tedit 58A7A7CB) (tstamp 58338265) + (at 78.3082 115.824) + (descr "Capacitor SMD 1210, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 1210") + (path /55D739F3) + (attr smd) + (fp_text reference F1 (at 0 -0.0127) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value F_Small (at 0 2.7) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.3 -1.6) (end 2.3 -1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.3 1.6) (end 2.3 1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.3 -1.6) (end -2.3 1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start 2.3 -1.6) (end 2.3 1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1 -1.475) (end -1 -1.475) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1 1.475) (end 1 1.475) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -1.5 0) (size 1 2.5) (layers F.Cu F.Paste F.Mask) + (net 17 /3V3_OUT)) + (pad 2 smd rect (at 1.5 0) (size 1 2.5) (layers F.Cu F.Paste F.Mask) + (net 7 /VCC_3V3)) + (model Capacitors_SMD.3dshapes/C_1210.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_1206 (layer F.Cu) (tedit 58A7A780) (tstamp 583382A1) + (at 99.0727 112.3188 180) + (descr "Resistor SMD 1206, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 1206") + (path /56E88440) + (attr smd) + (fp_text reference L2 (at 0 0 180) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value INDUCTOR (at 0 2.3 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.2 -1.2) (end 2.2 -1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 -1.2) (end -2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 2.2 -1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1 1.075) (end -1 1.075) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1 -1.075) (end 1 -1.075) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -1.45 0 180) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 7 /VCC_3V3)) + (pad 2 smd rect (at 1.45 0 180) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 8 /AVCC)) + (model Resistors_SMD.3dshapes/R_1206.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_1206 (layer F.Cu) (tedit 58A7A7AB) (tstamp 583382A7) + (at 86.868 113.919 180) + (descr "Resistor SMD 1206, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 1206") + (path /56E8DA35) + (attr smd) + (fp_text reference L3 (at 0.1143 0.0127 180) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value INDUCTOR (at 0 2.3 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.2 -1.2) (end 2.2 -1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 -1.2) (end -2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 2.2 -1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1 1.075) (end -1 1.075) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1 -1.075) (end 1 -1.075) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -1.45 0 180) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 52 "Net-(L3-Pad1)")) + (pad 2 smd rect (at 1.45 0 180) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 9 /PSU_Unfiltered_Raw)) + (model Resistors_SMD.3dshapes/R_1206.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_1206 (layer F.Cu) (tedit 58A7A7A9) (tstamp 583382AD) + (at 84.455 116.332) + (descr "Resistor SMD 1206, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 1206") + (path /573254B0) + (attr smd) + (fp_text reference L4 (at -0.0508 -0.0762) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value INDUCTOR (at 0 2.3) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.2 -1.2) (end 2.2 -1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 -1.2) (end -2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 2.2 -1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1 1.075) (end -1 1.075) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1 -1.075) (end 1 -1.075) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -1.45 0) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 14 /OPAMP_VCC)) + (pad 2 smd rect (at 1.45 0) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 52 "Net-(L3-Pad1)")) + (model Resistors_SMD.3dshapes/R_1206.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x04 (layer F.Cu) (tedit 58A7A914) (tstamp 583382CA) + (at 71.12 114.3) + (descr "Through hole pin header") + (tags "pin header") + (path /55CBF4D5) + (fp_text reference P3 (at 0 0) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value DIG_OUT (at 0 -3.1) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 9.4) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 1.27) (end -1.27 8.89) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 1.27) (end 1.27 8.89) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 8.89) (end 1.27 8.89) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 54 /D3-OUT)) + (pad 2 thru_hole oval (at 0 2.54) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 55 /D2-OUT)) + (pad 3 thru_hole oval (at 0 5.08) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 56 /D1_OUT)) + (pad 4 thru_hole oval (at 0 7.62) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 57 /D0_OUT)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x04.wrl + (at (xyz 0 -0.15 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_2x02 locked (layer F.Cu) (tedit 58A7A919) (tstamp 583382D2) + (at 71.12 109.22) + (descr "Through hole pin header") + (tags "pin header") + (path /56069A87) + (fp_text reference P4 (at 0 -0.0508) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value PDI/3V3 (at 0 -3.1) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.3 -1.75) (end 4.3 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 4.3 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 4.3 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0 -1.55) (end -1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 1.27) (end 1.27 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 1.27) (end 1.27 -1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 -1.27) (end 3.81 -1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start 3.81 -1.27) (end 3.81 3.81) (layer Dwgs.User) (width 0.15)) + (fp_line (start 3.81 3.81) (end -1.27 3.81) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 3.81) (end -1.27 1.27) (layer Dwgs.User) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 1.7272 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 17 /3V3_OUT)) + (pad 2 thru_hole oval (at 2.54 0) (size 1.7272 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 44 /PDI_CLK)) + (pad 3 thru_hole oval (at 0 2.54) (size 1.7272 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 6 /VGND)) + (pad 4 thru_hole oval (at 2.54 2.54) (size 1.7272 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 45 /PDI_DATA)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_2x02.wrl + (at (xyz 0.05 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x04 (layer F.Cu) (tedit 58A7A85E) (tstamp 583382DA) + (at 85.7885 132.5245 90) + (descr "Through hole pin header") + (tags "pin header") + (path /58320706) + (fp_text reference P5 (at -0.0127 0.0127 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value SCOPE_OUT (at 0 -3.1 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 9.4) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 1.27) (end -1.27 8.89) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 1.27) (end 1.27 8.89) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 8.89) (end 1.27 8.89) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 3 /Scope_CH2_DC)) + (pad 2 thru_hole oval (at 0 2.54 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 4 /Scope_CH2_AC)) + (pad 3 thru_hole oval (at 0 5.08 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 3 /Scope_CH2_DC)) + (pad 4 thru_hole oval (at 0 7.62 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 3 /Scope_CH2_DC)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x04.wrl + (at (xyz 0 -0.15 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x04 locked (layer F.Cu) (tedit 58A7A816) (tstamp 583382E2) + (at 71.12 124.46) + (descr "Through hole pin header") + (tags "pin header") + (path /566DF832) + (fp_text reference P6 (at 0.1016 0.0508) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value DAC_OUT (at 0 -3.1) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 9.4) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 1.27) (end -1.27 8.89) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 1.27) (end 1.27 8.89) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 8.89) (end 1.27 8.89) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 11 /S-Gen_CH1_DC)) + (pad 2 thru_hole oval (at 0 2.54) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 10 /S-Gen_CH1_AC)) + (pad 3 thru_hole oval (at 0 5.08) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 13 /S-Gen_CH2_DC)) + (pad 4 thru_hole oval (at 0 7.62) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 12 /S-Gen_CH2_AC)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x04.wrl + (at (xyz 0 -0.15 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x02 locked (layer F.Cu) (tedit 58A7A80B) (tstamp 583382E8) + (at 77.47 110.49 90) + (descr "Through hole pin header") + (tags "pin header") + (path /56F2A93D) + (fp_text reference P7 (at -0.0508 0.0127 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value PSU (at 0 -3.1 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 1.27 1.27) (end 1.27 3.81) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 1.27) (end -1.27 3.81) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 3.81) (end 1.27 3.81) (layer Dwgs.User) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 90) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 58 /PSU_OUT)) + (pad 2 thru_hole oval (at 0 2.54 90) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 6 /VGND)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x02.wrl + (at (xyz 0 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x02 (layer F.Cu) (tedit 54EA090C) (tstamp 583382EE) + (at 104.4702 129.6162) + (descr "Through hole pin header") + (tags "pin header") + (path /55D6DB77) + (fp_text reference P8 (at 0 0.0381) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value DIG_IN (at 0 -3.1) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 1.27 1.27) (end 1.27 3.81) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 1.27) (end -1.27 3.81) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 3.81) (end 1.27 3.81) (layer Dwgs.User) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 59 /L-Ana_IN_CH1)) + (pad 2 thru_hole oval (at 0 2.54) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 60 /L-Ana_IN_CH2)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x02.wrl + (at (xyz 0 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x03 (layer F.Cu) (tedit 58A7A7FF) (tstamp 583382F5) + (at 71.0692 101.5873) + (descr "Through hole pin header") + (tags "pin header") + (path /5837847B) + (fp_text reference P10 (at 0 -0.0635) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value EXPANSION (at 0 -3.1) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 6.85) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 6.85) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 6.85) (end 1.75 6.85) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 1.27) (end -1.27 6.35) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 6.35) (end 1.27 6.35) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 6.35) (end 1.27 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 9 /PSU_Unfiltered_Raw)) + (pad 2 thru_hole oval (at 0 2.54) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 18 /PSU_FDBK)) + (pad 3 thru_hole oval (at 0 5.08) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 6 /VGND)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x03.wrl + (at (xyz 0 -0.1 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x03 (layer F.Cu) (tedit 58A7A7FB) (tstamp 583382FC) + (at 73.66 101.6) + (descr "Through hole pin header") + (tags "pin header") + (path /58378536) + (fp_text reference P11 (at 0.0127 -0.0127) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value SWITCH (at 0 -3.1) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 6.85) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 6.85) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 6.85) (end 1.75 6.85) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 1.27) (end -1.27 6.35) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 6.35) (end 1.27 6.35) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 6.35) (end 1.27 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 61 /Switch_OC)) + (pad 2 thru_hole oval (at 0 2.54) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 9 /PSU_Unfiltered_Raw)) + (pad 3 thru_hole oval (at 0 5.08) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 58 /PSU_OUT)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x03.wrl + (at (xyz 0 -0.1 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module SMD:SOT-23-3 (layer F.Cu) (tedit 5508E933) (tstamp 58338303) + (at 95.758 101.6 180) + (path /583120F2) + (fp_text reference Q1 (at -0.0127 -0.0508 360) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value Q_NMOS_GSD (at -2.2 0 270) (layer F.Fab) hide + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_circle (center 1 -0.4) (end 1.1 -0.5) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.5 -0.8) (end -1.5 0.8) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.5 0.8) (end 1.5 0.8) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.5 0.8) (end 1.5 -0.8) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.5 -0.8) (end -1.5 -0.8) (layer Dwgs.User) (width 0.15)) + (pad 3 smd rect (at 0 1.4 180) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 15 /QTop)) + (pad 2 smd rect (at -0.95 -1.4 180) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 1 smd rect (at 0.95 -1.4 180) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 36 /PSU_PWM)) + (model 3D/SMD/SOT-23-3.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.3937 0.3937 0.3937)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A857) (tstamp 58338309) + (at 82.7532 131.318 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAAB95) + (attr smd) + (fp_text reference R1 (at 0 0 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1M (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 62 /Scope_Buffer_Input_CH1)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 1 /Scope_CH1_DC)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A876) (tstamp 5833830F) + (at 81.788 128.7018 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAAD4C) + (attr smd) + (fp_text reference R2 (at 0.0254 0 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1M (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 63 /Scope_Buffer_Input_CH2)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 3 /Scope_CH2_DC)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A859) (tstamp 58338315) + (at 81.1276 131.318 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAABF4) + (attr smd) + (fp_text reference R3 (at 0 0 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 75K (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 62 /Scope_Buffer_Input_CH1)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 51 /AVCC_ON_2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A883) (tstamp 5833831B) + (at 80.1878 128.7018 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAAD11) + (attr smd) + (fp_text reference R4 (at 0.0254 0.0254 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 75K (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 51 /AVCC_ON_2)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 63 /Scope_Buffer_Input_CH2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A86F) (tstamp 58338321) + (at 83.9343 129.3241 180) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAAC5F) + (attr smd) + (fp_text reference R5 (at 0.0127 0.0889 180) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 180) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 8 /AVCC)) + (pad 2 smd rect (at 0.75 0 180) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 51 /AVCC_ON_2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A864) (tstamp 58338327) + (at 83.9343 127.8509 180) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAACD2) + (attr smd) + (fp_text reference R6 (at -0.0889 0.0889 180) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 180) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 2 smd rect (at 0.75 0 180) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 51 /AVCC_ON_2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A7E8) (tstamp 5833832D) + (at 73.1012 122.2756 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBCDA5) + (attr smd) + (fp_text reference R7 (at 0.0127 0 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 28R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 64 /D0_MID)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 57 /D0_OUT)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A7DB) (tstamp 58338333) + (at 73.1012 119.761 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE401) + (attr smd) + (fp_text reference R8 (at -0.0127 -0.1905 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 28R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 65 /D1_MID)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 56 /D1_OUT)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A7D8) (tstamp 58338339) + (at 73.1012 117.1702 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE16B) + (attr smd) + (fp_text reference R9 (at -0.0254 0 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 28R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 66 /D2_MID)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 55 /D2-OUT)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A7D0) (tstamp 5833833F) + (at 73.1012 114.6302 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE2C7) + (attr smd) + (fp_text reference R10 (at -0.0254 -0.0635 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 28R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 67 /D3_MID)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 54 /D3-OUT)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A7E5) (tstamp 58338345) + (at 74.4982 122.2756 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBCD2A) + (attr smd) + (fp_text reference R11 (at -0.0762 0 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 28R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 40 /D0-prefuse)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 64 /D0_MID)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A7DF) (tstamp 5833834B) + (at 74.4982 119.761 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE362) + (attr smd) + (fp_text reference R12 (at -0.0508 -0.0635 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 28R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 41 /D1-prefuse)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 65 /D1_MID)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A7D6) (tstamp 58338351) + (at 74.4982 117.1702 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE0F4) + (attr smd) + (fp_text reference R13 (at -0.0381 0.127 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 28R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 42 /D2-prefuse)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 66 /D2_MID)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A7D2) (tstamp 58338357) + (at 74.4982 114.6302 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE21C) + (attr smd) + (fp_text reference R14 (at 0.0254 -0.0635 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 28R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 43 /D3-prefuse)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 67 /D3_MID)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A851) (tstamp 5833835D) + (at 79.0702 132.9944) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56B0C779) + (attr smd) + (fp_text reference R15 (at -0.0254 -0.0508) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 68 /V_minus_dac_out2)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 69 /S-Gen_Drain_Top_CH2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A888) (tstamp 58338363) + (at 78.232 131.6736) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56B0C86E) + (attr smd) + (fp_text reference R16 (at 0 0) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 68 /V_minus_dac_out2)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 69 /S-Gen_Drain_Top_CH2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A835) (tstamp 58338369) + (at 75.2856 128.6764) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56AFE83E) + (attr smd) + (fp_text reference R17 (at 0.0508 0) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 70 /V_minus_dac_out)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 71 /S-Gen_Drain_Top_CH1)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A839) (tstamp 5833836F) + (at 73.3044 128.1684 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56AFE8F3) + (attr smd) + (fp_text reference R18 (at 0 -0.0508 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 70 /V_minus_dac_out)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 71 /S-Gen_Drain_Top_CH1)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A82C) (tstamp 58338375) + (at 76.327 124.968 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56AECD86) + (attr smd) + (fp_text reference R19 (at 0.0508 0.0254 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 72 /Buffered_DAC_CH1)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 70 /V_minus_dac_out)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A84F) (tstamp 5833837B) + (at 76.5556 132.9944) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56B0C682) + (attr smd) + (fp_text reference R20 (at 0 0.0508) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 73 /Buffered_DAC_CH2)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 68 /V_minus_dac_out2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A891) (tstamp 58338381) + (at 85.852 125.095 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56E9851A) + (attr smd) + (fp_text reference R21 (at 0.0254 0 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 49 /CH1)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A837) (tstamp 58338387) + (at 75.2475 127.0635) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CB4680) + (attr smd) + (fp_text reference R22 (at 0.1905 0.0381) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 28R (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 74 /R22-R24)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 72 /Buffered_DAC_CH1)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A83F) (tstamp 5833838D) + (at 73.914 132.9944) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /566DE721) + (attr smd) + (fp_text reference R23 (at 0 0.0508) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 28R (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 75 /R23-R25)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 73 /Buffered_DAC_CH2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A826) (tstamp 58338393) + (at 74.7395 124.9045 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CB9020) + (attr smd) + (fp_text reference R24 (at 0.0127 -0.0381 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 28R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 11 /S-Gen_CH1_DC)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 74 /R22-R24)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A848) (tstamp 58338399) + (at 74.7268 130.9116 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /566DE7E8) + (attr smd) + (fp_text reference R25 (at 0.0508 -0.0508 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 28R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 13 /S-Gen_CH2_DC)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 75 /R23-R25)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A7A5) (tstamp 5833839F) + (at 83.312 112.776) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /566E5C29) + (attr smd) + (fp_text reference R26 (at 0.0762 0.0508) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 9 /PSU_Unfiltered_Raw)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 18 /PSU_FDBK)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A8B0) (tstamp 583383A5) + (at 83.312 114.3 180) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /566E5CBE) + (attr smd) + (fp_text reference R27 (at -0.0508 0 180) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 100R (at 0 1.9 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 180) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 18 /PSU_FDBK)) + (pad 2 smd rect (at 0.75 0 180) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A8A6) (tstamp 583383AB) + (at 85.8266 119.634 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56E985EF) + (attr smd) + (fp_text reference R28 (at 0 0.0254 90) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 19 /CH2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A7ED) (tstamp 583383B1) + (at 77.0255 119.6975 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56E9888A) + (attr smd) + (fp_text reference R29 (at -0.1397 -0.0127 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 72 /Buffered_DAC_CH1)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A84B) (tstamp 583383B7) + (at 76.2508 130.9624 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56E98921) + (attr smd) + (fp_text reference R30 (at -0.0508 -0.0508 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 73 /Buffered_DAC_CH2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A6E9) (tstamp 583383BD) + (at 98.0567 101.0158 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /5804605C) + (attr smd) + (fp_text reference R31 (at 0 0 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 36 /PSU_PWM)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 58A7A7F1) (tstamp 583383C3) + (at 77.343 113.03) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /5833E34C) + (attr smd) + (fp_text reference R32 (at 0.0127 0.0508) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 1K (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 58 /PSU_OUT)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 16 "Net-(D2-Pad2)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module SMD:SOT-23-3 (layer F.Cu) (tedit 5508E933) (tstamp 583383CA) + (at 102.8065 113.665) + (path /55CA99FA) + (fp_text reference U1 (at 0.0127 0 180) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value 78L05 (at -2.2 0 90) (layer F.Fab) hide + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_circle (center 1 -0.4) (end 1.1 -0.5) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.5 -0.8) (end -1.5 0.8) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.5 0.8) (end 1.5 0.8) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.5 0.8) (end 1.5 -0.8) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.5 -0.8) (end -1.5 -0.8) (layer Dwgs.User) (width 0.15)) + (pad 3 smd rect (at 0 1.4) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 5 +5V)) + (pad 2 smd rect (at -0.95 -1.4) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 7 /VCC_3V3)) + (pad 1 smd rect (at 0.95 -1.4) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model 3D/SMD/SOT-23-3.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.3937 0.3937 0.3937)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm (layer F.Cu) (tedit 58A7A87A) (tstamp 583383DC) + (at 81.534 122.555 180) + (descr "14-Lead Plastic Small Outline (SL) - Narrow, 3.90 mm Body [SOIC] (see Microchip Packaging Specification 00000049BS.pdf)") + (tags "SOIC 1.27") + (path /55CA87E2) + (attr smd) + (fp_text reference U2 (at 0 0.0254 180) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value LM324 (at 0 5.375 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -3.7 -4.65) (end -3.7 4.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.7 -4.65) (end 3.7 4.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.7 -4.65) (end 3.7 -4.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.7 4.65) (end 3.7 4.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.075 -4.45) (end -2.075 -4.335) (layer Dwgs.User) (width 0.15)) + (fp_line (start 2.075 -4.45) (end 2.075 -4.335) (layer Dwgs.User) (width 0.15)) + (fp_line (start 2.075 4.45) (end 2.075 4.335) (layer Dwgs.User) (width 0.15)) + (fp_line (start -2.075 4.45) (end -2.075 4.335) (layer Dwgs.User) (width 0.15)) + (fp_line (start -2.075 -4.45) (end 2.075 -4.45) (layer Dwgs.User) (width 0.15)) + (fp_line (start -2.075 4.45) (end 2.075 4.45) (layer Dwgs.User) (width 0.15)) + (fp_line (start -2.075 -4.335) (end -3.45 -4.335) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -2.7 -3.81 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 49 /CH1)) + (pad 2 smd rect (at -2.7 -2.54 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 49 /CH1)) + (pad 3 smd rect (at -2.7 -1.27 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 62 /Scope_Buffer_Input_CH1)) + (pad 4 smd rect (at -2.7 0 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 14 /OPAMP_VCC)) + (pad 5 smd rect (at -2.7 1.27 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 63 /Scope_Buffer_Input_CH2)) + (pad 6 smd rect (at -2.7 2.54 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 19 /CH2)) + (pad 7 smd rect (at -2.7 3.81 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 19 /CH2)) + (pad 8 smd rect (at 2.7 3.81 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 72 /Buffered_DAC_CH1)) + (pad 9 smd rect (at 2.7 2.54 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 70 /V_minus_dac_out)) + (pad 10 smd rect (at 2.7 1.27 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 23 /DAC_OUT)) + (pad 11 smd rect (at 2.7 0 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 12 smd rect (at 2.7 -1.27 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 24 /DAC_OUT2)) + (pad 13 smd rect (at 2.7 -2.54 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 68 /V_minus_dac_out2)) + (pad 14 smd rect (at 2.7 -3.81 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 73 /Buffered_DAC_CH2)) + (model Housings_SOIC.3dshapes/SOIC-14_3.9x8.7mm_Pitch1.27mm.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module TO_SOT_Packages_SMD:SOT-363 (layer F.Cu) (tedit 56735562) (tstamp 583383E6) + (at 77.978 129.3368 270) + (descr SOT353) + (path /56B012DD) + (attr smd) + (fp_text reference U3 (at 0.09906 0 360) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value DMN63D8LDW (at 0.09906 0 360) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 0.635 1.016) (end 0.635 -1.016) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.635 -1.016) (end -0.635 -1.016) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.635 -1.016) (end -0.635 1.016) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.635 1.016) (end 0.635 1.016) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -1.016 -0.635 270) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 3 smd rect (at -1.016 0.635 270) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 71 /S-Gen_Drain_Top_CH1)) + (pad 6 smd rect (at 1.016 -0.635 270) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 69 /S-Gen_Drain_Top_CH2)) + (pad 2 smd rect (at -1.016 0 270) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 21 /TO_B0)) + (pad 4 smd rect (at 1.016 0.635 270) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 5 smd rect (at 1.016 0 270) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 22 /TO_B1)) + (model TO_SOT_Packages_SMD.3dshapes/SOT-353.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.07000000000000001 0.09 0.08)) + (rotate (xyz 0 0 90)) + ) + ) + + (module TO_SOT_Packages_SMD:SOT-363 (layer F.Cu) (tedit 58A7A8FC) (tstamp 583383F0) + (at 96.8502 132.3848 90) + (descr SOT353) + (path /55D6ACFD) + (attr smd) + (fp_text reference U4 (at -0.0508 0.0254 180) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value DMN63D8LDW (at 0.09906 0 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 0.635 1.016) (end 0.635 -1.016) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.635 -1.016) (end -0.635 -1.016) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.635 -1.016) (end -0.635 1.016) (layer Dwgs.User) (width 0.15)) + (fp_line (start -0.635 1.016) (end 0.635 1.016) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -1.016 -0.635 90) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 3 smd rect (at -1.016 0.635 90) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 28 /DIG_CH2)) + (pad 6 smd rect (at 1.016 -0.635 90) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 30 /DIG_CH1)) + (pad 2 smd rect (at -1.016 0 90) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 60 /L-Ana_IN_CH2)) + (pad 4 smd rect (at 1.016 0.635 90) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (pad 5 smd rect (at 1.016 0 90) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 59 /L-Ana_IN_CH1)) + (model TO_SOT_Packages_SMD.3dshapes/SOT-353.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.07000000000000001 0.09 0.08)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x02 (layer F.Cu) (tedit 54EA090C) (tstamp 58345312) + (at 104.5972 115.3922) + (descr "Through hole pin header") + (tags "pin header") + (fp_text reference REF** (at 2.54 0.8001) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value Pin_Header_Straight_1x02 (at 0 -3.1) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 1.27 1.27) (end 1.27 3.81) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 1.27) (end -1.27 3.81) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 3.81) (end 1.27 3.81) (layer Dwgs.User) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask Dwgs.User)) + (pad 2 thru_hole oval (at 0 2.54) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask Dwgs.User)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x02.wrl + (at (xyz 0 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module labralogo:logo800dpi (layer F.Cu) (tedit 0) (tstamp 5834D8EB) + (at 100.4824 131.7752) + (fp_text reference G*** (at 0 0) (layer B.SilkS) hide + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value LOGO (at 0.75 0) (layer B.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy 1.300101 -1.955599) (xy 1.446523 -1.921512) (xy 1.598775 -1.86308) (xy 1.738746 -1.789516) + (xy 1.848326 -1.710034) (xy 1.901062 -1.649843) (xy 1.937895 -1.559705) (xy 1.972343 -1.419853) + (xy 2.00105 -1.244063) (xy 2.002296 -1.234407) (xy 2.021133 -0.974785) (xy 2.008538 -0.71766) + (xy 1.96231 -0.449504) (xy 1.880246 -0.156789) (xy 1.782364 0.117045) (xy 1.703808 0.323046) + (xy 1.645421 0.484308) (xy 1.603738 0.615033) (xy 1.575297 0.72942) (xy 1.556634 0.84167) + (xy 1.544287 0.965983) (xy 1.534791 1.116561) (xy 1.533701 1.13665) (xy 1.526091 1.294027) + (xy 1.524407 1.402112) (xy 1.530243 1.474964) (xy 1.545194 1.526645) (xy 1.570855 1.571213) + (xy 1.585264 1.591266) (xy 1.634976 1.681866) (xy 1.628672 1.742915) (xy 1.566546 1.773918) + (xy 1.512773 1.778) (xy 1.418335 1.76121) (xy 1.354913 1.70258) (xy 1.352858 1.699486) + (xy 1.31197 1.611809) (xy 1.27141 1.483589) (xy 1.236746 1.337567) (xy 1.21354 1.196482) + (xy 1.206969 1.103312) (xy 1.199187 1.026761) (xy 1.180479 0.9862) (xy 1.17475 0.98425) + (xy 1.154893 1.012884) (xy 1.145069 1.088072) (xy 1.144805 1.193743) (xy 1.153627 1.313827) + (xy 1.171063 1.432252) (xy 1.190308 1.51303) (xy 1.230059 1.617069) (xy 1.277885 1.70231) + (xy 1.301433 1.730088) (xy 1.361626 1.810923) (xy 1.367197 1.882959) (xy 1.327011 1.93608) + (xy 1.249932 1.960174) (xy 1.144827 1.945127) (xy 1.12068 1.936312) (xy 1.029236 1.868567) + (xy 0.942613 1.745049) (xy 0.864555 1.573478) (xy 0.798808 1.361573) (xy 0.763223 1.199354) + (xy 0.740779 1.086545) (xy 0.719593 1.02115) (xy 0.689603 0.988102) (xy 0.640748 0.972333) + (xy 0.607741 0.966493) (xy 0.488844 0.942368) (xy 0.36972 0.90773) (xy 0.234451 0.856911) + (xy 0.067122 0.784244) (xy -0.03175 0.738779) (xy -0.333375 0.59838) (xy -0.41275 0.700248) + (xy -0.471633 0.772384) (xy -0.556943 0.872766) (xy -0.652568 0.982495) (xy -0.67621 1.009189) + (xy -0.7735 1.12438) (xy -0.864628 1.242123) (xy -0.932651 1.340319) (xy -0.942274 1.356149) + (xy -1.024253 1.496036) (xy -0.934611 1.589602) (xy -0.879026 1.657363) (xy -0.869678 1.701477) + (xy -0.881841 1.72004) (xy -0.935439 1.735649) (xy -1.018916 1.726519) (xy -1.107042 1.699458) + (xy -1.174587 1.661272) (xy -1.19484 1.63559) (xy -1.199012 1.582907) (xy -1.193135 1.489376) + (xy -1.180771 1.391304) (xy -1.166363 1.286303) (xy -1.159067 1.209709) (xy -1.160145 1.17961) + (xy -1.180503 1.194493) (xy -1.213731 1.252291) (xy -1.252139 1.335839) (xy -1.288038 1.427973) + (xy -1.313737 1.511527) (xy -1.318412 1.532903) (xy -1.323565 1.637155) (xy -1.289207 1.735244) + (xy -1.273071 1.764051) (xy -1.228813 1.857166) (xy -1.231676 1.91221) (xy -1.28306 1.935178) + (xy -1.313431 1.93675) (xy -1.41128 1.914985) (xy -1.478348 1.845907) (xy -1.519341 1.723841) + (xy -1.52678 1.679448) (xy -1.549896 1.46779) (xy -1.550329 1.294364) (xy -1.526133 1.137382) + (xy -1.475366 0.975059) (xy -1.460501 0.936625) (xy -1.403848 0.775704) (xy -1.374335 0.635994) + (xy -1.36529 0.484955) (xy -1.36525 0.472026) (xy -1.366788 0.355507) (xy -1.373573 0.290639) + (xy -1.388864 0.265605) (xy -1.415921 0.268588) (xy -1.420813 0.270561) (xy -1.564552 0.307108) + (xy -1.721448 0.309448) (xy -1.867714 0.279593) (xy -1.974554 0.223732) (xy -2.046844 0.165194) + (xy -1.904485 0.127312) (xy -1.675733 0.04062) (xy -1.443532 -0.094541) (xy -1.226476 -0.267089) + (xy -1.198338 -0.293614) (xy -1.104658 -0.38321) (xy -1.026107 -0.452346) (xy -0.952602 -0.503885) + (xy -0.874056 -0.540693) (xy -0.780385 -0.565635) (xy -0.661503 -0.581574) (xy -0.507325 -0.591375) + (xy -0.307767 -0.597904) (xy -0.110331 -0.602656) (xy 0.588963 -0.619125) (xy 0.795662 -0.720945) + (xy 0.911205 -0.783891) (xy 1.013209 -0.84992) (xy 1.077902 -0.903175) (xy 1.12628 -0.959932) + (xy 1.133128 -0.997249) (xy 1.102063 -1.040344) (xy 1.098188 -1.044641) (xy 1.043977 -1.090472) + (xy 0.953029 -1.153917) (xy 0.844195 -1.221895) (xy 0.834796 -1.227421) (xy 0.658402 -1.35142) + (xy 0.540091 -1.482146) (xy 0.482091 -1.616813) (xy 0.47625 -1.675242) (xy 0.485478 -1.750663) + (xy 0.495387 -1.762125) (xy 1.11125 -1.762125) (xy 1.127359 -1.72261) (xy 1.145381 -1.720586) + (xy 1.178184 -1.753364) (xy 1.179512 -1.762125) (xy 1.154794 -1.799353) (xy 1.145381 -1.803665) + (xy 1.11643 -1.788339) (xy 1.11125 -1.762125) (xy 0.495387 -1.762125) (xy 0.520551 -1.791232) + (xy 0.592551 -1.80173) (xy 0.712559 -1.786936) (xy 0.728579 -1.784076) (xy 0.826296 -1.769176) + (xy 0.891712 -1.774276) (xy 0.952609 -1.806941) (xy 1.024811 -1.864737) (xy 1.108204 -1.929228) + (xy 1.172902 -1.958615) (xy 1.245963 -1.961831) (xy 1.300101 -1.955599)) (layer F.SilkS) (width 0.01)) + ) + + (module labralogo:oshwnotext500dpi (layer F.Cu) (tedit 0) (tstamp 58357672) + (at 100.6094 127.8382) + (fp_text reference G*** (at 0 0) (layer F.SilkS) hide + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value LOGO (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy 0.177882 -1.775032) (xy 0.268443 -1.751419) (xy 0.320356 -1.685099) (xy 0.35689 -1.554012) + (xy 0.379702 -1.442118) (xy 0.452739 -1.289777) (xy 0.538285 -1.226218) (xy 0.649654 -1.182309) + (xy 0.737367 -1.17844) (xy 0.838246 -1.221226) (xy 0.96826 -1.303455) (xy 1.172341 -1.43851) + (xy 1.34817 -1.26809) (xy 1.470554 -1.134678) (xy 1.514057 -1.02839) (xy 1.481895 -0.916497) + (xy 1.395186 -0.789538) (xy 1.316091 -0.677765) (xy 1.294075 -0.598072) (xy 1.323237 -0.502812) + (xy 1.352022 -0.441044) (xy 1.417259 -0.328757) (xy 1.498654 -0.268111) (xy 1.633861 -0.234896) + (xy 1.684036 -0.22755) (xy 1.9304 -0.193667) (xy 1.9304 0.396866) (xy 1.682566 0.430951) + (xy 1.529464 0.459034) (xy 1.4422 0.505331) (xy 1.385223 0.594563) (xy 1.360035 0.655198) + (xy 1.316477 0.783826) (xy 1.321076 0.869962) (xy 1.380408 0.96381) (xy 1.404417 0.994179) + (xy 1.496245 1.133528) (xy 1.511285 1.248223) (xy 1.446126 1.367218) (xy 1.34817 1.471289) + (xy 1.172341 1.641709) (xy 0.966279 1.505344) (xy 0.824767 1.423117) (xy 0.728026 1.401106) + (xy 0.662591 1.421226) (xy 0.61351 1.446848) (xy 0.576693 1.450881) (xy 0.541363 1.418496) + (xy 0.496742 1.334862) (xy 0.432051 1.18515) (xy 0.353919 0.996522) (xy 0.27456 0.802223) + (xy 0.231245 0.679398) (xy 0.221072 0.605681) (xy 0.241138 0.558707) (xy 0.28854 0.516112) + (xy 0.291292 0.513922) (xy 0.43702 0.345951) (xy 0.502875 0.152388) (xy 0.485884 -0.042043) + (xy 0.383076 -0.212619) (xy 0.379103 -0.216642) (xy 0.188816 -0.349634) (xy -0.009494 -0.382911) + (xy -0.205821 -0.316747) (xy -0.350722 -0.196734) (xy -0.440708 -0.032199) (xy -0.449477 0.159532) + (xy -0.381324 0.350785) (xy -0.240541 0.513884) (xy -0.240493 0.513922) (xy -0.191919 0.556849) + (xy -0.17055 0.60314) (xy -0.179289 0.675159) (xy -0.221038 0.795273) (xy -0.298699 0.985845) + (xy -0.30312 0.996522) (xy -0.393126 1.213524) (xy -0.453983 1.351926) (xy -0.496501 1.426539) + (xy -0.531491 1.452177) (xy -0.569764 1.443651) (xy -0.61272 1.42073) (xy -0.697408 1.399587) + (xy -0.800245 1.434326) (xy -0.900829 1.496793) (xy -1.020818 1.574325) (xy -1.103235 1.620227) + (xy -1.119428 1.6256) (xy -1.169002 1.592323) (xy -1.260994 1.50813) (xy -1.310835 1.458081) + (xy -1.427675 1.319186) (xy -1.464333 1.207391) (xy -1.423702 1.09131) (xy -1.353618 0.994179) + (xy -1.27966 0.890621) (xy -1.262068 0.807257) (xy -1.294268 0.693881) (xy -1.309236 0.655198) + (xy -1.364181 0.538631) (xy -1.43344 0.476103) (xy -1.552566 0.442895) (xy -1.631767 0.430951) + (xy -1.879601 0.396866) (xy -1.8796 0.1016) (xy -1.8796 -0.193667) (xy -1.633237 -0.22755) + (xy -1.477228 -0.25753) (xy -1.385113 -0.308456) (xy -1.319241 -0.40454) (xy -1.301223 -0.441044) + (xy -1.25062 -0.559304) (xy -1.248495 -0.640205) (xy -1.300749 -0.731392) (xy -1.344387 -0.789538) + (xy -1.439588 -0.932809) (xy -1.461914 -1.04208) (xy -1.408148 -1.150079) (xy -1.297371 -1.26809) + (xy -1.121542 -1.43851) (xy -0.917461 -1.303455) (xy -0.774137 -1.213795) (xy -0.676613 -1.176652) + (xy -0.588064 -1.18541) (xy -0.487486 -1.226218) (xy -0.370626 -1.332409) (xy -0.328903 -1.442118) + (xy -0.290732 -1.61989) (xy -0.250421 -1.720346) (xy -0.184698 -1.765547) (xy -0.070291 -1.777553) + (xy 0.025399 -1.778) (xy 0.177882 -1.775032)) (layer F.SilkS) (width 0.01)) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 58A7A6EF) (tstamp 58801242) + (at 99.5807 101.0158 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /588029E7) + (attr smd) + (fp_text reference C12 (at 0 -0.0635 270) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value C (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer Dwgs.User) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 36 /PSU_PWM)) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 6 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_1210 (layer F.Cu) (tedit 58FEC827) (tstamp 58F57B8D) + (at 88.5698 110.5408 180) + (descr "Capacitor SMD 1210, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 1210") + (path /58F5AF9C) + (attr smd) + (fp_text reference F2 (at -0.0127 0.4953 180) (layer Dwgs.User) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value F_Small (at 0 2.7 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.3 -1.6) (end 2.3 -1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.3 1.6) (end 2.3 1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.3 -1.6) (end -2.3 1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start 2.3 -1.6) (end 2.3 1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1 -1.475) (end -1 -1.475) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1 1.475) (end 1 1.475) (layer Dwgs.User) (width 0.15)) + (pad 1 smd rect (at -1.5 0 180) (size 1 2.5) (layers F.Cu F.Paste F.Mask) + (net 5 +5V)) + (pad 2 smd rect (at 1.5 0 180) (size 1 2.5) (layers F.Cu F.Paste F.Mask) + (net 76 "Net-(F2-Pad2)")) + (model Capacitors_SMD.3dshapes/C_1210.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Special_inductor:SMALL_INDUCTOR (layer F.Cu) (tedit 58F57C0A) (tstamp 58F5862C) + (at 87.757 105.9815 270) + (descr "SELF- WE-PD-XXL") + (path /5606EE9E) + (attr smd) + (fp_text reference L1 (at -0.0127 -0.2032 360) (layer Dwgs.User) + (effects (font (size 0.6 0.6) (thickness 0.1))) + ) + (fp_text value INDUCTOR (at 1.80086 0 360) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_circle (center 0 0) (end 0 -5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.99948 0) (end -5.99948 -5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.99948 -5.00126) (end -5.00126 -5.99948) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.00126 -5.99948) (end 5.00126 -5.99948) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.00126 -5.99948) (end 5.99948 -5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.99948 -5.00126) (end 5.99948 5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.99948 5.00126) (end 5.00126 5.99948) (layer Dwgs.User) (width 0.15)) + (fp_line (start 5.00126 5.99948) (end -5.00126 5.99948) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.00126 5.99948) (end -5.99948 5.00126) (layer Dwgs.User) (width 0.15)) + (fp_line (start -5.99948 5.00126) (end -5.99948 0) (layer Dwgs.User) (width 0.15)) + (fp_text user "" (at 0 0 270) (layer Dwgs.User) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text user "" (at 0 0 270) (layer Dwgs.User) + (effects (font (size 1 1) (thickness 0.15))) + ) + (pad 1 smd rect (at -5.00126 0 270) (size 2.90068 5.40004) (layers F.Cu F.Paste F.Mask) + (net 15 /QTop)) + (pad 2 smd rect (at 0.08 0 270) (size 2.9 5.40004) (layers F.Cu F.Paste F.Mask) + (net 76 "Net-(F2-Pad2)")) + (model Inductors.3dshapes/SELF-WE-PD-XXL.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x02 (layer F.Cu) (tedit 58FEC885) (tstamp 58FEA896) + (at 92.5195 102.1715) + (descr "Through hole pin header") + (tags "pin header") + (path /58FEDB8C) + (fp_text reference P9 (at 0 0.3175) (layer Dwgs.User) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value FUSE_BYPASS (at 0 -3.1) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 1.27 1.27) (end 1.27 3.81) (layer Dwgs.User) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 1.27) (end -1.27 3.81) (layer Dwgs.User) (width 0.15)) + (fp_line (start -1.27 3.81) (end 1.27 3.81) (layer Dwgs.User) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 5 +5V)) + (pad 2 thru_hole oval (at 0 2.54) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask Dwgs.User) + (net 76 "Net-(F2-Pad2)")) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x02.wrl + (at (xyz 0 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module labralogo:logo175dpi (layer F.Cu) (tedit 59116AC4) (tstamp 59116BA7) + (at 87.376 115.824) + (fp_text reference Main_Logo (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value LARGE_LOGO (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy 5.943322 -8.939877) (xy 6.612681 -8.784053) (xy 7.308687 -8.516935) (xy 7.948554 -8.180643) + (xy 8.449495 -7.817298) (xy 8.690571 -7.542137) (xy 8.858951 -7.130078) (xy 9.01643 -6.490753) + (xy 9.147658 -5.687144) (xy 9.153354 -5.643004) (xy 9.239469 -4.456159) (xy 9.181893 -3.280729) + (xy 8.970563 -2.054874) (xy 8.595414 -0.716748) (xy 8.147953 0.535066) (xy 7.78884 1.476784) + (xy 7.521925 2.213983) (xy 7.331375 2.811581) (xy 7.201359 3.334492) (xy 7.116044 3.847635) + (xy 7.059598 4.415926) (xy 7.01619 5.104281) (xy 7.011208 5.196118) (xy 6.97642 5.915555) + (xy 6.968721 6.409656) (xy 6.9954 6.742696) (xy 7.063747 6.978949) (xy 7.181053 7.182688) + (xy 7.246924 7.274362) (xy 7.474178 7.68853) (xy 7.445362 7.967614) (xy 7.161357 8.10934) + (xy 6.915534 8.128) (xy 6.483821 8.051249) (xy 6.193892 7.783226) (xy 6.184498 7.76908) + (xy 5.997578 7.368272) (xy 5.812164 6.782124) (xy 5.653697 6.114593) (xy 5.547615 5.469634) + (xy 5.517574 5.043714) (xy 5.481999 4.693767) (xy 5.396478 4.508345) (xy 5.370286 4.499428) + (xy 5.279515 4.630327) (xy 5.234606 4.974044) (xy 5.233397 5.457113) (xy 5.273728 6.006067) + (xy 5.353435 6.547439) (xy 5.441411 6.916709) (xy 5.623128 7.392319) (xy 5.841763 7.781988) + (xy 5.949411 7.908977) (xy 6.224577 8.278508) (xy 6.250044 8.607813) (xy 6.066336 8.850655) + (xy 5.713979 8.960799) (xy 5.233497 8.892011) (xy 5.123111 8.851716) (xy 4.705079 8.542021) + (xy 4.309089 7.977368) (xy 3.952255 7.193044) (xy 3.651694 6.224337) (xy 3.489022 5.482764) + (xy 3.386423 4.967063) (xy 3.289571 4.668116) (xy 3.152473 4.51704) (xy 2.929136 4.444952) + (xy 2.778249 4.418257) (xy 2.234719 4.307969) (xy 1.69015 4.149623) (xy 1.07178 3.917309) + (xy 0.306846 3.585116) (xy -0.145142 3.377276) (xy -1.524 2.735453) (xy -1.886857 3.201135) + (xy -2.156032 3.530902) (xy -2.546024 3.989788) (xy -2.983163 4.491408) (xy -3.091243 4.613435) + (xy -3.535995 5.140025) (xy -3.952585 5.678277) (xy -4.263547 6.127175) (xy -4.307535 6.199538) + (xy -4.682298 6.839023) (xy -4.272506 7.266754) (xy -4.0184 7.576517) (xy -3.975669 7.778183) + (xy -4.031269 7.863041) (xy -4.276288 7.934398) (xy -4.657898 7.892662) (xy -5.06076 7.768952) + (xy -5.369536 7.594387) (xy -5.462125 7.476983) (xy -5.481194 7.236147) (xy -5.454329 6.808578) + (xy -5.397807 6.360251) (xy -5.331941 5.880244) (xy -5.298587 5.530099) (xy -5.303516 5.392506) + (xy -5.396582 5.460542) (xy -5.548481 5.724761) (xy -5.724061 6.106695) (xy -5.888169 6.527878) + (xy -6.005654 6.90984) (xy -6.027025 7.007558) (xy -6.050578 7.484137) (xy -5.893517 7.932545) + (xy -5.819749 8.064235) (xy -5.61743 8.489905) (xy -5.630516 8.741532) (xy -5.865415 8.84653) + (xy -6.004253 8.853714) (xy -6.451562 8.754218) (xy -6.758159 8.438434) (xy -6.945557 7.880419) + (xy -6.979563 7.677479) (xy -7.085238 6.709901) (xy -7.087215 5.917093) (xy -6.976607 5.199463) + (xy -6.744528 4.457415) (xy -6.676571 4.281714) (xy -6.417588 3.546077) (xy -6.28267 2.907403) + (xy -6.241322 2.216939) (xy -6.241143 2.157836) (xy -6.24817 1.625176) (xy -6.279186 1.328637) + (xy -6.349089 1.214197) (xy -6.472778 1.227834) (xy -6.495142 1.23685) (xy -7.152236 1.403922) + (xy -7.869473 1.414621) (xy -8.538118 1.278142) (xy -9.026532 1.022775) (xy -9.357003 0.755176) + (xy -8.706216 0.582001) (xy -7.66049 0.185695) (xy -6.599001 -0.432186) (xy -5.606743 -1.220977) + (xy -5.478115 -1.342235) (xy -5.049862 -1.751817) (xy -4.690774 -2.067865) (xy -4.354748 -2.303474) + (xy -3.995682 -2.471739) (xy -3.56747 -2.585756) (xy -3.024011 -2.65862) (xy -2.319199 -2.703427) + (xy -1.406933 -2.733272) (xy -0.504369 -2.754996) (xy 2.692404 -2.830286) (xy 3.637314 -3.295749) + (xy 4.165512 -3.5835) (xy 4.631817 -3.885347) (xy 4.927556 -4.128799) (xy 5.148711 -4.388259) + (xy 5.180017 -4.558853) (xy 5.038004 -4.755856) (xy 5.020291 -4.775502) (xy 4.772468 -4.985013) + (xy 4.356705 -5.275048) (xy 3.859178 -5.585806) (xy 3.816212 -5.611065) (xy 3.009842 -6.177919) + (xy 2.468991 -6.775522) (xy 2.203849 -7.391143) (xy 2.177143 -7.658248) (xy 2.219331 -8.003029) + (xy 2.264632 -8.055429) (xy 5.08 -8.055429) (xy 5.153646 -7.874788) (xy 5.236029 -7.865534) + (xy 5.385985 -8.015377) (xy 5.392058 -8.055429) (xy 5.279061 -8.225614) (xy 5.236029 -8.245324) + (xy 5.103682 -8.175261) (xy 5.08 -8.055429) (xy 2.264632 -8.055429) (xy 2.379666 -8.188489) + (xy 2.708807 -8.236479) (xy 3.257415 -8.168848) (xy 3.330651 -8.155776) (xy 3.777356 -8.087659) + (xy 4.076399 -8.110973) (xy 4.354785 -8.260301) (xy 4.684854 -8.524512) (xy 5.06608 -8.819324) + (xy 5.361842 -8.953667) (xy 5.695831 -8.968366) (xy 5.943322 -8.939877)) (layer B.SilkS) (width 0.01)) + ) + + (gr_text "Batch 1" (at 99.3902 99.8728) (layer B.SilkS) + (effects (font (size 1 1) (thickness 0.25)) (justify mirror)) + ) + (gr_text Edition (at 80.0227 131.1783) (layer B.SilkS) + (effects (font (size 1.5 1.5) (thickness 0.3)) (justify mirror)) + ) + (gr_text "Backer's\n" (at 81.1022 128.7653) (layer B.SilkS) + (effects (font (size 1.5 1.5) (thickness 0.3)) (justify mirror)) + ) + (gr_text "EspoTek Labrador" (at 87.2617 126.1618) (layer B.SilkS) + (effects (font (size 1.5 1.5) (thickness 0.3)) (justify mirror)) + ) + (gr_line (start 69.4944 99.2124) (end 106.299 99.2124) (angle 90) (layer Edge.Cuts) (width 0.1)) + (gr_line (start 69.4944 133.9342) (end 69.4944 99.2124) (angle 90) (layer Edge.Cuts) (width 0.1)) + (gr_line (start 106.2736 133.9342) (end 69.5452 133.9342) (angle 90) (layer Edge.Cuts) (width 0.1)) + (gr_line (start 106.2736 99.2886) (end 106.2736 133.9342) (angle 90) (layer Edge.Cuts) (width 0.1)) + + (segment (start 95.9485 129.3495) (end 96.0755 129.3495) (width 0.25) (layer F.Cu) (net 1)) + (segment (start 96.0755 129.3495) (end 96.9525 128.4725) (width 0.25) (layer F.Cu) (net 1) (tstamp 5833F529)) + (segment (start 96.9525 128.4725) (end 98.044 128.4725) (width 0.25) (layer F.Cu) (net 1) (tstamp 5833F52A)) + (segment (start 93.4085 129.3495) (end 93.2561 129.3495) (width 0.25) (layer B.Cu) (net 1)) + (segment (start 93.2561 129.3495) (end 91.7448 130.8608) (width 0.25) (layer B.Cu) (net 1) (tstamp 5833F449)) + (segment (start 89.8398 130.8608) (end 88.3285 129.3495) (width 0.25) (layer B.Cu) (net 1) (tstamp 5833F44C)) + (segment (start 91.7448 130.8608) (end 89.8398 130.8608) (width 0.25) (layer B.Cu) (net 1) (tstamp 5833F44A)) + (segment (start 95.9485 129.3495) (end 93.4085 129.3495) (width 0.25) (layer F.Cu) (net 1)) + (segment (start 82.7532 130.568) (end 84.824 130.568) (width 0.25) (layer F.Cu) (net 1)) + (segment (start 86.6648 130.302) (end 87.6173 129.3495) (width 0.25) (layer F.Cu) (net 1) (tstamp 5833F3B8)) + (segment (start 85.09 130.302) (end 86.6648 130.302) (width 0.25) (layer F.Cu) (net 1) (tstamp 5833F3B7)) + (segment (start 84.824 130.568) (end 85.09 130.302) (width 0.25) (layer F.Cu) (net 1) (tstamp 5833F3B6)) + (segment (start 87.6173 129.3495) (end 88.3285 129.3495) (width 0.25) (layer F.Cu) (net 1) (tstamp 5833F3B9)) + (segment (start 98.044 129.9725) (end 97.2813 129.9725) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 92.2274 130.7084) (end 90.8685 129.3495) (width 0.25) (layer F.Cu) (net 2) (tstamp 5834D587)) + (segment (start 96.5454 130.7084) (end 92.2274 130.7084) (width 0.25) (layer F.Cu) (net 2) (tstamp 5834D586)) + (segment (start 97.2813 129.9725) (end 96.5454 130.7084) (width 0.25) (layer F.Cu) (net 2) (tstamp 5834D585)) + (segment (start 90.8685 129.3495) (end 90.932 129.3495) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 83.6302 133.2738) (end 85.0392 133.2738) (width 0.4) (layer F.Cu) (net 3)) + (segment (start 85.0392 133.2738) (end 85.7885 132.5245) (width 0.4) (layer F.Cu) (net 3) (tstamp 58801301)) + (segment (start 85.7885 132.5245) (end 85.9155 132.5245) (width 0.25) (layer B.Cu) (net 3)) + (segment (start 85.9155 132.5245) (end 87.5284 130.9116) (width 0.25) (layer B.Cu) (net 3) (tstamp 5833F450)) + (segment (start 89.0524 130.9116) (end 90.6653 132.5245) (width 0.25) (layer B.Cu) (net 3) (tstamp 5833F452)) + (segment (start 87.5284 130.9116) (end 89.0524 130.9116) (width 0.25) (layer B.Cu) (net 3) (tstamp 5833F451)) + (segment (start 90.6653 132.5245) (end 90.8685 132.5245) (width 0.25) (layer B.Cu) (net 3) (tstamp 5833F453)) + (segment (start 85.0646 133.2484) (end 85.7885 132.5245) (width 0.25) (layer F.Cu) (net 3) (tstamp 5833F432)) + (segment (start 90.8685 132.5245) (end 93.4085 132.5245) (width 0.25) (layer F.Cu) (net 3)) + (segment (start 85.7885 132.5245) (end 85.7885 132.6261) (width 0.25) (layer F.Cu) (net 3)) + (segment (start 84.582 131.318) (end 85.7885 132.5245) (width 0.25) (layer F.Cu) (net 3) (tstamp 5833F212)) + (segment (start 82.1944 131.318) (end 84.582 131.318) (width 0.25) (layer F.Cu) (net 3) (tstamp 5833F211)) + (segment (start 81.9404 131.064) (end 82.1944 131.318) (width 0.25) (layer F.Cu) (net 3) (tstamp 5833F210)) + (segment (start 81.9404 129.9972) (end 81.9404 131.064) (width 0.25) (layer F.Cu) (net 3) (tstamp 5833F20F)) + (segment (start 81.788 129.8448) (end 81.9404 129.9972) (width 0.25) (layer F.Cu) (net 3) (tstamp 5833F20E)) + (segment (start 81.788 129.4518) (end 81.788 129.8448) (width 0.25) (layer F.Cu) (net 3)) + (segment (start 81.788 129.4518) (end 81.788 129.667) (width 0.25) (layer F.Cu) (net 3)) + (segment (start 82.1182 133.2738) (end 81.2292 133.2738) (width 0.25) (layer F.Cu) (net 4)) + (via (at 81.2292 133.2738) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 4)) + (segment (start 81.2292 133.2738) (end 81.9912 132.8928) (width 0.25) (layer B.Cu) (net 4) (tstamp 5833F46A)) + (segment (start 81.9912 132.8928) (end 84.2772 132.8928) (width 0.25) (layer B.Cu) (net 4) (tstamp 5833F46B)) + (segment (start 84.2772 132.8928) (end 84.582 132.588) (width 0.25) (layer B.Cu) (net 4) (tstamp 5833F46C)) + (segment (start 84.582 132.588) (end 84.582 131.2164) (width 0.25) (layer B.Cu) (net 4) (tstamp 5833F46D)) + (segment (start 84.582 131.2164) (end 84.836 130.9624) (width 0.25) (layer B.Cu) (net 4) (tstamp 5833F46E)) + (segment (start 84.836 130.9624) (end 85.7504 130.9624) (width 0.25) (layer B.Cu) (net 4) (tstamp 5833F46F)) + (via (at 85.7504 130.9624) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 4)) + (segment (start 85.7504 130.9624) (end 85.8012 131.0132) (width 0.25) (layer F.Cu) (net 4) (tstamp 5833F472)) + (segment (start 85.8012 131.0132) (end 87.5284 131.0132) (width 0.25) (layer F.Cu) (net 4) (tstamp 5833F473)) + (segment (start 87.5284 131.0132) (end 88.3285 131.8133) (width 0.25) (layer F.Cu) (net 4) (tstamp 5833F474)) + (segment (start 88.3285 131.8133) (end 88.3285 132.5245) (width 0.25) (layer F.Cu) (net 4) (tstamp 5833F475)) + (segment (start 88.3285 132.5245) (end 88.3285 132.6769) (width 0.25) (layer B.Cu) (net 4)) + (segment (start 92.5195 102.1715) (end 95.1865 102.1715) (width 1.27) (layer B.Cu) (net 5)) + (segment (start 99.2505 103.124) (end 99.822 103.124) (width 1.27) (layer F.Cu) (net 5) (tstamp 58FEA9A1)) + (segment (start 99.2505 103.1875) (end 99.2505 103.124) (width 1.27) (layer F.Cu) (net 5) (tstamp 58FEA9A0)) + (via (at 99.2505 103.1875) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 5)) + (segment (start 96.2025 103.1875) (end 99.2505 103.1875) (width 1.27) (layer B.Cu) (net 5) (tstamp 58FEA99E)) + (segment (start 95.1865 102.1715) (end 96.2025 103.1875) (width 1.27) (layer B.Cu) (net 5) (tstamp 58FEA99D)) + (segment (start 99.14636 108.077) (end 99.14636 108.93044) (width 0.8) (layer F.Cu) (net 5)) + (segment (start 90.9574 110.5408) (end 90.0698 110.5408) (width 0.8) (layer F.Cu) (net 5) (tstamp 58F58671)) + (segment (start 91.5924 109.9058) (end 90.9574 110.5408) (width 0.8) (layer F.Cu) (net 5) (tstamp 58F58670)) + (segment (start 98.171 109.9058) (end 91.5924 109.9058) (width 0.8) (layer F.Cu) (net 5) (tstamp 58F5866F)) + (segment (start 99.14636 108.93044) (end 98.171 109.9058) (width 0.8) (layer F.Cu) (net 5) (tstamp 58F5866E)) + (segment (start 102.8065 115.065) (end 102.8065 112.1029) (width 0.635) (layer F.Cu) (net 5)) + (segment (start 100.8888 109.9312) (end 100.8888 109.0168) (width 0.635) (layer F.Cu) (net 5) (tstamp 5834D303)) + (segment (start 101.0412 110.0836) (end 100.8888 109.9312) (width 0.635) (layer F.Cu) (net 5) (tstamp 5834D302)) + (via (at 101.0412 110.0836) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 5)) + (segment (start 101.0412 110.3376) (end 101.0412 110.0836) (width 0.635) (layer B.Cu) (net 5) (tstamp 5834D300)) + (segment (start 102.7938 112.0902) (end 101.0412 110.3376) (width 0.635) (layer B.Cu) (net 5) (tstamp 5834D2FF)) + (via (at 102.7938 112.0902) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 5)) + (segment (start 102.8065 112.1029) (end 102.7938 112.0902) (width 0.635) (layer F.Cu) (net 5) (tstamp 5834D2FA)) + (segment (start 99.14636 108.077) (end 99.949 108.077) (width 1.27) (layer F.Cu) (net 5)) + (segment (start 99.949 108.077) (end 100.8888 109.0168) (width 1.27) (layer F.Cu) (net 5) (tstamp 5833EDF4)) + (segment (start 100.8888 109.0168) (end 101.0285 109.1565) (width 1.27) (layer F.Cu) (net 5) (tstamp 5834D306)) + (segment (start 101.0285 109.1565) (end 101.4215 109.0295) (width 1.27) (layer F.Cu) (net 5) (tstamp 5833EDF6)) + (segment (start 100.33 104.648) (end 100.33 103.632) (width 1.27) (layer F.Cu) (net 5)) + (segment (start 98.6155 103.124) (end 98.4885 102.997) (width 1.27) (layer F.Cu) (net 5) (tstamp 5833EDBD)) + (segment (start 99.822 103.124) (end 98.6155 103.124) (width 1.27) (layer F.Cu) (net 5) (tstamp 5833EDBC)) + (segment (start 100.33 103.632) (end 99.822 103.124) (width 1.27) (layer F.Cu) (net 5) (tstamp 5833EDBB)) + (segment (start 99.14636 108.077) (end 99.14636 106.72064) (width 1.27) (layer F.Cu) (net 5)) + (segment (start 100.33 105.537) (end 100.33 104.648) (width 1.27) (layer F.Cu) (net 5) (tstamp 5833EDB5)) + (segment (start 99.14636 106.72064) (end 100.33 105.537) (width 1.27) (layer F.Cu) (net 5) (tstamp 5833EDB4)) + (segment (start 102.13296 104.9964) (end 100.6784 104.9964) (width 0.4) (layer F.Cu) (net 5)) + (segment (start 100.6784 104.9964) (end 100.33 104.648) (width 0.4) (layer F.Cu) (net 5) (tstamp 5833ED79)) + (segment (start 98.6035 103.6955) (end 98.044 103.136) (width 0.4) (layer F.Cu) (net 5) (tstamp 5833ED7B)) + (segment (start 100.33 104.648) (end 99.3775 103.6955) (width 0.4) (layer F.Cu) (net 5) (tstamp 5833EDB8)) + (segment (start 99.3775 103.6955) (end 98.6035 103.6955) (width 0.4) (layer F.Cu) (net 5) (tstamp 5833ED7A)) + (segment (start 99.5807 101.7658) (end 100.2277 101.7658) (width 0.635) (layer F.Cu) (net 6)) + (segment (start 100.7971 101.1964) (end 102.13296 101.1964) (width 0.635) (layer F.Cu) (net 6) (tstamp 58801DCF)) + (segment (start 100.2277 101.7658) (end 100.7971 101.1964) (width 0.635) (layer F.Cu) (net 6) (tstamp 58801DCE)) + (segment (start 95.54464 108.077) (end 95.54464 107.90936) (width 0.635) (layer F.Cu) (net 6)) + (segment (start 95.54464 107.90936) (end 98.044 105.41) (width 0.635) (layer F.Cu) (net 6) (tstamp 58801DCA)) + (segment (start 98.044 105.41) (end 98.044 104.636) (width 0.635) (layer F.Cu) (net 6) (tstamp 58801DCB)) + (segment (start 96.708 103) (end 96.708 104.3661) (width 0.635) (layer F.Cu) (net 6)) + (segment (start 96.9779 104.636) (end 98.044 104.636) (width 0.635) (layer F.Cu) (net 6) (tstamp 58801DC7)) + (segment (start 96.708 104.3661) (end 96.9779 104.636) (width 0.635) (layer F.Cu) (net 6) (tstamp 58801DC6)) + (segment (start 98.0567 101.7658) (end 97.2432 101.7658) (width 0.635) (layer F.Cu) (net 6)) + (segment (start 96.708 102.301) (end 96.708 103) (width 0.635) (layer F.Cu) (net 6) (tstamp 58801DC3)) + (segment (start 97.2432 101.7658) (end 96.708 102.301) (width 0.635) (layer F.Cu) (net 6) (tstamp 58801DC2)) + (segment (start 99.5807 101.7658) (end 98.0567 101.7658) (width 0.635) (layer F.Cu) (net 6)) + (segment (start 98.0948 131.3688) (end 98.1456 131.4196) (width 0.25) (layer F.Cu) (net 6) (tstamp 58801C8F)) + (segment (start 97.4852 131.3688) (end 98.0948 131.3688) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 93.4974 108.077) (end 95.54464 108.077) (width 1.27) (layer F.Cu) (net 6) (tstamp 58801283)) + (segment (start 93.4212 108.0008) (end 93.4974 108.077) (width 1.27) (layer F.Cu) (net 6) (tstamp 58801282)) + (via (at 93.4212 108.0008) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 93.0402 108.0008) (end 93.4212 108.0008) (width 1.27) (layer B.Cu) (net 6) (tstamp 58801280)) + (segment (start 91.1352 106.0958) (end 93.0402 108.0008) (width 1.27) (layer B.Cu) (net 6) (tstamp 5880127F)) + (segment (start 72.39 107.95) (end 72.39 110.617) (width 0.25) (layer F.Cu) (net 6) (tstamp 58338F1A)) + (segment (start 72.39 107.95) (end 71.12 106.68) (width 0.25) (layer F.Cu) (net 6) (tstamp 58338F1D)) + (segment (start 71.0692 106.6292) (end 71.12 106.68) (width 0.25) (layer F.Cu) (net 6) (tstamp 588013C4)) + (segment (start 80.41386 106.172) (end 82.5754 106.172) (width 1.27) (layer F.Cu) (net 6)) + (segment (start 101.219 119.8125) (end 101.219 119.6594) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 101.219 119.6594) (end 100.5334 118.9738) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833F668)) + (segment (start 102.9215 109.0295) (end 102.9215 110.1725) (width 0.635) (layer F.Cu) (net 6)) + (segment (start 102.9215 110.1725) (end 103.5565 110.8075) (width 0.635) (layer F.Cu) (net 6) (tstamp 5833F5E9)) + (segment (start 103.7565 112.265) (end 103.7565 111.0075) (width 0.635) (layer F.Cu) (net 6)) + (segment (start 103.7565 111.0075) (end 103.5565 110.8075) (width 0.635) (layer F.Cu) (net 6) (tstamp 5833F5E6)) + (segment (start 103.1875 125.81636) (end 102.06736 125.81636) (width 0.635) (layer F.Cu) (net 6)) + (segment (start 101.219 124.968) (end 101.219 119.8125) (width 0.635) (layer F.Cu) (net 6) (tstamp 5833F5D4)) + (segment (start 102.06736 125.81636) (end 101.219 124.968) (width 0.635) (layer F.Cu) (net 6) (tstamp 5833F5D3)) + (segment (start 103.1875 125.81636) (end 102.45344 125.81636) (width 0.635) (layer F.Cu) (net 6)) + (segment (start 102.45344 125.81636) (end 99.6188 128.651) (width 0.635) (layer F.Cu) (net 6) (tstamp 5833F5CB)) + (segment (start 99.6188 128.651) (end 99.6188 130.4544) (width 0.635) (layer F.Cu) (net 6) (tstamp 5833F5CC)) + (segment (start 99.6188 130.4544) (end 98.584902 131.488298) (width 0.635) (layer F.Cu) (net 6) (tstamp 5833F5CD)) + (segment (start 98.584902 131.488298) (end 98.1456 131.488298) (width 0.635) (layer F.Cu) (net 6) (tstamp 5833F5CE)) + (segment (start 98.1456 131.488298) (end 98.1456 131.445) (width 0.635) (layer F.Cu) (net 6) (tstamp 5833F5D0)) + (segment (start 96.0755 133.477) (end 96.0755 132.5753) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 98.1202 131.445) (end 98.1456 131.445) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833F5B8)) + (segment (start 98.1456 131.4196) (end 98.1202 131.445) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833F5B7)) + (via (at 98.1456 131.4196) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 97.3836 132.1816) (end 98.1456 131.4196) (width 0.25) (layer B.Cu) (net 6) (tstamp 5833F5B5)) + (segment (start 96.6978 132.1816) (end 97.3836 132.1816) (width 0.25) (layer B.Cu) (net 6) (tstamp 5833F5B4)) + (segment (start 96.0628 132.5626) (end 96.6978 132.1816) (width 0.25) (layer B.Cu) (net 6) (tstamp 5833F5B3)) + (via (at 96.0628 132.5626) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 96.0755 132.5753) (end 96.0628 132.5626) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833F5B1)) + (segment (start 85.9155 127.8121) (end 86.9435 127.8121) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 87.122 127.9906) (end 90.5764 127.9906) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833F564)) + (segment (start 86.9435 127.8121) (end 87.122 127.9906) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833F563)) + (segment (start 102.9215 109.0295) (end 102.99986 109.0295) (width 1.27) (layer F.Cu) (net 6)) + (segment (start 102.99986 109.0295) (end 104.83296 107.1964) (width 1.27) (layer F.Cu) (net 6) (tstamp 5833EDF7)) + (segment (start 104.83296 107.1964) (end 103.13296 107.1964) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 103.13296 107.1964) (end 102.13296 106.1964) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833ED92)) + (segment (start 104.83296 100.1964) (end 104.83296 107.1964) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 102.13296 101.1964) (end 103.83296 101.1964) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 103.83296 101.1964) (end 104.83296 100.1964) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833ED8C)) + (segment (start 102.13296 102.3964) (end 102.13296 101.1964) (width 0.4) (layer F.Cu) (net 6)) + (segment (start 95.5675 112.5855) (end 95.5675 109.0295) (width 1.27) (layer B.Cu) (net 6)) + (segment (start 95.377 112.776) (end 95.5675 112.5855) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833ED16)) + (via (at 95.5675 112.5855) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 95.504 108.966) (end 95.54464 108.92536) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833ED1C)) + (via (at 95.504 108.966) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 95.54464 108.92536) (end 95.54464 108.077) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833ED1D)) + (segment (start 95.377 112.9545) (end 95.377 112.776) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 95.5675 109.0295) (end 95.504 108.966) (width 1.27) (layer B.Cu) (net 6) (tstamp 5833ED22)) + (segment (start 94.3736 113.3864) (end 94.8055 112.9545) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833ECD2)) + (segment (start 96.2025 112.9545) (end 95.377 112.9545) (width 0.635) (layer F.Cu) (net 6)) + (segment (start 95.377 112.9545) (end 94.8055 112.9545) (width 0.635) (layer F.Cu) (net 6) (tstamp 5833ED14)) + (segment (start 93.587 112.7125) (end 94.5635 112.7125) (width 0.635) (layer F.Cu) (net 6)) + (segment (start 94.5635 112.7125) (end 94.8055 112.9545) (width 0.635) (layer F.Cu) (net 6) (tstamp 5833ECCC)) + (segment (start 78.613 128.3208) (end 78.6638 128.3208) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 78.6638 128.3208) (end 79.2226 127.762) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833DCFA)) + (segment (start 81.9404 122.0216) (end 81.9404 123.1392) (width 0.25) (layer F.Cu) (net 6)) + (via (at 79.2226 127.762) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 80.0354 126.9492) (end 79.2226 127.762) (width 0.25) (layer B.Cu) (net 6) (tstamp 5833DCF2)) + (segment (start 80.0354 126.6444) (end 80.0354 126.9492) (width 0.25) (layer B.Cu) (net 6) (tstamp 5833DCF1)) + (segment (start 80.2894 126.3904) (end 80.0354 126.6444) (width 0.25) (layer B.Cu) (net 6) (tstamp 5833DCF0)) + (via (at 80.2894 126.3904) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 80.3656 126.3142) (end 80.2894 126.3904) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833DCEE)) + (segment (start 81.1784 126.3142) (end 80.3656 126.3142) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833DCED)) + (segment (start 81.788 125.7046) (end 81.1784 126.3142) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833DCEC)) + (segment (start 81.788 123.2916) (end 81.788 125.7046) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833DCEB)) + (segment (start 81.9404 123.1392) (end 81.788 123.2916) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833DCEA)) + (segment (start 77.343 130.3528) (end 77.343 129.970402) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 77.343 129.970402) (end 78.198004 129.115398) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833DCA8)) + (segment (start 78.198004 129.115398) (end 78.580402 129.115398) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833DCA9)) + (segment (start 78.580402 129.115398) (end 78.613 129.0828) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833DCAA)) + (segment (start 78.613 129.0828) (end 78.613 128.3208) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833DCAB)) + (segment (start 81.5975 116.955) (end 81.4458 116.955) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 81.4458 116.955) (end 80.7974 116.3066) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833BB26)) + (segment (start 81.0895 114.2365) (end 81.7245 114.2365) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833BB29)) + (segment (start 80.7974 114.5286) (end 81.0895 114.2365) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833BB28)) + (segment (start 80.7974 116.3066) (end 80.7974 114.5286) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833BB27)) + (segment (start 81.788 114.173) (end 81.788 114.0587) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833ADF1)) + (segment (start 81.7245 114.2365) (end 81.84515 114.11585) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833ADEE)) + (segment (start 81.84515 114.11585) (end 81.788 114.173) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833ADEF)) + (segment (start 75.3618 109.8296) (end 74.7014 110.49) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833BA22)) + (segment (start 75.5142 109.474) (end 75.3618 109.6264) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833BA20)) + (segment (start 75.3618 109.6264) (end 75.3618 109.8296) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833BA21)) + (segment (start 75.5142 109.474) (end 75.5142 109.1184) (width 0.635) (layer B.Cu) (net 6)) + (segment (start 80.01 110.49) (end 80.01 109.8296) (width 0.635) (layer B.Cu) (net 6)) + (segment (start 80.01 109.8296) (end 78.6384 108.458) (width 0.635) (layer B.Cu) (net 6) (tstamp 5833BA2C)) + (segment (start 78.6384 108.458) (end 76.1746 108.458) (width 0.635) (layer B.Cu) (net 6) (tstamp 5833BA2D)) + (segment (start 76.1746 108.458) (end 75.5142 109.1184) (width 0.635) (layer B.Cu) (net 6) (tstamp 5833BA2E)) + (segment (start 80.01 109.8296) (end 78.6384 108.458) (width 0.25) (layer B.Cu) (net 6) (tstamp 5833BA14)) + (segment (start 72.517 110.49) (end 72.39 110.617) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833BA24)) + (segment (start 74.7014 110.49) (end 72.517 110.49) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833BA23)) + (via (at 75.5142 109.474) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 75.5142 109.1184) (end 75.5142 109.474) (width 0.25) (layer B.Cu) (net 6) (tstamp 5833BA1B)) + (segment (start 76.1746 108.458) (end 75.5142 109.1184) (width 0.25) (layer B.Cu) (net 6) (tstamp 5833BA1A)) + (segment (start 78.6384 108.458) (end 76.1746 108.458) (width 0.25) (layer B.Cu) (net 6) (tstamp 5833BA16)) + (segment (start 86.0926 127.635) (end 85.9155 127.8121) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833B824)) + (segment (start 85.9155 127.8121) (end 85.9155 125.9085) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 85.9155 125.9085) (end 85.852 125.845) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833B7E8)) + (segment (start 84.6843 127.8509) (end 85.8767 127.8509) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 85.8767 127.8509) (end 85.9155 127.8121) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833B7E5)) + (segment (start 85.8266 120.384) (end 85.8266 121.6526) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 78.834 122.555) (end 79.8322 122.555) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 79.8322 122.555) (end 80.0608 122.3264) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833B0BE)) + (via (at 80.0608 122.3264) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 80.0608 122.3264) (end 80.3656 122.0216) (width 0.25) (layer B.Cu) (net 6) (tstamp 5833B0C0)) + (segment (start 80.3656 122.0216) (end 81.9404 122.0216) (width 0.25) (layer B.Cu) (net 6) (tstamp 5833B0C1)) + (via (at 81.9404 122.0216) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 81.8642 121.165198) (end 81.8642 117.6782) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833B0C7)) + (segment (start 81.9404 122.0216) (end 82.169 121.793) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833B0C4)) + (segment (start 82.169 121.793) (end 82.169 121.469998) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833B0C5)) + (segment (start 82.169 121.469998) (end 81.8642 121.165198) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833B0C6)) + (segment (start 76.2508 130.2124) (end 77.2026 130.2124) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 77.2026 130.2124) (end 77.343 130.3528) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833B041)) + (segment (start 78.834 122.555) (end 78.0542 122.555) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 77.0255 121.5263) (end 77.0255 120.4475) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833AECA)) + (segment (start 78.0542 122.555) (end 77.0255 121.5263) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833AEC9)) + (segment (start 81.5975 116.955) (end 81.5975 117.4115) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 81.5975 117.4115) (end 81.8642 117.6782) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833ADE3)) + (segment (start 80.7593 113.03) (end 80.7593 111.2393) (width 0.4) (layer F.Cu) (net 6)) + (segment (start 80.7593 111.2393) (end 80.01 110.49) (width 0.4) (layer F.Cu) (net 6) (tstamp 58338FD6)) + (segment (start 82.562 114.3) (end 82.0293 114.3) (width 0.4) (layer F.Cu) (net 6)) + (segment (start 82.0293 114.3) (end 81.788 114.0587) (width 0.4) (layer F.Cu) (net 6) (tstamp 58338FD3)) + (segment (start 81.788 114.0587) (end 80.7593 113.03) (width 0.4) (layer F.Cu) (net 6) (tstamp 5833ADF2)) + (segment (start 80.01 110.49) (end 80.01 109.728) (width 0.635) (layer B.Cu) (net 6)) + (segment (start 71.12 111.76) (end 71.247 111.76) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 71.247 111.76) (end 72.39 110.617) (width 0.25) (layer F.Cu) (net 6) (tstamp 58338F19)) + (segment (start 80.01 110.49) (end 80.01 106.57586) (width 1.27) (layer F.Cu) (net 6)) + (segment (start 80.01 106.57586) (end 80.41386 106.172) (width 1.27) (layer F.Cu) (net 6) (tstamp 58338EFC)) + (segment (start 100.5334 118.9738) (end 99.4236 118.9738) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833F669)) + (segment (start 99.4236 118.9738) (end 95.25 118.9738) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 95.1865 118.9355) (end 95.25 118.9355) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833E175)) + (segment (start 95.2117 118.9355) (end 95.1865 118.9355) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833E174)) + (segment (start 95.25 118.9738) (end 95.2117 118.9355) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833E173)) + (segment (start 95.25 122.428) (end 95.25 118.9355) (width 0.25) (layer F.Cu) (net 6) (tstamp 5834D6C8)) + (segment (start 95.25 118.9355) (end 95.25 117.094) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833E176)) + (segment (start 91.1736 127.622) (end 91.1736 126.4238) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833F566)) + (segment (start 90.805 127.9906) (end 91.1736 127.622) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833F565)) + (segment (start 90.5764 127.9906) (end 90.805 127.9906) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833F56A)) + (segment (start 95.1992 122.428) (end 95.25 122.428) (width 0.25) (layer F.Cu) (net 6) (tstamp 5834D6C4)) + (via (at 95.1992 122.428) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 94.6404 122.428) (end 95.1992 122.428) (width 0.25) (layer B.Cu) (net 6) (tstamp 5834D6C2)) + (segment (start 93.8784 121.666) (end 94.6404 122.428) (width 0.25) (layer B.Cu) (net 6) (tstamp 5834D6C1)) + (segment (start 90.4494 121.666) (end 93.8784 121.666) (width 0.25) (layer B.Cu) (net 6) (tstamp 5834D6C0)) + (segment (start 90.2716 121.8438) (end 90.4494 121.666) (width 0.25) (layer B.Cu) (net 6) (tstamp 5834D6BF)) + (via (at 90.2716 121.8438) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 95.25 122.428) (end 95.2246 122.428) (width 0.25) (layer F.Cu) (net 6) (tstamp 5834D6C5)) + (segment (start 95.2246 122.428) (end 95.25 122.428) (width 0.25) (layer F.Cu) (net 6) (tstamp 5834D6C7)) + (segment (start 90.5764 127.9906) (end 94.0816 127.9906) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 94.4626 127.6096) (end 94.4626 126.5128) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833F56D)) + (segment (start 94.0816 127.9906) (end 94.4626 127.6096) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833F56C)) + (segment (start 94.4626 126.5128) (end 94.3736 126.4238) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833F56E)) + (segment (start 94.3736 126.4238) (end 94.3736 125.2729) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 94.3736 125.2729) (end 95.25 124.3965) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833E16D)) + (segment (start 95.25 124.3965) (end 95.25 122.428) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833E16E)) + (segment (start 94.3736 114.7238) (end 94.3736 113.3864) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 94.3736 116.2176) (end 94.3736 114.7238) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833E170)) + (segment (start 95.25 117.094) (end 94.3736 116.2176) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833E16F)) + (segment (start 87.7236 122.1738) (end 88.8236 122.1738) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 89.5604 122.555) (end 90.2716 121.8438) (width 0.25) (layer F.Cu) (net 6) (tstamp 5834D6BC)) + (segment (start 89.2048 122.555) (end 89.5604 122.555) (width 0.25) (layer F.Cu) (net 6) (tstamp 5834D6BB)) + (segment (start 88.8236 122.1738) (end 89.2048 122.555) (width 0.25) (layer F.Cu) (net 6) (tstamp 5834D6BA)) + (segment (start 87.7236 122.1738) (end 86.3478 122.1738) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 82.7532 106.0958) (end 91.1352 106.0958) (width 1.27) (layer B.Cu) (net 6) (tstamp 5880127E)) + (via (at 82.6262 106.2228) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 82.5754 106.172) (end 82.6262 106.2228) (width 1.27) (layer F.Cu) (net 6) (tstamp 58801279)) + (segment (start 82.6262 106.2228) (end 82.7532 106.0958) (width 1.27) (layer B.Cu) (net 6) (tstamp 5880127D)) + (segment (start 86.3478 122.1738) (end 85.852 121.678) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833DC3D)) + (segment (start 85.8266 121.6526) (end 85.852 121.678) (width 0.25) (layer F.Cu) (net 6) (tstamp 5833B73D)) + (segment (start 85.852 121.678) (end 85.864 121.678) (width 0.4) (layer F.Cu) (net 6)) + (segment (start 95.1736 126.4238) (end 95.1736 125.6032) (width 0.25) (layer F.Cu) (net 7)) + (segment (start 95.1736 125.6032) (end 95.885 124.8918) (width 0.25) (layer F.Cu) (net 7) (tstamp 5833F622)) + (segment (start 103.1875 122.21464) (end 103.1875 121.1961) (width 0.635) (layer F.Cu) (net 7)) + (segment (start 103.1875 121.1961) (end 102.3874 120.396) (width 0.635) (layer F.Cu) (net 7) (tstamp 5834D6DC)) + (segment (start 101.9048 118.4148) (end 101.3213 118.4148) (width 0.635) (layer F.Cu) (net 7) (tstamp 5834D6DF)) + (segment (start 102.3874 118.8974) (end 101.9048 118.4148) (width 0.635) (layer F.Cu) (net 7) (tstamp 5834D6DE)) + (segment (start 102.3874 120.396) (end 102.3874 118.8974) (width 0.635) (layer F.Cu) (net 7) (tstamp 5834D6DD)) + (segment (start 101.3213 118.4148) (end 101.219 118.3125) (width 0.635) (layer F.Cu) (net 7) (tstamp 5834D6E0)) + (segment (start 104.4956 122.9868) (end 103.95966 122.9868) (width 0.25) (layer F.Cu) (net 7) (tstamp 5833F62E)) + (segment (start 104.7242 123.2154) (end 104.4956 122.9868) (width 0.25) (layer F.Cu) (net 7) (tstamp 5833F62D)) + (via (at 104.7242 123.2154) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 7)) + (segment (start 103.0224 124.9172) (end 104.7242 123.2154) (width 0.25) (layer B.Cu) (net 7) (tstamp 5833F62A)) + (segment (start 100.6602 124.9172) (end 103.0224 124.9172) (width 0.25) (layer B.Cu) (net 7) (tstamp 5833F629)) + (segment (start 100.4062 125.1712) (end 100.6602 124.9172) (width 0.25) (layer B.Cu) (net 7) (tstamp 5833F627)) + (segment (start 98.3742 125.1712) (end 100.4062 125.1712) (width 0.25) (layer B.Cu) (net 7) (tstamp 5833F626)) + (segment (start 98.0948 124.8918) (end 98.3742 125.1712) (width 0.25) (layer B.Cu) (net 7) (tstamp 5833F625)) + (segment (start 95.885 124.8918) (end 98.0948 124.8918) (width 0.25) (layer B.Cu) (net 7) (tstamp 5833F624)) + (via (at 95.885 124.8918) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 7)) + (segment (start 103.95966 122.9868) (end 103.1875 122.21464) (width 0.25) (layer F.Cu) (net 7) (tstamp 5833F62F)) + (segment (start 100.51 111.9505) (end 101.542 111.9505) (width 0.635) (layer F.Cu) (net 7)) + (segment (start 101.542 111.9505) (end 101.8565 112.265) (width 0.635) (layer F.Cu) (net 7) (tstamp 5833F5E0)) + (segment (start 101.8565 112.265) (end 101.8565 111.4323) (width 0.635) (layer F.Cu) (net 7) (tstamp 5833F5E1)) + (segment (start 101.8565 112.265) (end 101.8565 111.4323) (width 0.635) (layer F.Cu) (net 7)) + (segment (start 101.8565 111.4323) (end 101.8565 111.0075) (width 0.635) (layer F.Cu) (net 7) (tstamp 5833F5E4)) + (segment (start 101.8565 111.0075) (end 102.0565 110.8075) (width 0.635) (layer F.Cu) (net 7) (tstamp 5833F5DC)) + (segment (start 100.838 112.2785) (end 100.51 111.9505) (width 0.4) (layer F.Cu) (net 7) (tstamp 5833EE50)) + (segment (start 100.838 117.1575) (end 100.838 112.2785) (width 0.4) (layer F.Cu) (net 7) (tstamp 5833EE4F)) + (segment (start 101.219 117.5385) (end 100.838 117.1575) (width 0.4) (layer F.Cu) (net 7) (tstamp 5833EE4E)) + (segment (start 101.219 118.3125) (end 101.219 117.5385) (width 0.4) (layer F.Cu) (net 7)) + (segment (start 101.0803 118.1738) (end 101.219 118.3125) (width 0.4) (layer F.Cu) (net 7) (tstamp 5833EE4B)) + (segment (start 79.8082 115.824) (end 79.8082 114.1843) (width 0.635) (layer F.Cu) (net 7)) + (segment (start 99.441 111.9505) (end 100.51 111.9505) (width 0.635) (layer F.Cu) (net 7) (tstamp 5833ED37)) + (segment (start 99.1235 112.268) (end 99.441 111.9505) (width 0.635) (layer F.Cu) (net 7) (tstamp 5833ED36)) + (via (at 99.1235 112.268) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 7)) + (segment (start 97.9805 113.411) (end 99.1235 112.268) (width 0.635) (layer B.Cu) (net 7) (tstamp 5833ED33)) + (segment (start 97.028 114.3635) (end 97.9805 113.411) (width 0.635) (layer B.Cu) (net 7) (tstamp 5833ED32)) + (segment (start 88.138 114.3635) (end 97.028 114.3635) (width 0.635) (layer B.Cu) (net 7) (tstamp 5833ED31)) + (segment (start 87.3125 115.189) (end 88.138 114.3635) (width 0.635) (layer B.Cu) (net 7) (tstamp 5833ED30)) + (segment (start 86.36 115.189) (end 87.3125 115.189) (width 0.635) (layer B.Cu) (net 7) (tstamp 5833ED2F)) + (segment (start 85.852 114.681) (end 86.36 115.189) (width 0.635) (layer B.Cu) (net 7) (tstamp 5833ED2E)) + (segment (start 85.4075 114.681) (end 85.852 114.681) (width 0.635) (layer B.Cu) (net 7) (tstamp 5833ED2D)) + (segment (start 84.7725 114.046) (end 85.4075 114.681) (width 0.635) (layer B.Cu) (net 7) (tstamp 5833ED2C)) + (segment (start 79.9465 114.046) (end 84.7725 114.046) (width 0.635) (layer B.Cu) (net 7) (tstamp 5833ED2B)) + (via (at 79.9465 114.046) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 7)) + (segment (start 79.8082 114.1843) (end 79.9465 114.046) (width 0.635) (layer F.Cu) (net 7) (tstamp 5833ED29)) + (segment (start 99.4236 118.1738) (end 101.0803 118.1738) (width 0.4) (layer F.Cu) (net 7)) + (segment (start 85.9155 129.3121) (end 86.3085 129.3121) (width 0.25) (layer F.Cu) (net 8)) + (segment (start 86.3085 129.3121) (end 86.8172 128.8034) (width 0.25) (layer F.Cu) (net 8) (tstamp 5834D679)) + (segment (start 96.2025 111.4545) (end 97.114 111.4545) (width 0.635) (layer F.Cu) (net 8)) + (segment (start 97.114 111.4545) (end 97.61 111.9505) (width 0.635) (layer F.Cu) (net 8) (tstamp 5833ECD6)) + (segment (start 94.8055 111.4545) (end 96.2025 111.4545) (width 0.635) (layer F.Cu) (net 8)) + (segment (start 92.087 112.7125) (end 92.087 111.6845) (width 0.635) (layer F.Cu) (net 8)) + (segment (start 92.317 111.4545) (end 94.8055 111.4545) (width 0.635) (layer F.Cu) (net 8) (tstamp 5833ECC7)) + (segment (start 92.087 111.6845) (end 92.317 111.4545) (width 0.635) (layer F.Cu) (net 8) (tstamp 5833ECC6)) + (segment (start 92.087 113.2325) (end 92.087 112.7125) (width 0.25) (layer F.Cu) (net 8) (tstamp 5833ECC2)) + (segment (start 85.9155 129.3121) (end 86.2704 129.3121) (width 0.25) (layer F.Cu) (net 8)) + (segment (start 85.9155 129.3121) (end 86.0799 129.3121) (width 0.25) (layer F.Cu) (net 8)) + (segment (start 85.9155 129.3121) (end 84.6963 129.3121) (width 0.25) (layer F.Cu) (net 8)) + (segment (start 84.6963 129.3121) (end 84.6843 129.3241) (width 0.25) (layer F.Cu) (net 8) (tstamp 5833B7E2)) + (segment (start 93.5736 116.205) (end 93.5736 114.7238) (width 0.25) (layer F.Cu) (net 8) (tstamp 5834D698)) + (segment (start 93.8022 116.4336) (end 93.5736 116.205) (width 0.25) (layer F.Cu) (net 8) (tstamp 5834D696)) + (segment (start 93.8022 116.9416) (end 93.8022 116.4336) (width 0.25) (layer F.Cu) (net 8) (tstamp 5834D695)) + (segment (start 94.5134 117.6528) (end 93.8022 116.9416) (width 0.25) (layer F.Cu) (net 8) (tstamp 5834D694)) + (segment (start 94.5134 123.7234) (end 94.5134 117.6528) (width 0.25) (layer F.Cu) (net 8) (tstamp 5834D693)) + (via (at 94.5134 123.7234) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 8)) + (segment (start 94.3864 123.8504) (end 94.5134 123.7234) (width 0.25) (layer B.Cu) (net 8) (tstamp 5834D691)) + (segment (start 94.1578 123.8504) (end 94.3864 123.8504) (width 0.25) (layer B.Cu) (net 8) (tstamp 5834D68F)) + (segment (start 93.5736 123.2662) (end 94.1578 123.8504) (width 0.25) (layer B.Cu) (net 8) (tstamp 5834D68C)) + (segment (start 92.0496 123.2662) (end 93.5736 123.2662) (width 0.25) (layer B.Cu) (net 8) (tstamp 5834D68A)) + (segment (start 91.6178 123.698) (end 92.0496 123.2662) (width 0.25) (layer B.Cu) (net 8) (tstamp 5834D689)) + (segment (start 91.6178 124.206) (end 91.6178 123.698) (width 0.25) (layer B.Cu) (net 8) (tstamp 5834D688)) + (segment (start 89.1032 126.7206) (end 91.6178 124.206) (width 0.25) (layer B.Cu) (net 8) (tstamp 5834D681)) + (segment (start 88.519 126.7206) (end 89.1032 126.7206) (width 0.25) (layer B.Cu) (net 8) (tstamp 5834D680)) + (segment (start 86.9188 128.3208) (end 88.519 126.7206) (width 0.25) (layer B.Cu) (net 8) (tstamp 5834D67F)) + (segment (start 86.9188 128.7018) (end 86.9188 128.3208) (width 0.25) (layer B.Cu) (net 8) (tstamp 5834D67E)) + (segment (start 86.8172 128.8034) (end 86.9188 128.7018) (width 0.25) (layer B.Cu) (net 8) (tstamp 5834D67D)) + (via (at 86.8172 128.8034) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 8)) + (segment (start 93.5736 114.7238) (end 93.5736 113.5761) (width 0.25) (layer F.Cu) (net 8)) + (segment (start 93.5736 113.5761) (end 93.472 113.4745) (width 0.25) (layer F.Cu) (net 8) (tstamp 5833ECBF)) + (segment (start 93.472 113.4745) (end 92.329 113.4745) (width 0.25) (layer F.Cu) (net 8) (tstamp 5833ECC0)) + (segment (start 92.329 113.4745) (end 92.087 113.2325) (width 0.25) (layer F.Cu) (net 8) (tstamp 5833ECC1)) + (segment (start 93.6625 114.8127) (end 93.5736 114.7238) (width 0.25) (layer F.Cu) (net 8) (tstamp 5833E26A)) + (segment (start 93.726 114.8762) (end 93.5736 114.7238) (width 0.25) (layer F.Cu) (net 8) (tstamp 5833E110)) + (segment (start 71.0692 101.5873) (end 71.0692 100.5713) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 71.6407 99.9998) (end 71.0692 100.5713) (width 0.635) (layer F.Cu) (net 9) (tstamp 588013D5)) + (segment (start 75.6412 99.9998) (end 71.6407 99.9998) (width 0.635) (layer F.Cu) (net 9) (tstamp 588013D4)) + (segment (start 75.6412 99.9998) (end 76.61402 100.97262) (width 0.635) (layer F.Cu) (net 9) (tstamp 588013D3)) + (segment (start 76.61402 101.727) (end 76.61402 100.97262) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 83.0834 115.1128) (end 84.8868 115.1128) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 84.8868 115.1128) (end 85.418 114.5816) (width 0.25) (layer F.Cu) (net 9) (tstamp 5834D5ED)) + (segment (start 85.418 114.5816) (end 85.418 113.919) (width 0.25) (layer F.Cu) (net 9) (tstamp 5834D5EE)) + (segment (start 81.5975 115.455) (end 81.776 115.455) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 81.776 115.455) (end 82.1182 115.1128) (width 0.25) (layer F.Cu) (net 9) (tstamp 5834D5E3)) + (segment (start 83.058 112.776) (end 82.562 112.776) (width 0.25) (layer F.Cu) (net 9) (tstamp 5834D5EA)) + (segment (start 83.3628 113.0808) (end 83.058 112.776) (width 0.25) (layer F.Cu) (net 9) (tstamp 5834D5E9)) + (segment (start 83.3628 114.8334) (end 83.3628 113.0808) (width 0.25) (layer F.Cu) (net 9) (tstamp 5834D5E7)) + (segment (start 83.0834 115.1128) (end 83.3628 114.8334) (width 0.25) (layer F.Cu) (net 9) (tstamp 5834D5E5)) + (segment (start 82.1182 115.1128) (end 83.0834 115.1128) (width 0.25) (layer F.Cu) (net 9) (tstamp 5834D5E4)) + (segment (start 81.5975 115.455) (end 81.8395 115.455) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 81.661 115.685) (end 81.661 115.57) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 85.418 113.919) (end 85.418 114.607) (width 0.4) (layer F.Cu) (net 9)) + (segment (start 82.562 112.776) (end 82.562 109.105) (width 0.4) (layer F.Cu) (net 9)) + (segment (start 76.81214 105.30586) (end 76.81214 106.172) (width 0.4) (layer F.Cu) (net 9) (tstamp 58338FD0)) + (segment (start 77.47 104.648) (end 76.81214 105.30586) (width 0.4) (layer F.Cu) (net 9) (tstamp 58338FCF)) + (via (at 77.47 104.648) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 78.105 104.648) (end 77.47 104.648) (width 0.4) (layer B.Cu) (net 9) (tstamp 58338FC1)) + (segment (start 81.534 108.077) (end 78.105 104.648) (width 0.4) (layer B.Cu) (net 9) (tstamp 58338FC0)) + (via (at 81.534 108.077) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 82.562 109.105) (end 81.534 108.077) (width 0.4) (layer F.Cu) (net 9) (tstamp 58338FB9)) + (segment (start 73.66 104.14) (end 73.279 104.14) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 76.81214 106.172) (end 76.81214 106.02214) (width 1.27) (layer F.Cu) (net 9)) + (segment (start 76.81214 106.02214) (end 74.93 104.14) (width 1.27) (layer F.Cu) (net 9) (tstamp 58338EDA)) + (segment (start 76.61402 101.727) (end 76.61402 102.45598) (width 1.27) (layer F.Cu) (net 9)) + (segment (start 76.61402 102.45598) (end 74.93 104.14) (width 1.27) (layer F.Cu) (net 9) (tstamp 58338ED6)) + (segment (start 74.93 104.14) (end 73.66 104.14) (width 1.27) (layer F.Cu) (net 9) (tstamp 58338ED7)) + (segment (start 71.12 127) (end 72.0605 127) (width 0.25) (layer F.Cu) (net 10)) + (segment (start 72.0605 127) (end 73.2155 125.845) (width 0.25) (layer F.Cu) (net 10) (tstamp 5833AF35)) + (segment (start 73.2155 124.345) (end 71.235 124.345) (width 0.25) (layer F.Cu) (net 11)) + (segment (start 71.235 124.345) (end 71.12 124.46) (width 0.25) (layer F.Cu) (net 11) (tstamp 5833AF2C)) + (segment (start 74.7395 124.1545) (end 73.406 124.1545) (width 0.25) (layer F.Cu) (net 11)) + (segment (start 73.406 124.1545) (end 73.2155 124.345) (width 0.25) (layer F.Cu) (net 11) (tstamp 5833AF29)) + (segment (start 71.5892 131.6108) (end 71.12 132.08) (width 0.25) (layer F.Cu) (net 12) (tstamp 5833AF8C)) + (segment (start 71.3352 131.8648) (end 71.12 132.08) (width 0.25) (layer F.Cu) (net 12) (tstamp 5833AF5D)) + (segment (start 73.152 131.6108) (end 71.5892 131.6108) (width 0.25) (layer F.Cu) (net 12)) + (segment (start 73.152 130.1108) (end 74.676 130.1108) (width 0.25) (layer F.Cu) (net 13)) + (segment (start 74.676 130.1108) (end 74.7268 130.1616) (width 0.25) (layer F.Cu) (net 13) (tstamp 5833AF8F)) + (segment (start 73.152 130.1108) (end 71.6908 130.1108) (width 0.25) (layer F.Cu) (net 13)) + (segment (start 71.6908 130.1108) (end 71.12 129.54) (width 0.25) (layer F.Cu) (net 13) (tstamp 5833AF88)) + (segment (start 84.234 122.555) (end 83.2104 122.555) (width 0.25) (layer F.Cu) (net 14)) + (segment (start 82.314202 117.761598) (end 83.005 117.0708) (width 0.25) (layer F.Cu) (net 14) (tstamp 5833BB64)) + (segment (start 82.314202 120.8532) (end 82.314202 117.761598) (width 0.25) (layer F.Cu) (net 14) (tstamp 5833BB63)) + (segment (start 82.619002 121.158) (end 82.314202 120.8532) (width 0.25) (layer F.Cu) (net 14) (tstamp 5833BB62)) + (segment (start 82.619002 121.963602) (end 82.619002 121.158) (width 0.25) (layer F.Cu) (net 14) (tstamp 5833BB61)) + (segment (start 83.2104 122.555) (end 82.619002 121.963602) (width 0.25) (layer F.Cu) (net 14) (tstamp 5833BB60)) + (segment (start 83.005 117.0708) (end 83.005 116.332) (width 0.25) (layer F.Cu) (net 14) (tstamp 5833BB65)) + (segment (start 84.234 122.555) (end 85.229 122.555) (width 0.4) (layer F.Cu) (net 14)) + (segment (start 85.229 122.555) (end 85.852 123.178) (width 0.4) (layer F.Cu) (net 14) (tstamp 5833AC7D)) + (segment (start 80.61198 101.727) (end 87.32774 101.727) (width 1.27) (layer F.Cu) (net 15)) + (segment (start 87.32774 101.727) (end 88.138 100.91674) (width 1.27) (layer F.Cu) (net 15) (tstamp 58338ED3)) + (segment (start 95.758 100.2) (end 88.85474 100.2) (width 1.27) (layer F.Cu) (net 15)) + (segment (start 88.85474 100.2) (end 88.138 100.91674) (width 1.27) (layer F.Cu) (net 15) (tstamp 58338ECF)) + (segment (start 79.2607 113.03) (end 78.093 113.03) (width 0.4) (layer F.Cu) (net 16)) + (segment (start 76.8082 114.9844) (end 75.7936 113.9698) (width 0.25) (layer F.Cu) (net 17) (tstamp 5833DE0D)) + (segment (start 76.8082 115.824) (end 76.8082 114.9844) (width 0.25) (layer F.Cu) (net 17)) + (segment (start 75.7936 113.9698) (end 75.7936 113.7666) (width 0.25) (layer F.Cu) (net 17) (tstamp 5833DE0E)) + (segment (start 75.7936 113.7666) (end 75.184 113.157) (width 0.25) (layer F.Cu) (net 17) (tstamp 5833DE0F)) + (segment (start 75.184 113.157) (end 72.8218 113.157) (width 0.25) (layer F.Cu) (net 17) (tstamp 5833DE10)) + (segment (start 72.8218 113.157) (end 72.4916 112.8268) (width 0.25) (layer F.Cu) (net 17) (tstamp 5833DE11)) + (via (at 72.4916 112.8268) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 17)) + (segment (start 72.4916 112.8268) (end 72.4662 112.8014) (width 0.25) (layer B.Cu) (net 17) (tstamp 5833DE13)) + (segment (start 72.4662 112.8014) (end 72.4662 111.0996) (width 0.25) (layer B.Cu) (net 17) (tstamp 5833DE14)) + (segment (start 72.4662 111.0996) (end 71.12 109.7534) (width 0.25) (layer B.Cu) (net 17) (tstamp 5833DE15)) + (segment (start 71.12 109.7534) (end 71.12 109.22) (width 0.25) (layer B.Cu) (net 17) (tstamp 5833DE16)) + (segment (start 71.12 109.22) (end 71.12 109.474) (width 0.4) (layer B.Cu) (net 17)) + (segment (start 71.0692 103.4288) (end 72.5297 104.8893) (width 0.25) (layer B.Cu) (net 18) (tstamp 588013DA)) + (segment (start 72.5297 104.8893) (end 72.5297 105.2703) (width 0.25) (layer B.Cu) (net 18) (tstamp 588013DB)) + (segment (start 72.5297 105.2703) (end 72.6567 105.3973) (width 0.25) (layer B.Cu) (net 18) (tstamp 588013DC)) + (segment (start 72.6567 105.3973) (end 74.8157 105.3973) (width 0.25) (layer B.Cu) (net 18) (tstamp 588013DD)) + (segment (start 74.8157 105.3973) (end 76.9747 107.5563) (width 0.25) (layer B.Cu) (net 18) (tstamp 588013DE)) + (segment (start 76.9747 107.5563) (end 79.4512 107.5563) (width 0.25) (layer B.Cu) (net 18) (tstamp 588013DF)) + (segment (start 79.4512 107.5563) (end 82.8167 110.9218) (width 0.25) (layer B.Cu) (net 18) (tstamp 588013E1)) + (segment (start 82.8167 110.9218) (end 83.1088 110.9218) (width 0.25) (layer B.Cu) (net 18) (tstamp 588013E3)) + (segment (start 83.1088 110.9218) (end 83.693 111.506) (width 0.25) (layer B.Cu) (net 18) (tstamp 588013E4)) + (segment (start 83.693 112.3442) (end 83.693 111.506) (width 0.25) (layer B.Cu) (net 18) (tstamp 5833DDFE)) + (segment (start 84.3026 112.9538) (end 83.693 112.3442) (width 0.25) (layer B.Cu) (net 18) (tstamp 5833DDFD)) + (segment (start 85.852 112.9538) (end 84.3026 112.9538) (width 0.25) (layer B.Cu) (net 18) (tstamp 5833DDFC)) + (segment (start 86.7664 113.8682) (end 85.852 112.9538) (width 0.25) (layer B.Cu) (net 18) (tstamp 5833DDFB)) + (segment (start 86.8172 113.8682) (end 86.7664 113.8682) (width 0.25) (layer B.Cu) (net 18) (tstamp 5833DDFA)) + (segment (start 87.0204 114.0714) (end 86.8172 113.8682) (width 0.25) (layer B.Cu) (net 18) (tstamp 5833DDF9)) + (via (at 83.693 111.506) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 18)) + (segment (start 83.693 111.506) (end 84.074 111.887) (width 0.4) (layer F.Cu) (net 18) (tstamp 58338FB1)) + (via (at 87.0204 114.0714) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 18)) + (segment (start 84.062 114.3) (end 84.062 112.776) (width 0.4) (layer F.Cu) (net 18)) + (segment (start 84.074 111.887) (end 84.074 112.764) (width 0.4) (layer F.Cu) (net 18) (tstamp 58338FB2)) + (segment (start 84.074 112.764) (end 84.062 112.776) (width 0.4) (layer F.Cu) (net 18) (tstamp 58338FB3)) + (segment (start 87.0204 114.9604) (end 87.0204 114.0714) (width 0.25) (layer F.Cu) (net 18) (tstamp 5833DDF6)) + (segment (start 87.7236 115.6636) (end 87.0204 114.9604) (width 0.25) (layer F.Cu) (net 18) (tstamp 5833DDF5)) + (segment (start 87.7236 116.5738) (end 87.7236 115.6636) (width 0.25) (layer F.Cu) (net 18)) + (segment (start 85.8266 118.884) (end 85.8266 118.2116) (width 0.25) (layer F.Cu) (net 19)) + (segment (start 85.8266 118.2116) (end 86.5632 117.475) (width 0.25) (layer F.Cu) (net 19) (tstamp 5833DC33)) + (segment (start 84.234 118.745) (end 85.6876 118.745) (width 0.25) (layer F.Cu) (net 19)) + (segment (start 85.6876 118.745) (end 85.8266 118.884) (width 0.25) (layer F.Cu) (net 19) (tstamp 5833B73A)) + (segment (start 84.234 120.015) (end 84.234 118.745) (width 0.25) (layer F.Cu) (net 19)) + (segment (start 92.837 116.586) (end 92.837 114.7872) (width 0.25) (layer F.Cu) (net 19) (tstamp 5833E19A)) + (segment (start 92.9005 116.6495) (end 92.837 116.586) (width 0.25) (layer F.Cu) (net 19) (tstamp 5833E199)) + (via (at 92.9005 116.6495) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 19)) + (segment (start 92.202 116.967) (end 92.9005 116.6495) (width 0.25) (layer B.Cu) (net 19) (tstamp 5833E197)) + (segment (start 91.6305 117.094) (end 92.202 116.967) (width 0.25) (layer B.Cu) (net 19) (tstamp 5833E196)) + (segment (start 91.567 117.1575) (end 91.6305 117.094) (width 0.25) (layer B.Cu) (net 19) (tstamp 5833E195)) + (segment (start 89.4715 117.1575) (end 91.567 117.1575) (width 0.25) (layer B.Cu) (net 19) (tstamp 5833E194)) + (via (at 89.4715 117.1575) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 19)) + (segment (start 92.837 114.7872) (end 92.7736 114.7238) (width 0.25) (layer F.Cu) (net 19) (tstamp 5833E19B)) + (segment (start 92.7735 114.7239) (end 92.7736 114.7238) (width 0.25) (layer F.Cu) (net 19) (tstamp 5833E065)) + (segment (start 87.7236 117.3738) (end 89.3703 117.0563) (width 0.25) (layer F.Cu) (net 19)) + (segment (start 89.3703 117.0563) (end 89.4715 117.1575) (width 0.25) (layer F.Cu) (net 19) (tstamp 5833E192)) + (segment (start 86.5632 117.475) (end 87.6224 117.475) (width 0.25) (layer F.Cu) (net 19) (tstamp 5833DC34)) + (segment (start 87.6224 117.475) (end 87.7236 117.3738) (width 0.25) (layer F.Cu) (net 19) (tstamp 5833DC35)) + (segment (start 77.978 128.3208) (end 77.978 127.8255) (width 0.25) (layer F.Cu) (net 21)) + (segment (start 77.978 127.8255) (end 78.4225 127.381) (width 0.25) (layer F.Cu) (net 21) (tstamp 5833E0A6)) + (segment (start 78.0415 128.2573) (end 77.978 128.3208) (width 0.25) (layer F.Cu) (net 21) (tstamp 5833E022)) + (segment (start 90.9955 118.9355) (end 87.7619 118.9355) (width 0.25) (layer F.Cu) (net 21) (tstamp 5833E0B5)) + (segment (start 92.329 120.269) (end 90.9955 118.9355) (width 0.25) (layer F.Cu) (net 21) (tstamp 5833E0B4)) + (segment (start 92.329 121.9835) (end 92.329 120.269) (width 0.25) (layer F.Cu) (net 21) (tstamp 5833E0B3)) + (segment (start 90.6145 123.698) (end 92.329 121.9835) (width 0.25) (layer F.Cu) (net 21) (tstamp 5833E0B2)) + (via (at 90.6145 123.698) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 21)) + (segment (start 90.1065 123.3805) (end 90.6145 123.698) (width 0.25) (layer B.Cu) (net 21) (tstamp 5833E0B0)) + (segment (start 89.154 123.2535) (end 90.1065 123.3805) (width 0.25) (layer B.Cu) (net 21) (tstamp 5833E0AF)) + (segment (start 88.519 123.571) (end 89.154 123.2535) (width 0.25) (layer B.Cu) (net 21) (tstamp 5833E0AE)) + (segment (start 88.392 124.9045) (end 88.519 123.571) (width 0.25) (layer B.Cu) (net 21) (tstamp 5833E0AD)) + (segment (start 87.6935 125.603) (end 88.392 124.9045) (width 0.25) (layer B.Cu) (net 21) (tstamp 5833E0AC)) + (segment (start 79.8195 125.603) (end 87.6935 125.603) (width 0.25) (layer B.Cu) (net 21) (tstamp 5833E0AB)) + (segment (start 79.756 125.6665) (end 79.8195 125.603) (width 0.25) (layer B.Cu) (net 21) (tstamp 5833E0AA)) + (segment (start 79.756 126.0475) (end 79.756 125.6665) (width 0.25) (layer B.Cu) (net 21) (tstamp 5833E0A9)) + (segment (start 78.4225 127.381) (end 79.756 126.0475) (width 0.25) (layer B.Cu) (net 21) (tstamp 5833E0A8)) + (via (at 78.4225 127.381) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 21)) + (segment (start 87.7619 118.9355) (end 87.7236 118.9738) (width 0.25) (layer F.Cu) (net 21) (tstamp 5833E0B6)) + (segment (start 90.3098 119.7738) (end 87.7236 119.7738) (width 0.25) (layer F.Cu) (net 22) (tstamp 5833E097)) + (segment (start 90.932 120.396) (end 90.3098 119.7738) (width 0.25) (layer F.Cu) (net 22) (tstamp 5833E096)) + (segment (start 90.932 122.2375) (end 90.932 120.396) (width 0.25) (layer F.Cu) (net 22) (tstamp 5833E094)) + (segment (start 89.3445 123.952) (end 90.932 122.2375) (width 0.25) (layer F.Cu) (net 22) (tstamp 5833E093)) + (via (at 89.3445 123.952) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 22)) + (segment (start 89.281 124.0155) (end 89.3445 123.952) (width 0.25) (layer B.Cu) (net 22) (tstamp 5833E08F)) + (segment (start 88.773 125.476) (end 89.281 124.0155) (width 0.25) (layer B.Cu) (net 22) (tstamp 5833E08E)) + (segment (start 85.725 128.9685) (end 88.773 125.476) (width 0.25) (layer B.Cu) (net 22) (tstamp 5833E08C)) + (segment (start 83.5025 128.9685) (end 85.725 128.9685) (width 0.25) (layer B.Cu) (net 22) (tstamp 5833E08B)) + (segment (start 82.804 129.667) (end 83.5025 128.9685) (width 0.25) (layer B.Cu) (net 22) (tstamp 5833E08A)) + (segment (start 79.248 129.667) (end 82.804 129.667) (width 0.25) (layer B.Cu) (net 22) (tstamp 5833E089)) + (segment (start 79.1845 129.6035) (end 79.248 129.667) (width 0.25) (layer B.Cu) (net 22) (tstamp 5833E088)) + (via (at 79.1845 129.6035) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 22)) + (segment (start 78.4225 129.6035) (end 79.1845 129.6035) (width 0.25) (layer F.Cu) (net 22) (tstamp 5833E086)) + (segment (start 77.978 130.3528) (end 77.978 130.048) (width 0.25) (layer F.Cu) (net 22)) + (segment (start 77.978 130.048) (end 78.4225 129.6035) (width 0.25) (layer F.Cu) (net 22) (tstamp 5833E085)) + (segment (start 87.7236 120.5738) (end 89.0778 120.5738) (width 0.25) (layer F.Cu) (net 23)) + (via (at 89.154 120.65) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 23)) + (segment (start 89.0778 120.5738) (end 89.154 120.65) (width 0.25) (layer F.Cu) (net 23) (tstamp 5833E0B9)) + (segment (start 80.01 121.285) (end 78.834 121.285) (width 0.25) (layer F.Cu) (net 23) (tstamp 5833E0C6)) + (via (at 80.01 121.285) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 23)) + (segment (start 78.9305 121.285) (end 80.01 121.285) (width 0.25) (layer B.Cu) (net 23) (tstamp 5833E0C4)) + (segment (start 78.359 121.8565) (end 78.9305 121.285) (width 0.25) (layer B.Cu) (net 23) (tstamp 5833E0C3)) + (segment (start 78.359 123.1265) (end 78.359 121.8565) (width 0.25) (layer B.Cu) (net 23) (tstamp 5833E0C2)) + (segment (start 81.0895 123.1265) (end 78.359 123.1265) (width 0.25) (layer B.Cu) (net 23) (tstamp 5833E0C1)) + (segment (start 82.042 124.079) (end 81.0895 123.1265) (width 0.25) (layer B.Cu) (net 23) (tstamp 5833E0C0)) + (segment (start 82.804 124.079) (end 82.042 124.079) (width 0.25) (layer B.Cu) (net 23) (tstamp 5833E0BF)) + (segment (start 85.725 121.158) (end 82.804 124.079) (width 0.25) (layer B.Cu) (net 23) (tstamp 5833E0BD)) + (segment (start 88.646 121.158) (end 85.725 121.158) (width 0.25) (layer B.Cu) (net 23) (tstamp 5833E0BC)) + (segment (start 89.154 120.65) (end 88.646 121.158) (width 0.25) (layer B.Cu) (net 23) (tstamp 5833E0BB)) + (segment (start 87.7236 121.3738) (end 89.0523 121.3738) (width 0.25) (layer F.Cu) (net 24)) + (segment (start 89.0523 121.3738) (end 89.3445 121.666) (width 0.25) (layer F.Cu) (net 24) (tstamp 5833E0C9)) + (segment (start 79.883 123.825) (end 78.834 123.825) (width 0.25) (layer F.Cu) (net 24) (tstamp 5833E0D8)) + (via (at 79.883 123.825) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 24)) + (segment (start 81.153 125.095) (end 79.883 123.825) (width 0.25) (layer B.Cu) (net 24) (tstamp 5833E0D1)) + (segment (start 84.1375 125.095) (end 81.153 125.095) (width 0.25) (layer B.Cu) (net 24) (tstamp 5833E0CF)) + (segment (start 86.8045 122.428) (end 84.1375 125.095) (width 0.25) (layer B.Cu) (net 24) (tstamp 5833E0CD)) + (segment (start 88.5825 122.428) (end 86.8045 122.428) (width 0.25) (layer B.Cu) (net 24) (tstamp 5833E0CC)) + (segment (start 89.3445 121.666) (end 88.5825 122.428) (width 0.25) (layer B.Cu) (net 24) (tstamp 5833E0CB)) + (via (at 89.3445 121.666) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 24)) + (segment (start 93.5736 125.1204) (end 93.5736 126.4238) (width 0.25) (layer F.Cu) (net 27) (tstamp 5833E251)) + (segment (start 93.6625 125.0315) (end 93.5736 125.1204) (width 0.25) (layer F.Cu) (net 27) (tstamp 5833E250)) + (via (at 93.6625 125.0315) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 27)) + (segment (start 93.6625 124.46) (end 93.6625 125.0315) (width 0.25) (layer B.Cu) (net 27) (tstamp 5833E24D)) + (segment (start 93.2815 124.079) (end 93.6625 124.46) (width 0.25) (layer B.Cu) (net 27) (tstamp 5833E24C)) + (segment (start 92.456 123.8885) (end 93.2815 124.079) (width 0.25) (layer B.Cu) (net 27) (tstamp 5833E24B)) + (segment (start 92.329 124.0155) (end 92.456 123.8885) (width 0.25) (layer B.Cu) (net 27) (tstamp 5833E24A)) + (via (at 92.329 124.0155) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 27)) + (segment (start 92.1385 124.206) (end 92.329 124.0155) (width 0.25) (layer F.Cu) (net 27) (tstamp 5833E246)) + (segment (start 89.8525 124.3965) (end 92.1385 124.206) (width 0.25) (layer F.Cu) (net 27) (tstamp 5833E245)) + (segment (start 89.662 124.587) (end 89.8525 124.3965) (width 0.25) (layer F.Cu) (net 27) (tstamp 5833E244)) + (segment (start 87.7236 124.5738) (end 89.1408 124.5738) (width 0.25) (layer F.Cu) (net 27)) + (segment (start 89.154 124.587) (end 89.662 124.587) (width 0.25) (layer F.Cu) (net 27) (tstamp 5833E243)) + (segment (start 89.1408 124.5738) (end 89.154 124.587) (width 0.25) (layer F.Cu) (net 27) (tstamp 5833E242)) + (segment (start 89.5736 126.6312) (end 88.8492 127.3556) (width 0.25) (layer F.Cu) (net 28) (tstamp 5833F598)) + (segment (start 88.8492 127.3556) (end 89.3064 127.8128) (width 0.25) (layer B.Cu) (net 28) (tstamp 5833F59B)) + (segment (start 89.3064 127.8128) (end 90.2208 127.8128) (width 0.25) (layer B.Cu) (net 28) (tstamp 5833F59C)) + (segment (start 90.2208 127.8128) (end 91.5162 126.5174) (width 0.25) (layer B.Cu) (net 28) (tstamp 5833F59D)) + (segment (start 91.5162 126.5174) (end 98.3488 126.5174) (width 0.25) (layer B.Cu) (net 28) (tstamp 5833F59E)) + (segment (start 98.3488 126.5174) (end 99.3902 127.5588) (width 0.25) (layer B.Cu) (net 28) (tstamp 5833F59F)) + (segment (start 99.3902 127.5588) (end 99.3902 132.4102) (width 0.25) (layer B.Cu) (net 28) (tstamp 5833F5A1)) + (segment (start 99.3902 132.4102) (end 98.3107 133.4008) (width 0.25) (layer B.Cu) (net 28) (tstamp 5833F5A3)) + (via (at 98.3107 133.4008) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 28)) + (segment (start 98.3107 133.4008) (end 97.4852 133.4008) (width 0.25) (layer F.Cu) (net 28) (tstamp 5833F5A6)) + (via (at 88.8492 127.3556) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 28)) + (segment (start 89.5736 126.4238) (end 89.5736 126.6312) (width 0.25) (layer F.Cu) (net 28)) + (segment (start 89.5736 126.4238) (end 89.5736 126.6058) (width 0.25) (layer F.Cu) (net 28)) + (segment (start 91.9736 127.3554) (end 91.9736 126.4238) (width 0.25) (layer F.Cu) (net 30) (tstamp 5833F57A)) + (via (at 95.3262 131.445) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 30)) + (segment (start 96.0755 131.445) (end 95.3262 131.445) (width 0.25) (layer F.Cu) (net 30)) + (segment (start 95.3262 131.445) (end 94.6658 130.7846) (width 0.25) (layer B.Cu) (net 30) (tstamp 5833F573)) + (segment (start 94.6658 130.7846) (end 94.6658 128.4732) (width 0.25) (layer B.Cu) (net 30) (tstamp 5833F574)) + (segment (start 94.6658 128.4732) (end 94.107 127.9144) (width 0.25) (layer B.Cu) (net 30) (tstamp 5833F575)) + (segment (start 94.107 127.9144) (end 92.5322 127.9144) (width 0.25) (layer B.Cu) (net 30) (tstamp 5833F576)) + (segment (start 92.5322 127.9144) (end 91.9734 127.3556) (width 0.25) (layer B.Cu) (net 30) (tstamp 5833F577)) + (via (at 91.9734 127.3556) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 30)) + (segment (start 91.9734 127.3556) (end 91.9736 127.3554) (width 0.25) (layer F.Cu) (net 30) (tstamp 5833F579)) + (segment (start 98.0567 100.2658) (end 99.5807 100.2658) (width 0.25) (layer F.Cu) (net 36)) + (segment (start 94.808 103) (end 94.808 102.4865) (width 0.25) (layer F.Cu) (net 36)) + (segment (start 97.2827 100.2658) (end 98.0567 100.2658) (width 0.25) (layer F.Cu) (net 36) (tstamp 58801DB9)) + (segment (start 96.9772 100.5713) (end 97.2827 100.2658) (width 0.25) (layer F.Cu) (net 36) (tstamp 58801DB8)) + (segment (start 96.9772 100.8253) (end 96.9772 100.5713) (width 0.25) (layer F.Cu) (net 36) (tstamp 58801DB7)) + (segment (start 96.2787 101.5238) (end 96.9772 100.8253) (width 0.25) (layer F.Cu) (net 36) (tstamp 58801DB6)) + (segment (start 95.7707 101.5238) (end 96.2787 101.5238) (width 0.25) (layer F.Cu) (net 36) (tstamp 58801DB5)) + (segment (start 94.808 102.4865) (end 95.7707 101.5238) (width 0.25) (layer F.Cu) (net 36) (tstamp 58801DB4)) + (segment (start 98.146 123.7738) (end 99.4236 123.7738) (width 0.25) (layer F.Cu) (net 36) (tstamp 5834D340)) + (segment (start 94.8048 105.7014) (end 94.8182 105.7148) (width 0.25) (layer F.Cu) (net 36) (tstamp 5834D31F)) + (via (at 94.8182 105.7148) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 36)) + (segment (start 94.808 103) (end 94.8048 105.7014) (width 0.25) (layer F.Cu) (net 36)) + (segment (start 94.8182 105.7148) (end 99.9744 110.7948) (width 0.25) (layer B.Cu) (net 36) (tstamp 5834D325)) + (segment (start 99.9744 110.7948) (end 99.9744 114.8842) (width 0.25) (layer B.Cu) (net 36) (tstamp 5834D326)) + (segment (start 99.9744 114.8842) (end 97.663 117.1956) (width 0.25) (layer B.Cu) (net 36) (tstamp 5834D32E)) + (segment (start 97.663 117.1956) (end 97.663 118.9736) (width 0.25) (layer B.Cu) (net 36) (tstamp 5834D331)) + (segment (start 97.663 118.9736) (end 96.7994 119.8372) (width 0.25) (layer B.Cu) (net 36) (tstamp 5834D336)) + (segment (start 96.7994 119.8372) (end 96.7994 123.1392) (width 0.25) (layer B.Cu) (net 36) (tstamp 5834D337)) + (segment (start 96.7994 123.1392) (end 96.8756 123.2154) (width 0.25) (layer B.Cu) (net 36) (tstamp 5834D339)) + (via (at 96.8756 123.2154) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 36)) + (segment (start 96.8756 123.2154) (end 97.5868 123.9266) (width 0.25) (layer F.Cu) (net 36) (tstamp 5834D33D)) + (segment (start 97.5868 123.9266) (end 97.9932 123.9266) (width 0.25) (layer F.Cu) (net 36) (tstamp 5834D33E)) + (segment (start 97.9932 123.9266) (end 98.146 123.7738) (width 0.25) (layer F.Cu) (net 36) (tstamp 5834D33F)) + (segment (start 94.7692 103.0388) (end 94.808 103) (width 0.4) (layer F.Cu) (net 36) (tstamp 588012BE)) + (segment (start 99.4236 122.1738) (end 98.1458 122.1738) (width 0.25) (layer F.Cu) (net 38)) + (via (at 98.1456 122.174) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 38)) + (segment (start 98.1458 122.1738) (end 98.1456 122.174) (width 0.25) (layer F.Cu) (net 38) (tstamp 5834D634)) + (segment (start 103.2288 104.3464) (end 102.13296 104.3464) (width 0.25) (layer F.Cu) (net 38) (tstamp 5834D647)) + (segment (start 103.7082 104.8258) (end 103.2288 104.3464) (width 0.25) (layer F.Cu) (net 38) (tstamp 5834D646)) + (segment (start 103.7082 105.283) (end 103.7082 104.8258) (width 0.25) (layer F.Cu) (net 38) (tstamp 5834D645)) + (segment (start 103.5812 105.41) (end 103.7082 105.283) (width 0.25) (layer F.Cu) (net 38) (tstamp 5834D644)) + (via (at 103.5812 105.41) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 38)) + (segment (start 103.3018 105.6894) (end 103.5812 105.41) (width 0.25) (layer B.Cu) (net 38) (tstamp 5834D642)) + (segment (start 103.3018 107.823) (end 103.3018 105.6894) (width 0.25) (layer B.Cu) (net 38) (tstamp 5834D641)) + (segment (start 104.2416 108.7628) (end 103.3018 107.823) (width 0.25) (layer B.Cu) (net 38) (tstamp 5834D640)) + (segment (start 104.2416 113.0554) (end 104.2416 108.7628) (width 0.25) (layer B.Cu) (net 38) (tstamp 5834D63E)) + (segment (start 101.5492 115.7478) (end 104.2416 113.0554) (width 0.25) (layer B.Cu) (net 38) (tstamp 5834D63C)) + (segment (start 101.5492 120.0658) (end 101.5492 115.7478) (width 0.25) (layer B.Cu) (net 38) (tstamp 5834D63A)) + (segment (start 99.4156 122.1994) (end 101.5492 120.0658) (width 0.25) (layer B.Cu) (net 38) (tstamp 5834D638)) + (segment (start 98.171 122.1994) (end 99.4156 122.1994) (width 0.25) (layer B.Cu) (net 38) (tstamp 5834D637)) + (segment (start 98.1456 122.174) (end 98.171 122.1994) (width 0.25) (layer B.Cu) (net 38) (tstamp 5834D636)) + (segment (start 102.13616 104.3432) (end 102.13296 104.3464) (width 0.25) (layer F.Cu) (net 38) (tstamp 5833F610)) + (segment (start 99.4236 121.3738) (end 98.1836 121.3738) (width 0.25) (layer F.Cu) (net 39)) + (via (at 98.171 121.3612) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 39)) + (segment (start 98.1836 121.3738) (end 98.171 121.3612) (width 0.25) (layer F.Cu) (net 39) (tstamp 5834D61E)) + (segment (start 103.2628 103.6964) (end 102.13296 103.6964) (width 0.25) (layer F.Cu) (net 39) (tstamp 5834D62F)) + (segment (start 103.3018 103.6574) (end 103.2628 103.6964) (width 0.25) (layer F.Cu) (net 39) (tstamp 5834D62E)) + (via (at 103.3018 103.6574) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 39)) + (segment (start 100.4316 103.6574) (end 103.3018 103.6574) (width 0.25) (layer B.Cu) (net 39) (tstamp 5834D62C)) + (segment (start 99.9236 104.1654) (end 100.4316 103.6574) (width 0.25) (layer B.Cu) (net 39) (tstamp 5834D62B)) + (segment (start 99.9236 107.315) (end 99.9236 104.1654) (width 0.25) (layer B.Cu) (net 39) (tstamp 5834D629)) + (segment (start 103.7082 111.0996) (end 99.9236 107.315) (width 0.25) (layer B.Cu) (net 39) (tstamp 5834D627)) + (segment (start 103.7082 112.4712) (end 103.7082 111.0996) (width 0.25) (layer B.Cu) (net 39) (tstamp 5834D626)) + (segment (start 103.5304 112.649) (end 103.7082 112.4712) (width 0.25) (layer B.Cu) (net 39) (tstamp 5834D625)) + (segment (start 103.2256 112.649) (end 103.5304 112.649) (width 0.25) (layer B.Cu) (net 39) (tstamp 5834D624)) + (segment (start 98.1456 117.729) (end 103.2256 112.649) (width 0.25) (layer B.Cu) (net 39) (tstamp 5834D622)) + (segment (start 98.1456 121.3358) (end 98.1456 117.729) (width 0.25) (layer B.Cu) (net 39) (tstamp 5834D621)) + (segment (start 98.171 121.3612) (end 98.1456 121.3358) (width 0.25) (layer B.Cu) (net 39) (tstamp 5834D620)) + (segment (start 97.6757 120.5738) (end 99.4236 120.5738) (width 0.25) (layer F.Cu) (net 40) (tstamp 5833E1B4)) + (segment (start 97.282 120.9675) (end 97.6757 120.5738) (width 0.25) (layer F.Cu) (net 40) (tstamp 5833E1B3)) + (segment (start 96.647 120.9675) (end 97.282 120.9675) (width 0.25) (layer F.Cu) (net 40) (tstamp 5833E1B2)) + (segment (start 96.0755 121.539) (end 96.647 120.9675) (width 0.25) (layer F.Cu) (net 40) (tstamp 5833E1B1)) + (via (at 96.0755 121.539) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 40)) + (segment (start 94.5515 121.539) (end 96.0755 121.539) (width 0.25) (layer B.Cu) (net 40) (tstamp 5833E1AE)) + (segment (start 93.0275 120.015) (end 94.5515 121.539) (width 0.25) (layer B.Cu) (net 40) (tstamp 5833E1AC)) + (segment (start 88.519 120.015) (end 93.0275 120.015) (width 0.25) (layer B.Cu) (net 40) (tstamp 5833E1AB)) + (segment (start 88.011 120.523) (end 88.519 120.015) (width 0.25) (layer B.Cu) (net 40) (tstamp 5833E1AA)) + (segment (start 86.0425 120.523) (end 88.011 120.523) (width 0.25) (layer B.Cu) (net 40) (tstamp 5833E1A9)) + (segment (start 85.344 119.8245) (end 86.0425 120.523) (width 0.25) (layer B.Cu) (net 40) (tstamp 5833E1A8)) + (segment (start 82.55 119.8245) (end 85.344 119.8245) (width 0.25) (layer B.Cu) (net 40) (tstamp 5833E1A7)) + (segment (start 81.788 120.5865) (end 82.55 119.8245) (width 0.25) (layer B.Cu) (net 40) (tstamp 5833E1A6)) + (segment (start 78.613 120.5865) (end 81.788 120.5865) (width 0.25) (layer B.Cu) (net 40) (tstamp 5833E1A5)) + (segment (start 78.232 120.9675) (end 78.613 120.5865) (width 0.25) (layer B.Cu) (net 40) (tstamp 5833E1A4)) + (segment (start 78.232 121.2215) (end 78.232 120.9675) (width 0.25) (layer B.Cu) (net 40) (tstamp 5833E1A3)) + (segment (start 76.835 122.6185) (end 78.232 121.2215) (width 0.25) (layer B.Cu) (net 40) (tstamp 5833E1A2)) + (via (at 76.835 122.6185) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 40)) + (segment (start 74.4982 123.0256) (end 76.4279 123.0256) (width 0.25) (layer F.Cu) (net 40)) + (segment (start 76.4279 123.0256) (end 76.835 122.6185) (width 0.25) (layer F.Cu) (net 40) (tstamp 5833E1A0)) + (segment (start 97.8407 119.7738) (end 99.4236 119.7738) (width 0.25) (layer F.Cu) (net 41) (tstamp 5833E1C8)) + (segment (start 97.4725 120.142) (end 97.8407 119.7738) (width 0.25) (layer F.Cu) (net 41) (tstamp 5833E1C7)) + (segment (start 96.393 120.142) (end 97.4725 120.142) (width 0.25) (layer F.Cu) (net 41) (tstamp 5833E1C6)) + (segment (start 95.9485 120.5865) (end 96.393 120.142) (width 0.25) (layer F.Cu) (net 41) (tstamp 5833E1C5)) + (via (at 95.9485 120.5865) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 41)) + (segment (start 95.758 120.777) (end 95.9485 120.5865) (width 0.25) (layer B.Cu) (net 41) (tstamp 5833E1C3)) + (segment (start 94.9325 120.777) (end 95.758 120.777) (width 0.25) (layer B.Cu) (net 41) (tstamp 5833E1C2)) + (segment (start 93.5355 119.38) (end 94.9325 120.777) (width 0.25) (layer B.Cu) (net 41) (tstamp 5833E1C1)) + (segment (start 88.265 119.38) (end 93.5355 119.38) (width 0.25) (layer B.Cu) (net 41) (tstamp 5833E1C0)) + (segment (start 88.011 119.634) (end 88.265 119.38) (width 0.25) (layer B.Cu) (net 41) (tstamp 5833E1BF)) + (segment (start 86.2965 119.634) (end 88.011 119.634) (width 0.25) (layer B.Cu) (net 41) (tstamp 5833E1BE)) + (segment (start 85.7885 119.126) (end 86.2965 119.634) (width 0.25) (layer B.Cu) (net 41) (tstamp 5833E1BD)) + (segment (start 82.169 119.126) (end 85.7885 119.126) (width 0.25) (layer B.Cu) (net 41) (tstamp 5833E1BC)) + (segment (start 81.407 119.888) (end 82.169 119.126) (width 0.25) (layer B.Cu) (net 41) (tstamp 5833E1BB)) + (segment (start 76.0095 119.888) (end 81.407 119.888) (width 0.25) (layer B.Cu) (net 41) (tstamp 5833E1BA)) + (segment (start 75.7555 120.142) (end 76.0095 119.888) (width 0.25) (layer B.Cu) (net 41) (tstamp 5833E1B9)) + (via (at 75.7555 120.142) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 41)) + (segment (start 74.4982 120.511) (end 75.3865 120.511) (width 0.25) (layer F.Cu) (net 41)) + (segment (start 75.3865 120.511) (end 75.7555 120.142) (width 0.25) (layer F.Cu) (net 41) (tstamp 5833E1B7)) + (segment (start 97.9547 117.3738) (end 99.4236 117.3738) (width 0.25) (layer F.Cu) (net 42) (tstamp 5833E1D7)) + (segment (start 97.409 117.9195) (end 97.9547 117.3738) (width 0.25) (layer F.Cu) (net 42) (tstamp 5833E1D6)) + (segment (start 97.3455 117.9195) (end 97.409 117.9195) (width 0.25) (layer F.Cu) (net 42) (tstamp 5833E1D5)) + (segment (start 96.9645 118.3005) (end 97.3455 117.9195) (width 0.25) (layer F.Cu) (net 42) (tstamp 5833E1D4)) + (via (at 96.9645 118.3005) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 42)) + (segment (start 95.631 119.634) (end 96.9645 118.3005) (width 0.25) (layer B.Cu) (net 42) (tstamp 5833E1D2)) + (segment (start 94.6785 119.634) (end 95.631 119.634) (width 0.25) (layer B.Cu) (net 42) (tstamp 5833E1D0)) + (segment (start 93.5355 118.491) (end 94.6785 119.634) (width 0.25) (layer B.Cu) (net 42) (tstamp 5833E1CF)) + (segment (start 76.2 118.491) (end 93.5355 118.491) (width 0.25) (layer B.Cu) (net 42) (tstamp 5833E1CE)) + (segment (start 75.7555 118.0465) (end 76.2 118.491) (width 0.25) (layer B.Cu) (net 42) (tstamp 5833E1CD)) + (via (at 75.7555 118.0465) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 42)) + (segment (start 74.4982 117.9202) (end 75.6292 117.9202) (width 0.25) (layer F.Cu) (net 42)) + (segment (start 75.6292 117.9202) (end 75.7555 118.0465) (width 0.25) (layer F.Cu) (net 42) (tstamp 5833E1CB)) + (segment (start 97.1037 116.5738) (end 99.4236 116.5738) (width 0.25) (layer F.Cu) (net 43) (tstamp 5833E208)) + (segment (start 96.139 117.5385) (end 97.1037 116.5738) (width 0.25) (layer F.Cu) (net 43) (tstamp 5833E207)) + (via (at 96.139 117.5385) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 43)) + (segment (start 95.885 117.7925) (end 96.139 117.5385) (width 0.25) (layer B.Cu) (net 43) (tstamp 5833E205)) + (segment (start 79.375 117.7925) (end 95.885 117.7925) (width 0.25) (layer B.Cu) (net 43) (tstamp 5833E204)) + (segment (start 79.0575 117.475) (end 79.375 117.7925) (width 0.25) (layer B.Cu) (net 43) (tstamp 5833E203)) + (segment (start 77.6605 117.475) (end 79.0575 117.475) (width 0.25) (layer B.Cu) (net 43) (tstamp 5833E202)) + (segment (start 75.692 115.5065) (end 77.6605 117.475) (width 0.25) (layer B.Cu) (net 43) (tstamp 5833E201)) + (via (at 75.692 115.5065) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 43)) + (segment (start 74.4982 115.3802) (end 75.5657 115.3802) (width 0.25) (layer F.Cu) (net 43)) + (segment (start 75.5657 115.3802) (end 75.692 115.5065) (width 0.25) (layer F.Cu) (net 43) (tstamp 5833E1FF)) + (segment (start 98.2138 114.7238) (end 97.5736 114.7238) (width 0.25) (layer F.Cu) (net 44) (tstamp 5833E22A)) + (segment (start 73.66 109.22) (end 73.66 109.2835) (width 0.25) (layer B.Cu) (net 44)) + (segment (start 73.66 109.2835) (end 75.438 111.0615) (width 0.25) (layer B.Cu) (net 44) (tstamp 5833E21E)) + (segment (start 75.438 111.0615) (end 75.438 111.76) (width 0.25) (layer B.Cu) (net 44) (tstamp 5833E21F)) + (segment (start 75.438 111.76) (end 79.9465 116.2685) (width 0.25) (layer B.Cu) (net 44) (tstamp 5833E221)) + (segment (start 79.9465 116.2685) (end 87.8205 116.2685) (width 0.25) (layer B.Cu) (net 44) (tstamp 5833E222)) + (segment (start 87.8205 116.2685) (end 88.5825 115.5065) (width 0.25) (layer B.Cu) (net 44) (tstamp 5833E224)) + (segment (start 88.5825 115.5065) (end 91.8845 115.5065) (width 0.25) (layer B.Cu) (net 44) (tstamp 5833E225)) + (segment (start 91.8845 115.5065) (end 92.202 115.189) (width 0.25) (layer B.Cu) (net 44) (tstamp 5833E226)) + (segment (start 92.202 115.189) (end 98.679 115.189) (width 0.25) (layer B.Cu) (net 44) (tstamp 5833E227)) + (via (at 98.679 115.189) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 44)) + (segment (start 98.679 115.189) (end 98.2138 114.7238) (width 0.25) (layer F.Cu) (net 44) (tstamp 5833E229)) + (segment (start 96.7736 116.0149) (end 96.7736 114.7238) (width 0.25) (layer F.Cu) (net 45) (tstamp 5833E21A)) + (segment (start 73.66 111.76) (end 73.7235 111.76) (width 0.25) (layer B.Cu) (net 45)) + (segment (start 73.7235 111.76) (end 78.8035 116.84) (width 0.25) (layer B.Cu) (net 45) (tstamp 5833E20D)) + (segment (start 78.8035 116.84) (end 88.3285 116.84) (width 0.25) (layer B.Cu) (net 45) (tstamp 5833E20E)) + (segment (start 88.3285 116.84) (end 89.0905 116.078) (width 0.25) (layer B.Cu) (net 45) (tstamp 5833E210)) + (segment (start 89.0905 116.078) (end 92.3925 116.078) (width 0.25) (layer B.Cu) (net 45) (tstamp 5833E211)) + (segment (start 92.3925 116.078) (end 92.583 115.8875) (width 0.25) (layer B.Cu) (net 45) (tstamp 5833E212)) + (segment (start 92.583 115.8875) (end 93.7895 115.8875) (width 0.25) (layer B.Cu) (net 45) (tstamp 5833E213)) + (segment (start 93.7895 115.8875) (end 94.234 116.332) (width 0.25) (layer B.Cu) (net 45) (tstamp 5833E214)) + (segment (start 94.234 116.332) (end 95.8215 116.332) (width 0.25) (layer B.Cu) (net 45) (tstamp 5833E215)) + (via (at 95.8215 116.332) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 45)) + (segment (start 95.8215 116.332) (end 96.0755 116.078) (width 0.25) (layer F.Cu) (net 45) (tstamp 5833E217)) + (segment (start 96.0755 116.078) (end 96.7105 116.078) (width 0.25) (layer F.Cu) (net 45) (tstamp 5833E218)) + (segment (start 96.7105 116.078) (end 96.7736 116.0149) (width 0.25) (layer F.Cu) (net 45) (tstamp 5833E219)) + (segment (start 91.1736 115.8751) (end 91.1736 114.7238) (width 0.25) (layer F.Cu) (net 49) (tstamp 5833E18A)) + (segment (start 93.599 118.3005) (end 91.1736 115.8751) (width 0.25) (layer F.Cu) (net 49) (tstamp 5833E188)) + (segment (start 93.7641 122.5931) (end 93.599 118.3005) (width 0.25) (layer F.Cu) (net 49) (tstamp 5833E187)) + (segment (start 93.8276 122.6566) (end 93.7641 122.5931) (width 0.25) (layer F.Cu) (net 49) (tstamp 5833E186)) + (via (at 93.8276 122.6566) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 49)) + (segment (start 93.8276 122.8471) (end 93.8276 122.6566) (width 0.25) (layer B.Cu) (net 49) (tstamp 5833E184)) + (segment (start 93.2815 122.4915) (end 93.8276 122.8471) (width 0.25) (layer B.Cu) (net 49) (tstamp 5833E182)) + (segment (start 89.155398 122.4915) (end 93.2815 122.4915) (width 0.25) (layer B.Cu) (net 49) (tstamp 5833E181)) + (segment (start 88.706992 122.939906) (end 89.155398 122.4915) (width 0.25) (layer B.Cu) (net 49) (tstamp 5833E180)) + (segment (start 87.943594 122.939906) (end 88.706992 122.939906) (width 0.25) (layer B.Cu) (net 49) (tstamp 5833E17F)) + (segment (start 86.2965 124.587) (end 87.943594 122.939906) (width 0.25) (layer B.Cu) (net 49) (tstamp 5833E17E)) + (segment (start 86.2965 124.6505) (end 86.2965 124.587) (width 0.25) (layer B.Cu) (net 49) (tstamp 5833E17D)) + (segment (start 86.106 124.841) (end 86.2965 124.6505) (width 0.25) (layer B.Cu) (net 49) (tstamp 5833E17C)) + (segment (start 85.852 124.345) (end 85.852 124.587) (width 0.25) (layer F.Cu) (net 49)) + (segment (start 85.852 124.587) (end 86.106 124.841) (width 0.25) (layer F.Cu) (net 49) (tstamp 5833E17A)) + (via (at 86.106 124.841) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 49)) + (segment (start 84.234 126.365) (end 84.234 125.095) (width 0.25) (layer F.Cu) (net 49)) + (segment (start 84.234 125.095) (end 85.102 125.095) (width 0.25) (layer F.Cu) (net 49)) + (segment (start 85.102 125.095) (end 85.852 124.345) (width 0.25) (layer F.Cu) (net 49) (tstamp 5833B747)) + (segment (start 89.5736 116.0531) (end 89.5736 114.7238) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833E101)) + (segment (start 90.8685 117.348) (end 89.5736 116.0531) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833E100)) + (segment (start 90.8685 117.5385) (end 90.8685 117.348) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833E0FE)) + (segment (start 93.0275 119.6975) (end 90.8685 117.5385) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833E0FC)) + (segment (start 93.0275 123.063) (end 93.0275 119.6975) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833E0FB)) + (segment (start 92.9005 124.841) (end 93.0275 123.063) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833E0FA)) + (segment (start 90.043 124.968) (end 92.9005 124.841) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833E0F9)) + (segment (start 88.773 125.4125) (end 90.043 124.968) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833E0F8)) + (segment (start 87.9475 125.4125) (end 88.773 125.4125) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833E0F7)) + (segment (start 87.122 126.238) (end 87.9475 125.4125) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833E0F6)) + (via (at 87.122 126.238) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 51)) + (segment (start 87.0585 126.3015) (end 87.122 126.238) (width 0.25) (layer B.Cu) (net 51) (tstamp 5833E0F4)) + (segment (start 83.439 126.3015) (end 87.0585 126.3015) (width 0.25) (layer B.Cu) (net 51) (tstamp 5833E0F3)) + (segment (start 82.55 127.1905) (end 83.439 126.3015) (width 0.25) (layer B.Cu) (net 51) (tstamp 5833E0F2)) + (segment (start 83.1843 127.8509) (end 83.1843 127.8248) (width 0.25) (layer F.Cu) (net 51)) + (segment (start 83.1843 127.8248) (end 82.55 127.1905) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833E0F0)) + (via (at 82.55 127.1905) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 51)) + (segment (start 80.8108 130.568) (end 81.1276 130.568) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833DDBB)) + (segment (start 80.1878 129.4518) (end 80.1878 128.9812) (width 0.25) (layer F.Cu) (net 51)) + (segment (start 83.0072 128.7018) (end 83.1843 128.5247) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833B796)) + (segment (start 80.4672 128.7018) (end 83.0072 128.7018) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833B795)) + (segment (start 80.1878 128.9812) (end 80.4672 128.7018) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833B794)) + (segment (start 83.1843 127.8509) (end 83.1843 128.5247) (width 0.25) (layer F.Cu) (net 51)) + (segment (start 83.1843 128.5247) (end 83.1843 129.3241) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833B799)) + (segment (start 80.1878 129.4518) (end 80.1878 129.8956) (width 0.25) (layer F.Cu) (net 51)) + (segment (start 80.1878 129.8956) (end 80.8602 130.568) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833B709)) + (segment (start 80.8602 130.568) (end 81.1276 130.568) (width 0.25) (layer F.Cu) (net 51) (tstamp 5833B70A)) + (segment (start 87.757 113.919) (end 88.318 113.919) (width 0.25) (layer F.Cu) (net 52) (tstamp 5833DDEC)) + (segment (start 87.0204 113.1824) (end 87.757 113.919) (width 0.25) (layer F.Cu) (net 52) (tstamp 5833DDEB)) + (segment (start 86.7156 113.1824) (end 87.0204 113.1824) (width 0.25) (layer F.Cu) (net 52) (tstamp 5833DDEA)) + (segment (start 86.3854 113.5126) (end 86.7156 113.1824) (width 0.25) (layer F.Cu) (net 52) (tstamp 5833DDE9)) + (segment (start 86.3854 115.189) (end 86.3854 113.5126) (width 0.25) (layer F.Cu) (net 52) (tstamp 5833DDE8)) + (segment (start 87.884 113.919) (end 88.318 113.919) (width 0.4) (layer F.Cu) (net 52) (tstamp 5833ACB8)) + (segment (start 85.905 116.332) (end 85.905 115.6694) (width 0.25) (layer F.Cu) (net 52)) + (segment (start 85.905 115.6694) (end 86.3854 115.189) (width 0.25) (layer F.Cu) (net 52) (tstamp 5833DDE7)) + (segment (start 85.905 116.332) (end 85.905 115.898) (width 0.4) (layer F.Cu) (net 52)) + (segment (start 73.1012 115.3802) (end 72.2002 115.3802) (width 0.25) (layer F.Cu) (net 54)) + (segment (start 72.2002 115.3802) (end 71.12 114.3) (width 0.25) (layer F.Cu) (net 54) (tstamp 5833DEE3)) + (segment (start 73.1012 117.9202) (end 72.2002 117.9202) (width 0.25) (layer F.Cu) (net 55)) + (segment (start 72.2002 117.9202) (end 71.12 116.84) (width 0.25) (layer F.Cu) (net 55) (tstamp 5833DEE6)) + (segment (start 73.1012 120.511) (end 72.251 120.511) (width 0.25) (layer F.Cu) (net 56)) + (segment (start 72.251 120.511) (end 71.12 119.38) (width 0.25) (layer F.Cu) (net 56) (tstamp 5833DEE9)) + (segment (start 73.1012 123.0256) (end 72.2256 123.0256) (width 0.25) (layer F.Cu) (net 57)) + (segment (start 72.2256 123.0256) (end 71.12 121.92) (width 0.25) (layer F.Cu) (net 57) (tstamp 5833DEEC)) + (segment (start 76.593 113.03) (end 76.593 111.367) (width 0.4) (layer F.Cu) (net 58)) + (segment (start 76.593 111.367) (end 77.47 110.49) (width 0.4) (layer F.Cu) (net 58) (tstamp 58338FDB)) + (segment (start 77.47 110.49) (end 77.47 109.093) (width 1.27) (layer F.Cu) (net 58)) + (segment (start 74.93 107.95) (end 73.66 106.68) (width 1.27) (layer F.Cu) (net 58) (tstamp 58338EF4)) + (segment (start 76.327 107.95) (end 74.93 107.95) (width 1.27) (layer F.Cu) (net 58) (tstamp 58338EF3)) + (segment (start 77.47 109.093) (end 76.327 107.95) (width 1.27) (layer F.Cu) (net 58) (tstamp 58338EF2)) + (segment (start 104.4702 129.6162) (end 102.9843 129.6162) (width 0.25) (layer F.Cu) (net 59)) + (segment (start 96.8502 132.0673) (end 96.8502 131.3688) (width 0.25) (layer F.Cu) (net 59) (tstamp 58801CA2)) + (segment (start 96.9137 132.1308) (end 96.8502 132.0673) (width 0.25) (layer F.Cu) (net 59) (tstamp 58801CA1)) + (segment (start 100.4697 132.1308) (end 96.9137 132.1308) (width 0.25) (layer F.Cu) (net 59) (tstamp 58801C9F)) + (segment (start 102.9843 129.6162) (end 100.4697 132.1308) (width 0.25) (layer F.Cu) (net 59) (tstamp 58801C9D)) + (segment (start 96.8502 133.4008) (end 96.8502 133.0198) (width 0.25) (layer F.Cu) (net 60)) + (segment (start 97.1677 132.7023) (end 103.9241 132.7023) (width 0.25) (layer F.Cu) (net 60) (tstamp 58801C98)) + (segment (start 96.8502 133.0198) (end 97.1677 132.7023) (width 0.25) (layer F.Cu) (net 60) (tstamp 58801C97)) + (segment (start 103.9241 132.7023) (end 104.4702 132.1562) (width 0.25) (layer F.Cu) (net 60) (tstamp 58801C99)) + (segment (start 83.1088 126.238) (end 83.1088 124.0536) (width 0.25) (layer F.Cu) (net 62)) + (segment (start 83.8828 132.068) (end 83.9216 132.0292) (width 0.25) (layer F.Cu) (net 62) (tstamp 5833F40C)) + (via (at 83.9216 132.0292) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 62)) + (segment (start 83.9216 132.0292) (end 83.8708 131.9784) (width 0.25) (layer B.Cu) (net 62) (tstamp 5833F40E)) + (segment (start 83.8708 131.9784) (end 83.9216 129.8956) (width 0.25) (layer B.Cu) (net 62) (tstamp 5833F40F)) + (via (at 83.9216 129.8956) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 62)) + (segment (start 83.9216 129.8956) (end 83.9724 129.8448) (width 0.25) (layer F.Cu) (net 62) (tstamp 5833F417)) + (segment (start 83.9724 129.8448) (end 83.9724 127.3556) (width 0.25) (layer F.Cu) (net 62) (tstamp 5833F418)) + (segment (start 83.9724 127.3556) (end 83.6676 127.0508) (width 0.25) (layer F.Cu) (net 62) (tstamp 5833F419)) + (segment (start 83.6676 127.0508) (end 83.2612 127.0508) (width 0.25) (layer F.Cu) (net 62) (tstamp 5833F41A)) + (segment (start 83.2612 127.0508) (end 83.1088 126.8984) (width 0.25) (layer F.Cu) (net 62) (tstamp 5833F41B)) + (segment (start 83.1088 126.8984) (end 83.1088 126.238) (width 0.25) (layer F.Cu) (net 62) (tstamp 5833F41C)) + (segment (start 82.7532 132.068) (end 83.8828 132.068) (width 0.25) (layer F.Cu) (net 62)) + (segment (start 83.3374 123.825) (end 84.234 123.825) (width 0.25) (layer F.Cu) (net 62) (tstamp 5833F420)) + (segment (start 83.1088 124.0536) (end 83.3374 123.825) (width 0.25) (layer F.Cu) (net 62) (tstamp 5833F41F)) + (segment (start 81.1276 132.068) (end 82.7532 132.068) (width 0.25) (layer F.Cu) (net 62)) + (segment (start 81.788 127.9518) (end 81.788 127.0508) (width 0.25) (layer F.Cu) (net 63)) + (segment (start 83.9038 120.9548) (end 84.234 121.285) (width 0.25) (layer F.Cu) (net 63) (tstamp 5833BB72)) + (segment (start 83.3374 120.9548) (end 83.9038 120.9548) (width 0.25) (layer F.Cu) (net 63) (tstamp 5833BB71)) + (segment (start 82.9818 120.5992) (end 83.3374 120.9548) (width 0.25) (layer F.Cu) (net 63) (tstamp 5833BB70)) + (via (at 82.9818 120.5992) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 63)) + (segment (start 82.9818 122.9106) (end 82.9818 120.5992) (width 0.25) (layer B.Cu) (net 63) (tstamp 5833BB6E)) + (segment (start 82.804 123.0884) (end 82.9818 122.9106) (width 0.25) (layer B.Cu) (net 63) (tstamp 5833BB6D)) + (via (at 82.804 123.0884) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 63)) + (segment (start 82.804 123.1646) (end 82.804 123.0884) (width 0.25) (layer F.Cu) (net 63) (tstamp 5833BB6B)) + (segment (start 82.3468 123.6218) (end 82.804 123.1646) (width 0.25) (layer F.Cu) (net 63) (tstamp 5833BB6A)) + (segment (start 82.3468 126.492) (end 82.3468 123.6218) (width 0.25) (layer F.Cu) (net 63) (tstamp 5833BB69)) + (segment (start 81.788 127.0508) (end 82.3468 126.492) (width 0.25) (layer F.Cu) (net 63) (tstamp 5833BB68)) + (segment (start 80.1878 127.9518) (end 80.1878 127.7112) (width 0.25) (layer F.Cu) (net 63)) + (segment (start 81.788 127.9518) (end 80.1878 127.9518) (width 0.25) (layer F.Cu) (net 63)) + (segment (start 73.1012 121.5256) (end 74.4982 121.5256) (width 0.25) (layer F.Cu) (net 64)) + (segment (start 73.1012 119.011) (end 74.4982 119.011) (width 0.25) (layer F.Cu) (net 65)) + (segment (start 73.1012 116.4202) (end 74.4982 116.4202) (width 0.25) (layer F.Cu) (net 66)) + (segment (start 73.1012 113.8802) (end 74.4982 113.8802) (width 0.25) (layer F.Cu) (net 67)) + (segment (start 78.2066 131.318) (end 77.6732 130.7846) (width 0.25) (layer B.Cu) (net 68) (tstamp 5833B02F)) + (via (at 78.2066 131.318) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 68)) + (segment (start 77.851 131.6736) (end 78.2066 131.318) (width 0.25) (layer F.Cu) (net 68) (tstamp 5833B02D)) + (segment (start 77.6732 130.7846) (end 77.6732 130.639398) (width 0.25) (layer B.Cu) (net 68) (tstamp 5833B030)) + (segment (start 77.6732 130.639398) (end 77.183402 130.1496) (width 0.25) (layer B.Cu) (net 68) (tstamp 5833B031)) + (segment (start 77.183402 130.1496) (end 77.183402 128.099398) (width 0.25) (layer B.Cu) (net 68) (tstamp 5833B032)) + (segment (start 77.183402 128.099398) (end 77.6732 127.6096) (width 0.25) (layer B.Cu) (net 68) (tstamp 5833B034)) + (segment (start 77.6732 127.6096) (end 77.6732 125.476) (width 0.25) (layer B.Cu) (net 68) (tstamp 5833B035)) + (via (at 77.597 125.3998) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 68)) + (segment (start 77.6732 125.476) (end 77.597 125.3998) (width 0.25) (layer B.Cu) (net 68) (tstamp 5833B036)) + (segment (start 77.6224 125.1458) (end 77.6732 125.095) (width 0.25) (layer F.Cu) (net 68) (tstamp 5833B03B)) + (segment (start 77.6224 125.3744) (end 77.6224 125.1458) (width 0.25) (layer F.Cu) (net 68) (tstamp 5833B03A)) + (segment (start 77.597 125.3998) (end 77.6224 125.3744) (width 0.25) (layer F.Cu) (net 68) (tstamp 5833B039)) + (segment (start 77.482 131.6736) (end 77.851 131.6736) (width 0.25) (layer F.Cu) (net 68)) + (segment (start 77.6732 125.095) (end 78.834 125.095) (width 0.25) (layer F.Cu) (net 68) (tstamp 5833B03C)) + (segment (start 77.3056 132.9944) (end 78.3202 132.9944) (width 0.25) (layer F.Cu) (net 68)) + (segment (start 77.482 131.6736) (end 77.482 132.818) (width 0.25) (layer F.Cu) (net 68)) + (segment (start 77.482 132.818) (end 77.3056 132.9944) (width 0.25) (layer F.Cu) (net 68) (tstamp 5833B028)) + (segment (start 78.982 131.6736) (end 78.982 130.7218) (width 0.25) (layer F.Cu) (net 69)) + (segment (start 79.8202 132.5118) (end 78.982 131.6736) (width 0.25) (layer F.Cu) (net 69) (tstamp 5833B022)) + (segment (start 78.982 130.7218) (end 78.613 130.3528) (width 0.25) (layer F.Cu) (net 69) (tstamp 5833B025)) + (segment (start 79.8202 132.9944) (end 79.8202 132.5118) (width 0.25) (layer F.Cu) (net 69)) + (segment (start 76.5944 124.218) (end 77.6224 123.19) (width 0.25) (layer F.Cu) (net 70) (tstamp 5833AEC0)) + (segment (start 77.6224 123.19) (end 80.4164 123.19) (width 0.25) (layer F.Cu) (net 70) (tstamp 5833AEC1)) + (segment (start 80.4164 123.19) (end 80.8228 122.7836) (width 0.25) (layer F.Cu) (net 70) (tstamp 5833AEC3)) + (segment (start 80.8228 122.7836) (end 80.8228 120.4976) (width 0.25) (layer F.Cu) (net 70) (tstamp 5833AEC4)) + (segment (start 80.8228 120.4976) (end 80.3402 120.015) (width 0.25) (layer F.Cu) (net 70) (tstamp 5833AEC5)) + (segment (start 80.3402 120.015) (end 78.834 120.015) (width 0.25) (layer F.Cu) (net 70) (tstamp 5833AEC6)) + (segment (start 74.5356 128.6764) (end 74.5356 128.6136) (width 0.25) (layer F.Cu) (net 70)) + (segment (start 74.5356 128.6136) (end 75.2348 127.9144) (width 0.25) (layer F.Cu) (net 70) (tstamp 5833AF40)) + (segment (start 75.946 124.599) (end 76.327 124.218) (width 0.25) (layer F.Cu) (net 70) (tstamp 5833AF46)) + (segment (start 75.946 124.7648) (end 75.946 124.599) (width 0.25) (layer F.Cu) (net 70) (tstamp 5833AF45)) + (segment (start 75.5396 125.1712) (end 75.946 124.7648) (width 0.25) (layer F.Cu) (net 70) (tstamp 5833AF44)) + (segment (start 75.5396 126.1364) (end 75.5396 125.1712) (width 0.25) (layer F.Cu) (net 70) (tstamp 5833AF43)) + (segment (start 75.2348 126.4412) (end 75.5396 126.1364) (width 0.25) (layer F.Cu) (net 70) (tstamp 5833AF42)) + (segment (start 75.2348 127.9144) (end 75.2348 126.4412) (width 0.25) (layer F.Cu) (net 70) (tstamp 5833AF41)) + (segment (start 73.3044 127.4184) (end 73.3044 127.4452) (width 0.25) (layer F.Cu) (net 70)) + (segment (start 73.3044 127.4452) (end 74.5356 128.6764) (width 0.25) (layer F.Cu) (net 70) (tstamp 5833AF39)) + (segment (start 76.327 124.218) (end 76.5944 124.218) (width 0.25) (layer F.Cu) (net 70)) + (segment (start 77.343 128.3208) (end 76.3912 128.3208) (width 0.25) (layer F.Cu) (net 71)) + (segment (start 76.3912 128.3208) (end 76.0356 128.6764) (width 0.25) (layer F.Cu) (net 71) (tstamp 5833B018)) + (segment (start 73.3044 128.9184) (end 73.394 128.9184) (width 0.25) (layer F.Cu) (net 71)) + (segment (start 73.394 128.9184) (end 73.9648 129.4892) (width 0.25) (layer F.Cu) (net 71) (tstamp 5833AF6D)) + (segment (start 73.9648 129.4892) (end 75.4888 129.4892) (width 0.25) (layer F.Cu) (net 71) (tstamp 5833AF6E)) + (segment (start 75.4888 129.4892) (end 76.0356 128.9424) (width 0.25) (layer F.Cu) (net 71) (tstamp 5833AF6F)) + (segment (start 76.0356 128.9424) (end 76.0356 128.6764) (width 0.25) (layer F.Cu) (net 71) (tstamp 5833AF70)) + (segment (start 76.327 125.718) (end 76.327 125.603) (width 0.25) (layer F.Cu) (net 72)) + (segment (start 76.327 125.603) (end 77.47 124.46) (width 0.25) (layer F.Cu) (net 72) (tstamp 5833B095)) + (segment (start 79.756 118.745) (end 78.834 118.745) (width 0.25) (layer F.Cu) (net 72) (tstamp 5833B0AA)) + (segment (start 81.3054 120.2944) (end 79.756 118.745) (width 0.25) (layer F.Cu) (net 72) (tstamp 5833B0A4)) + (segment (start 81.3054 123.3678) (end 81.3054 120.2944) (width 0.25) (layer F.Cu) (net 72) (tstamp 5833B09A)) + (segment (start 80.2132 124.46) (end 81.3054 123.3678) (width 0.25) (layer F.Cu) (net 72) (tstamp 5833B099)) + (segment (start 77.47 124.46) (end 80.2132 124.46) (width 0.25) (layer F.Cu) (net 72) (tstamp 5833B096)) + (segment (start 75.9975 127.0635) (end 75.9975 126.0475) (width 0.25) (layer F.Cu) (net 72)) + (segment (start 75.9975 126.0475) (end 76.327 125.718) (width 0.25) (layer F.Cu) (net 72) (tstamp 5833B045)) + (segment (start 77.0255 118.9475) (end 78.6315 118.9475) (width 0.25) (layer F.Cu) (net 72)) + (segment (start 78.6315 118.9475) (end 78.834 118.745) (width 0.25) (layer F.Cu) (net 72) (tstamp 5833AE50)) + (segment (start 76.2508 131.7124) (end 76.2508 131.0894) (width 0.25) (layer F.Cu) (net 73)) + (via (at 76.327 131.0132) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 73)) + (segment (start 76.2508 131.0894) (end 76.327 131.0132) (width 0.25) (layer F.Cu) (net 73) (tstamp 5833B005)) + (segment (start 75.8056 132.9944) (end 75.8056 132.1576) (width 0.25) (layer F.Cu) (net 73)) + (segment (start 75.8056 132.1576) (end 76.2508 131.7124) (width 0.25) (layer F.Cu) (net 73) (tstamp 5833B002)) + (segment (start 76.327 131.0132) (end 76.7334 130.6068) (width 0.25) (layer B.Cu) (net 73) (tstamp 5833B007)) + (segment (start 76.7334 130.6068) (end 76.7334 127.635) (width 0.25) (layer B.Cu) (net 73) (tstamp 5833B008)) + (segment (start 76.7334 127.635) (end 77.0128 127.3556) (width 0.25) (layer B.Cu) (net 73) (tstamp 5833B00E)) + (via (at 77.0128 127.3556) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 73)) + (segment (start 77.216 127.1524) (end 77.216 126.8476) (width 0.25) (layer F.Cu) (net 73) (tstamp 5833B012)) + (segment (start 77.0128 127.3556) (end 77.216 127.1524) (width 0.25) (layer F.Cu) (net 73) (tstamp 5833B011)) + (segment (start 77.216 126.8476) (end 77.6986 126.365) (width 0.25) (layer F.Cu) (net 73) (tstamp 5833B013)) + (segment (start 77.6986 126.365) (end 78.834 126.365) (width 0.25) (layer F.Cu) (net 73) (tstamp 5833B014)) + (segment (start 74.664 132.9944) (end 75.8056 132.9944) (width 0.25) (layer F.Cu) (net 73)) + (segment (start 74.7395 125.6545) (end 74.7395 126.8215) (width 0.25) (layer F.Cu) (net 74)) + (segment (start 74.7395 126.8215) (end 74.4975 127.0635) (width 0.25) (layer F.Cu) (net 74) (tstamp 5833AF30)) + (segment (start 74.7268 131.6616) (end 74.5864 131.6616) (width 0.25) (layer F.Cu) (net 75)) + (segment (start 74.5864 131.6616) (end 73.914 132.334) (width 0.25) (layer F.Cu) (net 75) (tstamp 5833AF92)) + (segment (start 73.914 132.334) (end 73.914 132.6388) (width 0.25) (layer F.Cu) (net 75) (tstamp 5833AF93)) + (segment (start 73.914 132.6388) (end 73.5584 132.9944) (width 0.25) (layer F.Cu) (net 75) (tstamp 5833AF94)) + (segment (start 73.5584 132.9944) (end 73.164 132.9944) (width 0.25) (layer F.Cu) (net 75) (tstamp 5833AF95)) + (segment (start 92.5195 104.7115) (end 89.107 104.7115) (width 1.27) (layer F.Cu) (net 76)) + (segment (start 89.107 104.7115) (end 87.757 106.0615) (width 1.27) (layer F.Cu) (net 76) (tstamp 58FEA9A4)) + (segment (start 87.0698 108.1546) (end 87.0698 110.5408) (width 1.27) (layer F.Cu) (net 76) (tstamp 58F5867B)) + (segment (start 88.138 107.0864) (end 87.0698 108.1546) (width 1.27) (layer F.Cu) (net 76) (tstamp 58F5867A)) + (segment (start 88.138 105.998) (end 88.138 107.0864) (width 1.27) (layer F.Cu) (net 76)) + +) diff --git a/PCB/Tinylab_proto1.kicad_pcb-bak.REMOVED.git-id b/PCB/Tinylab_proto1.kicad_pcb-bak.REMOVED.git-id deleted file mode 100644 index d52c0e6b..00000000 --- a/PCB/Tinylab_proto1.kicad_pcb-bak.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6f634c97c3893e04560ade1472c2d06c3cdaab67 \ No newline at end of file diff --git a/PCB/Tinylab_proto1.kicad_pcb.REMOVED.git-id b/PCB/Tinylab_proto1.kicad_pcb.REMOVED.git-id deleted file mode 100644 index 2f9eda2d..00000000 --- a/PCB/Tinylab_proto1.kicad_pcb.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8a5607fed84d7fd1e329a1b2fcb6c9dae9ee91ff \ No newline at end of file diff --git a/PCB/Tinylab_proto1.kicad_pcb.bak b/PCB/Tinylab_proto1.kicad_pcb.bak new file mode 100644 index 00000000..92e0c41f --- /dev/null +++ b/PCB/Tinylab_proto1.kicad_pcb.bak @@ -0,0 +1,3418 @@ +(kicad_pcb (version 4) (host pcbnew 4.0.4-stable) + + (general + (links 149) + (no_connects 2) + (area 77.654324 86.021513 118.778 129.040952) + (thickness 1.6) + (drawings 8) + (tracks 815) + (zones 0) + (modules 72) + (nets 74) + ) + + (page A4) + (layers + (0 F.Cu signal hide) + (31 B.Cu signal hide) + (32 B.Adhes user hide) + (33 F.Adhes user hide) + (34 B.Paste user hide) + (35 F.Paste user hide) + (36 B.SilkS user hide) + (37 F.SilkS user) + (38 B.Mask user hide) + (39 F.Mask user hide) + (40 Dwgs.User user hide) + (41 Cmts.User user hide) + (42 Eco1.User user hide) + (43 Eco2.User user hide) + (44 Edge.Cuts user hide) + (45 Margin user hide) + (46 B.CrtYd user hide) + (47 F.CrtYd user hide) + (48 B.Fab user hide) + (49 F.Fab user hide) + ) + + (setup + (last_trace_width 0.25) + (user_trace_width 0.4) + (user_trace_width 0.635) + (user_trace_width 1.27) + (trace_clearance 0.2) + (zone_clearance 0.508) + (zone_45_only no) + (trace_min 0.2) + (segment_width 0.2) + (edge_width 0.1) + (via_size 0.6) + (via_drill 0.4) + (via_min_size 0.4) + (via_min_drill 0.3) + (uvia_size 0.3) + (uvia_drill 0.1) + (uvias_allowed no) + (uvia_min_size 0.2) + (uvia_min_drill 0.1) + (pcb_text_width 0.3) + (pcb_text_size 0.8 0.8) + (mod_edge_width 0.15) + (mod_text_size 0.8 0.8) + (mod_text_width 0.15) + (pad_size 1.5 1.5) + (pad_drill 0.6) + (pad_to_mask_clearance 0) + (aux_axis_origin 0 0) + (visible_elements 7FFEFFFF) + (pcbplotparams + (layerselection 0x010e0_80000001) + (usegerberextensions false) + (excludeedgelayer true) + (linewidth 0.100000) + (plotframeref false) + (viasonmask false) + (mode 1) + (useauxorigin false) + (hpglpennumber 1) + (hpglpenspeed 20) + (hpglpendiameter 15) + (hpglpenoverlay 2) + (psnegative false) + (psa4output false) + (plotreference true) + (plotvalue true) + (plotinvisibletext false) + (padsonsilk false) + (subtractmaskfromsilk false) + (outputformat 1) + (mirror false) + (drillshape 0) + (scaleselection 1) + (outputdirectory OUTPUT_V6/)) + ) + + (net 0 "") + (net 1 "Net-(C1-Pad1)") + (net 2 "Net-(C1-Pad2)") + (net 3 "Net-(C2-Pad1)") + (net 4 "Net-(C2-Pad2)") + (net 5 +5V) + (net 6 /VCC_3V3) + (net 7 /AVCC) + (net 8 /OPAMP_VCC) + (net 9 /VGND) + (net 10 "Net-(C13-Pad1)") + (net 11 "Net-(C13-Pad2)") + (net 12 "Net-(C14-Pad1)") + (net 13 "Net-(C14-Pad2)") + (net 14 /PSU_OUT) + (net 15 "Net-(D1-Pad2)") + (net 16 /PSU_FEEDBACK) + (net 17 /CH2) + (net 18 "Net-(IC1-Pad3)") + (net 19 /TO_B0) + (net 20 /TO_B1) + (net 21 /DAC_OUT) + (net 22 /DAC_OUT2) + (net 23 "Net-(IC1-Pad9)") + (net 24 "Net-(IC1-Pad10)") + (net 25 /XCK) + (net 26 /DIG_CH2) + (net 27 "Net-(IC1-Pad13)") + (net 28 "Net-(IC1-Pad16)") + (net 29 /DIG_CH1) + (net 30 "Net-(IC1-Pad20)") + (net 31 "Net-(IC1-Pad21)") + (net 32 "Net-(IC1-Pad22)") + (net 33 /PSU_PWM) + (net 34 "Net-(IC1-Pad25)") + (net 35 /D-) + (net 36 /D+) + (net 37 "Net-(IC1-Pad28)") + (net 38 "Net-(IC1-Pad29)") + (net 39 "Net-(IC1-Pad32)") + (net 40 "Net-(IC1-Pad33)") + (net 41 "Net-(IC1-Pad34)") + (net 42 "Net-(IC1-Pad35)") + (net 43 "Net-(IC1-Pad36)") + (net 44 "Net-(IC1-Pad37)") + (net 45 "Net-(IC1-Pad41)") + (net 46 /CH1) + (net 47 "Net-(IC1-Pad43)") + (net 48 /AVCC_ON_2) + (net 49 "Net-(P2-Pad4)") + (net 50 "Net-(P3-Pad1)") + (net 51 "Net-(P3-Pad2)") + (net 52 "Net-(P3-Pad3)") + (net 53 "Net-(P3-Pad4)") + (net 54 "Net-(P8-Pad1)") + (net 55 "Net-(P8-Pad2)") + (net 56 "Net-(R1-Pad1)") + (net 57 "Net-(R2-Pad1)") + (net 58 "Net-(R11-Pad2)") + (net 59 "Net-(R12-Pad2)") + (net 60 "Net-(R13-Pad2)") + (net 61 "Net-(R10-Pad1)") + (net 62 "Net-(R15-Pad1)") + (net 63 "Net-(R15-Pad2)") + (net 64 "Net-(R17-Pad1)") + (net 65 "Net-(R17-Pad2)") + (net 66 "Net-(R19-Pad1)") + (net 67 "Net-(R20-Pad1)") + (net 68 "Net-(R22-Pad1)") + (net 69 "Net-(R23-Pad1)") + (net 70 "Net-(L3-Pad2)") + (net 71 "Net-(F1-Pad1)") + (net 72 /ENABLE_VOUT) + (net 73 "Net-(P10-Pad1)") + + (net_class Default "This is the default net class." + (clearance 0.2) + (trace_width 0.25) + (via_dia 0.6) + (via_drill 0.4) + (uvia_dia 0.3) + (uvia_drill 0.1) + (add_net +5V) + (add_net /AVCC) + (add_net /AVCC_ON_2) + (add_net /CH1) + (add_net /CH2) + (add_net /D+) + (add_net /D-) + (add_net /DAC_OUT) + (add_net /DAC_OUT2) + (add_net /DIG_CH1) + (add_net /DIG_CH2) + (add_net /ENABLE_VOUT) + (add_net /OPAMP_VCC) + (add_net /PSU_FEEDBACK) + (add_net /PSU_OUT) + (add_net /PSU_PWM) + (add_net /TO_B0) + (add_net /TO_B1) + (add_net /VCC_3V3) + (add_net /VGND) + (add_net /XCK) + (add_net "Net-(C1-Pad1)") + (add_net "Net-(C1-Pad2)") + (add_net "Net-(C13-Pad1)") + (add_net "Net-(C13-Pad2)") + (add_net "Net-(C14-Pad1)") + (add_net "Net-(C14-Pad2)") + (add_net "Net-(C2-Pad1)") + (add_net "Net-(C2-Pad2)") + (add_net "Net-(D1-Pad2)") + (add_net "Net-(F1-Pad1)") + (add_net "Net-(IC1-Pad10)") + (add_net "Net-(IC1-Pad13)") + (add_net "Net-(IC1-Pad16)") + (add_net "Net-(IC1-Pad20)") + (add_net "Net-(IC1-Pad21)") + (add_net "Net-(IC1-Pad22)") + (add_net "Net-(IC1-Pad25)") + (add_net "Net-(IC1-Pad28)") + (add_net "Net-(IC1-Pad29)") + (add_net "Net-(IC1-Pad3)") + (add_net "Net-(IC1-Pad32)") + (add_net "Net-(IC1-Pad33)") + (add_net "Net-(IC1-Pad34)") + (add_net "Net-(IC1-Pad35)") + (add_net "Net-(IC1-Pad36)") + (add_net "Net-(IC1-Pad37)") + (add_net "Net-(IC1-Pad41)") + (add_net "Net-(IC1-Pad43)") + (add_net "Net-(IC1-Pad9)") + (add_net "Net-(L3-Pad2)") + (add_net "Net-(P10-Pad1)") + (add_net "Net-(P2-Pad4)") + (add_net "Net-(P3-Pad1)") + (add_net "Net-(P3-Pad2)") + (add_net "Net-(P3-Pad3)") + (add_net "Net-(P3-Pad4)") + (add_net "Net-(P8-Pad1)") + (add_net "Net-(P8-Pad2)") + (add_net "Net-(R1-Pad1)") + (add_net "Net-(R10-Pad1)") + (add_net "Net-(R11-Pad2)") + (add_net "Net-(R12-Pad2)") + (add_net "Net-(R13-Pad2)") + (add_net "Net-(R15-Pad1)") + (add_net "Net-(R15-Pad2)") + (add_net "Net-(R17-Pad1)") + (add_net "Net-(R17-Pad2)") + (add_net "Net-(R19-Pad1)") + (add_net "Net-(R2-Pad1)") + (add_net "Net-(R20-Pad1)") + (add_net "Net-(R22-Pad1)") + (add_net "Net-(R23-Pad1)") + ) + + (module Pin_Headers:Pin_Header_Straight_2x02 (layer F.Cu) (tedit 56F331EE) (tstamp 56EB479A) + (at 113.795 124.3076 180) + (descr "Through hole pin header") + (tags "pin header") + (path /56069A87) + (fp_text reference P4 (at 0.03556 -0.00508 180) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value PDI (at 0 -3.1 180) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.3 -1.75) (end 4.3 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 4.3 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 4.3 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start 0 -1.55) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 1.27) (end 1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end 1.27 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 -1.27) (end 3.81 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 -1.27) (end 3.81 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 3.81) (end -1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 3.81) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 180) (size 1.7272 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 71 "Net-(F1-Pad1)")) + (pad 2 thru_hole oval (at 2.54 0 180) (size 1.7272 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 41 "Net-(IC1-Pad34)")) + (pad 3 thru_hole oval (at 0 2.54 180) (size 1.7272 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 9 /VGND)) + (pad 4 thru_hole oval (at 2.54 2.54 180) (size 1.7272 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 42 "Net-(IC1-Pad35)")) + (model Pin_Headers.3dshapes/Pin_Header_Straight_2x02.wrl + (at (xyz 0.05 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x02 locked (layer F.Cu) (tedit 56F331C1) (tstamp 56EB47F4) + (at 103.378 119.38) + (descr "Through hole pin header") + (tags "pin header") + (path /56EA2D2D) + (fp_text reference P9 (at -0.0097 0.07112) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value SCOPE_IN_AC (at 0 -3.1) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start 1.27 1.27) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 1.27) (end -1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 3.81) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 4 "Net-(C2-Pad2)")) + (pad 2 thru_hole oval (at 0 2.54) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 2 "Net-(C1-Pad2)")) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x02.wrl + (at (xyz 0 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Housings_QFP:LQFP-44_10x10mm_Pitch0.8mm (layer F.Cu) (tedit 56F331B7) (tstamp 56EB472D) + (at 102.87 104.14 180) + (descr "LQFP44 (see Appnote_PCB_Guidelines_TRINAMIC_packages.pdf)") + (tags "QFP 0.8") + (path /55CA8F25) + (attr smd) + (fp_text reference IC1 (at -0.14524 0.0635 180) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value ATXMEGA16A4U-A (at 0 7.65 180) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -6.9 -6.9) (end -6.9 6.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start 6.9 -6.9) (end 6.9 6.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start -6.9 -6.9) (end 6.9 -6.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start -6.9 6.9) (end 6.9 6.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start -5.175 -5.175) (end -5.175 -4.505) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.175 -5.175) (end 5.175 -4.505) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.175 5.175) (end 5.175 4.505) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.175 5.175) (end -5.175 4.505) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.175 -5.175) (end -4.505 -5.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.175 5.175) (end -4.505 5.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.175 5.175) (end 4.505 5.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.175 -5.175) (end 4.505 -5.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.175 -4.505) (end -6.65 -4.505) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -5.85 -4 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 16 /PSU_FEEDBACK)) + (pad 2 smd rect (at -5.85 -3.2 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 17 /CH2)) + (pad 3 smd rect (at -5.85 -2.4 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 18 "Net-(IC1-Pad3)")) + (pad 4 smd rect (at -5.85 -1.6 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 19 /TO_B0)) + (pad 5 smd rect (at -5.85 -0.8 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 20 /TO_B1)) + (pad 6 smd rect (at -5.85 0 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 21 /DAC_OUT)) + (pad 7 smd rect (at -5.85 0.8 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 22 /DAC_OUT2)) + (pad 8 smd rect (at -5.85 1.6 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 9 smd rect (at -5.85 2.4 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 23 "Net-(IC1-Pad9)")) + (pad 10 smd rect (at -5.85 3.2 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 24 "Net-(IC1-Pad10)")) + (pad 11 smd rect (at -5.85 4 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 25 /XCK)) + (pad 12 smd rect (at -4 5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 26 /DIG_CH2)) + (pad 13 smd rect (at -3.2 5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 27 "Net-(IC1-Pad13)")) + (pad 14 smd rect (at -2.4 5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 15 smd rect (at -1.6 5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 25 /XCK)) + (pad 16 smd rect (at -0.8 5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 28 "Net-(IC1-Pad16)")) + (pad 17 smd rect (at 0 5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 29 /DIG_CH1)) + (pad 18 smd rect (at 0.8 5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 19 smd rect (at 1.6 5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 6 /VCC_3V3)) + (pad 20 smd rect (at 2.4 5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 30 "Net-(IC1-Pad20)")) + (pad 21 smd rect (at 3.2 5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 31 "Net-(IC1-Pad21)")) + (pad 22 smd rect (at 4 5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 32 "Net-(IC1-Pad22)")) + (pad 23 smd rect (at 5.85 4 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 72 /ENABLE_VOUT)) + (pad 24 smd rect (at 5.85 3.2 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 33 /PSU_PWM)) + (pad 25 smd rect (at 5.85 2.4 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 34 "Net-(IC1-Pad25)")) + (pad 26 smd rect (at 5.85 1.6 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 35 /D-)) + (pad 27 smd rect (at 5.85 0.8 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 36 /D+)) + (pad 28 smd rect (at 5.85 0 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 37 "Net-(IC1-Pad28)")) + (pad 29 smd rect (at 5.85 -0.8 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 38 "Net-(IC1-Pad29)")) + (pad 30 smd rect (at 5.85 -1.6 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 31 smd rect (at 5.85 -2.4 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 6 /VCC_3V3)) + (pad 32 smd rect (at 5.85 -3.2 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 39 "Net-(IC1-Pad32)")) + (pad 33 smd rect (at 5.85 -4 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 40 "Net-(IC1-Pad33)")) + (pad 34 smd rect (at 4 -5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 41 "Net-(IC1-Pad34)")) + (pad 35 smd rect (at 3.2 -5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 42 "Net-(IC1-Pad35)")) + (pad 36 smd rect (at 2.4 -5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 43 "Net-(IC1-Pad36)")) + (pad 37 smd rect (at 1.6 -5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 44 "Net-(IC1-Pad37)")) + (pad 38 smd rect (at 0.8 -5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 39 smd rect (at 0 -5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 7 /AVCC)) + (pad 40 smd rect (at -0.8 -5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 17 /CH2)) + (pad 41 smd rect (at -1.6 -5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 45 "Net-(IC1-Pad41)")) + (pad 42 smd rect (at -2.4 -5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 46 /CH1)) + (pad 43 smd rect (at -3.2 -5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 47 "Net-(IC1-Pad43)")) + (pad 44 smd rect (at -4 -5.85 270) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 48 /AVCC_ON_2)) + (model Housings_QFP.3dshapes/LQFP-44_10x10mm_Pitch0.8mm.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:c_elec_5x5.3 (layer F.Cu) (tedit 55725CA0) (tstamp 56EB4BFB) + (at 112.4488 112.4966 270) + (descr "SMT capacitor, aluminium electrolytic, 5x5.3") + (path /566F5A75) + (attr smd) + (fp_text reference C6 (at -0.02286 -0.12954 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value CP1 (at 0 3.81 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -3.95 -3) (end 3.95 -3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.95 -3) (end 3.95 3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.95 3) (end -3.95 3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.95 3) (end -3.95 -3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.286 -0.635) (end -2.286 0.762) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.159 -0.889) (end -2.159 0.889) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.032 -1.27) (end -2.032 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.905 1.397) (end -1.905 -1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 -1.524) (end -1.778 1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.651 1.651) (end -1.651 -1.651) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.524 -1.778) (end -1.524 1.778) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.667 -2.667) (end 1.905 -2.667) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.905 -2.667) (end 2.667 -1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.667 -1.905) (end 2.667 1.905) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.667 1.905) (end 1.905 2.667) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.905 2.667) (end -2.667 2.667) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.667 2.667) (end -2.667 -2.667) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.159 0) (end 1.397 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.778 -0.381) (end 1.778 0.381) (layer F.SilkS) (width 0.15)) + (fp_circle (center 0 0) (end -2.413 0) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at 2.19964 0 270) (size 2.99974 1.6002) (layers F.Cu F.Paste F.Mask) + (net 6 /VCC_3V3)) + (pad 2 smd rect (at -2.19964 0 270) (size 2.99974 1.6002) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Capacitors_SMD.3dshapes/c_elec_5x5.3.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x02 (layer F.Cu) (tedit 54EA090C) (tstamp 56EB47E3) + (at 113.7061 118.2243 270) + (descr "Through hole pin header") + (tags "pin header") + (path /55D6DB77) + (fp_text reference P8 (at 0.06096 -0.14478 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value DIG_IN (at 0 -3.1 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start 1.27 1.27) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 1.27) (end -1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 3.81) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 270) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 54 "Net-(P8-Pad1)")) + (pad 2 thru_hole oval (at 0 2.54 270) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 55 "Net-(P8-Pad2)")) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x02.wrl + (at (xyz 0 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 56EB45CF) + (at 101.5238 124.4346 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CAB611) + (attr smd) + (fp_text reference C1 (at -0.05126 0.12192 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 1 "Net-(C1-Pad1)")) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 2 "Net-(C1-Pad2)")) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 56EB45DB) + (at 101.8032 116.7892 90) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CAB4DE) + (attr smd) + (fp_text reference C2 (at -0.03348 -0.1651 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 3 "Net-(C2-Pad1)")) + (pad 2 smd rect (at 0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 4 "Net-(C2-Pad2)")) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 56EB45E7) + (at 114.303 108.6866 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CB13E1) + (attr smd) + (fp_text reference C3 (at -0.0508 0.04826 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value C_Small (at 0 1.9 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 5 +5V)) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 56EB45F3) + (at 108.7882 110.3122 180) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CB147C) + (attr smd) + (fp_text reference C4 (at -0.01016 0.04318 180) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value C_Small (at 0 1.9 180) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 180) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 6 /VCC_3V3)) + (pad 2 smd rect (at 0.75 0 180) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 56F331BD) (tstamp 56EB45FF) + (at 104.521 113.6015 90) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55D60181) + (attr smd) + (fp_text reference C5 (at 0.01778 0.08682 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value C_Small (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 7 /AVCC)) + (pad 2 smd rect (at 0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 56F331F5) (tstamp 56EB4633) + (at 94.488 115.316 180) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /56E8E263) + (attr smd) + (fp_text reference C7 (at 0.03002 -0.0889 180) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 180) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 180) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 8 /OPAMP_VCC)) + (pad 2 smd rect (at 0.75 0 180) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 56F335FD) (tstamp 56EB463F) + (at 101.854 111.76 180) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /56AF91A3) + (attr smd) + (fp_text reference C8 (at 0.01224 -0.05334 180) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 180) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 180) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 7 /AVCC)) + (pad 2 smd rect (at 0.75 0 180) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 56EB4673) + (at 86.36 99.695 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /56071A50) + (attr smd) + (fp_text reference C10 (at 0.1143 -0.003 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 5 +5V)) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 56EB467F) + (at 95.0595 106.807 90) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /5608B4BE) + (attr smd) + (fp_text reference C11 (at 0.11176 -0.01478 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 6 /VCC_3V3)) + (pad 2 smd rect (at 0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 56EB468B) + (at 82.423 117.348 90) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CB630B) + (attr smd) + (fp_text reference C13 (at -0.05334 0.0538 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 10 "Net-(C13-Pad1)")) + (pad 2 smd rect (at 0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 11 "Net-(C13-Pad2)")) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 56EB4697) + (at 82.55 124.206 90) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /566DF655) + (attr smd) + (fp_text reference C14 (at 0.02286 0.02078 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 12 "Net-(C14-Pad1)")) + (pad 2 smd rect (at 0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 13 "Net-(C14-Pad2)")) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_ThroughHole:C_Radial_D6.3_L11.2_P2.5 (layer F.Cu) (tedit 56F33237) (tstamp 56EB46C4) + (at 90.17 111.76 180) + (descr "Radial Electrolytic Capacitor, Diameter 6.3mm x Length 11.2mm, Pitch 2.5mm") + (tags "Electrolytic Capacitor") + (path /560735FE) + (fp_text reference C15 (at -0.22652 -0.47498 180) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value CP1 (at 1.25 4.4 180) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start 1.325 -3.149) (end 1.325 3.149) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.465 -3.143) (end 1.465 3.143) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.605 -3.13) (end 1.605 -0.446) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.605 0.446) (end 1.605 3.13) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.745 -3.111) (end 1.745 -0.656) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.745 0.656) (end 1.745 3.111) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.885 -3.085) (end 1.885 -0.789) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.885 0.789) (end 1.885 3.085) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.025 -3.053) (end 2.025 -0.88) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.025 0.88) (end 2.025 3.053) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.165 -3.014) (end 2.165 -0.942) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.165 0.942) (end 2.165 3.014) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.305 -2.968) (end 2.305 -0.981) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.305 0.981) (end 2.305 2.968) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.445 -2.915) (end 2.445 -0.998) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.445 0.998) (end 2.445 2.915) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.585 -2.853) (end 2.585 -0.996) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.585 0.996) (end 2.585 2.853) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.725 -2.783) (end 2.725 -0.974) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.725 0.974) (end 2.725 2.783) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.865 -2.704) (end 2.865 -0.931) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.865 0.931) (end 2.865 2.704) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.005 -2.616) (end 3.005 -0.863) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.005 0.863) (end 3.005 2.616) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.145 -2.516) (end 3.145 -0.764) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.145 0.764) (end 3.145 2.516) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.285 -2.404) (end 3.285 -0.619) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.285 0.619) (end 3.285 2.404) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.425 -2.279) (end 3.425 -0.38) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.425 0.38) (end 3.425 2.279) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.565 -2.136) (end 3.565 2.136) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.705 -1.974) (end 3.705 1.974) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.845 -1.786) (end 3.845 1.786) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.985 -1.563) (end 3.985 1.563) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.125 -1.287) (end 4.125 1.287) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.265 -0.912) (end 4.265 0.912) (layer F.SilkS) (width 0.15)) + (fp_circle (center 2.5 0) (end 2.5 -1) (layer F.SilkS) (width 0.15)) + (fp_circle (center 1.25 0) (end 1.25 -3.1875) (layer F.SilkS) (width 0.15)) + (fp_circle (center 1.25 0) (end 1.25 -3.4) (layer F.CrtYd) (width 0.05)) + (pad 2 thru_hole circle (at 2.5 0 180) (size 1.3 1.3) (drill 0.8) (layers *.Cu *.Mask F.SilkS) + (net 9 /VGND)) + (pad 1 thru_hole rect (at 0 0 180) (size 1.3 1.3) (drill 0.8) (layers *.Cu *.Mask F.SilkS) + (net 14 /PSU_OUT)) + (model Capacitors_ThroughHole.3dshapes/C_Radial_D6.3_L11.2_P2.5.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 56F331F9) (tstamp 56EB46D0) + (at 92.456 114.554 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /5607355F) + (attr smd) + (fp_text reference C16 (at 0.08128 0.0097 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 14 /PSU_OUT)) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Diodes_ThroughHole:Diode_DO-41_SOD81_Horizontal_RM10 (layer F.Cu) (tedit 552FFCCE) (tstamp 56EB46E4) + (at 93.345 106.68 90) + (descr "Diode, DO-41, SOD81, Horizontal, RM 10mm,") + (tags "Diode, DO-41, SOD81, Horizontal, RM 10mm, 1N4007, SB140,") + (path /5606FDB4) + (fp_text reference D1 (at 1.0541 -0.01224 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value D_Schottky (at 4.37134 -3.55854 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start 7.62 -0.00254) (end 8.636 -0.00254) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.794 -0.00254) (end 1.524 -0.00254) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.048 -1.27254) (end 3.048 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.302 -1.27254) (end 3.302 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.556 -1.27254) (end 3.556 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.794 -1.27254) (end 2.794 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 -1.27254) (end 2.54 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 -1.27254) (end 3.81 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 -1.27254) (end 3.81 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.175 -1.27254) (end 3.175 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 1.26746) (end 2.54 -1.27254) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 -1.27254) (end 7.62 -1.27254) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 -1.27254) (end 7.62 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 1.26746) (end 2.54 1.26746) (layer F.SilkS) (width 0.15)) + (pad 2 thru_hole circle (at 10.16 -0.00254 270) (size 1.99898 1.99898) (drill 1.27) (layers *.Cu *.Mask F.SilkS) + (net 15 "Net-(D1-Pad2)")) + (pad 1 thru_hole rect (at 0 -0.00254 270) (size 1.99898 1.99898) (drill 1.00076) (layers *.Cu *.Mask F.SilkS) + (net 14 /PSU_OUT)) + ) + + (module Inductors:INDUCTOR_V (layer F.Cu) (tedit 0) (tstamp 56EB4734) + (at 82.7532 98.5139 270) + (descr "Inductor (vertical)") + (tags INDUCTOR) + (path /5606EE9E) + (fp_text reference L1 (at -0.16764 0.04572 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value INDUCTOR (at 0.09906 -1.99898 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_circle (center 0 0) (end 3.81 0) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -2.54 0 270) (size 1.905 1.905) (drill 0.8128) (layers *.Cu *.Mask F.SilkS) + (net 15 "Net-(D1-Pad2)")) + (pad 2 thru_hole circle (at 2.54 0 270) (size 1.905 1.905) (drill 0.8128) (layers *.Cu *.Mask F.SilkS) + (net 5 +5V)) + (model Inductors.3dshapes/INDUCTOR_V.wrl + (at (xyz 0 0 0)) + (scale (xyz 2 2 2)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x02 locked (layer F.Cu) (tedit 54EA090C) (tstamp 56EB475D) + (at 105.918 124.46 270) + (descr "Through hole pin header") + (tags "pin header") + (path /56EA2C80) + (fp_text reference P1 (at -0.00254 -0.01824 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value SCOPE_IN_CH1 (at 0 -3.1 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start 1.27 1.27) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 1.27) (end -1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 3.81) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 270) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 1 "Net-(C1-Pad1)")) + (pad 2 thru_hole oval (at 0 2.54 270) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 1 "Net-(C1-Pad1)")) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x02.wrl + (at (xyz 0 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x04 (layer F.Cu) (tedit 0) (tstamp 56EB4786) + (at 80.4448 113.157 180) + (descr "Through hole pin header") + (tags "pin header") + (path /55CBF4D5) + (fp_text reference P3 (at -0.03302 -0.08128 180) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value DIG_OUT (at 0 -3.1 180) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 9.4) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 1.27) (end -1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end 1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 8.89) (end 1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 180) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 50 "Net-(P3-Pad1)")) + (pad 2 thru_hole oval (at 0 2.54 180) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 51 "Net-(P3-Pad2)")) + (pad 3 thru_hole oval (at 0 5.08 180) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 52 "Net-(P3-Pad3)")) + (pad 4 thru_hole oval (at 0 7.62 180) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 53 "Net-(P3-Pad4)")) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x04.wrl + (at (xyz 0 -0.15 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x02 locked (layer F.Cu) (tedit 54EA090C) (tstamp 56EB47AB) + (at 105.918 116.84 270) + (descr "Through hole pin header") + (tags "pin header") + (path /56EA3310) + (fp_text reference P5 (at 0.06096 -0.1427 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value SCOPE_IN_CH2 (at 0 -3.1 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start 1.27 1.27) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 1.27) (end -1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 3.81) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 270) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 3 "Net-(C2-Pad1)")) + (pad 2 thru_hole oval (at 0 2.54 270) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 3 "Net-(C2-Pad1)")) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x02.wrl + (at (xyz 0 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x04 (layer F.Cu) (tedit 0) (tstamp 56EB47BE) + (at 80.4448 115.697) + (descr "Through hole pin header") + (tags "pin header") + (path /566DF832) + (fp_text reference P6 (at 0.07112 0.04826) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value DAC_OUT (at 0 -3.1) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 9.4) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 1.27) (end -1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end 1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 8.89) (end 1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 11 "Net-(C13-Pad2)")) + (pad 2 thru_hole oval (at 0 2.54) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 10 "Net-(C13-Pad1)")) + (pad 3 thru_hole oval (at 0 5.08) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 13 "Net-(C14-Pad2)")) + (pad 4 thru_hole oval (at 0 7.62) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 12 "Net-(C14-Pad1)")) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x04.wrl + (at (xyz 0 -0.15 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 56EB480C) + (at 99.06 121.92 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAAB95) + (attr smd) + (fp_text reference R1 (at 0.04572 0.08428 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 56 "Net-(R1-Pad1)")) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 1 "Net-(C1-Pad1)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F331DA) (tstamp 56EB4818) + (at 99.06 119.3165 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAAD4C) + (attr smd) + (fp_text reference R2 (at -0.03302 -0.07666 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 57 "Net-(R2-Pad1)")) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 3 "Net-(C2-Pad1)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F331E1) (tstamp 56EB4824) + (at 100.6475 121.92 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAABF4) + (attr smd) + (fp_text reference R3 (at 0.12954 0.08174 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 56 "Net-(R1-Pad1)")) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 48 /AVCC_ON_2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F331DB) (tstamp 56EB4830) + (at 100.6475 119.3165 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAAD11) + (attr smd) + (fp_text reference R4 (at 0.1397 0.05888 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 48 /AVCC_ON_2)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 57 "Net-(R2-Pad1)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 56EB483C) + (at 106.426 114.3) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAAC5F) + (attr smd) + (fp_text reference R5 (at -0.0605 -0.00762) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 7 /AVCC)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 48 /AVCC_ON_2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 56EB4848) + (at 106.426 112.903) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAACD2) + (attr smd) + (fp_text reference R6 (at 0.0538 0.01524) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 48 /AVCC_ON_2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 56EB4854) + (at 82.55 106.68 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBCDA5) + (attr smd) + (fp_text reference R7 (at -0.12192 -0.02586 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 58 "Net-(R11-Pad2)")) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 53 "Net-(P3-Pad4)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 56EB4860) + (at 82.55 109.22 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE401) + (attr smd) + (fp_text reference R8 (at 0.00508 -0.07158 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 59 "Net-(R12-Pad2)")) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 52 "Net-(P3-Pad3)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 56EB486C) + (at 82.55 111.76 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE16B) + (attr smd) + (fp_text reference R9 (at 0.00508 -0.02332 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 60 "Net-(R13-Pad2)")) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 51 "Net-(P3-Pad2)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 56EB4878) + (at 82.55 114.3 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE2C7) + (attr smd) + (fp_text reference R10 (at 0.01016 -0.06904 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 61 "Net-(R10-Pad1)")) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 50 "Net-(P3-Pad1)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 56EB4884) + (at 84.328 106.68 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBCD2A) + (attr smd) + (fp_text reference R11 (at 0.17018 0.04618 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 37 "Net-(IC1-Pad28)")) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 58 "Net-(R11-Pad2)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 56EB4890) + (at 84.328 109.22 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE362) + (attr smd) + (fp_text reference R12 (at 0.06604 0.04618 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 38 "Net-(IC1-Pad29)")) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 59 "Net-(R12-Pad2)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 56EB489C) + (at 84.328 111.76 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE0F4) + (attr smd) + (fp_text reference R13 (at 0.01778 0.00046 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 39 "Net-(IC1-Pad32)")) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 60 "Net-(R13-Pad2)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 56EB48A8) + (at 84.328 114.3 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE21C) + (attr smd) + (fp_text reference R14 (at -0.1651 0.02586 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 40 "Net-(IC1-Pad33)")) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 61 "Net-(R10-Pad1)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F33220) (tstamp 56EB48B4) + (at 89.3953 124.3203 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56B0C779) + (attr smd) + (fp_text reference R15 (at -0.00762 -0.04364 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 62 "Net-(R15-Pad1)")) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 63 "Net-(R15-Pad2)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F3321C) (tstamp 56EB48C0) + (at 87.8713 124.3203 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56B0C86E) + (attr smd) + (fp_text reference R16 (at -0.00762 -0.03856 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 62 "Net-(R15-Pad1)")) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 63 "Net-(R15-Pad2)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F33257) (tstamp 56EB48CC) + (at 89.281 117.221 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56AFE83E) + (attr smd) + (fp_text reference R17 (at -0.01778 0.0284 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 64 "Net-(R17-Pad1)")) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 65 "Net-(R17-Pad2)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F3325E) (tstamp 56EB48D8) + (at 87.63 117.221 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56AFE8F3) + (attr smd) + (fp_text reference R18 (at -0.05842 0.03856 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 64 "Net-(R17-Pad1)")) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 65 "Net-(R17-Pad2)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F33244) (tstamp 56EB48E4) + (at 87.122 119.634) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56AECD86) + (attr smd) + (fp_text reference R19 (at 0.11984 -0.01524) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 66 "Net-(R19-Pad1)")) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 64 "Net-(R17-Pad1)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F3322A) (tstamp 56EB48F0) + (at 87.122 121.92) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56B0C682) + (attr smd) + (fp_text reference R20 (at 0.00808 0.06096) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 67 "Net-(R20-Pad1)")) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 62 "Net-(R15-Pad1)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F331E9) (tstamp 56EB48FC) + (at 99.568 124.079) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56E9851A) + (attr smd) + (fp_text reference R21 (at 0.003 0.03556) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 46 /CH1)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F33231) (tstamp 56EB4908) + (at 84.455 117.221 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CB4680) + (attr smd) + (fp_text reference R22 (at 0.00508 0.03856 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 68 "Net-(R22-Pad1)")) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 66 "Net-(R19-Pad1)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F33215) (tstamp 56EB4914) + (at 84.709 124.333 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /566DE721) + (attr smd) + (fp_text reference R23 (at 0.04064 -0.0411 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 69 "Net-(R23-Pad1)")) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 67 "Net-(R20-Pad1)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F3324C) (tstamp 56EB4920) + (at 84.074 119.634) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CB9020) + (attr smd) + (fp_text reference R24 (at 0.07666 0.04064) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 11 "Net-(C13-Pad2)")) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 68 "Net-(R22-Pad1)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F3322D) (tstamp 56EB492C) + (at 84.074 121.92) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /566DE7E8) + (attr smd) + (fp_text reference R25 (at 0.05126 0.02794) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 13 "Net-(C14-Pad2)")) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 69 "Net-(R23-Pad1)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 56EB4938) + (at 84.582 102.9462 180) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /566E5C29) + (attr smd) + (fp_text reference R26 (at -0.0284 -0.02794 180) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 180) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 180) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 14 /PSU_OUT)) + (pad 2 smd rect (at 0.75 0 180) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 16 /PSU_FEEDBACK)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 56EB4944) + (at 84.582 104.5464) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /566E5CBE) + (attr smd) + (fp_text reference R27 (at -0.02748 0.03048) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 16 /PSU_FEEDBACK)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F331D7) (tstamp 56EB4950) + (at 99.568 116.84 180) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56E985EF) + (attr smd) + (fp_text reference R28 (at -0.05634 -0.0508 180) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 180) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 180) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 2 smd rect (at 0.75 0 180) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 17 /CH2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F3325B) (tstamp 56EB495C) + (at 85.979 117.221 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56E9888A) + (attr smd) + (fp_text reference R29 (at 0.03302 -0.0538 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 66 "Net-(R19-Pad1)")) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 56F33218) (tstamp 56EB4968) + (at 86.233 124.333 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56E98921) + (attr smd) + (fp_text reference R30 (at 0.06096 -0.05634 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 67 "Net-(R20-Pad1)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module SMD:SOT-23-3 (layer F.Cu) (tedit 5508E933) (tstamp 56EB4974) + (at 112.0648 106.807 90) + (path /55CA99FA) + (fp_text reference U1 (at -0.07112 0.03856 180) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value 78L05 (at -2.2 0 180) (layer F.Fab) hide + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_circle (center 1 -0.4) (end 1.1 -0.5) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.5 -0.8) (end -1.5 0.8) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.5 0.8) (end 1.5 0.8) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.5 0.8) (end 1.5 -0.8) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.5 -0.8) (end -1.5 -0.8) (layer F.SilkS) (width 0.15)) + (pad 3 smd rect (at 0 1.4 90) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 5 +5V)) + (pad 2 smd rect (at -0.95 -1.4 90) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 6 /VCC_3V3)) + (pad 1 smd rect (at 0.95 -1.4 90) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model 3D/SMD/SOT-23-3.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.3937 0.3937 0.3937)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm (layer F.Cu) (tedit 56F33225) (tstamp 56EB4991) + (at 94.5134 120.6754 180) + (descr "14-Lead Plastic Small Outline (SL) - Narrow, 3.90 mm Body [SOIC] (see Microchip Packaging Specification 00000049BS.pdf)") + (tags "SOIC 1.27") + (path /55CA87E2) + (attr smd) + (fp_text reference U2 (at 0.01986 0 180) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value LM324 (at 0 5.375 180) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -3.7 -4.65) (end -3.7 4.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.7 -4.65) (end 3.7 4.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.7 -4.65) (end 3.7 -4.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.7 4.65) (end 3.7 4.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.075 -4.45) (end -2.075 -4.335) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.075 -4.45) (end 2.075 -4.335) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.075 4.45) (end 2.075 4.335) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.075 4.45) (end -2.075 4.335) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.075 -4.45) (end 2.075 -4.45) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.075 4.45) (end 2.075 4.45) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.075 -4.335) (end -3.45 -4.335) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -2.7 -3.81 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 46 /CH1)) + (pad 2 smd rect (at -2.7 -2.54 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 46 /CH1)) + (pad 3 smd rect (at -2.7 -1.27 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 56 "Net-(R1-Pad1)")) + (pad 4 smd rect (at -2.7 0 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 8 /OPAMP_VCC)) + (pad 5 smd rect (at -2.7 1.27 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 57 "Net-(R2-Pad1)")) + (pad 6 smd rect (at -2.7 2.54 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 17 /CH2)) + (pad 7 smd rect (at -2.7 3.81 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 17 /CH2)) + (pad 8 smd rect (at 2.7 3.81 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 66 "Net-(R19-Pad1)")) + (pad 9 smd rect (at 2.7 2.54 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 64 "Net-(R17-Pad1)")) + (pad 10 smd rect (at 2.7 1.27 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 21 /DAC_OUT)) + (pad 11 smd rect (at 2.7 0 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 12 smd rect (at 2.7 -1.27 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 22 /DAC_OUT2)) + (pad 13 smd rect (at 2.7 -2.54 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 62 "Net-(R15-Pad1)")) + (pad 14 smd rect (at 2.7 -3.81 180) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 67 "Net-(R20-Pad1)")) + (model Housings_SOIC.3dshapes/SOIC-14_3.9x8.7mm_Pitch1.27mm.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module TO_SOT_Packages_SMD:SOT-363 (layer F.Cu) (tedit 56735562) (tstamp 56EB499F) + (at 89.5604 120.7262 270) + (descr SOT353) + (path /56B012DD) + (attr smd) + (fp_text reference U3 (at 0.09906 0 360) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value DMN63D8LDW (at 0.09906 0 360) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start 0.635 1.016) (end 0.635 -1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.635 -1.016) (end -0.635 -1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.635 -1.016) (end -0.635 1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.635 1.016) (end 0.635 1.016) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.016 -0.635 270) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 3 smd rect (at -1.016 0.635 270) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 65 "Net-(R17-Pad2)")) + (pad 6 smd rect (at 1.016 -0.635 270) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 63 "Net-(R15-Pad2)")) + (pad 2 smd rect (at -1.016 0 270) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 19 /TO_B0)) + (pad 4 smd rect (at 1.016 0.635 270) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 5 smd rect (at 1.016 0 270) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 20 /TO_B1)) + (model TO_SOT_Packages_SMD.3dshapes/SOT-353.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.07000000000000001 0.09 0.08)) + (rotate (xyz 0 0 90)) + ) + ) + + (module TO_SOT_Packages_SMD:SOT-363 (layer F.Cu) (tedit 56735562) (tstamp 56EB49AD) + (at 108.7755 97.4725 90) + (descr SOT353) + (path /55D6ACFD) + (attr smd) + (fp_text reference U4 (at -0.03556 -0.01478 180) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value DMN63D8LDW (at 0.09906 0 180) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start 0.635 1.016) (end 0.635 -1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.635 -1.016) (end -0.635 -1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.635 -1.016) (end -0.635 1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.635 1.016) (end 0.635 1.016) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.016 -0.635 90) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 3 smd rect (at -1.016 0.635 90) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 26 /DIG_CH2)) + (pad 6 smd rect (at 1.016 -0.635 90) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 29 /DIG_CH1)) + (pad 2 smd rect (at -1.016 0 90) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 55 "Net-(P8-Pad2)")) + (pad 4 smd rect (at 1.016 0.635 90) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 5 smd rect (at 1.016 0 90) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 54 "Net-(P8-Pad1)")) + (model TO_SOT_Packages_SMD.3dshapes/SOT-353.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.07000000000000001 0.09 0.08)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Capacitors_SMD:c_elec_4x5.3 (layer F.Cu) (tedit 556FDE77) (tstamp 56EB4C01) + (at 89.535 99.06 90) + (descr "SMT capacitor, aluminium electrolytic, 4x5.3") + (path /560719D9) + (attr smd) + (fp_text reference C9 (at -0.00508 0.0665 90) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value CP1 (at 0 3.175 90) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start -3.35 -2.65) (end 3.35 -2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.35 -2.65) (end 3.35 2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.35 2.65) (end -3.35 2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.35 2.65) (end -3.35 -2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.651 0) (end 0.889 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 -0.381) (end 1.27 0.381) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 2.286) (end -2.286 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.286 -1.524) (end 2.286 1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 2.286) (end 2.286 1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 -2.286) (end -2.286 -2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 -2.286) (end 2.286 -1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.032 0.127) (end -2.032 -0.127) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.905 -0.635) (end -1.905 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 0.889) (end -1.778 -0.889) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.651 1.143) (end -1.651 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.524 -1.27) (end -1.524 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.397 1.397) (end -1.397 -1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 -1.524) (end -1.27 1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.143 -1.651) (end -1.143 1.651) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.286 -2.286) (end -2.286 2.286) (layer F.SilkS) (width 0.15)) + (fp_circle (center 0 0) (end -2.032 0) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at 1.80086 0 90) (size 2.60096 1.6002) (layers F.Cu F.Paste F.Mask) + (net 5 +5V)) + (pad 2 smd rect (at -1.80086 0 90) (size 2.60096 1.6002) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Capacitors_SMD.3dshapes/c_elec_4x5.3.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x02 (layer F.Cu) (tedit 54EA090C) (tstamp 56F32A3D) + (at 90.6048 106.807 270) + (descr "Through hole pin header") + (tags "pin header") + (path /56F2A93D) + (fp_text reference P7 (at -0.01524 -0.15748 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value CONN_01X02 (at 0 -3.1 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start 1.27 1.27) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 1.27) (end -1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 3.81) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 270) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 14 /PSU_OUT)) + (pad 2 thru_hole oval (at 0 2.54 270) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 73 "Net-(P10-Pad1)")) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x02.wrl + (at (xyz 0 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x02 (layer F.Cu) (tedit 54EA090C) (tstamp 56F32A4E) + (at 90.6048 104.267 270) + (descr "Through hole pin header") + (tags "pin header") + (path /56F2A840) + (fp_text reference P10 (at -0.1524 -0.18288 270) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_text value CONN_01X02 (at 0 -3.1 270) (layer F.Fab) + (effects (font (size 0.8 0.8) (thickness 0.15))) + ) + (fp_line (start 1.27 1.27) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 1.27) (end -1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 3.81) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 270) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 73 "Net-(P10-Pad1)")) + (pad 2 thru_hole oval (at 0 2.54 270) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 73 "Net-(P10-Pad1)")) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x02.wrl + (at (xyz 0 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x02 (layer F.Cu) (tedit 580F14F6) (tstamp 57319373) + (at 99.3394 95.9358 90) + (descr "Through hole pin header") + (tags "pin header") + (fp_text reference REF** (at 1.8288 1.4986 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Pin_Header_Straight_1x02 (at 0 -3.1 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 1.27 1.27) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 1.27) (end -1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 3.81) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 90) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (pad 2 thru_hole oval (at 0 2.54 90) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x02.wrl + (at (xyz 0 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 580F14E8) (tstamp 575636C7) + (at 108.4961 116.0399) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /575646EC) + (attr smd) + (fp_text reference C12 (at -0.0381 -0.0889) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 7 /AVCC)) + (pad 2 smd rect (at 0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 580F14E7) (tstamp 575636CD) + (at 108.4961 117.1956) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /57564635) + (attr smd) + (fp_text reference C17 (at -0.0381 -0.0381) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 7 /AVCC)) + (pad 2 smd rect (at 0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 580F14E5) (tstamp 575636D3) + (at 108.5088 118.3513) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /57564580) + (attr smd) + (fp_text reference C18 (at 0.0127 -0.0508) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 7 /AVCC)) + (pad 2 smd rect (at 0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_1210 (layer F.Cu) (tedit 580F14E1) (tstamp 575636DA) + (at 107.6325 120.777) + (descr "Capacitor SMD 1210, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 1210") + (path /55D739F3) + (attr smd) + (fp_text reference F1 (at 0.254 0.1905) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value F_Small (at 0 2.7) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.3 -1.6) (end 2.3 -1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.3 1.6) (end 2.3 1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.3 -1.6) (end -2.3 1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start 2.3 -1.6) (end 2.3 1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1 -1.475) (end -1 -1.475) (layer F.SilkS) (width 0.15)) + (fp_line (start -1 1.475) (end 1 1.475) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.5 0) (size 1 2.5) (layers F.Cu F.Paste F.Mask) + (net 71 "Net-(F1-Pad1)")) + (pad 2 smd rect (at 1.5 0) (size 1 2.5) (layers F.Cu F.Paste F.Mask) + (net 6 /VCC_3V3)) + (model Capacitors_SMD.3dshapes/C_1210.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Connect:USB_Micro-B_WIDE (layer F.Cu) (tedit 56F1EFCA) (tstamp 575636DF) + (at 112.903 100.6094 90) + (descr "Micro USB Type B Receptacle") + (tags "USB USB_B USB_micro USB_OTG") + (path /55CA90D2) + (attr smd) + (fp_text reference P2 (at 0 -3.45 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value USB_OTG (at 0 4.8 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -4.6 -2.8) (end 4.6 -2.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.6 -2.8) (end 4.6 4.05) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.6 4.05) (end -4.6 4.05) (layer F.CrtYd) (width 0.05)) + (fp_line (start -4.6 4.05) (end -4.6 -2.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -4.3509 3.81746) (end 4.3491 3.81746) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.3509 -2.58754) (end 4.3491 -2.58754) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.3491 -2.58754) (end 4.3491 3.81746) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.3491 2.58746) (end -4.3509 2.58746) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.3509 3.81746) (end -4.3509 -2.58754) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.3009 -1.56254 180) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 5 +5V)) + (pad 2 smd rect (at -0.6509 -1.56254 180) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 35 /D-)) + (pad 3 smd rect (at -0.0009 -1.56254 180) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 36 /D+)) + (pad 4 smd rect (at 0.6491 -1.56254 180) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 49 "Net-(P2-Pad4)")) + (pad 5 smd rect (at 1.2991 -1.56254 180) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 6 thru_hole oval (at -2.5009 -1.56254 180) (size 0.95 1.4) (drill oval 0.55 1) (layers *.Cu *.Mask F.SilkS) + (net 9 /VGND)) + (pad 6 thru_hole oval (at 2.4991 -1.56254 180) (size 0.95 1.4) (drill oval 0.55 1) (layers *.Cu *.Mask F.SilkS) + (net 9 /VGND)) + (pad 6 thru_hole oval (at -3.5009 1.13746 180) (size 1.55 1.2) (drill oval 1.15 0.7) (layers *.Cu *.Mask F.SilkS) + (net 9 /VGND)) + (pad 6 thru_hole oval (at 3.4991 1.13746 180) (size 1.55 1.2) (drill oval 1.15 0.7) (layers *.Cu *.Mask F.SilkS) + (net 9 /VGND)) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 580F14EE) (tstamp 58043F7B) + (at 93.98 98.933 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /5804605C) + (attr smd) + (fp_text reference R31 (at -0.1905 0.0635 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 33 /PSU_PWM)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module TO_SOT_Packages_SMD:SOT-363 (layer F.Cu) (tedit 580F14F1) (tstamp 58043F85) + (at 96.3295 98.425) + (descr SOT353) + (path /58057F8D) + (attr smd) + (fp_text reference U5 (at 0.127 0.0635 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DMN63D8LDW (at 0.09906 0 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 0.635 1.016) (end 0.635 -1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.635 -1.016) (end -0.635 -1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.635 -1.016) (end -0.635 1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.635 1.016) (end 0.635 1.016) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.016 -0.635) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 3 smd rect (at -1.016 0.635) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 73 "Net-(P10-Pad1)")) + (pad 6 smd rect (at 1.016 -0.635) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 15 "Net-(D1-Pad2)")) + (pad 2 smd rect (at -1.016 0) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 33 /PSU_PWM)) + (pad 4 smd rect (at 1.016 0.635) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 9 /VGND)) + (pad 5 smd rect (at 1.016 0) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 72 /ENABLE_VOUT)) + (model TO_SOT_Packages_SMD.3dshapes/SOT-353.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.07000000000000001 0.09 0.08)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Resistors_SMD:R_1206 (layer F.Cu) (tedit 580F155D) (tstamp 5804467C) + (at 98.171 112.649) + (descr "Resistor SMD 1206, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 1206") + (path /56E88440) + (attr smd) + (fp_text reference L2 (at 0 0.0635) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value INDUCTOR (at 0 2.3) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.2 -1.2) (end 2.2 -1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 -1.2) (end -2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 2.2 -1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1 1.075) (end -1 1.075) (layer F.SilkS) (width 0.15)) + (fp_line (start -1 -1.075) (end 1 -1.075) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.45 0) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 6 /VCC_3V3)) + (pad 2 smd rect (at 1.45 0) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 7 /AVCC)) + (model Resistors_SMD.3dshapes/R_1206.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_1206 (layer F.Cu) (tedit 580F1562) (tstamp 58044687) + (at 94.5926 112.5982 90) + (descr "Resistor SMD 1206, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 1206") + (path /56E8DA35) + (attr smd) + (fp_text reference L3 (at -0.0508 -0.1046 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value INDUCTOR (at 0 2.3 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.2 -1.2) (end 2.2 -1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 -1.2) (end -2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 2.2 -1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1 1.075) (end -1 1.075) (layer F.SilkS) (width 0.15)) + (fp_line (start -1 -1.075) (end 1 -1.075) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.45 0 90) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 8 /OPAMP_VCC)) + (pad 2 smd rect (at 1.45 0 90) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 70 "Net-(L3-Pad2)")) + (model Resistors_SMD.3dshapes/R_1206.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_1206 (layer F.Cu) (tedit 5415CFA7) (tstamp 58044692) + (at 93.7036 103.4034 270) + (descr "Resistor SMD 1206, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 1206") + (path /573254B0) + (attr smd) + (fp_text reference L4 (at 0 -2.3 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value INDUCTOR (at 0 2.3 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.2 -1.2) (end 2.2 -1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 -1.2) (end -2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 2.2 -1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1 1.075) (end -1 1.075) (layer F.SilkS) (width 0.15)) + (fp_line (start -1 -1.075) (end 1 -1.075) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.45 0 270) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 70 "Net-(L3-Pad2)")) + (pad 2 smd rect (at 1.45 0 270) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 14 /PSU_OUT)) + (model Resistors_SMD.3dshapes/R_1206.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (gr_text "EspoTek Labrador v7b" (at 109.8296 95.1992) (layer F.SilkS) + (effects (font (size 0.8 0.8) (thickness 0.2))) + ) + (gr_line (start 78.7908 126.0983) (end 78.7908 125.9078) (angle 90) (layer Edge.Cuts) (width 0.1)) + (gr_line (start 116.5098 126.0983) (end 78.7908 126.0983) (angle 90) (layer Edge.Cuts) (width 0.1)) + (gr_line (start 116.5098 94.5261) (end 116.5098 126.0983) (angle 90) (layer Edge.Cuts) (width 0.1)) + (gr_line (start 78.7654 94.5261) (end 116.5098 94.5261) (angle 90) (layer Edge.Cuts) (width 0.1)) + (gr_line (start 78.7908 94.6912) (end 78.7908 94.5388) (angle 90) (layer Edge.Cuts) (width 0.1)) + (gr_line (start 78.7908 95.1992) (end 78.7908 94.615) (angle 90) (layer Edge.Cuts) (width 0.1)) + (gr_line (start 78.78618 126.09068) (end 78.78618 95.20174) (angle 90) (layer Edge.Cuts) (width 0.1)) + + (segment (start 101.5238 123.6846) (end 101.842 123.6846) (width 0.4) (layer F.Cu) (net 1)) + (segment (start 101.842 123.6846) (end 102.2223 123.3043) (width 0.4) (layer F.Cu) (net 1) (tstamp 57563749)) + (segment (start 99.06 121.17) (end 99.06 121.412) (width 0.25) (layer F.Cu) (net 1)) + (segment (start 99.06 121.412) (end 99.568 121.92) (width 0.25) (layer F.Cu) (net 1) (tstamp 56EB5D83)) + (segment (start 99.568 121.92) (end 101.473 121.92) (width 0.25) (layer F.Cu) (net 1) (tstamp 56EB5D84)) + (segment (start 101.473 121.92) (end 101.854 122.301) (width 0.25) (layer F.Cu) (net 1) (tstamp 56EB5D85)) + (segment (start 101.854 122.301) (end 101.854 122.936) (width 0.25) (layer F.Cu) (net 1) (tstamp 56EB5D86)) + (segment (start 101.854 122.936) (end 102.2223 123.3043) (width 0.25) (layer F.Cu) (net 1) (tstamp 56EB5D87)) + (segment (start 102.2223 123.3043) (end 103.378 124.46) (width 0.25) (layer F.Cu) (net 1) (tstamp 5756374C)) + (segment (start 105.918 124.46) (end 103.378 124.46) (width 0.635) (layer F.Cu) (net 1)) + (segment (start 101.5238 125.1846) (end 101.842 125.1846) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 101.842 125.1846) (end 102.489 125.8316) (width 0.25) (layer F.Cu) (net 2) (tstamp 57563753)) + (segment (start 102.489 125.8316) (end 107.1372 125.8316) (width 0.25) (layer F.Cu) (net 2) (tstamp 57563754)) + (segment (start 107.1372 125.8316) (end 107.5182 125.4506) (width 0.25) (layer F.Cu) (net 2) (tstamp 57563755)) + (segment (start 107.5182 125.4506) (end 107.5182 123.2662) (width 0.25) (layer F.Cu) (net 2) (tstamp 57563756)) + (segment (start 107.5182 123.2662) (end 107.1118 122.8598) (width 0.25) (layer F.Cu) (net 2) (tstamp 57563757)) + (segment (start 107.1118 122.8598) (end 104.3178 122.8598) (width 0.25) (layer F.Cu) (net 2) (tstamp 57563758)) + (segment (start 104.3178 122.8598) (end 103.378 121.92) (width 0.25) (layer F.Cu) (net 2) (tstamp 57563759)) + (segment (start 99.06 120.0665) (end 99.1355 120.0665) (width 0.25) (layer F.Cu) (net 3)) + (segment (start 99.1355 120.0665) (end 99.822 119.38) (width 0.25) (layer F.Cu) (net 3) (tstamp 56EB5D8A)) + (segment (start 99.822 119.38) (end 101.346 119.38) (width 0.25) (layer F.Cu) (net 3) (tstamp 56EB5D8B)) + (segment (start 101.346 119.38) (end 101.981 118.745) (width 0.25) (layer F.Cu) (net 3) (tstamp 56EB5D8C)) + (segment (start 101.981 118.745) (end 101.981 117.221) (width 0.25) (layer F.Cu) (net 3) (tstamp 56EB5D8D)) + (segment (start 101.981 117.221) (end 102.362 116.84) (width 0.25) (layer F.Cu) (net 3) (tstamp 56EB5D8E)) + (segment (start 102.362 116.84) (end 103.378 116.84) (width 0.25) (layer F.Cu) (net 3) (tstamp 56EB5D8F)) + (segment (start 105.918 116.84) (end 103.378 116.84) (width 0.635) (layer F.Cu) (net 3)) + (segment (start 101.8032 116.0392) (end 101.3834 116.0392) (width 0.25) (layer F.Cu) (net 4)) + (segment (start 101.854 120.904) (end 103.378 119.38) (width 0.25) (layer B.Cu) (net 4) (tstamp 57563737)) + (segment (start 101.219 120.904) (end 101.854 120.904) (width 0.25) (layer B.Cu) (net 4) (tstamp 57563736)) + (segment (start 100.5586 120.2436) (end 101.219 120.904) (width 0.25) (layer B.Cu) (net 4) (tstamp 57563735)) + (segment (start 100.5586 116.0272) (end 100.5586 120.2436) (width 0.25) (layer B.Cu) (net 4) (tstamp 57563734)) + (segment (start 100.965 115.6208) (end 100.5586 116.0272) (width 0.25) (layer B.Cu) (net 4) (tstamp 57563733)) + (via (at 100.965 115.6208) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 4)) + (segment (start 101.3834 116.0392) (end 100.965 115.6208) (width 0.25) (layer F.Cu) (net 4) (tstamp 57563731)) + (segment (start 82.7532 101.0539) (end 82.8167 101.0539) (width 1.27) (layer F.Cu) (net 5)) + (segment (start 82.8167 101.0539) (end 84.895602 98.974998) (width 1.27) (layer F.Cu) (net 5) (tstamp 575639BE)) + (segment (start 84.895602 98.974998) (end 86.36 98.974998) (width 1.27) (layer F.Cu) (net 5) (tstamp 575639BF)) + (segment (start 86.36 98.974998) (end 86.36 98.945) (width 1.27) (layer F.Cu) (net 5) (tstamp 575639C1)) + (segment (start 114.303 107.9366) (end 114.303 107.6452) (width 0.25) (layer F.Cu) (net 5)) + (segment (start 114.303 107.6452) (end 113.4648 106.807) (width 0.25) (layer F.Cu) (net 5) (tstamp 57318D88)) + (segment (start 113.4648 105.7656) (end 113.4648 106.807) (width 0.4) (layer F.Cu) (net 5) (tstamp 56F1DCE2)) + (segment (start 112.5305 101.9103) (end 112.6774 102.0572) (width 0.4) (layer F.Cu) (net 5) (tstamp 56F1DCDF)) + (segment (start 112.6774 102.0572) (end 112.6774 104.9782) (width 0.4) (layer F.Cu) (net 5) (tstamp 56F1DCE0)) + (segment (start 112.6774 104.9782) (end 113.4648 105.7656) (width 0.4) (layer F.Cu) (net 5) (tstamp 56F1DCE1)) + (segment (start 89.535 97.25914) (end 90.28984 97.25914) (width 0.635) (layer F.Cu) (net 5)) + (segment (start 90.28984 97.25914) (end 91.3287 98.298) (width 1.27) (layer F.Cu) (net 5) (tstamp 56F1DDCD)) + (segment (start 112.5432 101.9103) (end 112.5305 101.9103) (width 0.635) (layer F.Cu) (net 5) (tstamp 56F1DDD5)) + (segment (start 112.5885 101.9556) (end 112.5432 101.9103) (width 0.635) (layer F.Cu) (net 5) (tstamp 56F1DDD4)) + (via (at 112.5885 101.9556) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 5)) + (segment (start 112.5885 101.5238) (end 112.5885 101.9556) (width 0.635) (layer B.Cu) (net 5) (tstamp 56F1DDD2)) + (segment (start 109.4389 98.3742) (end 112.5885 101.5238) (width 0.635) (layer B.Cu) (net 5) (tstamp 56F1DDD1)) + (segment (start 91.4049 98.3742) (end 109.4389 98.3742) (width 1.27) (layer B.Cu) (net 5) (tstamp 56F1DDD0)) + (segment (start 91.3287 98.298) (end 91.4049 98.3742) (width 0.635) (layer B.Cu) (net 5) (tstamp 56F1DDCF)) + (via (at 91.3287 98.298) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 5)) + (segment (start 111.34046 101.9103) (end 112.5305 101.9103) (width 0.4) (layer F.Cu) (net 5)) + (segment (start 86.36 98.945) (end 87.84914 98.945) (width 1.27) (layer F.Cu) (net 5)) + (segment (start 87.84914 98.945) (end 89.535 97.25914) (width 1.27) (layer F.Cu) (net 5) (tstamp 56EB542D)) + (segment (start 115.6335 115.57) (end 115.6335 122.1105) (width 1.27) (layer F.Cu) (net 6) (tstamp 58044263)) + (segment (start 114.75974 114.69624) (end 115.6335 115.57) (width 1.27) (layer F.Cu) (net 6) (tstamp 58044262)) + (segment (start 112.4488 114.69624) (end 114.75974 114.69624) (width 1.27) (layer F.Cu) (net 6)) + (segment (start 115.6335 115.57) (end 114.75974 114.69624) (width 0.25) (layer F.Cu) (net 6) (tstamp 5804424D)) + (segment (start 115.6335 122.1105) (end 115.6335 115.57) (width 0.25) (layer F.Cu) (net 6) (tstamp 5804424B)) + (segment (start 114.681 123.063) (end 115.6335 122.1105) (width 0.25) (layer F.Cu) (net 6) (tstamp 58044248)) + (segment (start 112.7125 123.063) (end 114.681 123.063) (width 0.25) (layer F.Cu) (net 6) (tstamp 58044246)) + (segment (start 112.649 122.9995) (end 112.7125 123.063) (width 0.25) (layer F.Cu) (net 6) (tstamp 58044243)) + (segment (start 110.49 122.9995) (end 112.649 122.9995) (width 0.25) (layer F.Cu) (net 6) (tstamp 58044240)) + (segment (start 109.855 122.3645) (end 110.49 122.9995) (width 0.25) (layer F.Cu) (net 6) (tstamp 5804423F)) + (segment (start 109.855 121.285) (end 109.855 122.3645) (width 0.25) (layer F.Cu) (net 6) (tstamp 5804423E)) + (segment (start 109.347 120.777) (end 109.855 121.285) (width 0.25) (layer F.Cu) (net 6) (tstamp 5804423D)) + (segment (start 109.1325 120.777) (end 109.347 120.777) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 110.6708 110.2868) (end 109.5636 110.2868) (width 1.27) (layer F.Cu) (net 6)) + (segment (start 109.5636 110.2868) (end 109.5382 110.3122) (width 1.27) (layer F.Cu) (net 6) (tstamp 573192EF)) + (segment (start 110.6708 113.2713) (end 110.6708 110.2868) (width 1.27) (layer F.Cu) (net 6)) + (segment (start 110.6708 110.2868) (end 110.6708 107.763) (width 1.27) (layer F.Cu) (net 6) (tstamp 573192ED)) + (segment (start 110.6708 107.763) (end 110.6648 107.757) (width 1.27) (layer F.Cu) (net 6) (tstamp 573192EA)) + (segment (start 96.721 112.649) (end 96.721 114.2313) (width 0.635) (layer F.Cu) (net 6)) + (segment (start 110.6648 113.2653) (end 110.6648 112.91224) (width 0.635) (layer F.Cu) (net 6) (tstamp 56F1DFE8)) + (segment (start 110.6708 113.2713) (end 110.6648 113.2653) (width 0.635) (layer F.Cu) (net 6) (tstamp 56F1DFE7)) + (via (at 110.6708 113.2713) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 109.8961 114.046) (end 110.6708 113.2713) (width 0.635) (layer B.Cu) (net 6) (tstamp 56F1DFE3)) + (segment (start 106.7211 114.046) (end 109.8961 114.046) (width 0.635) (layer B.Cu) (net 6) (tstamp 56F1DFDA)) + (segment (start 106.2131 114.554) (end 106.7211 114.046) (width 0.635) (layer B.Cu) (net 6) (tstamp 56F1DFD9)) + (segment (start 98.5169 114.554) (end 106.2131 114.554) (width 0.635) (layer B.Cu) (net 6) (tstamp 56F1DFD4)) + (segment (start 98.0089 115.062) (end 98.5169 114.554) (width 0.635) (layer B.Cu) (net 6) (tstamp 56F1DFD3)) + (via (at 98.0089 115.062) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 6)) + (segment (start 97.5517 115.062) (end 98.0089 115.062) (width 0.635) (layer F.Cu) (net 6) (tstamp 56F1DFD1)) + (segment (start 96.721 114.2313) (end 97.5517 115.062) (width 0.635) (layer F.Cu) (net 6) (tstamp 56F1DFD0)) + (segment (start 110.6648 112.91224) (end 112.4488 114.69624) (width 1.27) (layer F.Cu) (net 6) (tstamp 56F1DD70)) + (segment (start 96.721 112.649) (end 96.721 110.797) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 98.031 106.54) (end 97.02 106.54) (width 0.25) (layer F.Cu) (net 6) (tstamp 56F1CFE4)) + (segment (start 98.171 106.68) (end 98.031 106.54) (width 0.25) (layer F.Cu) (net 6) (tstamp 56F1CFE2)) + (segment (start 98.171 109.347) (end 98.171 106.68) (width 0.25) (layer F.Cu) (net 6) (tstamp 56F1CFE1)) + (segment (start 96.721 110.797) (end 98.171 109.347) (width 0.25) (layer F.Cu) (net 6) (tstamp 56F1CFDB)) + (segment (start 97.02 106.54) (end 95.9615 106.54) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 95.9615 106.54) (end 95.0595 107.442) (width 0.25) (layer F.Cu) (net 6) (tstamp 56F1CF7E)) + (segment (start 95.0595 107.442) (end 95.0595 107.557) (width 0.25) (layer F.Cu) (net 6) (tstamp 56F1CF7F)) + (segment (start 107.7588 118.3513) (end 107.7588 117.2083) (width 0.635) (layer F.Cu) (net 7)) + (segment (start 107.7588 117.2083) (end 107.7461 117.1956) (width 0.635) (layer F.Cu) (net 7) (tstamp 57563975)) + (segment (start 107.7588 118.3513) (end 107.7588 116.0526) (width 0.635) (layer F.Cu) (net 7)) + (segment (start 107.7588 116.0526) (end 107.7461 116.0399) (width 0.635) (layer F.Cu) (net 7) (tstamp 5756396F)) + (segment (start 107.7461 116.0399) (end 107.7461 118.3386) (width 0.635) (layer F.Cu) (net 7)) + (segment (start 107.7461 118.3386) (end 107.7588 118.3513) (width 0.635) (layer F.Cu) (net 7) (tstamp 57563939)) + (segment (start 105.676 114.3) (end 106.0062 114.3) (width 0.25) (layer F.Cu) (net 7)) + (segment (start 106.0062 114.3) (end 107.7461 116.0399) (width 0.25) (layer F.Cu) (net 7) (tstamp 575638B1)) + (segment (start 105.676 114.3) (end 105.6894 114.3) (width 0.25) (layer F.Cu) (net 7)) + (segment (start 99.621 112.649) (end 102.604 112.649) (width 0.4) (layer F.Cu) (net 7)) + (segment (start 102.604 112.649) (end 102.362 112.649) (width 0.4) (layer F.Cu) (net 7) (tstamp 56F1DA2E)) + (segment (start 104.521 114.3515) (end 103.239 114.3515) (width 0.4) (layer F.Cu) (net 7)) + (segment (start 102.604 113.7165) (end 102.604 111.76) (width 0.4) (layer F.Cu) (net 7) (tstamp 56F1DA2B)) + (segment (start 103.239 114.3515) (end 102.604 113.7165) (width 0.4) (layer F.Cu) (net 7) (tstamp 56F1DA2A)) + (segment (start 102.604 111.76) (end 102.604 111.4545) (width 0.25) (layer F.Cu) (net 7)) + (segment (start 102.604 111.4545) (end 102.87 111.1885) (width 0.25) (layer F.Cu) (net 7) (tstamp 56F1CFED)) + (segment (start 102.87 111.1885) (end 102.87 109.99) (width 0.25) (layer F.Cu) (net 7) (tstamp 56F1CFEE)) + (segment (start 102.362 112.649) (end 102.604 112.407) (width 0.25) (layer F.Cu) (net 7) (tstamp 56F1CFE8)) + (segment (start 102.604 112.407) (end 102.604 111.76) (width 0.25) (layer F.Cu) (net 7) (tstamp 56F1CFE9)) + (segment (start 104.521 114.3515) (end 105.6245 114.3515) (width 0.635) (layer F.Cu) (net 7)) + (segment (start 105.6245 114.3515) (end 105.676 114.3) (width 0.635) (layer F.Cu) (net 7) (tstamp 56F1CBA6)) + (segment (start 94.5926 114.0482) (end 94.5926 114.6706) (width 0.25) (layer F.Cu) (net 8)) + (segment (start 94.5926 114.6706) (end 95.238 115.316) (width 0.25) (layer F.Cu) (net 8) (tstamp 57318976)) + (segment (start 97.2134 120.6754) (end 95.9739 120.6754) (width 0.635) (layer F.Cu) (net 8)) + (segment (start 95.238 119.9395) (end 95.238 115.316) (width 0.635) (layer F.Cu) (net 8) (tstamp 56EB5873)) + (segment (start 95.9739 120.6754) (end 95.238 119.9395) (width 0.635) (layer F.Cu) (net 8) (tstamp 56EB5872)) + (segment (start 109.7915 118.884) (end 109.2588 118.3513) (width 0.4) (layer F.Cu) (net 9) (tstamp 580441B2)) + (segment (start 109.7915 118.999) (end 109.7915 118.884) (width 0.4) (layer F.Cu) (net 9) (tstamp 580441B1)) + (segment (start 110.871 120.0785) (end 109.7915 118.999) (width 0.4) (layer F.Cu) (net 9) (tstamp 580441AD)) + (segment (start 112.649 120.0785) (end 110.871 120.0785) (width 0.4) (layer F.Cu) (net 9) (tstamp 580441AC)) + (segment (start 113.795 121.2245) (end 112.649 120.0785) (width 0.4) (layer F.Cu) (net 9) (tstamp 580441AB)) + (segment (start 113.795 121.7676) (end 113.795 121.2245) (width 0.4) (layer F.Cu) (net 9)) + (segment (start 95.3135 97.79) (end 95.758 97.79) (width 0.4) (layer F.Cu) (net 9)) + (segment (start 95.758 97.79) (end 96.139 98.171) (width 0.4) (layer F.Cu) (net 9) (tstamp 5804411E)) + (segment (start 96.139 98.171) (end 96.139 98.6155) (width 0.4) (layer F.Cu) (net 9) (tstamp 5804411F)) + (segment (start 96.139 98.6155) (end 96.5835 99.06) (width 0.4) (layer F.Cu) (net 9) (tstamp 58044120)) + (segment (start 96.5835 99.06) (end 97.3455 99.06) (width 0.4) (layer F.Cu) (net 9) (tstamp 58044121)) + (segment (start 93.98 98.183) (end 94.095 98.183) (width 0.4) (layer F.Cu) (net 9)) + (segment (start 94.095 98.183) (end 94.488 97.79) (width 0.4) (layer F.Cu) (net 9) (tstamp 5804411A)) + (segment (start 94.488 97.79) (end 95.3135 97.79) (width 0.4) (layer F.Cu) (net 9) (tstamp 5804411B)) + (segment (start 85.5726 105.791) (end 85.5726 100.6729) (width 1.27) (layer B.Cu) (net 9)) + (via (at 87.503 100.457) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 85.7885 100.457) (end 87.503 100.457) (width 1.27) (layer B.Cu) (net 9) (tstamp 580440CC)) + (segment (start 85.5726 100.6729) (end 85.7885 100.457) (width 1.27) (layer B.Cu) (net 9) (tstamp 580440CB)) + (segment (start 87.503 100.457) (end 87.503 100.445) (width 1.27) (layer F.Cu) (net 9) (tstamp 580440CE)) + (segment (start 87.503 100.445) (end 87.503 100.457) (width 1.27) (layer F.Cu) (net 9) (tstamp 580440CF)) + (segment (start 87.503 100.457) (end 87.503 100.445) (width 1.27) (layer F.Cu) (net 9) (tstamp 580440D1)) + (segment (start 87.67 111.76) (end 87.67 111.673) (width 1.27) (layer B.Cu) (net 9)) + (segment (start 87.67 111.673) (end 85.5726 109.5756) (width 1.27) (layer B.Cu) (net 9) (tstamp 580440C7)) + (segment (start 85.5726 109.5756) (end 85.5726 105.791) (width 1.27) (layer B.Cu) (net 9) (tstamp 580440C8)) + (segment (start 93.98 98.183) (end 93.333 98.183) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 90.65514 100.86086) (end 89.535 100.86086) (width 0.635) (layer F.Cu) (net 9) (tstamp 580440B5)) + (segment (start 93.333 98.183) (end 90.65514 100.86086) (width 0.635) (layer F.Cu) (net 9) (tstamp 580440B4)) + (segment (start 97.3455 99.06) (end 96.5835 99.06) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 96.139 98.171) (end 95.758 97.79) (width 0.25) (layer F.Cu) (net 9) (tstamp 58044072)) + (segment (start 96.139 98.6155) (end 96.139 98.171) (width 0.25) (layer F.Cu) (net 9) (tstamp 58044071)) + (segment (start 96.5835 99.06) (end 96.139 98.6155) (width 0.25) (layer F.Cu) (net 9) (tstamp 58044070)) + (segment (start 110.2487 115.6462) (end 111.633 114.2619) (width 0.635) (layer B.Cu) (net 9)) + (segment (start 111.633 114.2619) (end 111.633 112.5252) (width 0.635) (layer B.Cu) (net 9) (tstamp 57563980)) + (segment (start 111.633 112.5252) (end 110.6898 111.582) (width 0.635) (layer B.Cu) (net 9) (tstamp 57563981)) + (segment (start 109.2461 117.1956) (end 109.2461 116.0399) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 109.2588 118.3513) (end 109.2588 117.2083) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 109.2588 117.2083) (end 109.2461 117.1956) (width 0.635) (layer F.Cu) (net 9) (tstamp 57563978)) + (segment (start 109.2461 116.0399) (end 109.2461 118.3386) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 109.2461 118.3386) (end 109.2588 118.3513) (width 0.635) (layer F.Cu) (net 9) (tstamp 57563972)) + (segment (start 109.1565 118.3513) (end 109.2588 118.3513) (width 0.25) (layer F.Cu) (net 9) (tstamp 57563944)) + (segment (start 109.2461 118.3386) (end 109.2588 118.3513) (width 0.635) (layer F.Cu) (net 9) (tstamp 5756393C)) + (segment (start 109.2461 116.0399) (end 109.855 116.0399) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 109.855 116.0399) (end 110.2487 115.6462) (width 0.25) (layer F.Cu) (net 9) (tstamp 575638B5)) + (via (at 110.2487 115.6462) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 111.633 114.2619) (end 111.633 112.5252) (width 0.25) (layer B.Cu) (net 9) (tstamp 575638B8)) + (segment (start 111.633 112.5252) (end 110.6898 111.582) (width 0.25) (layer B.Cu) (net 9) (tstamp 575638B9)) + (segment (start 108.72 102.54) (end 107.8232 102.54) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 102.108 99.7204) (end 102.108 99.6315) (width 0.25) (layer F.Cu) (net 9) (tstamp 575637CE)) + (segment (start 104.2416 101.854) (end 102.108 99.7204) (width 0.25) (layer F.Cu) (net 9) (tstamp 575637CC)) + (segment (start 107.1372 101.854) (end 104.2416 101.854) (width 0.25) (layer F.Cu) (net 9) (tstamp 575637CB)) + (segment (start 107.8232 102.54) (end 107.1372 101.854) (width 0.25) (layer F.Cu) (net 9) (tstamp 575637CA)) + (segment (start 93.738 115.316) (end 92.468 115.316) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 92.468 115.316) (end 92.456 115.304) (width 0.635) (layer F.Cu) (net 9) (tstamp 573192F4)) + (segment (start 110.6648 105.857) (end 110.6648 104.7466) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 109.779 102.54) (end 108.72 102.54) (width 0.25) (layer F.Cu) (net 9) (tstamp 57318DA3)) + (segment (start 110.1598 102.9208) (end 109.779 102.54) (width 0.25) (layer F.Cu) (net 9) (tstamp 57318DA2)) + (segment (start 110.1598 104.2416) (end 110.1598 102.9208) (width 0.25) (layer F.Cu) (net 9) (tstamp 57318DA1)) + (segment (start 110.6648 104.7466) (end 110.1598 104.2416) (width 0.25) (layer F.Cu) (net 9) (tstamp 57318DA0)) + (segment (start 114.303 109.4366) (end 113.30916 109.4366) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 113.30916 109.4366) (end 112.4488 110.29696) (width 0.25) (layer F.Cu) (net 9) (tstamp 57318D85)) + (segment (start 107.9142 110.2868) (end 107.9142 109.4366) (width 0.25) (layer F.Cu) (net 9)) + (via (at 108.0546 109.2962) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 107.9142 109.4366) (end 108.0546 109.2962) (width 0.25) (layer F.Cu) (net 9) (tstamp 57318C41)) + (segment (start 108.0546 109.2962) (end 108.0546 109.2581) (width 0.25) (layer B.Cu) (net 9) (tstamp 57318C43)) + (segment (start 108.0546 109.2581) (end 108.0546 109.2962) (width 0.25) (layer B.Cu) (net 9) (tstamp 57318C44)) + (segment (start 108.0546 109.2962) (end 108.0546 109.2581) (width 0.25) (layer B.Cu) (net 9) (tstamp 57318C46)) + (segment (start 89.535 100.86086) (end 89.87074 100.86086) (width 0.4) (layer F.Cu) (net 9)) + (segment (start 108.1405 98.4885) (end 107.95 98.4885) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 107.95 98.4885) (end 107.6325 98.171) (width 0.25) (layer F.Cu) (net 9) (tstamp 56F1D054)) + (segment (start 108.1405 98.4885) (end 108.1405 98.1075) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 109.4105 97.028) (end 109.4105 96.4565) (width 0.25) (layer F.Cu) (net 9) (tstamp 56F1D03D)) + (segment (start 109.1565 97.282) (end 109.4105 97.028) (width 0.25) (layer F.Cu) (net 9) (tstamp 56F1D03C)) + (segment (start 108.966 97.282) (end 109.1565 97.282) (width 0.25) (layer F.Cu) (net 9) (tstamp 56F1D03B)) + (segment (start 108.1405 98.1075) (end 108.966 97.282) (width 0.25) (layer F.Cu) (net 9) (tstamp 56F1D03A)) + (segment (start 107.6325 98.171) (end 107.6325 97.155) (width 0.25) (layer F.Cu) (net 9) (tstamp 56F1D059)) + (segment (start 107.6325 97.155) (end 107.442 96.9645) (width 0.25) (layer F.Cu) (net 9) (tstamp 56F1D05A)) + (segment (start 107.442 96.9645) (end 105.6005 96.9645) (width 0.25) (layer F.Cu) (net 9) (tstamp 56F1D05B)) + (segment (start 105.6005 96.9645) (end 105.27 97.295) (width 0.25) (layer F.Cu) (net 9) (tstamp 56F1D05C)) + (segment (start 102.50724 108.0008) (end 103.26162 108.0008) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E23F)) + (segment (start 103.26162 108.0008) (end 103.28956 107.97286) (width 0.635) (layer B.Cu) (net 9) (tstamp 56F1E245)) + (segment (start 103.28956 107.97286) (end 105.86004 107.97286) (width 0.635) (layer B.Cu) (net 9) (tstamp 56F1E246)) + (segment (start 105.86004 107.97286) (end 107.14528 109.2581) (width 0.635) (layer B.Cu) (net 9) (tstamp 56F1E248)) + (via (at 103.26162 108.0008) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 105.12344 112.87252) (end 109.39928 112.87252) (width 1.27) (layer B.Cu) (net 9)) + (segment (start 109.39928 112.87252) (end 110.6898 111.582) (width 1.27) (layer B.Cu) (net 9) (tstamp 56F1E627)) + (segment (start 110.6898 111.582) (end 111.0148 111.582) (width 1.27) (layer B.Cu) (net 9) (tstamp 56F1E62B)) + (segment (start 111.0148 111.582) (end 112.4648 110.132) (width 1.27) (layer B.Cu) (net 9) (tstamp 56F1E62C)) + (segment (start 112.4648 110.132) (end 112.4648 107.982) (width 1.27) (layer B.Cu) (net 9) (tstamp 56F1E630)) + (segment (start 99.822 115.8875) (end 99.822 115.5476) (width 0.635) (layer F.Cu) (net 9)) + (via (at 105.12344 112.87252) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 104.30048 113.69548) (end 105.12344 112.87252) (width 0.635) (layer B.Cu) (net 9) (tstamp 56F1E39C)) + (segment (start 101.919518 113.69548) (end 104.30048 113.69548) (width 0.635) (layer B.Cu) (net 9) (tstamp 56F1E39B)) + (segment (start 101.886498 113.66246) (end 101.919518 113.69548) (width 0.635) (layer B.Cu) (net 9) (tstamp 56F1E39A)) + (via (at 101.886498 113.66246) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 101.70714 113.66246) (end 101.886498 113.66246) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E398)) + (segment (start 99.822 115.5476) (end 101.70714 113.66246) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E395)) + (segment (start 105.12344 112.87252) (end 105.12344 112.8515) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E39E)) + (segment (start 105.12344 112.8515) (end 105.12344 112.87252) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E39F)) + (segment (start 105.12344 112.87252) (end 105.12344 112.8515) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E3A1)) + (segment (start 97.02 105.74) (end 100.18294 105.74) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 102.44374 108.0008) (end 102.50724 108.0008) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E259)) + (segment (start 100.18294 105.74) (end 102.44374 108.0008) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E258)) + (segment (start 102.07 109.99) (end 102.07 108.43804) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 102.07 108.43804) (end 102.50724 108.0008) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E23E)) + (segment (start 95.0595 106.057) (end 95.6952 106.057) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 96.0122 105.74) (end 97.02 105.74) (width 0.25) (layer F.Cu) (net 9) (tstamp 56F1DBA5)) + (segment (start 95.6952 106.057) (end 96.0122 105.74) (width 0.25) (layer F.Cu) (net 9) (tstamp 56F1DBA4)) + (segment (start 105.27 98.29) (end 105.27 99.6185) (width 0.4) (layer F.Cu) (net 9)) + (segment (start 105.27 99.6185) (end 105.283 99.6315) (width 0.4) (layer F.Cu) (net 9) (tstamp 56F1D1BF)) + (via (at 105.283 99.6315) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 105.283 99.6315) (end 105.0925 99.822) (width 0.4) (layer B.Cu) (net 9) (tstamp 56F1D1C1)) + (segment (start 105.0925 99.822) (end 102.2985 99.822) (width 0.4) (layer B.Cu) (net 9) (tstamp 56F1D1C2)) + (segment (start 102.2985 99.822) (end 102.108 99.6315) (width 0.4) (layer B.Cu) (net 9) (tstamp 56F1D1C3)) + (via (at 102.108 99.6315) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 102.07 99.5935) (end 102.07 98.29) (width 0.4) (layer F.Cu) (net 9) (tstamp 56F1D1C6)) + (segment (start 102.108 99.6315) (end 102.07 99.5935) (width 0.4) (layer F.Cu) (net 9) (tstamp 56F1D1C5)) + (segment (start 93.738 120.003) (end 93.8015 120.003) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 93.738 115.836) (end 93.738 115.316) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1D199)) + (segment (start 94.402998 116.500998) (end 93.738 115.836) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1D198)) + (segment (start 94.402998 119.401502) (end 94.402998 116.500998) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1D197)) + (segment (start 93.8015 120.003) (end 94.402998 119.401502) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1D196)) + (segment (start 105.27 97.295) (end 105.27 98.29) (width 0.25) (layer F.Cu) (net 9) (tstamp 56F1D05D)) + (segment (start 101.104 111.76) (end 101.219 111.76) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 101.219 111.76) (end 102.07 110.909) (width 0.25) (layer F.Cu) (net 9) (tstamp 56F1CFF4)) + (segment (start 102.07 110.909) (end 102.07 109.99) (width 0.25) (layer F.Cu) (net 9) (tstamp 56F1CFF5)) + (segment (start 95.0595 106.057) (end 95.0595 105.918) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 104.521 112.8515) (end 105.12344 112.8515) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 105.12344 112.8515) (end 105.6245 112.8515) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E3A2)) + (segment (start 105.6245 112.8515) (end 105.676 112.903) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1CBA9)) + (segment (start 100.318 116.84) (end 100.318 116.193) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 94.488 123.698) (end 94.361 123.698) (width 0.635) (layer F.Cu) (net 9) (tstamp 56EB5E3B)) + (via (at 94.488 123.698) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 95.631 123.698) (end 94.488 123.698) (width 0.635) (layer B.Cu) (net 9) (tstamp 56EB5E38)) + (segment (start 96.139 124.206) (end 95.631 123.698) (width 0.635) (layer B.Cu) (net 9) (tstamp 56EB5E35)) + (segment (start 97.028 124.206) (end 96.139 124.206) (width 0.635) (layer B.Cu) (net 9) (tstamp 56EB5E34)) + (segment (start 98.171 123.063) (end 97.028 124.206) (width 0.635) (layer B.Cu) (net 9) (tstamp 56EB5E31)) + (segment (start 98.171 116.713) (end 98.171 123.063) (width 0.635) (layer B.Cu) (net 9) (tstamp 56EB5E30)) + (segment (start 99.06 115.8875) (end 98.171 116.713) (width 0.635) (layer B.Cu) (net 9) (tstamp 56EB5E2F)) + (segment (start 99.822 115.8875) (end 99.06 115.8875) (width 0.635) (layer B.Cu) (net 9) (tstamp 56EB5E2E)) + (via (at 99.822 115.8875) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 100.318 116.193) (end 99.822 115.8875) (width 0.635) (layer F.Cu) (net 9) (tstamp 56EB5E2B)) + (segment (start 100.318 124.079) (end 100.318 124.726) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 94.361 120.626) (end 93.738 120.003) (width 0.635) (layer F.Cu) (net 9) (tstamp 56EB5D77)) + (segment (start 94.361 123.698) (end 94.361 120.626) (width 0.635) (layer F.Cu) (net 9) (tstamp 56EB5D76)) + (segment (start 96.012 125.349) (end 94.361 123.698) (width 0.635) (layer F.Cu) (net 9) (tstamp 56EB5D75)) + (segment (start 99.695 125.349) (end 96.012 125.349) (width 0.635) (layer F.Cu) (net 9) (tstamp 56EB5D74)) + (segment (start 100.318 124.726) (end 99.695 125.349) (width 0.635) (layer F.Cu) (net 9) (tstamp 56EB5D73)) + (segment (start 91.8134 120.6754) (end 93.0656 120.6754) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 93.0656 120.6754) (end 93.738 120.003) (width 0.635) (layer F.Cu) (net 9) (tstamp 56EB586A)) + (segment (start 85.332 104.5464) (end 85.332 105.5504) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 85.6234 120.9802) (end 85.6234 120.9548) (width 0.25) (layer F.Cu) (net 9) (tstamp 56EB4FDE)) + (via (at 85.6234 120.9802) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 85.6234 105.8418) (end 85.6234 120.9802) (width 0.25) (layer B.Cu) (net 9) (tstamp 56EB4FD6)) + (segment (start 85.5726 105.791) (end 85.6234 105.8418) (width 0.25) (layer B.Cu) (net 9) (tstamp 56EB4FD5)) + (via (at 85.5726 105.791) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 85.332 105.5504) (end 85.5726 105.791) (width 0.25) (layer F.Cu) (net 9) (tstamp 56EB4FD3)) + (segment (start 91.8134 120.6754) (end 89.7382 120.6754) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 89.7128 120.7008) (end 89.7128 120.7262) (width 0.25) (layer F.Cu) (net 9) (tstamp 56EBF512)) + (segment (start 89.7382 120.6754) (end 89.7128 120.7008) (width 0.25) (layer F.Cu) (net 9) (tstamp 56EBF510)) + (segment (start 88.3666 120.9548) (end 89.4842 120.9548) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 90.1954 120.2436) (end 90.1954 119.7102) (width 0.25) (layer F.Cu) (net 9) (tstamp 56EBF509)) + (segment (start 89.4842 120.9548) (end 89.7128 120.7262) (width 0.25) (layer F.Cu) (net 9) (tstamp 56EBF508)) + (segment (start 89.7128 120.7262) (end 90.1954 120.2436) (width 0.25) (layer F.Cu) (net 9) (tstamp 56EBF513)) + (segment (start 88.9254 121.7422) (end 88.9254 121.5136) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 88.9254 121.5136) (end 88.3666 120.9548) (width 0.25) (layer F.Cu) (net 9) (tstamp 56EBF455)) + (segment (start 88.3666 120.9548) (end 85.6234 120.9548) (width 0.25) (layer F.Cu) (net 9) (tstamp 56EBF456)) + (segment (start 86.233 123.3678) (end 85.6234 122.7582) (width 0.25) (layer F.Cu) (net 9) (tstamp 56EBF34C)) + (segment (start 85.979 118.3386) (end 85.979 117.971) (width 0.25) (layer F.Cu) (net 9) (tstamp 56EBF34F)) + (segment (start 85.6234 118.6942) (end 85.979 118.3386) (width 0.25) (layer F.Cu) (net 9) (tstamp 56EBF34E)) + (segment (start 85.6234 122.7582) (end 85.6234 120.9548) (width 0.25) (layer F.Cu) (net 9) (tstamp 56EBF34D)) + (segment (start 85.6234 120.9548) (end 85.6234 118.6942) (width 0.25) (layer F.Cu) (net 9) (tstamp 56EBF459)) + (segment (start 86.233 123.583) (end 86.233 123.3678) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 86.36 100.445) (end 87.503 100.445) (width 1.27) (layer F.Cu) (net 9)) + (segment (start 87.503 100.445) (end 89.11914 100.445) (width 1.27) (layer F.Cu) (net 9) (tstamp 580440D2)) + (segment (start 89.11914 100.445) (end 89.535 100.86086) (width 1.27) (layer F.Cu) (net 9) (tstamp 56EB5429)) + (segment (start 92.456 115.304) (end 91.428 115.304) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 90.424 115.062) (end 87.67 112.308) (width 0.635) (layer F.Cu) (net 9) (tstamp 56EB5203)) + (segment (start 91.186 115.062) (end 90.424 115.062) (width 0.635) (layer F.Cu) (net 9) (tstamp 56EB5201)) + (segment (start 91.428 115.304) (end 91.186 115.062) (width 0.635) (layer F.Cu) (net 9) (tstamp 56EB5200)) + (segment (start 87.67 112.308) (end 87.67 111.76) (width 0.635) (layer F.Cu) (net 9) (tstamp 56EB5204)) + (segment (start 112.4488 110.29696) (end 112.4488 107.641) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 112.4488 107.641) (end 111.6233 106.8155) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1DD7B)) + (via (at 112.4648 107.982) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 112.4648 107.982) (end 112.4488 107.982) (width 1.27) (layer F.Cu) (net 9) (tstamp 56F1E633)) + (segment (start 112.4488 107.982) (end 112.4488 110.29696) (width 1.27) (layer F.Cu) (net 9) (tstamp 56F1E634)) + (segment (start 111.6233 106.7816) (end 111.6233 106.8155) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E254)) + (segment (start 111.60635 106.79855) (end 111.6233 106.7816) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E252)) + (segment (start 111.6233 106.7816) (end 111.60635 106.79855) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E251)) + (segment (start 107.14528 109.2581) (end 108.0546 109.2581) (width 0.635) (layer B.Cu) (net 9) (tstamp 56F1E249)) + (segment (start 108.0546 109.2581) (end 109.1468 109.2581) (width 0.635) (layer B.Cu) (net 9) (tstamp 57318C47)) + (segment (start 109.1468 109.2581) (end 111.6233 106.7816) (width 0.635) (layer B.Cu) (net 9) (tstamp 56F1E24A)) + (via (at 111.6233 106.7816) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 9)) + (segment (start 111.6233 106.8155) (end 110.6648 105.857) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E255)) + (segment (start 113.795 121.7676) (end 113.795 121.3866) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 113.795 121.0848) (end 113.795 121.7676) (width 0.25) (layer F.Cu) (net 9) (tstamp 5756396B)) + (segment (start 113.795 121.7676) (end 113.795 121.666) (width 0.25) (layer F.Cu) (net 9)) + (segment (start 113.795 121.7676) (end 113.795 121.7422) (width 0.4) (layer F.Cu) (net 9)) + (segment (start 114.7051 104.1103) (end 114.04046 104.1103) (width 0.25) (layer F.Cu) (net 9) (tstamp 57318D6D)) + (segment (start 114.04046 104.1103) (end 112.34046 104.1103) (width 0.635) (layer B.Cu) (net 9)) + (segment (start 112.34046 104.1103) (end 111.34046 103.1103) (width 0.635) (layer B.Cu) (net 9) (tstamp 56F1E26A)) + (segment (start 114.04046 104.1103) (end 114.04046 97.1103) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 111.34046 98.1103) (end 113.04046 98.1103) (width 0.635) (layer F.Cu) (net 9)) + (segment (start 113.04046 98.1103) (end 114.04046 97.1103) (width 0.635) (layer F.Cu) (net 9) (tstamp 56F1E265)) + (segment (start 111.34046 99.3103) (end 111.34046 98.1103) (width 0.4) (layer F.Cu) (net 9)) + (segment (start 82.423 118.098) (end 80.5838 118.098) (width 0.25) (layer F.Cu) (net 10)) + (segment (start 80.5838 118.098) (end 80.4448 118.237) (width 0.25) (layer F.Cu) (net 10) (tstamp 56F46D1D)) + (segment (start 82.423 116.598) (end 81.3458 116.598) (width 0.25) (layer F.Cu) (net 11)) + (segment (start 81.3458 116.598) (end 80.4448 115.697) (width 0.25) (layer F.Cu) (net 11) (tstamp 56F46D20)) + (segment (start 83.2866 117.0418) (end 83.2866 119.5966) (width 0.25) (layer F.Cu) (net 11) (tstamp 56EBF325)) + (segment (start 82.8428 116.598) (end 83.2866 117.0418) (width 0.25) (layer F.Cu) (net 11) (tstamp 56EBF324)) + (segment (start 82.423 116.598) (end 82.8428 116.598) (width 0.25) (layer F.Cu) (net 11)) + (segment (start 83.2866 119.5966) (end 83.324 119.634) (width 0.25) (layer F.Cu) (net 11) (tstamp 56EBF326)) + (segment (start 82.181 116.84) (end 82.423 116.598) (width 0.25) (layer F.Cu) (net 11) (tstamp 56EBF31D)) + (segment (start 82.55 124.956) (end 82.0838 124.956) (width 0.25) (layer F.Cu) (net 12)) + (segment (start 82.0838 124.956) (end 80.4448 123.317) (width 0.25) (layer F.Cu) (net 12) (tstamp 56F46D16)) + (segment (start 83.324 121.92) (end 81.5878 121.92) (width 0.25) (layer F.Cu) (net 13)) + (segment (start 81.5878 121.92) (end 80.4448 120.777) (width 0.25) (layer F.Cu) (net 13) (tstamp 56F46D19)) + (segment (start 83.324 121.92) (end 83.324 122.682) (width 0.25) (layer F.Cu) (net 13)) + (segment (start 83.324 122.682) (end 82.55 123.456) (width 0.25) (layer F.Cu) (net 13) (tstamp 56EBF340)) + (segment (start 93.7036 106.31886) (end 93.34246 106.68) (width 1.27) (layer F.Cu) (net 14) (tstamp 5731898C)) + (segment (start 93.7036 104.8534) (end 93.7036 106.31886) (width 1.27) (layer F.Cu) (net 14)) + (segment (start 90.6048 106.807) (end 90.7572 106.807) (width 0.25) (layer F.Cu) (net 14)) + (segment (start 90.7572 106.807) (end 92.1796 105.3846) (width 0.25) (layer F.Cu) (net 14) (tstamp 57318787)) + (segment (start 92.1796 105.3846) (end 92.1796 103.124) (width 0.25) (layer F.Cu) (net 14) (tstamp 5731878A)) + (segment (start 92.1796 103.124) (end 91.824 102.7684) (width 0.25) (layer F.Cu) (net 14) (tstamp 5731878C)) + (segment (start 91.824 102.7684) (end 85.5098 102.7684) (width 0.25) (layer F.Cu) (net 14) (tstamp 5731878D)) + (segment (start 85.5098 102.7684) (end 85.332 102.9462) (width 0.25) (layer F.Cu) (net 14) (tstamp 57318790)) + (segment (start 90.17 106.68) (end 90.17 106.172) (width 0.25) (layer F.Cu) (net 14)) + (segment (start 85.471 102.9462) (end 85.332 102.9462) (width 0.25) (layer F.Cu) (net 14) (tstamp 56EB4FCD)) + (segment (start 92.456 113.804) (end 90.944 113.804) (width 1.27) (layer F.Cu) (net 14)) + (segment (start 90.17 113.03) (end 90.17 111.76) (width 1.27) (layer F.Cu) (net 14) (tstamp 56EB51FA)) + (segment (start 90.944 113.804) (end 90.17 113.03) (width 1.27) (layer F.Cu) (net 14) (tstamp 56EB51F9)) + (segment (start 90.17 106.68) (end 93.34246 106.68) (width 1.27) (layer B.Cu) (net 14)) + (segment (start 90.17 111.76) (end 90.17 106.68) (width 1.27) (layer B.Cu) (net 14)) + (segment (start 97.3455 97.79) (end 97.3455 97.282) (width 0.4) (layer F.Cu) (net 15)) + (segment (start 97.3455 97.282) (end 97.2185 97.155) (width 0.4) (layer F.Cu) (net 15) (tstamp 58044126)) + (segment (start 97.2185 97.155) (end 97.2185 97.0915) (width 0.4) (layer F.Cu) (net 15) (tstamp 58044127)) + (segment (start 97.2185 97.0915) (end 97.2185 97.155) (width 0.4) (layer F.Cu) (net 15) (tstamp 58044128)) + (segment (start 96.647 96.5835) (end 97.2185 97.155) (width 0.635) (layer F.Cu) (net 15) (tstamp 5804408C)) + (segment (start 97.2185 97.155) (end 97.3455 97.282) (width 0.635) (layer F.Cu) (net 15) (tstamp 58044129)) + (segment (start 96.647 96.5835) (end 96.647 96.52) (width 0.635) (layer F.Cu) (net 15)) + (segment (start 93.34246 96.52) (end 96.647 96.52) (width 1.27) (layer F.Cu) (net 15)) + (segment (start 96.647 96.52) (end 96.7105 96.52) (width 1.27) (layer F.Cu) (net 15) (tstamp 5804408A)) + (segment (start 96.7105 96.52) (end 96.8375 96.647) (width 1.27) (layer F.Cu) (net 15) (tstamp 5804407F)) + (segment (start 82.7532 95.9739) (end 92.79636 95.9739) (width 1.27) (layer B.Cu) (net 15)) + (segment (start 92.79636 95.9739) (end 93.34246 96.52) (width 1.27) (layer B.Cu) (net 15) (tstamp 575639BB)) + (segment (start 93.72646 96.136) (end 93.34246 96.52) (width 0.635) (layer F.Cu) (net 15) (tstamp 56F1CCF4)) + (segment (start 83.832 102.9462) (end 83.832 102.48254) (width 0.25) (layer F.Cu) (net 16)) + (segment (start 83.832 102.48254) (end 84.48086 101.83368) (width 0.25) (layer F.Cu) (net 16) (tstamp 56F1E1CC)) + (segment (start 84.48086 101.83368) (end 87.69142 101.83368) (width 0.25) (layer F.Cu) (net 16) (tstamp 56F1E1CD)) + (via (at 87.69142 101.83368) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 16)) + (segment (start 87.69142 101.83368) (end 88.91062 100.61448) (width 0.25) (layer B.Cu) (net 16) (tstamp 56F1E1CF)) + (segment (start 88.91062 100.61448) (end 93.72646 100.61448) (width 0.25) (layer B.Cu) (net 16) (tstamp 56F1E1D0)) + (segment (start 93.72646 100.61448) (end 97.155 100.6475) (width 0.25) (layer B.Cu) (net 16) (tstamp 56F1E1D2)) + (segment (start 97.155 100.6475) (end 98.91822 99.96932) (width 0.25) (layer B.Cu) (net 16) (tstamp 56F1E1D4)) + (via (at 98.91822 99.96932) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 16)) + (segment (start 98.91822 99.96932) (end 103.81026 104.86136) (width 0.25) (layer F.Cu) (net 16) (tstamp 56F1E1EF)) + (segment (start 103.81026 104.86136) (end 104.45542 104.86136) (width 0.25) (layer F.Cu) (net 16) (tstamp 56F1E1F0)) + (via (at 104.45542 104.86136) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 16)) + (segment (start 104.45542 104.86136) (end 104.55702 104.96296) (width 0.25) (layer B.Cu) (net 16) (tstamp 56F1E1F5)) + (segment (start 104.55702 104.96296) (end 105.79654 104.96296) (width 0.25) (layer B.Cu) (net 16) (tstamp 56F1E1F6)) + (segment (start 105.79654 104.96296) (end 107.15798 106.3244) (width 0.25) (layer B.Cu) (net 16) (tstamp 56F1E1F7)) + (segment (start 107.15798 106.3244) (end 107.15798 107.76712) (width 0.25) (layer B.Cu) (net 16) (tstamp 56F1E1F9)) + (segment (start 107.15798 107.76712) (end 107.46278 108.07192) (width 0.25) (layer B.Cu) (net 16) (tstamp 56F1E1FB)) + (via (at 107.46278 108.07192) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 16)) + (segment (start 107.46278 108.07192) (end 107.53086 108.14) (width 0.25) (layer F.Cu) (net 16) (tstamp 56F1E1FD)) + (segment (start 107.53086 108.14) (end 108.72 108.14) (width 0.25) (layer F.Cu) (net 16) (tstamp 56F1E1FE)) + (segment (start 83.832 104.5464) (end 83.832 102.9462) (width 0.635) (layer F.Cu) (net 16)) + (segment (start 98.818 116.84) (end 98.818 114.7408) (width 0.25) (layer F.Cu) (net 17)) + (segment (start 103.6731 112.522) (end 103.6731 109.9931) (width 0.25) (layer F.Cu) (net 17) (tstamp 56F1DFAF)) + (segment (start 103.3429 112.8522) (end 103.6731 112.522) (width 0.25) (layer F.Cu) (net 17) (tstamp 56F1DFAE)) + (via (at 103.3429 112.8522) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 17)) + (segment (start 102.7333 112.2426) (end 103.3429 112.8522) (width 0.25) (layer B.Cu) (net 17) (tstamp 56F1DFA9)) + (segment (start 100.0155 112.2426) (end 102.7333 112.2426) (width 0.25) (layer B.Cu) (net 17) (tstamp 56F1DFA8)) + (segment (start 98.5423 113.7158) (end 100.0155 112.2426) (width 0.25) (layer B.Cu) (net 17) (tstamp 56F1DFA7)) + (via (at 98.5423 113.7158) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 17)) + (segment (start 98.2883 113.9698) (end 98.5423 113.7158) (width 0.25) (layer F.Cu) (net 17) (tstamp 56F1DFA4)) + (segment (start 98.2883 114.2111) (end 98.2883 113.9698) (width 0.25) (layer F.Cu) (net 17) (tstamp 56F1DFA3)) + (segment (start 98.818 114.7408) (end 98.2883 114.2111) (width 0.25) (layer F.Cu) (net 17) (tstamp 56F1DF9D)) + (segment (start 103.6731 109.9931) (end 103.67 109.99) (width 0.25) (layer F.Cu) (net 17) (tstamp 56F1DFB0)) + (segment (start 103.67 109.99) (end 103.67 108.6105) (width 0.4) (layer F.Cu) (net 17)) + (segment (start 103.67 108.6105) (end 104.9405 107.34) (width 0.4) (layer F.Cu) (net 17) (tstamp 56F1D91E)) + (segment (start 104.9405 107.34) (end 108.72 107.34) (width 0.4) (layer F.Cu) (net 17) (tstamp 56F1D91F)) + (segment (start 103.6955 110.0155) (end 103.67 109.99) (width 0.4) (layer F.Cu) (net 17) (tstamp 56F1D91B)) + (segment (start 98.818 116.84) (end 97.2388 116.84) (width 0.4) (layer F.Cu) (net 17)) + (segment (start 97.2388 116.84) (end 97.2134 116.8654) (width 0.4) (layer F.Cu) (net 17) (tstamp 56F1D8FD)) + (segment (start 97.2134 118.1354) (end 97.2134 116.8654) (width 0.635) (layer F.Cu) (net 17)) + (segment (start 89.5604 119.7102) (end 89.5604 119.31188) (width 0.25) (layer F.Cu) (net 19)) + (segment (start 107.42214 105.67416) (end 108.65416 105.67416) (width 0.25) (layer F.Cu) (net 19) (tstamp 56F1E12A)) + (segment (start 107.02082 105.27284) (end 107.42214 105.67416) (width 0.25) (layer F.Cu) (net 19) (tstamp 56F1E129)) + (via (at 107.02082 105.27284) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 19)) + (segment (start 107.02082 102.81666) (end 107.02082 105.27284) (width 0.25) (layer B.Cu) (net 19) (tstamp 56F1E126)) + (segment (start 106.47726 102.2731) (end 107.02082 102.81666) (width 0.25) (layer B.Cu) (net 19) (tstamp 56F1E124)) + (segment (start 101.06706 102.2731) (end 106.47726 102.2731) (width 0.25) (layer B.Cu) (net 19) (tstamp 56F1E120)) + (segment (start 98.89536 104.4448) (end 101.06706 102.2731) (width 0.25) (layer B.Cu) (net 19) (tstamp 56F1E11E)) + (segment (start 98.89536 107.7595) (end 98.89536 104.4448) (width 0.25) (layer B.Cu) (net 19) (tstamp 56F1E11C)) + (segment (start 91.38966 115.2652) (end 98.89536 107.7595) (width 0.25) (layer B.Cu) (net 19) (tstamp 56F1E119)) + (segment (start 91.38966 117.76456) (end 91.38966 115.2652) (width 0.25) (layer B.Cu) (net 19) (tstamp 56F1E116)) + (segment (start 90.3762 118.77802) (end 91.38966 117.76456) (width 0.25) (layer B.Cu) (net 19) (tstamp 56F1E115)) + (via (at 90.3762 118.77802) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 19)) + (segment (start 90.09426 118.77802) (end 90.3762 118.77802) (width 0.25) (layer F.Cu) (net 19) (tstamp 56F1E113)) + (segment (start 89.5604 119.31188) (end 90.09426 118.77802) (width 0.25) (layer F.Cu) (net 19) (tstamp 56F1E109)) + (segment (start 108.65416 105.67416) (end 108.72 105.74) (width 0.25) (layer F.Cu) (net 19) (tstamp 56F1E12B)) + (segment (start 89.5604 121.7422) (end 89.5604 122.22018) (width 0.25) (layer F.Cu) (net 20)) + (segment (start 107.64566 104.902) (end 108.682 104.902) (width 0.25) (layer F.Cu) (net 20) (tstamp 56F1E161)) + (segment (start 107.36118 104.61752) (end 107.64566 104.902) (width 0.25) (layer F.Cu) (net 20) (tstamp 56F1E160)) + (segment (start 106.9751 104.61752) (end 107.36118 104.61752) (width 0.25) (layer F.Cu) (net 20) (tstamp 56F1E15F)) + (segment (start 106.30454 103.94696) (end 106.9751 104.61752) (width 0.25) (layer F.Cu) (net 20) (tstamp 56F1E15E)) + (via (at 106.30454 103.94696) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 20)) + (segment (start 106.30454 102.9716) (end 106.30454 103.94696) (width 0.25) (layer B.Cu) (net 20) (tstamp 56F1E15A)) + (segment (start 106.08102 102.74808) (end 106.30454 102.9716) (width 0.25) (layer B.Cu) (net 20) (tstamp 56F1E159)) + (segment (start 101.30582 102.74808) (end 106.08102 102.74808) (width 0.25) (layer B.Cu) (net 20) (tstamp 56F1E157)) + (segment (start 99.444 104.6099) (end 101.30582 102.74808) (width 0.25) (layer B.Cu) (net 20) (tstamp 56F1E154)) + (segment (start 99.444 107.95) (end 99.444 104.6099) (width 0.25) (layer B.Cu) (net 20) (tstamp 56F1E152)) + (segment (start 91.839662 115.554338) (end 99.444 107.95) (width 0.25) (layer B.Cu) (net 20) (tstamp 56F1E14F)) + (segment (start 91.839662 118.259438) (end 91.839662 115.554338) (width 0.25) (layer B.Cu) (net 20) (tstamp 56F1E14C)) + (segment (start 90.49304 119.60606) (end 91.839662 118.259438) (width 0.25) (layer B.Cu) (net 20) (tstamp 56F1E14A)) + (segment (start 89.06556 119.60606) (end 90.49304 119.60606) (width 0.25) (layer B.Cu) (net 20) (tstamp 56F1E149)) + (segment (start 88.05972 120.6119) (end 89.06556 119.60606) (width 0.25) (layer B.Cu) (net 20) (tstamp 56F1E148)) + (segment (start 88.05972 121.9835) (end 88.05972 120.6119) (width 0.25) (layer B.Cu) (net 20) (tstamp 56F1E147)) + (segment (start 88.59566 122.51944) (end 88.05972 121.9835) (width 0.25) (layer B.Cu) (net 20) (tstamp 56F1E146)) + (segment (start 89.1443 122.51944) (end 88.59566 122.51944) (width 0.25) (layer B.Cu) (net 20) (tstamp 56F1E145)) + (segment (start 89.20272 122.57786) (end 89.1443 122.51944) (width 0.25) (layer B.Cu) (net 20) (tstamp 56F1E144)) + (via (at 89.20272 122.57786) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 20)) + (segment (start 89.5604 122.22018) (end 89.20272 122.57786) (width 0.25) (layer F.Cu) (net 20) (tstamp 56F1E142)) + (segment (start 108.682 104.902) (end 108.72 104.94) (width 0.25) (layer F.Cu) (net 20) (tstamp 56F1E162)) + (segment (start 91.8134 119.4054) (end 92.61394 119.4054) (width 0.25) (layer F.Cu) (net 21)) + (segment (start 107.4323 104.14) (end 108.72 104.14) (width 0.25) (layer F.Cu) (net 21) (tstamp 56F1E181)) + (segment (start 107.30784 104.01554) (end 107.4323 104.14) (width 0.25) (layer F.Cu) (net 21) (tstamp 56F1E180)) + (segment (start 107.30784 103.48976) (end 107.30784 104.01554) (width 0.25) (layer F.Cu) (net 21) (tstamp 56F1E17F)) + (segment (start 106.95224 103.13416) (end 107.30784 103.48976) (width 0.25) (layer F.Cu) (net 21) (tstamp 56F1E17E)) + (segment (start 105.78892 103.13416) (end 106.95224 103.13416) (width 0.25) (layer F.Cu) (net 21) (tstamp 56F1E17D)) + (segment (start 105.52476 103.39832) (end 105.78892 103.13416) (width 0.25) (layer F.Cu) (net 21) (tstamp 56F1E17C)) + (via (at 105.52476 103.39832) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 21)) + (segment (start 101.84684 103.39832) (end 105.52476 103.39832) (width 0.25) (layer B.Cu) (net 21) (tstamp 56F1E172)) + (segment (start 100.07646 105.1687) (end 101.84684 103.39832) (width 0.25) (layer B.Cu) (net 21) (tstamp 56F1E170)) + (segment (start 100.07646 108.2802) (end 100.07646 105.1687) (width 0.25) (layer B.Cu) (net 21) (tstamp 56F1E16C)) + (segment (start 93.62486 114.7318) (end 100.07646 108.2802) (width 0.25) (layer B.Cu) (net 21) (tstamp 56F1E16A)) + (segment (start 93.62486 116.4844) (end 93.62486 114.7318) (width 0.25) (layer B.Cu) (net 21) (tstamp 56F1E169)) + (segment (start 93.40134 116.70792) (end 93.62486 116.4844) (width 0.25) (layer B.Cu) (net 21) (tstamp 56F1E168)) + (via (at 93.40134 116.70792) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 21)) + (segment (start 93.40134 118.618) (end 93.40134 116.70792) (width 0.25) (layer F.Cu) (net 21) (tstamp 56F1E166)) + (segment (start 92.61394 119.4054) (end 93.40134 118.618) (width 0.25) (layer F.Cu) (net 21) (tstamp 56F1E165)) + (segment (start 91.8134 119.4054) (end 92.5576 119.4054) (width 0.4) (layer F.Cu) (net 21)) + (segment (start 91.8134 121.9454) (end 92.96954 121.9454) (width 0.25) (layer F.Cu) (net 22)) + (segment (start 107.74218 103.22052) (end 108.60052 103.22052) (width 0.25) (layer F.Cu) (net 22) (tstamp 56F1E197)) + (segment (start 107.12242 102.60076) (end 107.74218 103.22052) (width 0.25) (layer F.Cu) (net 22) (tstamp 56F1E196)) + (segment (start 105.20472 102.60076) (end 107.12242 102.60076) (width 0.25) (layer F.Cu) (net 22) (tstamp 56F1E195)) + (segment (start 104.88214 102.92334) (end 105.20472 102.60076) (width 0.25) (layer F.Cu) (net 22) (tstamp 56F1E193)) + (segment (start 104.88214 103.69804) (end 104.88214 102.92334) (width 0.25) (layer F.Cu) (net 22) (tstamp 56F1E192)) + (segment (start 104.51892 104.06126) (end 104.88214 103.69804) (width 0.25) (layer F.Cu) (net 22) (tstamp 56F1E191)) + (via (at 104.51892 104.06126) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 22)) + (segment (start 102.39548 104.06126) (end 104.51892 104.06126) (width 0.25) (layer B.Cu) (net 22) (tstamp 56F1E18E)) + (segment (start 100.64796 105.80878) (end 102.39548 104.06126) (width 0.25) (layer B.Cu) (net 22) (tstamp 56F1E18C)) + (segment (start 100.64796 108.5977) (end 100.64796 105.80878) (width 0.25) (layer B.Cu) (net 22) (tstamp 56F1E18A)) + (segment (start 94.32336 114.9223) (end 100.64796 108.5977) (width 0.25) (layer B.Cu) (net 22) (tstamp 56F1E188)) + (segment (start 94.32336 120.59158) (end 94.32336 114.9223) (width 0.25) (layer B.Cu) (net 22) (tstamp 56F1E187)) + (segment (start 93.50802 121.40692) (end 94.32336 120.59158) (width 0.25) (layer B.Cu) (net 22) (tstamp 56F1E186)) + (via (at 93.50802 121.40692) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 22)) + (segment (start 92.96954 121.9454) (end 93.50802 121.40692) (width 0.25) (layer F.Cu) (net 22) (tstamp 56F1E184)) + (segment (start 108.60052 103.22052) (end 108.72 103.34) (width 0.25) (layer F.Cu) (net 22) (tstamp 56F1E199)) + (segment (start 108.6945 103.3145) (end 108.72 103.34) (width 0.4) (layer F.Cu) (net 22) (tstamp 56F1D8FA)) + (segment (start 104.47 98.29) (end 104.47 99.898) (width 0.4) (layer F.Cu) (net 25)) + (segment (start 106.4255 100.14) (end 108.72 100.14) (width 0.4) (layer F.Cu) (net 25) (tstamp 56F1D1CC)) + (segment (start 106.172 100.3935) (end 106.4255 100.14) (width 0.4) (layer F.Cu) (net 25) (tstamp 56F1D1CB)) + (segment (start 104.9655 100.3935) (end 106.172 100.3935) (width 0.4) (layer F.Cu) (net 25) (tstamp 56F1D1CA)) + (segment (start 104.47 99.898) (end 104.9655 100.3935) (width 0.4) (layer F.Cu) (net 25) (tstamp 56F1D1C9)) + (segment (start 109.4105 98.4885) (end 109.4105 98.806) (width 0.25) (layer F.Cu) (net 26)) + (segment (start 107.767 99.187) (end 106.87 98.29) (width 0.25) (layer F.Cu) (net 26) (tstamp 56F1D049)) + (segment (start 109.0295 99.187) (end 107.767 99.187) (width 0.25) (layer F.Cu) (net 26) (tstamp 56F1D048)) + (segment (start 109.4105 98.806) (end 109.0295 99.187) (width 0.25) (layer F.Cu) (net 26) (tstamp 56F1D047)) + (segment (start 108.1405 96.4565) (end 103.5685 96.4565) (width 0.25) (layer F.Cu) (net 29)) + (segment (start 102.87 97.155) (end 102.87 98.29) (width 0.25) (layer F.Cu) (net 29) (tstamp 56F1D034)) + (segment (start 103.5685 96.4565) (end 102.87 97.155) (width 0.25) (layer F.Cu) (net 29) (tstamp 56F1D033)) + (segment (start 97.02 100.94) (end 95.86 100.94) (width 0.25) (layer F.Cu) (net 33)) + (segment (start 94.3095 100.0125) (end 93.98 99.683) (width 0.25) (layer F.Cu) (net 33) (tstamp 580440A1)) + (segment (start 94.9325 100.0125) (end 94.3095 100.0125) (width 0.25) (layer F.Cu) (net 33) (tstamp 580440A0)) + (segment (start 95.86 100.94) (end 94.9325 100.0125) (width 0.25) (layer F.Cu) (net 33) (tstamp 5804409F)) + (segment (start 95.3135 98.425) (end 94.996 98.425) (width 0.25) (layer F.Cu) (net 33)) + (segment (start 94.361 99.302) (end 93.98 99.683) (width 0.25) (layer F.Cu) (net 33) (tstamp 58044079)) + (segment (start 94.361 99.06) (end 94.361 99.302) (width 0.25) (layer F.Cu) (net 33) (tstamp 58044078)) + (segment (start 94.996 98.425) (end 94.361 99.06) (width 0.25) (layer F.Cu) (net 33) (tstamp 58044077)) + (segment (start 111.34046 101.2603) (end 110.5406 101.2603) (width 0.4) (layer F.Cu) (net 35)) + (segment (start 99.2406 102.54) (end 97.02 102.54) (width 0.4) (layer F.Cu) (net 35) (tstamp 56F1DDB1)) + (segment (start 99.6853 102.0953) (end 99.2406 102.54) (width 0.4) (layer F.Cu) (net 35) (tstamp 56F1DDB0)) + (via (at 99.6853 102.0953) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 35)) + (segment (start 99.6853 101.831702) (end 99.6853 102.0953) (width 0.4) (layer B.Cu) (net 35) (tstamp 56F1DDAE)) + (segment (start 100.2949 101.222102) (end 99.6853 101.831702) (width 0.4) (layer B.Cu) (net 35) (tstamp 56F1DDAD)) + (segment (start 109.708702 101.222102) (end 100.2949 101.222102) (width 0.4) (layer B.Cu) (net 35) (tstamp 56F1DDAC)) + (segment (start 110.0612 101.5746) (end 109.708702 101.222102) (width 0.4) (layer B.Cu) (net 35) (tstamp 56F1DDAB)) + (via (at 110.0612 101.5746) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 35)) + (segment (start 110.2263 101.5746) (end 110.0612 101.5746) (width 0.4) (layer F.Cu) (net 35) (tstamp 56F1DDA9)) + (segment (start 110.5406 101.2603) (end 110.2263 101.5746) (width 0.4) (layer F.Cu) (net 35) (tstamp 56F1DDA8)) + (segment (start 110.2127 100.6103) (end 111.34046 100.6103) (width 0.4) (layer F.Cu) (net 36) (tstamp 56F1DD9A)) + (segment (start 110.2009 100.6221) (end 110.2127 100.6103) (width 0.4) (layer F.Cu) (net 36) (tstamp 56F1DD99)) + (via (at 110.2009 100.6221) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 36)) + (segment (start 99.8631 100.6221) (end 110.2009 100.6221) (width 0.4) (layer B.Cu) (net 36) (tstamp 56F1DD97)) + (segment (start 98.8852 101.6) (end 99.8631 100.6221) (width 0.4) (layer B.Cu) (net 36) (tstamp 56F1DD96)) + (segment (start 98.8852 102.9462) (end 98.8852 101.6) (width 0.4) (layer B.Cu) (net 36) (tstamp 56F1DD95)) + (segment (start 98.5804 103.251) (end 98.8852 102.9462) (width 0.4) (layer B.Cu) (net 36) (tstamp 56F1DD94)) + (via (at 98.5804 103.251) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 36)) + (segment (start 98.4914 103.34) (end 98.5804 103.251) (width 0.4) (layer F.Cu) (net 36) (tstamp 56F1DD92)) + (segment (start 97.02 103.34) (end 98.4914 103.34) (width 0.4) (layer F.Cu) (net 36)) + (segment (start 84.328 107.43) (end 86.1702 107.43) (width 0.25) (layer F.Cu) (net 37)) + (segment (start 95.631 104.14) (end 97.02 104.14) (width 0.25) (layer F.Cu) (net 37) (tstamp 57319293)) + (segment (start 95.5802 104.1908) (end 95.631 104.14) (width 0.25) (layer F.Cu) (net 37) (tstamp 57319292)) + (via (at 95.5802 104.1908) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 37)) + (segment (start 94.8182 104.1908) (end 95.5802 104.1908) (width 0.25) (layer B.Cu) (net 37) (tstamp 57319290)) + (segment (start 94.5134 104.4956) (end 94.8182 104.1908) (width 0.25) (layer B.Cu) (net 37) (tstamp 5731928F)) + (segment (start 94.5134 105.1306) (end 94.5134 104.4956) (width 0.25) (layer B.Cu) (net 37) (tstamp 5731928E)) + (segment (start 95.0468 105.664) (end 94.5134 105.1306) (width 0.25) (layer B.Cu) (net 37) (tstamp 57319289)) + (segment (start 95.0468 107.830366) (end 95.0468 105.664) (width 0.25) (layer B.Cu) (net 37) (tstamp 57319288)) + (segment (start 94.393766 108.4834) (end 95.0468 107.830366) (width 0.25) (layer B.Cu) (net 37) (tstamp 57319287)) + (segment (start 92.0242 108.4834) (end 94.393766 108.4834) (width 0.25) (layer B.Cu) (net 37) (tstamp 57319286)) + (segment (start 91.8718 108.6358) (end 92.0242 108.4834) (width 0.25) (layer B.Cu) (net 37) (tstamp 57319285)) + (via (at 91.8718 108.6358) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 37)) + (segment (start 87.376 108.6358) (end 91.8718 108.6358) (width 0.25) (layer F.Cu) (net 37) (tstamp 57319280)) + (segment (start 86.1702 107.43) (end 87.376 108.6358) (width 0.25) (layer F.Cu) (net 37) (tstamp 5731927E)) + (segment (start 84.328 109.97) (end 91.0964 109.97) (width 0.25) (layer F.Cu) (net 38)) + (segment (start 95.6692 104.94) (end 97.02 104.94) (width 0.25) (layer F.Cu) (net 38) (tstamp 5731927B)) + (segment (start 95.5294 105.0798) (end 95.6692 104.94) (width 0.25) (layer F.Cu) (net 38) (tstamp 5731927A)) + (via (at 95.5294 105.0798) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 38)) + (segment (start 95.5294 105.5116) (end 95.5294 105.0798) (width 0.25) (layer B.Cu) (net 38) (tstamp 57319278)) + (segment (start 95.829698 105.811898) (end 95.5294 105.5116) (width 0.25) (layer B.Cu) (net 38) (tstamp 57319277)) + (segment (start 95.829698 107.683866) (end 95.829698 105.811898) (width 0.25) (layer B.Cu) (net 38) (tstamp 57319271)) + (segment (start 94.191964 109.3216) (end 95.829698 107.683866) (width 0.25) (layer B.Cu) (net 38) (tstamp 5731926A)) + (segment (start 91.7448 109.3216) (end 94.191964 109.3216) (width 0.25) (layer B.Cu) (net 38) (tstamp 57319269)) + (segment (start 91.3892 109.6772) (end 91.7448 109.3216) (width 0.25) (layer B.Cu) (net 38) (tstamp 57319268)) + (via (at 91.3892 109.6772) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 38)) + (segment (start 91.0964 109.97) (end 91.3892 109.6772) (width 0.25) (layer F.Cu) (net 38) (tstamp 57319264)) + (segment (start 95.9646 107.34) (end 97.02 107.34) (width 0.25) (layer F.Cu) (net 39) (tstamp 573189F7)) + (segment (start 95.8626 107.442) (end 95.9646 107.34) (width 0.25) (layer F.Cu) (net 39) (tstamp 573189F6)) + (segment (start 95.8626 108.1532) (end 95.8626 107.442) (width 0.25) (layer F.Cu) (net 39) (tstamp 573189F5)) + (segment (start 95.634 108.3818) (end 95.8626 108.1532) (width 0.25) (layer F.Cu) (net 39) (tstamp 573189F4)) + (segment (start 93.5766 108.3818) (end 95.634 108.3818) (width 0.25) (layer F.Cu) (net 39) (tstamp 573189F2)) + (segment (start 91.3922 110.5662) (end 93.5766 108.3818) (width 0.25) (layer F.Cu) (net 39) (tstamp 573189F0)) + (segment (start 86.5408 110.5662) (end 91.3922 110.5662) (width 0.25) (layer F.Cu) (net 39) (tstamp 573189EE)) + (segment (start 84.597 112.51) (end 86.5408 110.5662) (width 0.25) (layer F.Cu) (net 39) (tstamp 573189ED)) + (segment (start 84.328 112.51) (end 84.597 112.51) (width 0.25) (layer F.Cu) (net 39)) + (segment (start 84.328 112.51) (end 84.328 112.452002) (width 0.25) (layer F.Cu) (net 39)) + (segment (start 86.8336 115.05) (end 84.328 115.05) (width 0.25) (layer F.Cu) (net 40) (tstamp 57318A0E)) + (segment (start 86.871 115.0874) (end 86.8336 115.05) (width 0.25) (layer F.Cu) (net 40) (tstamp 57318A0D)) + (via (at 86.871 115.0874) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 40)) + (segment (start 88.8776 115.0874) (end 86.871 115.0874) (width 0.25) (layer B.Cu) (net 40) (tstamp 57318A0A)) + (segment (start 93.7798 110.1852) (end 88.8776 115.0874) (width 0.25) (layer B.Cu) (net 40) (tstamp 57318A08)) + (segment (start 95.833262 110.1852) (end 93.7798 110.1852) (width 0.25) (layer B.Cu) (net 40) (tstamp 57318A07)) + (segment (start 96.254331 109.764131) (end 95.833262 110.1852) (width 0.25) (layer B.Cu) (net 40) (tstamp 57318A06)) + (segment (start 96.254331 109.488669) (end 96.254331 109.764131) (width 0.25) (layer B.Cu) (net 40) (tstamp 57318A05)) + (segment (start 96.5992 109.1438) (end 96.254331 109.488669) (width 0.25) (layer B.Cu) (net 40) (tstamp 57318A04)) + (via (at 96.5992 109.1438) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 40)) + (segment (start 97.02 108.723) (end 96.5992 109.1438) (width 0.25) (layer F.Cu) (net 40) (tstamp 57318A02)) + (segment (start 97.02 108.14) (end 97.02 108.723) (width 0.25) (layer F.Cu) (net 40)) + (segment (start 111.255 124.3076) (end 110.8456 124.3076) (width 0.25) (layer B.Cu) (net 41)) + (segment (start 110.8456 124.3076) (end 109.093 122.555) (width 0.25) (layer B.Cu) (net 41) (tstamp 57563857)) + (segment (start 98.164398 109.99) (end 98.87 109.99) (width 0.25) (layer F.Cu) (net 41) (tstamp 57563873)) + (segment (start 97.7392 110.415198) (end 98.164398 109.99) (width 0.25) (layer F.Cu) (net 41) (tstamp 57563872)) + (segment (start 97.7392 111.2774) (end 97.7392 110.415198) (width 0.25) (layer F.Cu) (net 41) (tstamp 57563871)) + (segment (start 98.298 111.8362) (end 97.7392 111.2774) (width 0.25) (layer F.Cu) (net 41) (tstamp 57563870)) + (segment (start 98.5266 111.8362) (end 98.298 111.8362) (width 0.25) (layer F.Cu) (net 41) (tstamp 5756386F)) + (segment (start 98.5774 111.7854) (end 98.5266 111.8362) (width 0.25) (layer F.Cu) (net 41) (tstamp 5756386E)) + (via (at 98.5774 111.7854) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 41)) + (segment (start 99.7204 110.6424) (end 98.5774 111.7854) (width 0.25) (layer B.Cu) (net 41) (tstamp 5756386B)) + (segment (start 107.0102 110.6424) (end 99.7204 110.6424) (width 0.25) (layer B.Cu) (net 41) (tstamp 57563865)) + (segment (start 108.0516 111.6838) (end 107.0102 110.6424) (width 0.25) (layer B.Cu) (net 41) (tstamp 57563864)) + (via (at 108.0516 111.6838) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 41)) + (segment (start 108.839 112.4712) (end 108.0516 111.6838) (width 0.25) (layer F.Cu) (net 41) (tstamp 57563861)) + (segment (start 108.839 114.3254) (end 108.839 112.4712) (width 0.25) (layer F.Cu) (net 41) (tstamp 57563860)) + (segment (start 109.474 114.9604) (end 108.839 114.3254) (width 0.25) (layer F.Cu) (net 41) (tstamp 5756385F)) + (via (at 109.474 114.9604) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 41)) + (segment (start 109.093 115.3414) (end 109.474 114.9604) (width 0.25) (layer B.Cu) (net 41) (tstamp 5756385D)) + (segment (start 109.093 122.555) (end 109.093 115.3414) (width 0.25) (layer B.Cu) (net 41) (tstamp 57563858)) + (segment (start 111.255 124.3076) (end 110.8654 124.3076) (width 0.25) (layer B.Cu) (net 41)) + (segment (start 111.255 121.7676) (end 110.7694 121.7676) (width 0.25) (layer F.Cu) (net 42)) + (segment (start 111.255 121.7676) (end 111.255 121.2372) (width 0.25) (layer B.Cu) (net 42)) + (segment (start 111.255 121.2372) (end 109.5502 119.5324) (width 0.25) (layer B.Cu) (net 42) (tstamp 57563826)) + (segment (start 99.67 108.6862) (end 99.67 109.99) (width 0.25) (layer F.Cu) (net 42) (tstamp 5756383D)) + (segment (start 100.1268 108.2294) (end 99.67 108.6862) (width 0.25) (layer F.Cu) (net 42) (tstamp 5756383C)) + (segment (start 101.1682 108.2294) (end 100.1268 108.2294) (width 0.25) (layer F.Cu) (net 42) (tstamp 5756383B)) + (segment (start 101.2952 108.1024) (end 101.1682 108.2294) (width 0.25) (layer F.Cu) (net 42) (tstamp 5756383A)) + (via (at 101.2952 108.1024) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 42)) + (segment (start 103.3526 110.1598) (end 101.2952 108.1024) (width 0.25) (layer B.Cu) (net 42) (tstamp 57563836)) + (segment (start 107.5944 110.1598) (end 103.3526 110.1598) (width 0.25) (layer B.Cu) (net 42) (tstamp 57563835)) + (segment (start 108.9406 111.506) (end 107.5944 110.1598) (width 0.25) (layer B.Cu) (net 42) (tstamp 57563834)) + (via (at 108.9406 111.506) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 42)) + (segment (start 109.4994 112.0648) (end 108.9406 111.506) (width 0.25) (layer F.Cu) (net 42) (tstamp 57563831)) + (segment (start 109.4994 113.8936) (end 109.4994 112.0648) (width 0.25) (layer F.Cu) (net 42) (tstamp 5756382F)) + (segment (start 111.1504 115.5446) (end 109.4994 113.8936) (width 0.25) (layer F.Cu) (net 42) (tstamp 5756382E)) + (segment (start 111.1504 116.078) (end 111.1504 115.5446) (width 0.25) (layer F.Cu) (net 42) (tstamp 5756382D)) + (segment (start 110.8202 116.4082) (end 111.1504 116.078) (width 0.25) (layer F.Cu) (net 42) (tstamp 5756382C)) + (via (at 110.8202 116.4082) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 42)) + (segment (start 110.2614 116.4082) (end 110.8202 116.4082) (width 0.25) (layer B.Cu) (net 42) (tstamp 5756382A)) + (segment (start 109.5502 117.1194) (end 110.2614 116.4082) (width 0.25) (layer B.Cu) (net 42) (tstamp 57563829)) + (segment (start 109.5502 119.5324) (end 109.5502 117.1194) (width 0.25) (layer B.Cu) (net 42) (tstamp 57563827)) + (segment (start 97.2134 123.2154) (end 96.2817 123.2154) (width 0.25) (layer F.Cu) (net 46)) + (segment (start 105.27 110.8997) (end 105.27 109.99) (width 0.25) (layer F.Cu) (net 46) (tstamp 56F1DF9A)) + (segment (start 104.8415 111.3282) (end 105.27 110.8997) (width 0.25) (layer F.Cu) (net 46) (tstamp 56F1DF99)) + (segment (start 104.6129 111.3282) (end 104.8415 111.3282) (width 0.25) (layer F.Cu) (net 46) (tstamp 56F1DF98)) + (segment (start 104.397 111.5441) (end 104.6129 111.3282) (width 0.25) (layer F.Cu) (net 46) (tstamp 56F1DF97)) + (via (at 104.397 111.5441) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 46)) + (segment (start 99.825 111.5441) (end 104.397 111.5441) (width 0.25) (layer B.Cu) (net 46) (tstamp 56F1DF94)) + (segment (start 95.1895 116.1796) (end 99.825 111.5441) (width 0.25) (layer B.Cu) (net 46) (tstamp 56F1DF86)) + (segment (start 95.1895 120.9548) (end 95.1895 116.1796) (width 0.25) (layer B.Cu) (net 46) (tstamp 56F1DF7C)) + (segment (start 95.6975 121.4628) (end 95.1895 120.9548) (width 0.25) (layer B.Cu) (net 46) (tstamp 56F1DF7B)) + (via (at 95.6975 121.4628) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 46)) + (segment (start 95.6975 122.6312) (end 95.6975 121.4628) (width 0.25) (layer F.Cu) (net 46) (tstamp 56F1DF79)) + (segment (start 96.2817 123.2154) (end 95.6975 122.6312) (width 0.25) (layer F.Cu) (net 46) (tstamp 56F1DF78)) + (segment (start 105.283 110.003) (end 105.27 109.99) (width 0.4) (layer F.Cu) (net 46) (tstamp 56F1DA92)) + (segment (start 96.9975 122.9995) (end 97.2134 123.2154) (width 0.4) (layer F.Cu) (net 46) (tstamp 56F1D962)) + (segment (start 97.2134 124.4854) (end 98.4116 124.4854) (width 0.635) (layer F.Cu) (net 46)) + (segment (start 98.4116 124.4854) (end 98.818 124.079) (width 0.635) (layer F.Cu) (net 46) (tstamp 56EB5D70)) + (segment (start 97.2134 123.2154) (end 97.2134 124.4854) (width 0.635) (layer F.Cu) (net 46)) + (segment (start 100.6475 120.0665) (end 101.5485 120.0665) (width 0.25) (layer F.Cu) (net 48)) + (segment (start 108.1024 114.3) (end 107.176 114.3) (width 0.25) (layer F.Cu) (net 48) (tstamp 5756388D)) + (segment (start 108.3818 114.5794) (end 108.1024 114.3) (width 0.25) (layer F.Cu) (net 48) (tstamp 5756388C)) + (segment (start 108.3818 114.8588) (end 108.3818 114.5794) (width 0.25) (layer F.Cu) (net 48) (tstamp 5756388B)) + (segment (start 108.4072 114.8842) (end 108.3818 114.8588) (width 0.25) (layer F.Cu) (net 48) (tstamp 5756388A)) + (via (at 108.4072 114.8842) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 48)) + (segment (start 108.0262 115.2652) (end 108.4072 114.8842) (width 0.25) (layer B.Cu) (net 48) (tstamp 57563883)) + (segment (start 102.7684 115.2652) (end 108.0262 115.2652) (width 0.25) (layer B.Cu) (net 48) (tstamp 57563882)) + (segment (start 101.9556 116.078) (end 102.7684 115.2652) (width 0.25) (layer B.Cu) (net 48) (tstamp 57563881)) + (segment (start 101.9556 119.6594) (end 101.9556 116.078) (width 0.25) (layer B.Cu) (net 48) (tstamp 57563880)) + (segment (start 101.727 119.888) (end 101.9556 119.6594) (width 0.25) (layer B.Cu) (net 48) (tstamp 5756387F)) + (via (at 101.727 119.888) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 48)) + (segment (start 101.5485 120.0665) (end 101.727 119.888) (width 0.25) (layer F.Cu) (net 48) (tstamp 5756387D)) + (segment (start 107.176 112.903) (end 107.176 110.296) (width 0.4) (layer F.Cu) (net 48)) + (segment (start 107.176 110.296) (end 106.87 109.99) (width 0.4) (layer F.Cu) (net 48) (tstamp 56F1D9FF)) + (segment (start 107.176 112.903) (end 107.176 114.3) (width 0.635) (layer F.Cu) (net 48)) + (segment (start 100.6475 121.17) (end 100.6475 120.0665) (width 0.635) (layer F.Cu) (net 48)) + (segment (start 82.55 115.05) (end 82.3378 115.05) (width 0.25) (layer F.Cu) (net 50)) + (segment (start 82.3378 115.05) (end 80.4448 113.157) (width 0.25) (layer F.Cu) (net 50) (tstamp 56F46D23)) + (segment (start 82.55 115.05) (end 82.1824 115.05) (width 0.25) (layer F.Cu) (net 50)) + (segment (start 82.55 112.51) (end 82.3378 112.51) (width 0.25) (layer F.Cu) (net 51)) + (segment (start 82.3378 112.51) (end 80.4448 110.617) (width 0.25) (layer F.Cu) (net 51) (tstamp 56F46D26)) + (segment (start 82.55 112.51) (end 82.3856 112.51) (width 0.25) (layer F.Cu) (net 51)) + (segment (start 82.55 109.97) (end 82.3378 109.97) (width 0.25) (layer F.Cu) (net 52)) + (segment (start 82.3378 109.97) (end 80.4448 108.077) (width 0.25) (layer F.Cu) (net 52) (tstamp 56F46D29)) + (segment (start 82.55 109.97) (end 82.3094 109.97) (width 0.25) (layer F.Cu) (net 52)) + (segment (start 82.55 107.43) (end 82.3378 107.43) (width 0.25) (layer F.Cu) (net 53)) + (segment (start 82.3378 107.43) (end 80.4448 105.537) (width 0.25) (layer F.Cu) (net 53) (tstamp 56F46D2C)) + (segment (start 113.7061 118.2243) (end 113.7061 112.37976) (width 0.25) (layer B.Cu) (net 54)) + (segment (start 108.7755 96.09628) (end 108.7755 96.4565) (width 0.25) (layer F.Cu) (net 54) (tstamp 56F1E373)) + (segment (start 109.0833 95.78848) (end 108.7755 96.09628) (width 0.25) (layer F.Cu) (net 54) (tstamp 56F1E372)) + (segment (start 109.78434 95.78848) (end 109.0833 95.78848) (width 0.25) (layer F.Cu) (net 54) (tstamp 56F1E371)) + (segment (start 109.98246 95.9866) (end 109.78434 95.78848) (width 0.25) (layer F.Cu) (net 54) (tstamp 56F1E370)) + (segment (start 109.98246 96.03232) (end 109.98246 95.9866) (width 0.25) (layer F.Cu) (net 54) (tstamp 56F1E36F)) + (segment (start 110.3787 96.42856) (end 109.98246 96.03232) (width 0.25) (layer F.Cu) (net 54) (tstamp 56F1E36E)) + (via (at 110.3787 96.42856) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 54)) + (segment (start 112.11606 96.42856) (end 110.3787 96.42856) (width 0.25) (layer B.Cu) (net 54) (tstamp 56F1E368)) + (segment (start 112.764182 97.076682) (end 112.11606 96.42856) (width 0.25) (layer B.Cu) (net 54) (tstamp 56F1E367)) + (segment (start 112.764182 98.204442) (end 112.764182 97.076682) (width 0.25) (layer B.Cu) (net 54) (tstamp 56F1E366)) + (segment (start 116.00226 101.44252) (end 112.764182 98.204442) (width 0.25) (layer B.Cu) (net 54) (tstamp 56F1E35F)) + (segment (start 116.00226 110.0836) (end 116.00226 101.44252) (width 0.25) (layer B.Cu) (net 54) (tstamp 56F1E35E)) + (segment (start 113.7061 112.37976) (end 116.00226 110.0836) (width 0.25) (layer B.Cu) (net 54) (tstamp 56F1E35C)) + (segment (start 111.1661 118.2243) (end 113.1346 112.141) (width 0.25) (layer B.Cu) (net 55)) + (segment (start 108.7755 98.108898) (end 108.7755 98.4885) (width 0.25) (layer F.Cu) (net 55) (tstamp 56F1E325)) + (segment (start 109.129958 97.75444) (end 108.7755 98.108898) (width 0.25) (layer F.Cu) (net 55) (tstamp 56F1E322)) + (segment (start 109.81482 97.75444) (end 109.129958 97.75444) (width 0.25) (layer F.Cu) (net 55) (tstamp 56F1E321)) + (segment (start 110.13486 97.4344) (end 109.81482 97.75444) (width 0.25) (layer F.Cu) (net 55) (tstamp 56F1E320)) + (via (at 110.13486 97.4344) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 55)) + (segment (start 110.51586 97.0534) (end 110.13486 97.4344) (width 0.25) (layer B.Cu) (net 55) (tstamp 56F1E31C)) + (segment (start 111.87222 97.0534) (end 110.51586 97.0534) (width 0.25) (layer B.Cu) (net 55) (tstamp 56F1E31B)) + (segment (start 112.31418 97.49536) (end 111.87222 97.0534) (width 0.25) (layer B.Cu) (net 55) (tstamp 56F1E31A)) + (segment (start 112.31418 98.66884) (end 112.31418 97.49536) (width 0.25) (layer B.Cu) (net 55) (tstamp 56F1E318)) + (segment (start 115.34694 101.7016) (end 112.31418 98.66884) (width 0.25) (layer B.Cu) (net 55) (tstamp 56F1E316)) + (segment (start 115.34694 109.88548) (end 115.34694 101.7016) (width 0.25) (layer B.Cu) (net 55) (tstamp 56F1E313)) + (segment (start 113.1346 112.141) (end 115.34694 109.88548) (width 0.25) (layer B.Cu) (net 55) (tstamp 56F1E30F)) + (segment (start 99.06 122.67) (end 100.6475 122.67) (width 0.635) (layer F.Cu) (net 56)) + (segment (start 97.2134 121.9454) (end 98.3354 121.9454) (width 0.635) (layer F.Cu) (net 56)) + (segment (start 98.3354 121.9454) (end 99.06 122.67) (width 0.635) (layer F.Cu) (net 56) (tstamp 56EB5D7A)) + (segment (start 97.2134 119.4054) (end 98.2211 119.4054) (width 0.635) (layer F.Cu) (net 57)) + (segment (start 98.2211 119.4054) (end 99.06 118.5665) (width 0.635) (layer F.Cu) (net 57) (tstamp 56EB5D95)) + (segment (start 100.6475 118.5665) (end 99.06 118.5665) (width 0.635) (layer F.Cu) (net 57)) + (segment (start 82.55 105.93) (end 84.328 105.93) (width 0.25) (layer F.Cu) (net 58)) + (segment (start 82.55 108.47) (end 84.328 108.47) (width 0.25) (layer F.Cu) (net 59)) + (segment (start 82.55 111.01) (end 84.328 111.01) (width 0.25) (layer F.Cu) (net 60)) + (segment (start 82.55 113.55) (end 84.328 113.55) (width 0.25) (layer F.Cu) (net 61)) + (segment (start 89.3953 123.5703) (end 90.4755 123.5703) (width 0.25) (layer F.Cu) (net 62)) + (segment (start 90.8304 123.2154) (end 91.8134 123.2154) (width 0.25) (layer F.Cu) (net 62) (tstamp 56EBF44F)) + (segment (start 90.4755 123.5703) (end 90.8304 123.2154) (width 0.25) (layer F.Cu) (net 62) (tstamp 56EBF44E)) + (segment (start 87.8713 123.5703) (end 87.8713 121.9207) (width 0.25) (layer F.Cu) (net 62)) + (segment (start 87.8713 121.9207) (end 87.872 121.92) (width 0.25) (layer F.Cu) (net 62) (tstamp 56EBF35E)) + (segment (start 87.8713 123.5703) (end 89.3953 123.5703) (width 0.25) (layer F.Cu) (net 62)) + (segment (start 89.3953 125.0703) (end 89.6613 125.0703) (width 0.25) (layer F.Cu) (net 63)) + (segment (start 89.6613 125.0703) (end 90.4748 124.2568) (width 0.25) (layer F.Cu) (net 63) (tstamp 56EBF444)) + (segment (start 90.2208 122.3264) (end 90.2208 121.7676) (width 0.25) (layer F.Cu) (net 63) (tstamp 56EBF44A)) + (segment (start 90.5002 122.6058) (end 90.2208 122.3264) (width 0.25) (layer F.Cu) (net 63) (tstamp 56EBF449)) + (via (at 90.5002 122.6058) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 63)) + (segment (start 90.5002 124.2314) (end 90.5002 122.6058) (width 0.25) (layer B.Cu) (net 63) (tstamp 56EBF447)) + (segment (start 90.4748 124.2568) (end 90.5002 124.2314) (width 0.25) (layer B.Cu) (net 63) (tstamp 56EBF446)) + (via (at 90.4748 124.2568) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 63)) + (segment (start 90.2208 121.7676) (end 90.1954 121.7422) (width 0.25) (layer F.Cu) (net 63) (tstamp 56EBF44B)) + (segment (start 87.8713 125.0703) (end 89.3953 125.0703) (width 0.25) (layer F.Cu) (net 63)) + (segment (start 91.8134 118.1354) (end 90.2716 118.1354) (width 0.25) (layer F.Cu) (net 64)) + (segment (start 90.1072 117.971) (end 89.281 117.971) (width 0.25) (layer F.Cu) (net 64) (tstamp 56EBF470)) + (segment (start 90.2716 118.1354) (end 90.1072 117.971) (width 0.25) (layer F.Cu) (net 64) (tstamp 56EBF46F)) + (segment (start 87.872 119.634) (end 87.872 118.213) (width 0.25) (layer F.Cu) (net 64)) + (segment (start 87.872 118.213) (end 87.63 117.971) (width 0.25) (layer F.Cu) (net 64) (tstamp 56EBF339)) + (segment (start 87.63 117.971) (end 89.281 117.971) (width 0.25) (layer F.Cu) (net 64)) + (segment (start 89.281 116.471) (end 90.3344 116.471) (width 0.25) (layer F.Cu) (net 65)) + (segment (start 88.9254 118.9228) (end 88.9254 119.7102) (width 0.25) (layer F.Cu) (net 65) (tstamp 56EBF46B)) + (segment (start 88.9762 118.872) (end 88.9254 118.9228) (width 0.25) (layer F.Cu) (net 65) (tstamp 56EBF46A)) + (via (at 88.9762 118.872) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 65)) + (segment (start 89.1032 118.745) (end 88.9762 118.872) (width 0.25) (layer B.Cu) (net 65) (tstamp 56EBF468)) + (segment (start 89.4334 118.745) (end 89.1032 118.745) (width 0.25) (layer B.Cu) (net 65) (tstamp 56EBF467)) + (segment (start 90.5256 117.6528) (end 89.4334 118.745) (width 0.25) (layer B.Cu) (net 65) (tstamp 56EBF466)) + (segment (start 90.5256 116.6622) (end 90.5256 117.6528) (width 0.25) (layer B.Cu) (net 65) (tstamp 56EBF465)) + (segment (start 90.4494 116.586) (end 90.5256 116.6622) (width 0.25) (layer B.Cu) (net 65) (tstamp 56EBF464)) + (via (at 90.4494 116.586) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 65)) + (segment (start 90.3344 116.471) (end 90.4494 116.586) (width 0.25) (layer F.Cu) (net 65) (tstamp 56EBF462)) + (segment (start 87.63 116.471) (end 89.281 116.471) (width 0.25) (layer F.Cu) (net 65)) + (segment (start 85.979 116.471) (end 86.1956 116.471) (width 0.25) (layer F.Cu) (net 66)) + (segment (start 86.1956 116.471) (end 86.8172 115.8494) (width 0.25) (layer F.Cu) (net 66) (tstamp 56EBF473)) + (segment (start 90.805 115.8494) (end 91.8134 116.8578) (width 0.25) (layer F.Cu) (net 66) (tstamp 56EBF475)) + (segment (start 86.8172 115.8494) (end 90.805 115.8494) (width 0.25) (layer F.Cu) (net 66) (tstamp 56EBF474)) + (segment (start 91.8134 116.8578) (end 91.8134 116.8654) (width 0.25) (layer F.Cu) (net 66) (tstamp 56EBF476)) + (segment (start 85.979 116.471) (end 86.0672 116.471) (width 0.25) (layer F.Cu) (net 66)) + (segment (start 86.0672 116.471) (end 86.7918 117.1956) (width 0.25) (layer F.Cu) (net 66) (tstamp 56EBF32F)) + (segment (start 86.372 119.0124) (end 86.372 119.634) (width 0.25) (layer F.Cu) (net 66) (tstamp 56EBF334)) + (segment (start 86.5124 118.872) (end 86.372 119.0124) (width 0.25) (layer F.Cu) (net 66) (tstamp 56EBF333)) + (segment (start 86.5378 118.872) (end 86.5124 118.872) (width 0.25) (layer F.Cu) (net 66) (tstamp 56EBF332)) + (segment (start 86.7918 118.618) (end 86.5378 118.872) (width 0.25) (layer F.Cu) (net 66) (tstamp 56EBF331)) + (segment (start 86.7918 117.1956) (end 86.7918 118.618) (width 0.25) (layer F.Cu) (net 66) (tstamp 56EBF330)) + (segment (start 84.455 116.471) (end 85.979 116.471) (width 0.25) (layer F.Cu) (net 66)) + (segment (start 86.233 125.083) (end 86.8814 125.083) (width 0.25) (layer F.Cu) (net 67)) + (segment (start 91.3054 124.9934) (end 91.8134 124.4854) (width 0.25) (layer F.Cu) (net 67) (tstamp 56EBF43D)) + (segment (start 90.7796 124.9934) (end 91.3054 124.9934) (width 0.25) (layer F.Cu) (net 67) (tstamp 56EBF43C)) + (segment (start 90.678 125.095) (end 90.7796 124.9934) (width 0.25) (layer F.Cu) (net 67) (tstamp 56EBF43B)) + (via (at 90.678 125.095) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 67)) + (segment (start 86.9442 125.095) (end 90.678 125.095) (width 0.25) (layer B.Cu) (net 67) (tstamp 56EBF439)) + (segment (start 86.9188 125.1204) (end 86.9442 125.095) (width 0.25) (layer B.Cu) (net 67) (tstamp 56EBF438)) + (via (at 86.9188 125.1204) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 67)) + (segment (start 86.8814 125.083) (end 86.9188 125.1204) (width 0.25) (layer F.Cu) (net 67) (tstamp 56EBF430)) + (segment (start 86.372 121.92) (end 86.372 122.5162) (width 0.25) (layer F.Cu) (net 67)) + (segment (start 86.233 124.8156) (end 86.233 125.083) (width 0.25) (layer F.Cu) (net 67) (tstamp 56EBF357)) + (segment (start 86.4362 124.6124) (end 86.233 124.8156) (width 0.25) (layer F.Cu) (net 67) (tstamp 56EBF356)) + (segment (start 86.614 124.6124) (end 86.4362 124.6124) (width 0.25) (layer F.Cu) (net 67) (tstamp 56EBF355)) + (segment (start 87.0458 124.1806) (end 86.7918 124.4346) (width 0.25) (layer F.Cu) (net 67) (tstamp 56EBF354)) + (segment (start 86.7918 124.4346) (end 86.614 124.6124) (width 0.25) (layer F.Cu) (net 67) (tstamp 56EBF417)) + (segment (start 87.0458 123.19) (end 87.0458 124.1806) (width 0.25) (layer F.Cu) (net 67) (tstamp 56EBF353)) + (segment (start 86.372 122.5162) (end 87.0458 123.19) (width 0.25) (layer F.Cu) (net 67) (tstamp 56EBF352)) + (segment (start 84.709 125.083) (end 86.233 125.083) (width 0.25) (layer F.Cu) (net 67)) + (segment (start 84.824 119.634) (end 84.824 119.0378) (width 0.25) (layer F.Cu) (net 68)) + (segment (start 84.455 118.6688) (end 84.455 117.971) (width 0.25) (layer F.Cu) (net 68) (tstamp 56EBF32A)) + (segment (start 84.824 119.0378) (end 84.455 118.6688) (width 0.25) (layer F.Cu) (net 68) (tstamp 56EBF329)) + (segment (start 84.824 121.92) (end 84.824 123.468) (width 0.25) (layer F.Cu) (net 69)) + (segment (start 84.824 123.468) (end 84.709 123.583) (width 0.25) (layer F.Cu) (net 69) (tstamp 56EBF347)) + (segment (start 94.8466 110.8942) (end 94.5926 111.1482) (width 0.635) (layer F.Cu) (net 70) (tstamp 573189E8)) + (segment (start 94.8466 110.0836) (end 94.8466 110.8942) (width 0.635) (layer F.Cu) (net 70) (tstamp 573189E7)) + (segment (start 95.5832 109.347) (end 94.8466 110.0836) (width 0.635) (layer F.Cu) (net 70) (tstamp 573189E6)) + (via (at 95.5832 109.347) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 70)) + (segment (start 95.5832 108.839) (end 95.5832 109.347) (width 0.635) (layer B.Cu) (net 70) (tstamp 573189E4)) + (segment (start 96.4722 107.95) (end 95.5832 108.839) (width 0.635) (layer B.Cu) (net 70) (tstamp 573189E3)) + (segment (start 96.4722 103.8098) (end 96.4722 107.95) (width 0.635) (layer B.Cu) (net 70) (tstamp 573189E2)) + (segment (start 95.38 102.7176) (end 96.4722 103.8098) (width 0.635) (layer B.Cu) (net 70) (tstamp 573189E1)) + (via (at 95.38 102.7176) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 70)) + (segment (start 94.6158 101.9534) (end 95.38 102.7176) (width 0.635) (layer F.Cu) (net 70) (tstamp 573189DF)) + (segment (start 93.7036 101.9534) (end 94.6158 101.9534) (width 0.635) (layer F.Cu) (net 70)) + (segment (start 94.5926 111.196002) (end 94.5926 111.1482) (width 0.635) (layer F.Cu) (net 70) (tstamp 573189AC)) + (segment (start 106.1325 120.777) (end 106.6165 120.777) (width 0.4) (layer F.Cu) (net 71)) + (segment (start 106.6165 120.777) (end 107.6325 121.793) (width 0.4) (layer F.Cu) (net 71) (tstamp 580441F4)) + (via (at 107.6325 121.793) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 71)) + (segment (start 107.6325 121.793) (end 107.823 121.9835) (width 0.4) (layer B.Cu) (net 71) (tstamp 580441F6)) + (segment (start 107.823 121.9835) (end 107.823 124.2695) (width 0.4) (layer B.Cu) (net 71) (tstamp 580441F7)) + (segment (start 107.823 124.2695) (end 109.22 125.6665) (width 0.4) (layer B.Cu) (net 71) (tstamp 580441F8)) + (segment (start 109.22 125.6665) (end 112.4361 125.6665) (width 0.4) (layer B.Cu) (net 71) (tstamp 580441F9)) + (segment (start 112.4361 125.6665) (end 113.795 124.3076) (width 0.4) (layer B.Cu) (net 71) (tstamp 580441FA)) + (segment (start 113.795 124.3076) (end 114.049 124.3076) (width 0.4) (layer B.Cu) (net 71)) + (segment (start 97.02 100.14) (end 97.726 100.14) (width 0.25) (layer F.Cu) (net 72)) + (segment (start 97.726 100.14) (end 98.044 99.822) (width 0.25) (layer F.Cu) (net 72) (tstamp 58044099)) + (segment (start 98.044 99.822) (end 98.044 98.6155) (width 0.25) (layer F.Cu) (net 72) (tstamp 5804409A)) + (segment (start 98.044 98.6155) (end 97.8535 98.425) (width 0.25) (layer F.Cu) (net 72) (tstamp 5804409B)) + (segment (start 97.8535 98.425) (end 97.3455 98.425) (width 0.25) (layer F.Cu) (net 72) (tstamp 5804409C)) + (segment (start 92.9005 99.949) (end 95.377 99.949) (width 0.635) (layer B.Cu) (net 73)) + (segment (start 95.377 99.949) (end 95.631 99.695) (width 0.635) (layer B.Cu) (net 73) (tstamp 5804410E)) + (segment (start 91.1225 102.108) (end 91.8845 101.346) (width 0.635) (layer F.Cu) (net 73)) + (segment (start 91.8845 101.346) (end 91.8845 100.965) (width 0.635) (layer F.Cu) (net 73) (tstamp 58044104)) + (segment (start 91.8845 100.965) (end 92.9005 99.949) (width 0.635) (layer F.Cu) (net 73) (tstamp 58044105)) + (segment (start 91.1225 102.108) (end 91.1225 103.7493) (width 1.27) (layer B.Cu) (net 73)) + (segment (start 91.1225 103.7493) (end 90.6048 104.267) (width 1.27) (layer B.Cu) (net 73) (tstamp 580440FD)) + (segment (start 95.3135 99.06) (end 95.3135 99.3775) (width 0.25) (layer F.Cu) (net 73)) + (segment (start 91.186 102.1715) (end 91.186 103.6858) (width 0.25) (layer B.Cu) (net 73) (tstamp 580440F5)) + (segment (start 91.1225 102.108) (end 91.186 102.1715) (width 0.25) (layer B.Cu) (net 73) (tstamp 580440F4)) + (via (at 91.1225 102.108) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 73)) + (segment (start 91.8845 100.965) (end 91.8845 101.346) (width 0.25) (layer F.Cu) (net 73) (tstamp 580440F1)) + (segment (start 92.9005 99.949) (end 91.8845 100.965) (width 0.25) (layer F.Cu) (net 73) (tstamp 580440F0)) + (via (at 92.9005 99.949) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 73)) + (segment (start 95.631 99.695) (end 95.377 99.949) (width 0.25) (layer B.Cu) (net 73) (tstamp 580440EC)) + (via (at 95.631 99.695) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 73)) + (segment (start 95.3135 99.3775) (end 95.631 99.695) (width 0.25) (layer F.Cu) (net 73) (tstamp 580440E9)) + (segment (start 91.186 103.6858) (end 90.6048 104.267) (width 0.25) (layer B.Cu) (net 73) (tstamp 580440F6)) + (segment (start 87.63 104.14) (end 90.17 104.14) (width 1.27) (layer B.Cu) (net 73)) + (segment (start 87.63 106.68) (end 87.63 104.14) (width 1.27) (layer B.Cu) (net 73)) + (segment (start 87.67 106.72) (end 87.63 106.68) (width 1.27) (layer B.Cu) (net 73) (tstamp 56EB4D70)) + +) diff --git a/PCB/Tinylab_proto1.kicad_pcb.bak.REMOVED.git-id b/PCB/Tinylab_proto1.kicad_pcb.bak.REMOVED.git-id deleted file mode 100644 index a5f697f7..00000000 --- a/PCB/Tinylab_proto1.kicad_pcb.bak.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -92e0c41fc7972d9e8666544a2b6e435ef85d88d7 \ No newline at end of file diff --git a/PCB/Tinylab_proto1.kicad_pcb.bak.recent b/PCB/Tinylab_proto1.kicad_pcb.bak.recent new file mode 100644 index 00000000..f5e295c5 --- /dev/null +++ b/PCB/Tinylab_proto1.kicad_pcb.bak.recent @@ -0,0 +1,3009 @@ +(kicad_pcb (version 4) (host pcbnew 4.0.4-stable) + + (general + (links 154) + (no_connects 60) + (area 142.611905 78.002452 230.013976 133.938405) + (thickness 1.6) + (drawings 0) + (tracks 326) + (zones 0) + (modules 74) + (nets 76) + ) + + (page A4) + (layers + (0 F.Cu signal) + (31 B.Cu signal) + (32 B.Adhes user) + (33 F.Adhes user) + (34 B.Paste user) + (35 F.Paste user) + (36 B.SilkS user) + (37 F.SilkS user) + (38 B.Mask user) + (39 F.Mask user) + (40 Dwgs.User user) + (41 Cmts.User user) + (42 Eco1.User user) + (43 Eco2.User user) + (44 Edge.Cuts user) + (45 Margin user) + (46 B.CrtYd user) + (47 F.CrtYd user) + (48 B.Fab user) + (49 F.Fab user) + ) + + (setup + (last_trace_width 0.4) + (user_trace_width 0.4) + (user_trace_width 0.635) + (user_trace_width 1.27) + (trace_clearance 0.2) + (zone_clearance 0.508) + (zone_45_only no) + (trace_min 0.2) + (segment_width 0.2) + (edge_width 0.1) + (via_size 0.6) + (via_drill 0.4) + (via_min_size 0.4) + (via_min_drill 0.3) + (uvia_size 0.3) + (uvia_drill 0.1) + (uvias_allowed no) + (uvia_min_size 0.2) + (uvia_min_drill 0.1) + (pcb_text_width 0.3) + (pcb_text_size 1.5 1.5) + (mod_edge_width 0.15) + (mod_text_size 1 1) + (mod_text_width 0.15) + (pad_size 1.5 1.5) + (pad_drill 0.6) + (pad_to_mask_clearance 0) + (aux_axis_origin 0 0) + (visible_elements 7FFFF7FF) + (pcbplotparams + (layerselection 0x00030_80000001) + (usegerberextensions false) + (excludeedgelayer true) + (linewidth 0.100000) + (plotframeref false) + (viasonmask false) + (mode 1) + (useauxorigin false) + (hpglpennumber 1) + (hpglpenspeed 20) + (hpglpendiameter 15) + (hpglpenoverlay 2) + (psnegative false) + (psa4output false) + (plotreference true) + (plotvalue true) + (plotinvisibletext false) + (padsonsilk false) + (subtractmaskfromsilk false) + (outputformat 1) + (mirror false) + (drillshape 1) + (scaleselection 1) + (outputdirectory "")) + ) + + (net 0 "") + (net 1 +5V) + (net 2 /VGND) + (net 3 /VCC_3V3) + (net 4 /AVCC) + (net 5 /OPAMP_VCC) + (net 6 "Net-(D2-Pad2)") + (net 7 /PSU_FDBK) + (net 8 /CH2) + (net 9 "Net-(IC1-Pad3)") + (net 10 /TO_B0) + (net 11 /TO_B1) + (net 12 /DAC_OUT) + (net 13 /DAC_OUT2) + (net 14 "Net-(IC1-Pad9)") + (net 15 "Net-(IC1-Pad10)") + (net 16 /XCK) + (net 17 /DIG_CH2) + (net 18 "Net-(IC1-Pad13)") + (net 19 /DIG_CH1) + (net 20 "Net-(IC1-Pad16)") + (net 21 "Net-(IC1-Pad20)") + (net 22 "Net-(IC1-Pad21)") + (net 23 "Net-(IC1-Pad22)") + (net 24 "Net-(IC1-Pad23)") + (net 25 /PSU_PWM) + (net 26 "Net-(IC1-Pad25)") + (net 27 /D-) + (net 28 /D+) + (net 29 "Net-(IC1-Pad36)") + (net 30 "Net-(IC1-Pad37)") + (net 31 "Net-(IC1-Pad41)") + (net 32 /CH1) + (net 33 "Net-(IC1-Pad43)") + (net 34 /AVCC_ON_2) + (net 35 "Net-(L3-Pad1)") + (net 36 /PSU_OUT) + (net 37 "Net-(R22-Pad1)") + (net 38 "Net-(R23-Pad1)") + (net 39 /QTop) + (net 40 /Scope_CH1_DC) + (net 41 /Scoe_CH1_AC) + (net 42 /Scope_CH2_DC) + (net 43 /Scope_CH2_AC) + (net 44 /S-Gen_CH1_AC) + (net 45 /S-Gen_CH1_DC) + (net 46 /S-Gen_CH2_AC) + (net 47 /S-Gen_CH2_DC) + (net 48 /3V3_OUT) + (net 49 /D0-prefuse) + (net 50 /D1-prefuse) + (net 51 /D2-prefuse) + (net 52 /D3-prefuse) + (net 53 /PDI_CLK) + (net 54 /Switch_OC) + (net 55 /Scope_Buffer_Input_CH1) + (net 56 /Scope_Buffer_Input_CH2) + (net 57 /V_minus_dac_out2) + (net 58 /S-Gen_Drain_Top_CH2) + (net 59 /V_minus_dac_out) + (net 60 /S-Gen_Drain_Top_CH1) + (net 61 /Buffered_DAC_CH1) + (net 62 /Buffered_DAC_CH2) + (net 63 /PDI_DATA) + (net 64 /PSU_Unfiltered_Raw) + (net 65 /Disconnected_USB) + (net 66 /D3-OUT) + (net 67 /D2-OUT) + (net 68 /D1_OUT) + (net 69 /D0_OUT) + (net 70 /L-Ana_IN_CH1) + (net 71 /L-Ana_IN_CH2) + (net 72 /D0_MID) + (net 73 /D1_MID) + (net 74 /D2_MID) + (net 75 /D3_MID) + + (net_class Default "This is the default net class." + (clearance 0.2) + (trace_width 0.25) + (via_dia 0.6) + (via_drill 0.4) + (uvia_dia 0.3) + (uvia_drill 0.1) + (add_net +5V) + (add_net /3V3_OUT) + (add_net /AVCC) + (add_net /AVCC_ON_2) + (add_net /Buffered_DAC_CH1) + (add_net /Buffered_DAC_CH2) + (add_net /CH1) + (add_net /CH2) + (add_net /D+) + (add_net /D-) + (add_net /D0-prefuse) + (add_net /D0_MID) + (add_net /D0_OUT) + (add_net /D1-prefuse) + (add_net /D1_MID) + (add_net /D1_OUT) + (add_net /D2-OUT) + (add_net /D2-prefuse) + (add_net /D2_MID) + (add_net /D3-OUT) + (add_net /D3-prefuse) + (add_net /D3_MID) + (add_net /DAC_OUT) + (add_net /DAC_OUT2) + (add_net /DIG_CH1) + (add_net /DIG_CH2) + (add_net /Disconnected_USB) + (add_net /L-Ana_IN_CH1) + (add_net /L-Ana_IN_CH2) + (add_net /OPAMP_VCC) + (add_net /PDI_CLK) + (add_net /PDI_DATA) + (add_net /PSU_FDBK) + (add_net /PSU_OUT) + (add_net /PSU_PWM) + (add_net /PSU_Unfiltered_Raw) + (add_net /QTop) + (add_net /S-Gen_CH1_AC) + (add_net /S-Gen_CH1_DC) + (add_net /S-Gen_CH2_AC) + (add_net /S-Gen_CH2_DC) + (add_net /S-Gen_Drain_Top_CH1) + (add_net /S-Gen_Drain_Top_CH2) + (add_net /Scoe_CH1_AC) + (add_net /Scope_Buffer_Input_CH1) + (add_net /Scope_Buffer_Input_CH2) + (add_net /Scope_CH1_DC) + (add_net /Scope_CH2_AC) + (add_net /Scope_CH2_DC) + (add_net /Switch_OC) + (add_net /TO_B0) + (add_net /TO_B1) + (add_net /VCC_3V3) + (add_net /VGND) + (add_net /V_minus_dac_out) + (add_net /V_minus_dac_out2) + (add_net /XCK) + (add_net "Net-(D2-Pad2)") + (add_net "Net-(IC1-Pad10)") + (add_net "Net-(IC1-Pad13)") + (add_net "Net-(IC1-Pad16)") + (add_net "Net-(IC1-Pad20)") + (add_net "Net-(IC1-Pad21)") + (add_net "Net-(IC1-Pad22)") + (add_net "Net-(IC1-Pad23)") + (add_net "Net-(IC1-Pad25)") + (add_net "Net-(IC1-Pad3)") + (add_net "Net-(IC1-Pad36)") + (add_net "Net-(IC1-Pad37)") + (add_net "Net-(IC1-Pad41)") + (add_net "Net-(IC1-Pad43)") + (add_net "Net-(IC1-Pad9)") + (add_net "Net-(L3-Pad1)") + (add_net "Net-(R22-Pad1)") + (add_net "Net-(R23-Pad1)") + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 5831542F) + (at 150.5585 114.4905 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE0F4) + (attr smd) + (fp_text reference R13 (at 0 -1.9 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 51 /D2-prefuse)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 74 /D2_MID)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Connect:USB_Micro-B_WIDE (layer F.Cu) (tedit 56F1EFCA) (tstamp 583153A0) + (at 170.18 107.95 180) + (descr "Micro USB Type B Receptacle") + (tags "USB USB_B USB_micro USB_OTG") + (path /55CA90D2) + (attr smd) + (fp_text reference P2 (at 0 -3.45 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value USB_OTG (at 0 4.8 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -4.6 -2.8) (end 4.6 -2.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.6 -2.8) (end 4.6 4.05) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.6 4.05) (end -4.6 4.05) (layer F.CrtYd) (width 0.05)) + (fp_line (start -4.6 4.05) (end -4.6 -2.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -4.3509 3.81746) (end 4.3491 3.81746) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.3509 -2.58754) (end 4.3491 -2.58754) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.3491 -2.58754) (end 4.3491 3.81746) (layer F.SilkS) (width 0.15)) + (fp_line (start 4.3491 2.58746) (end -4.3509 2.58746) (layer F.SilkS) (width 0.15)) + (fp_line (start -4.3509 3.81746) (end -4.3509 -2.58754) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.3009 -1.56254 270) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 1 +5V)) + (pad 2 smd rect (at -0.6509 -1.56254 270) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 27 /D-)) + (pad 3 smd rect (at -0.0009 -1.56254 270) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 28 /D+)) + (pad 4 smd rect (at 0.6491 -1.56254 270) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 65 /Disconnected_USB)) + (pad 5 smd rect (at 1.2991 -1.56254 270) (size 1.35 0.4) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 6 thru_hole oval (at -2.5009 -1.56254 270) (size 0.95 1.4) (drill oval 0.55 1) (layers *.Cu *.Mask F.SilkS) + (net 2 /VGND)) + (pad 6 thru_hole oval (at 2.4991 -1.56254 270) (size 0.95 1.4) (drill oval 0.55 1) (layers *.Cu *.Mask F.SilkS) + (net 2 /VGND)) + (pad 6 thru_hole oval (at -3.5009 1.13746 270) (size 1.55 1.2) (drill oval 1.15 0.7) (layers *.Cu *.Mask F.SilkS) + (net 2 /VGND)) + (pad 6 thru_hole oval (at 3.4991 1.13746 270) (size 1.55 1.2) (drill oval 1.15 0.7) (layers *.Cu *.Mask F.SilkS) + (net 2 /VGND)) + ) + + (module Inductors:INDUCTOR_V (layer F.Cu) (tedit 0) (tstamp 58315379) + (at 161.925 108.585 90) + (descr "Inductor (vertical)") + (tags INDUCTOR) + (path /5606EE9E) + (fp_text reference L1 (at 0 1.99898 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value INDUCTOR (at 0.09906 -1.99898 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_circle (center 0 0) (end 3.81 0) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at -2.54 0 90) (size 1.905 1.905) (drill 0.8128) (layers *.Cu *.Mask F.SilkS) + (net 39 /QTop)) + (pad 2 thru_hole circle (at 2.54 0 90) (size 1.905 1.905) (drill 0.8128) (layers *.Cu *.Mask F.SilkS) + (net 1 +5V)) + (model Inductors.3dshapes/INDUCTOR_V.wrl + (at (xyz 0 0 0)) + (scale (xyz 2 2 2)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 583152CB) + (at 174.5615 124.1425 90) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CAB611) + (attr smd) + (fp_text reference C1 (at 0 -1.9 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 40 /Scope_CH1_DC)) + (pad 2 smd rect (at 0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 41 /Scoe_CH1_AC)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 583152D1) + (at 174.498 129.794 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CAB4DE) + (attr smd) + (fp_text reference C2 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 42 /Scope_CH2_DC)) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 43 /Scope_CH2_AC)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 583152D7) + (at 170.561 111.887 180) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CB13E1) + (attr smd) + (fp_text reference C3 (at 0 -1.9 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C_Small (at 0 1.9 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 180) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 1 +5V)) + (pad 2 smd rect (at 0.75 0 180) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 583152DD) + (at 169.8625 114.046 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CB147C) + (attr smd) + (fp_text reference C4 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C_Small (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 3 /VCC_3V3)) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 583152E3) + (at 223.393 127.889) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55D60181) + (attr smd) + (fp_text reference C5 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C_Small (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 4 /AVCC)) + (pad 2 smd rect (at 0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 583152EF) + (at 161.0995 119.1895 90) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /56E8E263) + (attr smd) + (fp_text reference C7 (at 0 -1.9 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 64 /PSU_Unfiltered_Raw)) + (pad 2 smd rect (at 0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 583152F5) + (at 225.933 101.346) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /56AF91A3) + (attr smd) + (fp_text reference C8 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 4 /AVCC)) + (pad 2 smd rect (at 0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:c_elec_4x5.3 (layer F.Cu) (tedit 556FDE77) (tstamp 583152FB) + (at 157.099 113.8555) + (descr "SMT capacitor, aluminium electrolytic, 4x5.3") + (path /560719D9) + (attr smd) + (fp_text reference C9 (at 0 -3.175) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value CP1 (at 0 3.175) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -3.35 -2.65) (end 3.35 -2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.35 -2.65) (end 3.35 2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.35 2.65) (end -3.35 2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.35 2.65) (end -3.35 -2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.651 0) (end 0.889 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 -0.381) (end 1.27 0.381) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 2.286) (end -2.286 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.286 -1.524) (end 2.286 1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 2.286) (end 2.286 1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 -2.286) (end -2.286 -2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 -2.286) (end 2.286 -1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.032 0.127) (end -2.032 -0.127) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.905 -0.635) (end -1.905 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 0.889) (end -1.778 -0.889) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.651 1.143) (end -1.651 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.524 -1.27) (end -1.524 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.397 1.397) (end -1.397 -1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 -1.524) (end -1.27 1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.143 -1.651) (end -1.143 1.651) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.286 -2.286) (end -2.286 2.286) (layer F.SilkS) (width 0.15)) + (fp_circle (center 0 0) (end -2.032 0) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at 1.80086 0) (size 2.60096 1.6002) (layers F.Cu F.Paste F.Mask) + (net 1 +5V)) + (pad 2 smd rect (at -1.80086 0) (size 2.60096 1.6002) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Capacitors_SMD.3dshapes/c_elec_4x5.3.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 58315301) + (at 161.29 116.205 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /56071A50) + (attr smd) + (fp_text reference C10 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 1 +5V)) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 58315307) + (at 225.8695 92.456) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /5608B4BE) + (attr smd) + (fp_text reference C11 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 3 /VCC_3V3)) + (pad 2 smd rect (at 0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 5831530D) + (at 225.878501 94.501) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /575646EC) + (attr smd) + (fp_text reference C12 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 4 /AVCC)) + (pad 2 smd rect (at 0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 58315313) + (at 148.59 123.7615 90) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /55CB630B) + (attr smd) + (fp_text reference C13 (at 0 -1.9 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 44 /S-Gen_CH1_AC)) + (pad 2 smd rect (at 0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 45 /S-Gen_CH1_DC)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 58315319) + (at 148.59 129.8575 90) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /566DF655) + (attr smd) + (fp_text reference C14 (at 0 -1.9 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 46 /S-Gen_CH2_AC)) + (pad 2 smd rect (at 0.75 0 90) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 47 /S-Gen_CH2_DC)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 58315325) + (at 167.64 128.397 270) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /5607355F) + (attr smd) + (fp_text reference C16 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 5 /OPAMP_VCC)) + (pad 2 smd rect (at 0.75 0 270) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 5831532B) + (at 225.806 96.9645) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /57564635) + (attr smd) + (fp_text reference C17 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 4 /AVCC)) + (pad 2 smd rect (at 0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:C_0603 (layer F.Cu) (tedit 5415D631) (tstamp 58315331) + (at 225.8695 99.5045) + (descr "Capacitor SMD 0603, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 0603") + (path /57564580) + (attr smd) + (fp_text reference C18 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value C (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.45 -0.75) (end 1.45 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.45 -0.75) (end -1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.45 -0.75) (end 1.45 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -0.35 -0.6) (end 0.35 -0.6) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.35 0.6) (end -0.35 0.6) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 4 /AVCC)) + (pad 2 smd rect (at 0.75 0) (size 0.8 0.75) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Capacitors_SMD.3dshapes/C_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Diodes_ThroughHole:Diode_DO-41_SOD81_Horizontal_RM10 (layer F.Cu) (tedit 552FFCCE) (tstamp 58315337) + (at 164.465 122.555 180) + (descr "Diode, DO-41, SOD81, Horizontal, RM 10mm,") + (tags "Diode, DO-41, SOD81, Horizontal, RM 10mm, 1N4007, SB140,") + (path /5606FDB4) + (fp_text reference D1 (at 5.38734 2.53746 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value D_Schottky (at 4.37134 -3.55854 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 7.62 -0.00254) (end 8.636 -0.00254) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.794 -0.00254) (end 1.524 -0.00254) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.048 -1.27254) (end 3.048 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.302 -1.27254) (end 3.302 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.556 -1.27254) (end 3.556 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.794 -1.27254) (end 2.794 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 -1.27254) (end 2.54 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 -1.27254) (end 3.81 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 -1.27254) (end 3.81 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.175 -1.27254) (end 3.175 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 1.26746) (end 2.54 -1.27254) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.54 -1.27254) (end 7.62 -1.27254) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 -1.27254) (end 7.62 1.26746) (layer F.SilkS) (width 0.15)) + (fp_line (start 7.62 1.26746) (end 2.54 1.26746) (layer F.SilkS) (width 0.15)) + (pad 2 thru_hole circle (at 10.16 -0.00254) (size 1.99898 1.99898) (drill 1.27) (layers *.Cu *.Mask F.SilkS) + (net 39 /QTop)) + (pad 1 thru_hole rect (at 0 -0.00254) (size 1.99898 1.99898) (drill 1.00076) (layers *.Cu *.Mask F.SilkS) + (net 64 /PSU_Unfiltered_Raw)) + ) + + (module LEDs:LED_0603 (layer F.Cu) (tedit 55BDE255) (tstamp 5831533D) + (at 153.67 105.41) + (descr "LED 0603 smd package") + (tags "LED led 0603 SMD smd SMT smt smdled SMDLED smtled SMTLED") + (path /5833E159) + (attr smd) + (fp_text reference D2 (at 0 -1.5) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value LED (at 0 1.5) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -0.3 -0.2) (end -0.3 0.2) (layer F.Fab) (width 0.15)) + (fp_line (start -0.2 0) (end 0.1 -0.2) (layer F.Fab) (width 0.15)) + (fp_line (start 0.1 0.2) (end -0.2 0) (layer F.Fab) (width 0.15)) + (fp_line (start 0.1 -0.2) (end 0.1 0.2) (layer F.Fab) (width 0.15)) + (fp_line (start 0.8 0.4) (end -0.8 0.4) (layer F.Fab) (width 0.15)) + (fp_line (start 0.8 -0.4) (end 0.8 0.4) (layer F.Fab) (width 0.15)) + (fp_line (start -0.8 -0.4) (end 0.8 -0.4) (layer F.Fab) (width 0.15)) + (fp_line (start -0.8 0.4) (end -0.8 -0.4) (layer F.Fab) (width 0.15)) + (fp_line (start -1.1 0.55) (end 0.8 0.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.1 -0.55) (end 0.8 -0.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.2 0) (end 0.25 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.25 -0.25) (end -0.25 0.25) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.25 0) (end 0 -0.25) (layer F.SilkS) (width 0.15)) + (fp_line (start 0 -0.25) (end 0 0.25) (layer F.SilkS) (width 0.15)) + (fp_line (start 0 0.25) (end -0.25 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.4 -0.75) (end 1.4 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.4 0.75) (end -1.4 0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.4 0.75) (end -1.4 -0.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.4 -0.75) (end 1.4 -0.75) (layer F.CrtYd) (width 0.05)) + (pad 2 smd rect (at 0.7493 0 180) (size 0.79756 0.79756) (layers F.Cu F.Paste F.Mask) + (net 6 "Net-(D2-Pad2)")) + (pad 1 smd rect (at -0.7493 0 180) (size 0.79756 0.79756) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model LEDs.3dshapes/LED_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 180)) + ) + ) + + (module Capacitors_SMD:C_1210 (layer F.Cu) (tedit 5415D85D) (tstamp 58315343) + (at 175.7045 113.6015 270) + (descr "Capacitor SMD 1210, reflow soldering, AVX (see smccp.pdf)") + (tags "capacitor 1210") + (path /55D739F3) + (attr smd) + (fp_text reference F1 (at 0 -2.7 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value F_Small (at 0 2.7 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.3 -1.6) (end 2.3 -1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.3 1.6) (end 2.3 1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.3 -1.6) (end -2.3 1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start 2.3 -1.6) (end 2.3 1.6) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1 -1.475) (end -1 -1.475) (layer F.SilkS) (width 0.15)) + (fp_line (start -1 1.475) (end 1 1.475) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.5 0 270) (size 1 2.5) (layers F.Cu F.Paste F.Mask) + (net 48 /3V3_OUT)) + (pad 2 smd rect (at 1.5 0 270) (size 1 2.5) (layers F.Cu F.Paste F.Mask) + (net 3 /VCC_3V3)) + (model Capacitors_SMD.3dshapes/C_1210.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Housings_QFP:LQFP-44_10x10mm_Pitch0.8mm (layer F.Cu) (tedit 54130A77) (tstamp 58315373) + (at 187.8965 112.2045 90) + (descr "LQFP44 (see Appnote_PCB_Guidelines_TRINAMIC_packages.pdf)") + (tags "QFP 0.8") + (path /55CA8F25) + (attr smd) + (fp_text reference IC1 (at 0 -7.65 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value ATXMEGA16A4U-A (at 0 7.65 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -6.9 -6.9) (end -6.9 6.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start 6.9 -6.9) (end 6.9 6.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start -6.9 -6.9) (end 6.9 -6.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start -6.9 6.9) (end 6.9 6.9) (layer F.CrtYd) (width 0.05)) + (fp_line (start -5.175 -5.175) (end -5.175 -4.505) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.175 -5.175) (end 5.175 -4.505) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.175 5.175) (end 5.175 4.505) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.175 5.175) (end -5.175 4.505) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.175 -5.175) (end -4.505 -5.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.175 5.175) (end -4.505 5.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.175 5.175) (end 4.505 5.175) (layer F.SilkS) (width 0.15)) + (fp_line (start 5.175 -5.175) (end 4.505 -5.175) (layer F.SilkS) (width 0.15)) + (fp_line (start -5.175 -4.505) (end -6.65 -4.505) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -5.85 -4 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 7 /PSU_FDBK)) + (pad 2 smd rect (at -5.85 -3.2 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 8 /CH2)) + (pad 3 smd rect (at -5.85 -2.4 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 9 "Net-(IC1-Pad3)")) + (pad 4 smd rect (at -5.85 -1.6 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 10 /TO_B0)) + (pad 5 smd rect (at -5.85 -0.8 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 11 /TO_B1)) + (pad 6 smd rect (at -5.85 0 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 12 /DAC_OUT)) + (pad 7 smd rect (at -5.85 0.8 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 13 /DAC_OUT2)) + (pad 8 smd rect (at -5.85 1.6 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 9 smd rect (at -5.85 2.4 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 14 "Net-(IC1-Pad9)")) + (pad 10 smd rect (at -5.85 3.2 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 15 "Net-(IC1-Pad10)")) + (pad 11 smd rect (at -5.85 4 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 16 /XCK)) + (pad 12 smd rect (at -4 5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 17 /DIG_CH2)) + (pad 13 smd rect (at -3.2 5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 18 "Net-(IC1-Pad13)")) + (pad 14 smd rect (at -2.4 5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 15 smd rect (at -1.6 5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 19 /DIG_CH1)) + (pad 16 smd rect (at -0.8 5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 20 "Net-(IC1-Pad16)")) + (pad 17 smd rect (at 0 5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 16 /XCK)) + (pad 18 smd rect (at 0.8 5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 19 smd rect (at 1.6 5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 3 /VCC_3V3)) + (pad 20 smd rect (at 2.4 5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 21 "Net-(IC1-Pad20)")) + (pad 21 smd rect (at 3.2 5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 22 "Net-(IC1-Pad21)")) + (pad 22 smd rect (at 4 5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 23 "Net-(IC1-Pad22)")) + (pad 23 smd rect (at 5.85 4 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 24 "Net-(IC1-Pad23)")) + (pad 24 smd rect (at 5.85 3.2 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 25 /PSU_PWM)) + (pad 25 smd rect (at 5.85 2.4 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 26 "Net-(IC1-Pad25)")) + (pad 26 smd rect (at 5.85 1.6 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 27 /D-)) + (pad 27 smd rect (at 5.85 0.8 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 28 /D+)) + (pad 28 smd rect (at 5.85 0 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 49 /D0-prefuse)) + (pad 29 smd rect (at 5.85 -0.8 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 50 /D1-prefuse)) + (pad 30 smd rect (at 5.85 -1.6 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 31 smd rect (at 5.85 -2.4 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 3 /VCC_3V3)) + (pad 32 smd rect (at 5.85 -3.2 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 51 /D2-prefuse)) + (pad 33 smd rect (at 5.85 -4 90) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 52 /D3-prefuse)) + (pad 34 smd rect (at 4 -5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 53 /PDI_CLK)) + (pad 35 smd rect (at 3.2 -5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 63 /PDI_DATA)) + (pad 36 smd rect (at 2.4 -5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 29 "Net-(IC1-Pad36)")) + (pad 37 smd rect (at 1.6 -5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 30 "Net-(IC1-Pad37)")) + (pad 38 smd rect (at 0.8 -5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 39 smd rect (at 0 -5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 4 /AVCC)) + (pad 40 smd rect (at -0.8 -5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 8 /CH2)) + (pad 41 smd rect (at -1.6 -5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 31 "Net-(IC1-Pad41)")) + (pad 42 smd rect (at -2.4 -5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 32 /CH1)) + (pad 43 smd rect (at -3.2 -5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 33 "Net-(IC1-Pad43)")) + (pad 44 smd rect (at -4 -5.85 180) (size 1.6 0.56) (layers F.Cu F.Paste F.Mask) + (net 34 /AVCC_ON_2)) + (model Housings_QFP.3dshapes/LQFP-44_10x10mm_Pitch0.8mm.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_1206 (layer F.Cu) (tedit 5415CFA7) (tstamp 5831537F) + (at 226.1235 89.7255) + (descr "Resistor SMD 1206, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 1206") + (path /56E88440) + (attr smd) + (fp_text reference L2 (at 0 -2.3) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value INDUCTOR (at 0 2.3) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.2 -1.2) (end 2.2 -1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 -1.2) (end -2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 2.2 -1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1 1.075) (end -1 1.075) (layer F.SilkS) (width 0.15)) + (fp_line (start -1 -1.075) (end 1 -1.075) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.45 0) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 3 /VCC_3V3)) + (pad 2 smd rect (at 1.45 0) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 4 /AVCC)) + (model Resistors_SMD.3dshapes/R_1206.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_1206 (layer F.Cu) (tedit 5415CFA7) (tstamp 58315385) + (at 169.545 122.3645 270) + (descr "Resistor SMD 1206, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 1206") + (path /56E8DA35) + (attr smd) + (fp_text reference L3 (at 0 -2.3 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value INDUCTOR (at 0 2.3 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.2 -1.2) (end 2.2 -1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 -1.2) (end -2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 2.2 -1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1 1.075) (end -1 1.075) (layer F.SilkS) (width 0.15)) + (fp_line (start -1 -1.075) (end 1 -1.075) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.45 0 270) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 35 "Net-(L3-Pad1)")) + (pad 2 smd rect (at 1.45 0 270) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 64 /PSU_Unfiltered_Raw)) + (model Resistors_SMD.3dshapes/R_1206.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_1206 (layer F.Cu) (tedit 5415CFA7) (tstamp 5831538B) + (at 171.958 122.3645 90) + (descr "Resistor SMD 1206, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 1206") + (path /573254B0) + (attr smd) + (fp_text reference L4 (at 0 -2.3 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value INDUCTOR (at 0 2.3 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -2.2 -1.2) (end 2.2 -1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.2 -1.2) (end -2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 2.2 -1.2) (end 2.2 1.2) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1 1.075) (end -1 1.075) (layer F.SilkS) (width 0.15)) + (fp_line (start -1 -1.075) (end 1 -1.075) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.45 0 90) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 5 /OPAMP_VCC)) + (pad 2 smd rect (at 1.45 0 90) (size 0.9 1.7) (layers F.Cu F.Paste F.Mask) + (net 35 "Net-(L3-Pad1)")) + (model Resistors_SMD.3dshapes/R_1206.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x04 (layer F.Cu) (tedit 0) (tstamp 58315393) + (at 177.038 124.333 90) + (descr "Through hole pin header") + (tags "pin header") + (path /5832064B) + (fp_text reference P1 (at 0 -5.1 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SCOPE_OUT (at 0 -3.1 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 9.4) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 1.27) (end -1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end 1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 8.89) (end 1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 40 /Scope_CH1_DC)) + (pad 2 thru_hole oval (at 0 2.54 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 41 /Scoe_CH1_AC)) + (pad 3 thru_hole oval (at 0 5.08 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 40 /Scope_CH1_DC)) + (pad 4 thru_hole oval (at 0 7.62 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 40 /Scope_CH1_DC)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x04.wrl + (at (xyz 0 -0.15 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x04 locked (layer F.Cu) (tedit 0) (tstamp 583153A8) + (at 146.05 111.76) + (descr "Through hole pin header") + (tags "pin header") + (path /55CBF4D5) + (fp_text reference P3 (at 0 -5.1) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DIG_OUT (at 0 -3.1) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 9.4) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 1.27) (end -1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end 1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 8.89) (end 1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 66 /D3-OUT)) + (pad 2 thru_hole oval (at 0 2.54) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 67 /D2-OUT)) + (pad 3 thru_hole oval (at 0 5.08) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 68 /D1_OUT)) + (pad 4 thru_hole oval (at 0 7.62) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 69 /D0_OUT)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x04.wrl + (at (xyz 0 -0.15 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_2x02 locked (layer F.Cu) (tedit 0) (tstamp 583153B0) + (at 146.05 106.68) + (descr "Through hole pin header") + (tags "pin header") + (path /56069A87) + (fp_text reference P4 (at 0 -5.1) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value PDI/3V3 (at 0 -3.1) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 4.3 -1.75) (end 4.3 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 4.3 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 4.3 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start 0 -1.55) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 1.27) (end 1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end 1.27 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 -1.27) (end 3.81 -1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 -1.27) (end 3.81 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 3.81 3.81) (end -1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 3.81) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 1.7272 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 48 /3V3_OUT)) + (pad 2 thru_hole oval (at 2.54 0) (size 1.7272 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 53 /PDI_CLK)) + (pad 3 thru_hole oval (at 0 2.54) (size 1.7272 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 2 /VGND)) + (pad 4 thru_hole oval (at 2.54 2.54) (size 1.7272 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 63 /PDI_DATA)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_2x02.wrl + (at (xyz 0.05 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x04 (layer F.Cu) (tedit 0) (tstamp 583153B8) + (at 177.038 129.4765 90) + (descr "Through hole pin header") + (tags "pin header") + (path /58320706) + (fp_text reference P5 (at 0 -5.1 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SCOPE_OUT (at 0 -3.1 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 9.4) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 1.27) (end -1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end 1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 8.89) (end 1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 42 /Scope_CH2_DC)) + (pad 2 thru_hole oval (at 0 2.54 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 43 /Scope_CH2_AC)) + (pad 3 thru_hole oval (at 0 5.08 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 42 /Scope_CH2_DC)) + (pad 4 thru_hole oval (at 0 7.62 90) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 42 /Scope_CH2_DC)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x04.wrl + (at (xyz 0 -0.15 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x04 locked (layer F.Cu) (tedit 0) (tstamp 583153C0) + (at 146.05 121.92) + (descr "Through hole pin header") + (tags "pin header") + (path /566DF832) + (fp_text reference P6 (at 0 -5.1) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DAC_OUT (at 0 -3.1) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 9.4) (end 1.75 9.4) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 1.27) (end -1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end 1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 8.89) (end 1.27 8.89) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 45 /S-Gen_CH1_DC)) + (pad 2 thru_hole oval (at 0 2.54) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 44 /S-Gen_CH1_AC)) + (pad 3 thru_hole oval (at 0 5.08) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 47 /S-Gen_CH2_DC)) + (pad 4 thru_hole oval (at 0 7.62) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 46 /S-Gen_CH2_AC)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x04.wrl + (at (xyz 0 -0.15 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x02 locked (layer F.Cu) (tedit 54EA090C) (tstamp 583153C6) + (at 156.21 107.95 270) + (descr "Through hole pin header") + (tags "pin header") + (path /56F2A93D) + (fp_text reference P7 (at 0 -5.1 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value PSU (at 0 -3.1 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 1.27 1.27) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 1.27) (end -1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 3.81) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 270) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 36 /PSU_OUT)) + (pad 2 thru_hole oval (at 0 2.54 270) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 2 /VGND)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x02.wrl + (at (xyz 0 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x02 (layer F.Cu) (tedit 54EA090C) (tstamp 583153CC) + (at 205.1685 121.793) + (descr "Through hole pin header") + (tags "pin header") + (path /55D6DB77) + (fp_text reference P8 (at 0 -5.1) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DIG_IN (at 0 -3.1) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 1.27 1.27) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.75 -1.75) (end -1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 4.3) (end 1.75 4.3) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 1.27) (end -1.27 3.81) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 3.81) (end 1.27 3.81) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 70 /L-Ana_IN_CH1)) + (pad 2 thru_hole oval (at 0 2.54) (size 2.032 2.032) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 71 /L-Ana_IN_CH2)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x02.wrl + (at (xyz 0 -0.05 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x03 (layer F.Cu) (tedit 0) (tstamp 583153D3) + (at 165.735 119.38 180) + (descr "Through hole pin header") + (tags "pin header") + (path /5837847B) + (fp_text reference P10 (at 0 -5.1 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value EXPANSION (at 0 -3.1 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 6.85) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 6.85) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 6.85) (end 1.75 6.85) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 1.27) (end -1.27 6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 6.35) (end 1.27 6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 6.35) (end 1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 180) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 64 /PSU_Unfiltered_Raw)) + (pad 2 thru_hole oval (at 0 2.54 180) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 7 /PSU_FDBK)) + (pad 3 thru_hole oval (at 0 5.08 180) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 2 /VGND)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x03.wrl + (at (xyz 0 -0.1 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Pin_Headers:Pin_Header_Straight_1x03 locked (layer F.Cu) (tedit 0) (tstamp 583153DA) + (at 163.195 119.38 180) + (descr "Through hole pin header") + (tags "pin header") + (path /58378536) + (fp_text reference P11 (at 0 -5.1 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value SWITCH (at 0 -3.1 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.75 -1.75) (end -1.75 6.85) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.75 -1.75) (end 1.75 6.85) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 -1.75) (end 1.75 -1.75) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.75 6.85) (end 1.75 6.85) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.27 1.27) (end -1.27 6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 6.35) (end 1.27 6.35) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 6.35) (end 1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.55 -1.55) (end 1.55 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 1.27) (end -1.27 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 0) (end -1.55 -1.55) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.55 -1.55) (end 1.55 -1.55) (layer F.SilkS) (width 0.15)) + (pad 1 thru_hole rect (at 0 0 180) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 54 /Switch_OC)) + (pad 2 thru_hole oval (at 0 2.54 180) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 64 /PSU_Unfiltered_Raw)) + (pad 3 thru_hole oval (at 0 5.08 180) (size 2.032 1.7272) (drill 1.016) (layers *.Cu *.Mask F.SilkS) + (net 36 /PSU_OUT)) + (model Pin_Headers.3dshapes/Pin_Header_Straight_1x03.wrl + (at (xyz 0 -0.1 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 90)) + ) + ) + + (module SMD:SOT-23-3 (layer F.Cu) (tedit 5508E933) (tstamp 583153E1) + (at 156.21 118.11 270) + (path /583120F2) + (fp_text reference Q1 (at 2.5 0 360) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value Q_NMOS_GSD (at -2.2 0 360) (layer F.Fab) hide + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_circle (center 1 -0.4) (end 1.1 -0.5) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.5 -0.8) (end -1.5 0.8) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.5 0.8) (end 1.5 0.8) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.5 0.8) (end 1.5 -0.8) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.5 -0.8) (end -1.5 -0.8) (layer F.SilkS) (width 0.15)) + (pad 3 smd rect (at 0 1.4 270) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 39 /QTop)) + (pad 2 smd rect (at -0.95 -1.4 270) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 1 smd rect (at 0.95 -1.4 270) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 25 /PSU_PWM)) + (model 3D/SMD/SOT-23-3.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.3937 0.3937 0.3937)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 583153E7) + (at 177.165 126.873) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAAB95) + (attr smd) + (fp_text reference R1 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 55 /Scope_Buffer_Input_CH1)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 40 /Scope_CH1_DC)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 583153ED) + (at 184.9755 126.873) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAAD4C) + (attr smd) + (fp_text reference R2 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 56 /Scope_Buffer_Input_CH2)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 42 /Scope_CH2_DC)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 583153F3) + (at 179.7685 126.873) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAABF4) + (attr smd) + (fp_text reference R3 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 55 /Scope_Buffer_Input_CH1)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 34 /AVCC_ON_2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 583153F9) + (at 182.372 126.873) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAAD11) + (attr smd) + (fp_text reference R4 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 34 /AVCC_ON_2)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 56 /Scope_Buffer_Input_CH2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 583153FF) + (at 222.504 125.1585) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAAC5F) + (attr smd) + (fp_text reference R5 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 4 /AVCC)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 34 /AVCC_ON_2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315405) + (at 221.615 121.9835) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CAACD2) + (attr smd) + (fp_text reference R6 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 34 /AVCC_ON_2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 5831540B) + (at 148.971 119.6975 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBCDA5) + (attr smd) + (fp_text reference R7 (at 0 -1.9 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 72 /D0_MID)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 69 /D0_OUT)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315411) + (at 148.971 117.094 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE401) + (attr smd) + (fp_text reference R8 (at 0 -1.9 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 73 /D1_MID)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 68 /D1_OUT)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315417) + (at 148.971 114.4905 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE16B) + (attr smd) + (fp_text reference R9 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 74 /D2_MID)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 67 /D2-OUT)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 5831541D) + (at 148.971 111.9505 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE2C7) + (attr smd) + (fp_text reference R10 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 75 /D3_MID)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 66 /D3-OUT)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315423) + (at 150.5585 119.6975 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBCD2A) + (attr smd) + (fp_text reference R11 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 49 /D0-prefuse)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 72 /D0_MID)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315429) + (at 150.5585 117.094 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE362) + (attr smd) + (fp_text reference R12 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 50 /D1-prefuse)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 73 /D1_MID)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315435) + (at 150.5585 111.9505 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CBE21C) + (attr smd) + (fp_text reference R14 (at 0 -1.9 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 52 /D3-prefuse)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 75 /D3_MID)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 5831543B) + (at 156.591 127.8255 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56B0C779) + (attr smd) + (fp_text reference R15 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 57 /V_minus_dac_out2)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 58 /S-Gen_Drain_Top_CH2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315441) + (at 154.94 127.8255 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56B0C86E) + (attr smd) + (fp_text reference R16 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 57 /V_minus_dac_out2)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 58 /S-Gen_Drain_Top_CH2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315447) + (at 154.94 125.2855 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56AFE83E) + (attr smd) + (fp_text reference R17 (at 0 -1.9 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 59 /V_minus_dac_out)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 60 /S-Gen_Drain_Top_CH1)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 5831544D) + (at 156.464 125.2855 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56AFE8F3) + (attr smd) + (fp_text reference R18 (at 0 -1.9 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 59 /V_minus_dac_out)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 60 /S-Gen_Drain_Top_CH1)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315453) + (at 153.3525 125.2855 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56AECD86) + (attr smd) + (fp_text reference R19 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 61 /Buffered_DAC_CH1)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 59 /V_minus_dac_out)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315459) + (at 153.3525 127.889 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56B0C682) + (attr smd) + (fp_text reference R20 (at 0 -1.9 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 62 /Buffered_DAC_CH2)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 57 /V_minus_dac_out2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 5831545F) + (at 178.054 119.888) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56E9851A) + (attr smd) + (fp_text reference R21 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 32 /CH1)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315465) + (at 150.1775 123.7615 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CB4680) + (attr smd) + (fp_text reference R22 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 37 "Net-(R22-Pad1)")) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 61 /Buffered_DAC_CH1)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 5831546B) + (at 150.114 129.6035 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /566DE721) + (attr smd) + (fp_text reference R23 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 38 "Net-(R23-Pad1)")) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 62 /Buffered_DAC_CH2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315471) + (at 149.606 121.666) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /55CB9020) + (attr smd) + (fp_text reference R24 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 45 /S-Gen_CH1_DC)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 37 "Net-(R22-Pad1)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315477) + (at 149.098 127.5715) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /566DE7E8) + (attr smd) + (fp_text reference R25 (at 0 -1.9) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 47 /S-Gen_CH2_DC)) + (pad 2 smd rect (at 0.75 0) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 38 "Net-(R23-Pad1)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 5831547D) + (at 167.8305 118.618 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /566E5C29) + (attr smd) + (fp_text reference R26 (at 0 -1.9 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 64 /PSU_Unfiltered_Raw)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 7 /PSU_FDBK)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315483) + (at 167.8305 115.951 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /566E5CBE) + (attr smd) + (fp_text reference R27 (at 0 -1.9 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 7 /PSU_FDBK)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315489) + (at 178.054 121.4755 180) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56E985EF) + (attr smd) + (fp_text reference R28 (at 0 -1.9 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 180) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 2 smd rect (at 0.75 0 180) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 8 /CH2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 5831548F) + (at 151.7015 125.2855 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56E9888A) + (attr smd) + (fp_text reference R29 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 61 /Buffered_DAC_CH1)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 58315495) + (at 151.7015 127.889 270) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /56E98921) + (attr smd) + (fp_text reference R30 (at 0 -1.9 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 2 smd rect (at 0.75 0 270) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 62 /Buffered_DAC_CH2)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 5831549B) + (at 159.385 118.11 90) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /5804605C) + (attr smd) + (fp_text reference R31 (at 0 -1.9 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R (at 0 1.9 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 25 /PSU_PWM)) + (pad 2 smd rect (at 0.75 0 90) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Resistors_SMD:R_0603 (layer F.Cu) (tedit 5415CC62) (tstamp 583154A1) + (at 156.21 105.41 180) + (descr "Resistor SMD 0603, reflow soldering, Vishay (see dcrcw.pdf)") + (tags "resistor 0603") + (path /5833E34C) + (attr smd) + (fp_text reference R32 (at 0 -1.9 180) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value R_Small (at 0 1.9 180) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -1.3 -0.8) (end 1.3 -0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start -1.3 -0.8) (end -1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.3 -0.8) (end 1.3 0.8) (layer F.CrtYd) (width 0.05)) + (fp_line (start 0.5 0.675) (end -0.5 0.675) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.5 -0.675) (end 0.5 -0.675) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -0.75 0 180) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 36 /PSU_OUT)) + (pad 2 smd rect (at 0.75 0 180) (size 0.5 0.9) (layers F.Cu F.Paste F.Mask) + (net 6 "Net-(D2-Pad2)")) + (model Resistors_SMD.3dshapes/R_0603.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module SMD:SOT-23-3 (layer F.Cu) (tedit 5508E933) (tstamp 583154A8) + (at 172.49775 113.37925 180) + (path /55CA99FA) + (fp_text reference U1 (at 2.5 0 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value 78L05 (at -2.2 0 270) (layer F.Fab) hide + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_circle (center 1 -0.4) (end 1.1 -0.5) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.5 -0.8) (end -1.5 0.8) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.5 0.8) (end 1.5 0.8) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.5 0.8) (end 1.5 -0.8) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.5 -0.8) (end -1.5 -0.8) (layer F.SilkS) (width 0.15)) + (pad 3 smd rect (at 0 1.4 180) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 1 +5V)) + (pad 2 smd rect (at -0.95 -1.4 180) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 3 /VCC_3V3)) + (pad 1 smd rect (at 0.95 -1.4 180) (size 0.6 0.9) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model 3D/SMD/SOT-23-3.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.3937 0.3937 0.3937)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm (layer F.Cu) (tedit 54130A77) (tstamp 583154BA) + (at 162.179 127.4445 270) + (descr "14-Lead Plastic Small Outline (SL) - Narrow, 3.90 mm Body [SOIC] (see Microchip Packaging Specification 00000049BS.pdf)") + (tags "SOIC 1.27") + (path /55CA87E2) + (attr smd) + (fp_text reference U2 (at 0 -5.375 270) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value LM324 (at 0 5.375 270) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -3.7 -4.65) (end -3.7 4.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.7 -4.65) (end 3.7 4.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.7 -4.65) (end 3.7 -4.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.7 4.65) (end 3.7 4.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -2.075 -4.45) (end -2.075 -4.335) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.075 -4.45) (end 2.075 -4.335) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.075 4.45) (end 2.075 4.335) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.075 4.45) (end -2.075 4.335) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.075 -4.45) (end 2.075 -4.45) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.075 4.45) (end 2.075 4.45) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.075 -4.335) (end -3.45 -4.335) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -2.7 -3.81 270) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 32 /CH1)) + (pad 2 smd rect (at -2.7 -2.54 270) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 32 /CH1)) + (pad 3 smd rect (at -2.7 -1.27 270) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 55 /Scope_Buffer_Input_CH1)) + (pad 4 smd rect (at -2.7 0 270) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 5 /OPAMP_VCC)) + (pad 5 smd rect (at -2.7 1.27 270) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 56 /Scope_Buffer_Input_CH2)) + (pad 6 smd rect (at -2.7 2.54 270) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 8 /CH2)) + (pad 7 smd rect (at -2.7 3.81 270) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 8 /CH2)) + (pad 8 smd rect (at 2.7 3.81 270) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 61 /Buffered_DAC_CH1)) + (pad 9 smd rect (at 2.7 2.54 270) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 59 /V_minus_dac_out)) + (pad 10 smd rect (at 2.7 1.27 270) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 12 /DAC_OUT)) + (pad 11 smd rect (at 2.7 0 270) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 12 smd rect (at 2.7 -1.27 270) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 13 /DAC_OUT2)) + (pad 13 smd rect (at 2.7 -2.54 270) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 57 /V_minus_dac_out2)) + (pad 14 smd rect (at 2.7 -3.81 270) (size 1.5 0.6) (layers F.Cu F.Paste F.Mask) + (net 62 /Buffered_DAC_CH2)) + (model Housings_SOIC.3dshapes/SOIC-14_3.9x8.7mm_Pitch1.27mm.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module TO_SOT_Packages_SMD:SOT-363 (layer F.Cu) (tedit 58316B81) (tstamp 583154C4) + (at 158.3055 122.1105) + (descr SOT353) + (path /56B012DD) + (attr smd) + (fp_text reference U3 (at -0.2515 1.5735 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DMN63D8LDW (at 0.09906 0 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 0.635 1.016) (end 0.635 -1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.635 -1.016) (end -0.635 -1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.635 -1.016) (end -0.635 1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.635 1.016) (end 0.635 1.016) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.016 -0.635) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 3 smd rect (at -1.016 0.635) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 60 /S-Gen_Drain_Top_CH1)) + (pad 6 smd rect (at 1.016 -0.635) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 58 /S-Gen_Drain_Top_CH2)) + (pad 2 smd rect (at -1.016 0) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 10 /TO_B0)) + (pad 4 smd rect (at 1.016 0.635) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 5 smd rect (at 1.016 0) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 11 /TO_B1)) + (model TO_SOT_Packages_SMD.3dshapes/SOT-353.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.07000000000000001 0.09 0.08)) + (rotate (xyz 0 0 90)) + ) + ) + + (module TO_SOT_Packages_SMD:SOT-363 (layer F.Cu) (tedit 56735562) (tstamp 583154CE) + (at 208.153 121.031) + (descr SOT353) + (path /55D6ACFD) + (attr smd) + (fp_text reference U4 (at 0.09906 0 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value DMN63D8LDW (at 0.09906 0 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start 0.635 1.016) (end 0.635 -1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start 0.635 -1.016) (end -0.635 -1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.635 -1.016) (end -0.635 1.016) (layer F.SilkS) (width 0.15)) + (fp_line (start -0.635 1.016) (end 0.635 1.016) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at -1.016 -0.635) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 3 smd rect (at -1.016 0.635) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 17 /DIG_CH2)) + (pad 6 smd rect (at 1.016 -0.635) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 19 /DIG_CH1)) + (pad 2 smd rect (at -1.016 0) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 71 /L-Ana_IN_CH2)) + (pad 4 smd rect (at 1.016 0.635) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (pad 5 smd rect (at 1.016 0) (size 0.508 0.3048) (layers F.Cu F.Paste F.Mask) + (net 70 /L-Ana_IN_CH1)) + (model TO_SOT_Packages_SMD.3dshapes/SOT-353.wrl + (at (xyz 0 0 0)) + (scale (xyz 0.07000000000000001 0.09 0.08)) + (rotate (xyz 0 0 90)) + ) + ) + + (module Capacitors_SMD:c_elec_4x5.3 (layer F.Cu) (tedit 556FDE77) (tstamp 5831599C) + (at 171.958 117.7925) + (descr "SMT capacitor, aluminium electrolytic, 4x5.3") + (path /566F5A75) + (attr smd) + (fp_text reference C6 (at 0 -3.175) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value CP1 (at 0 3.175) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -3.35 -2.65) (end 3.35 -2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.35 -2.65) (end 3.35 2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.35 2.65) (end -3.35 2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.35 2.65) (end -3.35 -2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.651 0) (end 0.889 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 -0.381) (end 1.27 0.381) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 2.286) (end -2.286 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.286 -1.524) (end 2.286 1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 2.286) (end 2.286 1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 -2.286) (end -2.286 -2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 -2.286) (end 2.286 -1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.032 0.127) (end -2.032 -0.127) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.905 -0.635) (end -1.905 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 0.889) (end -1.778 -0.889) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.651 1.143) (end -1.651 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.524 -1.27) (end -1.524 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.397 1.397) (end -1.397 -1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 -1.524) (end -1.27 1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.143 -1.651) (end -1.143 1.651) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.286 -2.286) (end -2.286 2.286) (layer F.SilkS) (width 0.15)) + (fp_circle (center 0 0) (end -2.032 0) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at 1.80086 0) (size 2.60096 1.6002) (layers F.Cu F.Paste F.Mask) + (net 3 /VCC_3V3)) + (pad 2 smd rect (at -1.80086 0) (size 2.60096 1.6002) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Capacitors_SMD.3dshapes/c_elec_4x5.3.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module Capacitors_SMD:c_elec_4x5.3 (layer F.Cu) (tedit 556FDE77) (tstamp 583159A1) + (at 171.0055 127.889 90) + (descr "SMT capacitor, aluminium electrolytic, 4x5.3") + (path /560735FE) + (attr smd) + (fp_text reference C15 (at 0 -3.175 90) (layer F.SilkS) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_text value CP1 (at 0 3.175 90) (layer F.Fab) + (effects (font (size 1 1) (thickness 0.15))) + ) + (fp_line (start -3.35 -2.65) (end 3.35 -2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.35 -2.65) (end 3.35 2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 3.35 2.65) (end -3.35 2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start -3.35 2.65) (end -3.35 -2.65) (layer F.CrtYd) (width 0.05)) + (fp_line (start 1.651 0) (end 0.889 0) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.27 -0.381) (end 1.27 0.381) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 2.286) (end -2.286 2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 2.286 -1.524) (end 2.286 1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 2.286) (end 2.286 1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 -2.286) (end -2.286 -2.286) (layer F.SilkS) (width 0.15)) + (fp_line (start 1.524 -2.286) (end 2.286 -1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.032 0.127) (end -2.032 -0.127) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.905 -0.635) (end -1.905 0.635) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.778 0.889) (end -1.778 -0.889) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.651 1.143) (end -1.651 -1.143) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.524 -1.27) (end -1.524 1.27) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.397 1.397) (end -1.397 -1.397) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.27 -1.524) (end -1.27 1.524) (layer F.SilkS) (width 0.15)) + (fp_line (start -1.143 -1.651) (end -1.143 1.651) (layer F.SilkS) (width 0.15)) + (fp_line (start -2.286 -2.286) (end -2.286 2.286) (layer F.SilkS) (width 0.15)) + (fp_circle (center 0 0) (end -2.032 0) (layer F.SilkS) (width 0.15)) + (pad 1 smd rect (at 1.80086 0 90) (size 2.60096 1.6002) (layers F.Cu F.Paste F.Mask) + (net 5 /OPAMP_VCC)) + (pad 2 smd rect (at -1.80086 0 90) (size 2.60096 1.6002) (layers F.Cu F.Paste F.Mask) + (net 2 /VGND)) + (model Capacitors_SMD.3dshapes/c_elec_4x5.3.wrl + (at (xyz 0 0 0)) + (scale (xyz 1 1 1)) + (rotate (xyz 0 0 0)) + ) + ) + + (module labralogo:logo300dpi (layer F.Cu) (tedit 0) (tstamp 58316E86) + (at 153.162 83.439) + (fp_text reference G*** (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value LOGO (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy 3.466938 -5.214928) (xy 3.857397 -5.124031) (xy 4.263401 -4.968212) (xy 4.636657 -4.772042) + (xy 4.928872 -4.56009) (xy 5.0695 -4.39958) (xy 5.167722 -4.159212) (xy 5.259584 -3.786272) + (xy 5.336134 -3.317501) (xy 5.339456 -3.291752) (xy 5.38969 -2.599426) (xy 5.356104 -1.913759) + (xy 5.232828 -1.198676) (xy 5.013992 -0.418103) (xy 4.752972 0.312122) (xy 4.54349 0.861457) + (xy 4.38779 1.29149) (xy 4.276636 1.640089) (xy 4.200793 1.945121) (xy 4.151026 2.244454) + (xy 4.118099 2.575957) (xy 4.092777 2.977497) (xy 4.089871 3.031069) (xy 4.069579 3.450741) + (xy 4.065087 3.738966) (xy 4.08065 3.933239) (xy 4.120519 4.071053) (xy 4.188947 4.189901) + (xy 4.227372 4.243378) (xy 4.359937 4.484976) (xy 4.343128 4.647775) (xy 4.177458 4.730448) + (xy 4.034062 4.741333) (xy 3.782229 4.696562) (xy 3.613104 4.540215) (xy 3.607624 4.531963) + (xy 3.498587 4.298159) (xy 3.390429 3.956239) (xy 3.29799 3.566846) (xy 3.236109 3.19062) + (xy 3.218585 2.942167) (xy 3.197833 2.738031) (xy 3.147946 2.629868) (xy 3.132667 2.624667) + (xy 3.079717 2.701024) (xy 3.05352 2.901526) (xy 3.052815 3.183316) (xy 3.076341 3.503539) + (xy 3.122837 3.819339) (xy 3.174157 4.034747) (xy 3.280158 4.312186) (xy 3.407695 4.539493) + (xy 3.47049 4.61357) (xy 3.631003 4.82913) (xy 3.645859 5.021224) (xy 3.538696 5.162882) + (xy 3.333154 5.227133) (xy 3.052873 5.187006) (xy 2.988482 5.163501) (xy 2.74463 4.982845) + (xy 2.513635 4.653465) (xy 2.305482 4.195943) (xy 2.130155 3.630863) (xy 2.035263 3.198279) + (xy 1.975413 2.897453) (xy 1.918916 2.723068) (xy 1.838943 2.63494) (xy 1.708662 2.592889) + (xy 1.620645 2.577316) (xy 1.303586 2.512982) (xy 0.985921 2.420614) (xy 0.625205 2.285097) + (xy 0.178993 2.091317) (xy -0.084666 1.970077) (xy -0.889 1.595681) (xy -1.100666 1.867329) + (xy -1.257686 2.059693) (xy -1.48518 2.327376) (xy -1.740179 2.619988) (xy -1.803225 2.691171) + (xy -2.062664 2.998348) (xy -2.305674 3.312329) (xy -2.487069 3.574185) (xy -2.512729 3.616397) + (xy -2.731341 3.98943) (xy -2.492295 4.23894) (xy -2.344067 4.419635) (xy -2.31914 4.537274) + (xy -2.351574 4.586774) (xy -2.494502 4.628399) (xy -2.717107 4.604053) (xy -2.95211 4.531889) + (xy -3.132229 4.430059) (xy -3.18624 4.361573) (xy -3.197363 4.221086) (xy -3.181692 3.97167) + (xy -3.148721 3.710146) (xy -3.110299 3.430142) (xy -3.090843 3.225891) (xy -3.093718 3.145629) + (xy -3.148006 3.185316) (xy -3.236614 3.339444) (xy -3.339035 3.562239) (xy -3.434765 3.807929) + (xy -3.503298 4.03074) (xy -3.515765 4.087742) (xy -3.529504 4.365747) (xy -3.437885 4.627318) + (xy -3.394854 4.704137) (xy -3.276834 4.952445) (xy -3.284468 5.099227) (xy -3.421492 5.160476) + (xy -3.502481 5.164667) (xy -3.763411 5.106627) (xy -3.94226 4.92242) (xy -4.051575 4.596911) + (xy -4.071412 4.47853) (xy -4.133056 3.914109) (xy -4.134209 3.451638) (xy -4.069688 3.03302) + (xy -3.934308 2.600159) (xy -3.894667 2.497667) (xy -3.743593 2.068545) (xy -3.664891 1.695985) + (xy -3.640771 1.293214) (xy -3.640666 1.258737) (xy -3.644766 0.948019) (xy -3.662859 0.775038) + (xy -3.703635 0.708282) (xy -3.775787 0.716237) (xy -3.788833 0.721496) (xy -4.172138 0.818955) + (xy -4.590526 0.825196) (xy -4.980569 0.745583) (xy -5.265477 0.596619) (xy -5.458251 0.440519) + (xy -5.078626 0.339501) (xy -4.468619 0.108322) (xy -3.849417 -0.252108) (xy -3.2706 -0.712236) + (xy -3.195567 -0.78297) (xy -2.945753 -1.021893) (xy -2.736285 -1.206254) (xy -2.54027 -1.343693) + (xy -2.330814 -1.441848) (xy -2.081024 -1.508358) (xy -1.764006 -1.550862) (xy -1.352866 -1.576999) + (xy -0.820711 -1.594408) (xy -0.294215 -1.607081) (xy 1.570569 -1.651) (xy 2.121767 -1.92252) + (xy 2.429882 -2.090375) (xy 2.701893 -2.266452) (xy 2.874407 -2.408466) (xy 3.003415 -2.559818) + (xy 3.021677 -2.659331) (xy 2.938836 -2.774249) (xy 2.928503 -2.785709) (xy 2.78394 -2.907924) + (xy 2.541411 -3.077111) (xy 2.251187 -3.258387) (xy 2.226124 -3.273121) (xy 1.755741 -3.603786) + (xy 1.440244 -3.952388) (xy 1.285578 -4.3115) (xy 1.27 -4.467311) (xy 1.294609 -4.668434) + (xy 1.321034 -4.699) (xy 2.963334 -4.699) (xy 3.006293 -4.593627) (xy 3.05435 -4.588228) + (xy 3.141825 -4.675636) (xy 3.145367 -4.699) (xy 3.079452 -4.798275) (xy 3.05435 -4.809772) + (xy 2.977148 -4.768902) (xy 2.963334 -4.699) (xy 1.321034 -4.699) (xy 1.388138 -4.776619) + (xy 1.580138 -4.804613) (xy 1.900159 -4.765161) (xy 1.94288 -4.757536) (xy 2.203458 -4.717801) + (xy 2.377899 -4.731401) (xy 2.540291 -4.818509) (xy 2.732831 -4.972632) (xy 2.955213 -5.144606) + (xy 3.127741 -5.222972) (xy 3.322568 -5.231547) (xy 3.466938 -5.214928)) (layer F.SilkS) (width 0.01)) + ) + + (segment (start 172.49475 111.98225) (end 172.49775 111.97925) (width 0.25) (layer F.Cu) (net 1) (tstamp 58317579)) + (segment (start 171.4809 111.7806) (end 171.27925 111.98225) (width 0.25) (layer F.Cu) (net 1) (tstamp 58317576)) + (segment (start 161.925 106.045) (end 162.814 106.045) (width 0.635) (layer B.Cu) (net 1)) + (segment (start 162.814 106.045) (end 165.1 108.331) (width 0.635) (layer B.Cu) (net 1) (tstamp 58316155)) + (segment (start 171.4809 108.2349) (end 171.2595 108.0135) (width 0.25) (layer F.Cu) (net 1) (tstamp 5831614F)) + (via (at 171.2595 108.0135) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 1)) + (segment (start 171.4809 109.51254) (end 171.4809 108.2349) (width 0.25) (layer F.Cu) (net 1)) + (segment (start 168.5925 108.0135) (end 171.2595 108.0135) (width 0.635) (layer B.Cu) (net 1) (tstamp 58316158)) + (segment (start 168.275 108.331) (end 168.5925 108.0135) (width 0.635) (layer B.Cu) (net 1) (tstamp 58316157)) + (segment (start 165.1 108.331) (end 168.275 108.331) (width 0.635) (layer B.Cu) (net 1) (tstamp 58316156)) + (segment (start 161.925 106.045) (end 161.925 108.331) (width 1.27) (layer B.Cu) (net 1)) + (segment (start 158.89986 112.29086) (end 158.89986 113.8555) (width 1.27) (layer F.Cu) (net 1) (tstamp 58316135)) + (segment (start 158.6865 112.0775) (end 158.89986 112.29086) (width 1.27) (layer F.Cu) (net 1) (tstamp 58316134)) + (via (at 158.6865 112.0775) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 1)) + (segment (start 159.639 111.125) (end 158.6865 112.0775) (width 1.27) (layer B.Cu) (net 1) (tstamp 58316132)) + (segment (start 159.639 109.9185) (end 159.639 111.125) (width 1.27) (layer B.Cu) (net 1) (tstamp 58316131)) + (segment (start 160.4645 109.093) (end 159.639 109.9185) (width 1.27) (layer B.Cu) (net 1) (tstamp 58316130)) + (segment (start 161.163 109.093) (end 160.4645 109.093) (width 1.27) (layer B.Cu) (net 1) (tstamp 5831612F)) + (segment (start 161.925 108.331) (end 161.163 109.093) (width 1.27) (layer B.Cu) (net 1) (tstamp 5831612E)) + (segment (start 161.29 115.455) (end 160.49936 115.455) (width 0.635) (layer F.Cu) (net 1)) + (segment (start 160.49936 115.455) (end 158.89986 113.8555) (width 0.635) (layer F.Cu) (net 1) (tstamp 5831610F)) + (segment (start 161.0995 118.4395) (end 161.0995 117.1455) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 161.0995 117.1455) (end 161.29 116.955) (width 0.25) (layer F.Cu) (net 2) (tstamp 583177F9)) + (segment (start 153.67 107.95) (end 153.67 108.712) (width 1.27) (layer F.Cu) (net 2)) + (segment (start 153.67 108.712) (end 155.29814 110.34014) (width 1.27) (layer F.Cu) (net 2) (tstamp 58317718)) + (segment (start 155.29814 110.34014) (end 155.29814 113.8555) (width 1.27) (layer F.Cu) (net 2) (tstamp 58317719)) + (segment (start 170.15714 117.7925) (end 170.15714 115.09064) (width 0.4) (layer F.Cu) (net 2)) + (segment (start 170.15714 115.09064) (end 169.8625 114.796) (width 0.4) (layer F.Cu) (net 2) (tstamp 583175FA)) + (segment (start 167.8305 115.201) (end 169.4575 115.201) (width 0.4) (layer F.Cu) (net 2)) + (segment (start 169.4575 115.201) (end 169.8625 114.796) (width 0.4) (layer F.Cu) (net 2) (tstamp 583175E3)) + (segment (start 169.8625 114.796) (end 171.531 114.796) (width 0.4) (layer F.Cu) (net 2)) + (segment (start 171.531 114.796) (end 171.54775 114.77925) (width 0.4) (layer F.Cu) (net 2) (tstamp 583175BE)) + (segment (start 169.7115 114.947) (end 169.8625 114.796) (width 0.4) (layer F.Cu) (net 2) (tstamp 583175BB)) + (segment (start 169.76725 111.98225) (end 169.77925 111.98225) (width 0.4) (layer F.Cu) (net 2) (tstamp 58317599)) + (segment (start 169.77925 111.98225) (end 169.77925 111.74025) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 167.8305 115.201) (end 166.636 115.201) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 166.636 115.201) (end 165.735 114.3) (width 0.25) (layer F.Cu) (net 2) (tstamp 58317519)) + (segment (start 171.0055 129.68986) (end 170.60164 129.68986) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 170.60164 129.68986) (end 169.4815 130.81) (width 0.25) (layer F.Cu) (net 2) (tstamp 58317269)) + (segment (start 162.179 130.4925) (end 162.179 130.1445) (width 0.25) (layer F.Cu) (net 2) (tstamp 58317272)) + (via (at 162.179 130.4925) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 2)) + (segment (start 166.0525 130.4925) (end 162.179 130.4925) (width 0.25) (layer B.Cu) (net 2) (tstamp 58317270)) + (segment (start 166.37 130.175) (end 166.0525 130.4925) (width 0.25) (layer B.Cu) (net 2) (tstamp 5831726F)) + (segment (start 167.3225 130.175) (end 166.37 130.175) (width 0.25) (layer B.Cu) (net 2) (tstamp 5831726E)) + (segment (start 168.021 130.8735) (end 167.3225 130.175) (width 0.25) (layer B.Cu) (net 2) (tstamp 5831726D)) + (segment (start 169.418 130.8735) (end 168.021 130.8735) (width 0.25) (layer B.Cu) (net 2) (tstamp 5831726C)) + (segment (start 169.4815 130.81) (end 169.418 130.8735) (width 0.25) (layer B.Cu) (net 2) (tstamp 5831726B)) + (via (at 169.4815 130.81) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 2)) + (segment (start 168.18286 129.68986) (end 167.64 129.147) (width 1.27) (layer F.Cu) (net 2) (tstamp 5831721D)) + (segment (start 171.0055 129.68986) (end 168.18286 129.68986) (width 1.27) (layer F.Cu) (net 2)) + (segment (start 153.416 107.95) (end 149.6695 111.6965) (width 1.27) (layer B.Cu) (net 2) (tstamp 58317183)) + (segment (start 149.6695 111.6965) (end 153.416 107.95) (width 0.25) (layer B.Cu) (net 2) (tstamp 5831717D)) + (segment (start 149.6695 111.6965) (end 149.6695 125.349) (width 1.27) (layer B.Cu) (net 2) (tstamp 58317184)) + (segment (start 149.6695 124.968) (end 149.6695 111.6965) (width 0.25) (layer B.Cu) (net 2) (tstamp 58317187)) + (segment (start 150.6855 126.238) (end 150.368 126.238) (width 0.635) (layer B.Cu) (net 2)) + (segment (start 150.888 126.0355) (end 150.6855 126.238) (width 0.25) (layer F.Cu) (net 2) (tstamp 58317177)) + (via (at 150.6855 126.238) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 2)) + (segment (start 150.6855 126.238) (end 150.622 126.3015) (width 0.25) (layer B.Cu) (net 2) (tstamp 58317179)) + (segment (start 150.622 126.3015) (end 150.3045 126.3015) (width 0.25) (layer B.Cu) (net 2) (tstamp 5831717A)) + (segment (start 150.3045 126.3015) (end 149.6695 125.6665) (width 0.25) (layer B.Cu) (net 2) (tstamp 5831717B)) + (segment (start 149.6695 125.6665) (end 149.6695 124.968) (width 0.25) (layer B.Cu) (net 2) (tstamp 5831717C)) + (segment (start 151.7015 126.0355) (end 150.888 126.0355) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 149.6695 125.349) (end 149.6695 124.968) (width 1.27) (layer B.Cu) (net 2) (tstamp 5831718F)) + (segment (start 150.368 126.238) (end 149.733 125.603) (width 0.635) (layer B.Cu) (net 2) (tstamp 5831718B)) + (segment (start 149.733 125.603) (end 149.733 125.349) (width 0.635) (layer B.Cu) (net 2) (tstamp 5831718C)) + (segment (start 149.733 125.349) (end 149.6695 125.349) (width 0.635) (layer B.Cu) (net 2) (tstamp 5831718E)) + (segment (start 153.67 107.95) (end 153.416 107.95) (width 1.27) (layer B.Cu) (net 2)) + (segment (start 162.179 130.1445) (end 162.179 128.905) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 151.7015 127.635) (end 151.7015 127.139) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316F68)) + (segment (start 152.019 127.9525) (end 151.7015 127.635) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316F67)) + (segment (start 161.2265 127.9525) (end 152.019 127.9525) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316F66)) + (segment (start 162.179 128.905) (end 161.2265 127.9525) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316F65)) + (segment (start 151.7015 126.0355) (end 151.7135 126.0355) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 159.3215 122.7455) (end 158.75 122.7455) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 157.861 121.4755) (end 157.2895 121.4755) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316E66)) + (segment (start 158.242 121.8565) (end 157.861 121.4755) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316E65)) + (segment (start 158.242 122.2375) (end 158.242 121.8565) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316E64)) + (segment (start 158.75 122.7455) (end 158.242 122.2375) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316E63)) + (segment (start 157.2895 121.4755) (end 157.2895 121.2215) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 156.337 118.433) (end 157.61 117.16) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316E5F)) + (segment (start 156.337 120.269) (end 156.337 118.433) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316E5E)) + (segment (start 157.2895 121.2215) (end 156.337 120.269) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316E5D)) + (segment (start 151.7015 127.139) (end 151.7015 126.0355) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 161.29 116.955) (end 161.29 116.84) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 161.29 116.84) (end 162.2425 115.8875) (width 0.25) (layer F.Cu) (net 2) (tstamp 5831615F)) + (segment (start 164.4015 115.6335) (end 165.735 114.3) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316163)) + (segment (start 162.433 115.6335) (end 164.4015 115.6335) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316162)) + (segment (start 162.2425 115.824) (end 162.433 115.6335) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316161)) + (segment (start 162.2425 115.8875) (end 162.2425 115.824) (width 0.25) (layer F.Cu) (net 2) (tstamp 58316160)) + (segment (start 167.6809 109.51254) (end 168.8809 109.51254) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 173.6809 106.81254) (end 173.6809 108.51254) (width 1.27) (layer F.Cu) (net 2)) + (segment (start 173.6809 108.51254) (end 172.6809 109.51254) (width 1.27) (layer F.Cu) (net 2) (tstamp 58316148)) + (segment (start 166.6809 106.81254) (end 173.6809 106.81254) (width 1.27) (layer F.Cu) (net 2)) + (segment (start 167.6809 109.51254) (end 167.6809 107.81254) (width 1.27) (layer F.Cu) (net 2)) + (segment (start 167.6809 107.81254) (end 166.6809 106.81254) (width 1.27) (layer F.Cu) (net 2) (tstamp 58316143)) + (segment (start 165.735 114.3) (end 165.735 111.45844) (width 1.27) (layer F.Cu) (net 2)) + (segment (start 165.735 111.45844) (end 167.6809 109.51254) (width 1.27) (layer F.Cu) (net 2) (tstamp 58316140)) + (segment (start 159.385 117.36) (end 160.885 117.36) (width 0.635) (layer F.Cu) (net 2)) + (segment (start 160.885 117.36) (end 161.29 116.955) (width 0.635) (layer F.Cu) (net 2) (tstamp 5831610A)) + (segment (start 159.385 117.36) (end 157.81 117.36) (width 0.635) (layer F.Cu) (net 2)) + (segment (start 157.81 117.36) (end 157.61 117.16) (width 0.635) (layer F.Cu) (net 2) (tstamp 58316107)) + (segment (start 155.29814 113.8555) (end 155.29814 114.84814) (width 0.635) (layer F.Cu) (net 2)) + (segment (start 155.29814 114.84814) (end 157.61 117.16) (width 0.635) (layer F.Cu) (net 2) (tstamp 58316103)) + (segment (start 155.29814 113.8555) (end 155.29814 113.57864) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 157.81 117.36) (end 157.61 117.16) (width 0.25) (layer F.Cu) (net 2) (tstamp 583160A7)) + (segment (start 152.9207 105.41) (end 152.9207 107.2007) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 152.9207 107.2007) (end 153.67 107.95) (width 0.25) (layer F.Cu) (net 2) (tstamp 58315F80)) + (segment (start 153.67 107.95) (end 147.32 107.95) (width 0.25) (layer F.Cu) (net 2)) + (segment (start 147.32 107.95) (end 146.05 109.22) (width 0.25) (layer F.Cu) (net 2) (tstamp 58315F31)) + (segment (start 173.44775 114.77925) (end 175.38225 114.77925) (width 0.4) (layer F.Cu) (net 3)) + (segment (start 175.38225 114.77925) (end 175.7045 115.1015) (width 0.4) (layer F.Cu) (net 3) (tstamp 58317700)) + (segment (start 173.75886 117.7925) (end 173.75886 115.09036) (width 0.4) (layer F.Cu) (net 3)) + (segment (start 173.75886 115.09036) (end 173.44775 114.77925) (width 0.4) (layer F.Cu) (net 3) (tstamp 583175FD)) + (segment (start 169.8625 113.296) (end 171.9645 113.296) (width 0.4) (layer F.Cu) (net 3)) + (segment (start 171.9645 113.296) (end 173.44775 114.77925) (width 0.4) (layer F.Cu) (net 3) (tstamp 583175C1)) + (segment (start 169.05986 126.08814) (end 171.0055 126.08814) (width 1.27) (layer F.Cu) (net 5) (tstamp 58317221)) + (segment (start 167.64 127.508) (end 169.05986 126.08814) (width 1.27) (layer F.Cu) (net 5) (tstamp 58317220)) + (segment (start 167.64 127.647) (end 167.64 127.508) (width 1.27) (layer F.Cu) (net 5)) + (segment (start 171.958 125.13564) (end 171.0055 126.08814) (width 1.27) (layer F.Cu) (net 5) (tstamp 5831721A)) + (segment (start 171.958 123.8145) (end 171.958 125.13564) (width 1.27) (layer F.Cu) (net 5)) + (segment (start 171.37414 125.021) (end 171.069 125.32614) (width 0.635) (layer F.Cu) (net 5) (tstamp 583171CA)) + (segment (start 154.4193 105.41) (end 155.46 105.41) (width 0.25) (layer F.Cu) (net 6)) + (segment (start 167.8305 116.701) (end 165.874 116.701) (width 0.25) (layer F.Cu) (net 7)) + (segment (start 165.874 116.701) (end 165.735 116.84) (width 0.25) (layer F.Cu) (net 7) (tstamp 58317520)) + (segment (start 167.8305 117.868) (end 167.8305 116.701) (width 0.25) (layer F.Cu) (net 7)) + (segment (start 165.874 116.701) (end 165.735 116.84) (width 0.25) (layer F.Cu) (net 7) (tstamp 58317516)) + (segment (start 158.369 124.7445) (end 159.639 124.7445) (width 0.25) (layer F.Cu) (net 8)) + (segment (start 159.385 118.86) (end 157.81 118.86) (width 0.635) (layer F.Cu) (net 25)) + (segment (start 157.81 118.86) (end 157.61 119.06) (width 0.635) (layer F.Cu) (net 25) (tstamp 5831613B)) + (segment (start 164.719 124.7445) (end 165.989 124.7445) (width 0.25) (layer F.Cu) (net 32)) + (segment (start 180.5185 126.873) (end 181.622 126.873) (width 0.25) (layer F.Cu) (net 34)) + (segment (start 169.545 120.9145) (end 171.958 120.9145) (width 1.27) (layer F.Cu) (net 35)) + (segment (start 163.195 114.3) (end 163.195 113.3475) (width 1.27) (layer F.Cu) (net 36)) + (segment (start 163.195 113.3475) (end 164.0205 112.522) (width 1.27) (layer F.Cu) (net 36) (tstamp 583160E3)) + (segment (start 164.0205 112.522) (end 164.0205 109.6645) (width 1.27) (layer F.Cu) (net 36) (tstamp 583160E4)) + (segment (start 164.0205 109.6645) (end 162.306 107.95) (width 1.27) (layer F.Cu) (net 36) (tstamp 583160E5)) + (segment (start 162.306 107.95) (end 156.21 107.95) (width 1.27) (layer F.Cu) (net 36) (tstamp 583160E6)) + (segment (start 156.96 105.41) (end 156.96 107.2) (width 0.25) (layer F.Cu) (net 36)) + (segment (start 156.96 107.2) (end 156.21 107.95) (width 0.25) (layer F.Cu) (net 36) (tstamp 58315F85)) + (segment (start 150.356 121.666) (end 150.356 122.833) (width 0.25) (layer F.Cu) (net 37)) + (segment (start 150.356 122.833) (end 150.1775 123.0115) (width 0.25) (layer F.Cu) (net 37) (tstamp 58316DF8)) + (segment (start 149.848 127.5715) (end 149.848 128.5875) (width 0.25) (layer F.Cu) (net 38)) + (segment (start 149.848 128.5875) (end 150.114 128.8535) (width 0.25) (layer F.Cu) (net 38) (tstamp 58316E29)) + (segment (start 154.305 122.55754) (end 154.305 118.745) (width 1.27) (layer B.Cu) (net 39)) + (segment (start 154.305 118.745) (end 161.925 111.125) (width 1.27) (layer B.Cu) (net 39) (tstamp 58316118)) + (segment (start 154.81 118.11) (end 154.81 122.05254) (width 1.27) (layer F.Cu) (net 39)) + (segment (start 154.81 122.05254) (end 154.305 122.55754) (width 1.27) (layer F.Cu) (net 39) (tstamp 583160F4)) + (segment (start 161.3535 111.125) (end 161.925 111.125) (width 0.25) (layer B.Cu) (net 39) (tstamp 583160B9)) + (segment (start 154.81 122.05254) (end 154.305 122.55754) (width 0.25) (layer F.Cu) (net 39) (tstamp 583160B3)) + (segment (start 177.038 124.333) (end 177.038 124.46) (width 0.25) (layer B.Cu) (net 40)) + (segment (start 177.038 124.46) (end 178.308 125.73) (width 0.25) (layer B.Cu) (net 40) (tstamp 58321FE5)) + (segment (start 180.721 125.73) (end 182.118 124.333) (width 0.25) (layer B.Cu) (net 40) (tstamp 58321FE8)) + (segment (start 178.308 125.73) (end 180.721 125.73) (width 0.25) (layer B.Cu) (net 40) (tstamp 58321FE6)) + (segment (start 174.5615 124.8925) (end 176.4785 124.8925) (width 0.25) (layer F.Cu) (net 40)) + (segment (start 176.4785 124.8925) (end 177.038 124.333) (width 0.25) (layer F.Cu) (net 40) (tstamp 58321FB6)) + (segment (start 177.915 126.873) (end 177.915 125.21) (width 0.25) (layer F.Cu) (net 40)) + (segment (start 177.915 125.21) (end 177.038 124.333) (width 0.25) (layer F.Cu) (net 40) (tstamp 5831789A)) + (segment (start 182.118 124.333) (end 184.658 124.333) (width 0.25) (layer F.Cu) (net 40)) + (segment (start 177.038 124.333) (end 177.038 124.206) (width 0.25) (layer F.Cu) (net 40)) + (segment (start 174.5615 123.3925) (end 175.1845 123.3925) (width 0.25) (layer F.Cu) (net 41)) + (segment (start 178.689 122.809) (end 179.578 123.698) (width 0.25) (layer F.Cu) (net 41) (tstamp 58321FD4)) + (segment (start 175.768 122.809) (end 178.689 122.809) (width 0.25) (layer F.Cu) (net 41) (tstamp 58321FD3)) + (segment (start 175.1845 123.3925) (end 175.768 122.809) (width 0.25) (layer F.Cu) (net 41) (tstamp 58321FD2)) + (segment (start 179.578 123.698) (end 179.578 124.333) (width 0.25) (layer F.Cu) (net 41) (tstamp 58321FD5)) + (segment (start 174.5615 123.3925) (end 174.74 123.3925) (width 0.25) (layer F.Cu) (net 41)) + (segment (start 177.038 129.4765) (end 177.2285 129.4765) (width 0.25) (layer B.Cu) (net 42)) + (segment (start 177.2285 129.4765) (end 178.7525 127.9525) (width 0.25) (layer B.Cu) (net 42) (tstamp 58321FDF)) + (segment (start 181.229 127.9525) (end 182.118 128.8415) (width 0.25) (layer B.Cu) (net 42) (tstamp 58321FE1)) + (segment (start 178.7525 127.9525) (end 181.229 127.9525) (width 0.25) (layer B.Cu) (net 42) (tstamp 58321FE0)) + (segment (start 182.118 128.8415) (end 182.118 129.4765) (width 0.25) (layer B.Cu) (net 42) (tstamp 58321FE2)) + (segment (start 177.038 129.4765) (end 177.038 130.2385) (width 0.25) (layer F.Cu) (net 42)) + (segment (start 174.498 129.044) (end 176.6055 129.044) (width 0.25) (layer F.Cu) (net 42)) + (segment (start 176.6055 129.044) (end 177.038 129.4765) (width 0.25) (layer F.Cu) (net 42) (tstamp 58321FC3)) + (segment (start 184.658 129.4765) (end 182.118 129.4765) (width 0.25) (layer F.Cu) (net 42)) + (segment (start 185.7255 126.873) (end 185.7255 128.409) (width 0.25) (layer F.Cu) (net 42)) + (segment (start 185.7255 128.409) (end 184.658 129.4765) (width 0.25) (layer F.Cu) (net 42) (tstamp 58321F84)) + (segment (start 174.498 130.544) (end 175.5655 130.544) (width 0.25) (layer F.Cu) (net 43)) + (segment (start 179.578 130.6195) (end 179.578 129.4765) (width 0.25) (layer F.Cu) (net 43) (tstamp 58321FDC)) + (segment (start 179.2605 130.937) (end 179.578 130.6195) (width 0.25) (layer F.Cu) (net 43) (tstamp 58321FDB)) + (segment (start 175.9585 130.937) (end 179.2605 130.937) (width 0.25) (layer F.Cu) (net 43) (tstamp 58321FDA)) + (segment (start 175.5655 130.544) (end 175.9585 130.937) (width 0.25) (layer F.Cu) (net 43) (tstamp 58321FD9)) + (segment (start 148.59 124.5115) (end 146.1015 124.5115) (width 0.25) (layer F.Cu) (net 44)) + (segment (start 146.1015 124.5115) (end 146.05 124.46) (width 0.25) (layer F.Cu) (net 44) (tstamp 58316DE7)) + (segment (start 148.856 121.666) (end 148.856 122.3525) (width 0.25) (layer F.Cu) (net 45)) + (segment (start 148.856 122.3525) (end 148.59 122.6185) (width 0.25) (layer F.Cu) (net 45) (tstamp 58316DE3)) + (segment (start 148.59 122.6185) (end 148.59 123.0115) (width 0.25) (layer F.Cu) (net 45) (tstamp 58316DE4)) + (segment (start 146.05 121.92) (end 148.602 121.92) (width 0.25) (layer F.Cu) (net 45)) + (segment (start 148.602 121.92) (end 148.856 121.666) (width 0.25) (layer F.Cu) (net 45) (tstamp 58316DE0)) + (segment (start 146.05 129.54) (end 147.5225 129.54) (width 0.25) (layer F.Cu) (net 46)) + (segment (start 147.5225 129.54) (end 148.59 130.6075) (width 0.25) (layer F.Cu) (net 46) (tstamp 58316E25)) + (segment (start 148.59 129.1075) (end 148.59 127.8135) (width 0.25) (layer F.Cu) (net 47)) + (segment (start 148.59 127.8135) (end 148.348 127.5715) (width 0.25) (layer F.Cu) (net 47) (tstamp 58316E22)) + (segment (start 148.348 127.5715) (end 146.6215 127.5715) (width 0.25) (layer F.Cu) (net 47)) + (segment (start 146.6215 127.5715) (end 146.05 127) (width 0.25) (layer F.Cu) (net 47) (tstamp 58316E1F)) + (segment (start 175.7045 112.1015) (end 175.7045 109.728) (width 0.4) (layer F.Cu) (net 48)) + (segment (start 147.5105 105.2195) (end 146.05 106.68) (width 0.4) (layer F.Cu) (net 48) (tstamp 58317713)) + (segment (start 151.511 105.2195) (end 147.5105 105.2195) (width 0.4) (layer F.Cu) (net 48) (tstamp 58317712)) + (segment (start 151.638 105.3465) (end 151.511 105.2195) (width 0.4) (layer F.Cu) (net 48) (tstamp 58317711)) + (via (at 151.638 105.3465) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 48)) + (segment (start 158.0515 105.3465) (end 151.638 105.3465) (width 0.4) (layer B.Cu) (net 48) (tstamp 5831770F)) + (segment (start 158.1785 105.4735) (end 158.0515 105.3465) (width 0.4) (layer B.Cu) (net 48) (tstamp 5831770E)) + (via (at 158.1785 105.4735) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 48)) + (segment (start 160.401 105.4735) (end 158.1785 105.4735) (width 0.4) (layer F.Cu) (net 48) (tstamp 5831770C)) + (segment (start 161.3535 104.521) (end 160.401 105.4735) (width 0.4) (layer F.Cu) (net 48) (tstamp 5831770B)) + (segment (start 163.3855 104.521) (end 161.3535 104.521) (width 0.4) (layer F.Cu) (net 48) (tstamp 5831770A)) + (segment (start 164.1475 105.283) (end 163.3855 104.521) (width 0.4) (layer F.Cu) (net 48) (tstamp 58317709)) + (segment (start 174.9425 105.283) (end 164.1475 105.283) (width 0.4) (layer F.Cu) (net 48) (tstamp 58317708)) + (segment (start 175.3235 105.664) (end 174.9425 105.283) (width 0.4) (layer F.Cu) (net 48) (tstamp 58317707)) + (segment (start 175.3235 109.347) (end 175.3235 105.664) (width 0.4) (layer F.Cu) (net 48) (tstamp 58317706)) + (segment (start 175.7045 109.728) (end 175.3235 109.347) (width 0.4) (layer F.Cu) (net 48) (tstamp 58317705)) + (segment (start 179.0185 126.873) (end 179.0185 127.75) (width 0.25) (layer F.Cu) (net 55)) + (segment (start 176.415 127.3295) (end 176.415 126.873) (width 0.25) (layer F.Cu) (net 55) (tstamp 58321F56)) + (segment (start 176.9745 127.889) (end 176.415 127.3295) (width 0.25) (layer F.Cu) (net 55) (tstamp 58321F55)) + (segment (start 178.8795 127.889) (end 176.9745 127.889) (width 0.25) (layer F.Cu) (net 55) (tstamp 58321F54)) + (segment (start 179.0185 127.75) (end 178.8795 127.889) (width 0.25) (layer F.Cu) (net 55) (tstamp 58321F53)) + (segment (start 183.122 126.873) (end 184.3405 126.873) (width 0.25) (layer F.Cu) (net 56)) + (segment (start 184.3405 126.873) (end 184.2255 126.873) (width 0.25) (layer F.Cu) (net 56) (tstamp 58321F81)) + (segment (start 156.591 127.0755) (end 157.116502 127.0755) (width 0.25) (layer F.Cu) (net 57)) + (segment (start 164.719 128.651) (end 164.719 130.1445) (width 0.25) (layer F.Cu) (net 57) (tstamp 58322017)) + (segment (start 164.338 128.27) (end 164.719 128.651) (width 0.25) (layer F.Cu) (net 57) (tstamp 58322016)) + (segment (start 163.0045 128.27) (end 164.338 128.27) (width 0.25) (layer F.Cu) (net 57) (tstamp 58322015)) + (segment (start 162.687 128.5875) (end 163.0045 128.27) (width 0.25) (layer F.Cu) (net 57) (tstamp 58322014)) + (segment (start 162.497898 128.5875) (end 162.687 128.5875) (width 0.25) (layer F.Cu) (net 57) (tstamp 58322013)) + (segment (start 161.291398 127.381) (end 162.497898 128.5875) (width 0.25) (layer F.Cu) (net 57) (tstamp 58322011)) + (segment (start 157.422002 127.381) (end 161.291398 127.381) (width 0.25) (layer F.Cu) (net 57) (tstamp 58322010)) + (segment (start 157.116502 127.0755) (end 157.422002 127.381) (width 0.25) (layer F.Cu) (net 57) (tstamp 5832200F)) + (segment (start 154.94 127.0755) (end 156.591 127.0755) (width 0.25) (layer F.Cu) (net 57)) + (segment (start 153.3525 127.139) (end 154.8765 127.139) (width 0.25) (layer F.Cu) (net 57)) + (segment (start 154.8765 127.139) (end 154.94 127.0755) (width 0.25) (layer F.Cu) (net 57) (tstamp 58316E33)) + (segment (start 156.591 128.5755) (end 160.135 128.5755) (width 0.25) (layer F.Cu) (net 58)) + (segment (start 160.274 121.4755) (end 159.3215 121.4755) (width 0.25) (layer F.Cu) (net 58) (tstamp 583170C7)) + (via (at 160.274 121.4755) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 58)) + (segment (start 160.5915 121.4755) (end 160.274 121.4755) (width 0.25) (layer B.Cu) (net 58) (tstamp 583170C5)) + (segment (start 161.6075 122.4915) (end 160.5915 121.4755) (width 0.25) (layer B.Cu) (net 58) (tstamp 583170BC)) + (segment (start 161.6075 127.127) (end 161.6075 122.4915) (width 0.25) (layer B.Cu) (net 58) (tstamp 5831709F)) + (segment (start 160.147 128.5875) (end 161.6075 127.127) (width 0.25) (layer B.Cu) (net 58) (tstamp 5831709E)) + (via (at 160.147 128.5875) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 58)) + (segment (start 160.135 128.5755) (end 160.147 128.5875) (width 0.25) (layer F.Cu) (net 58) (tstamp 58317097)) + (segment (start 154.94 128.5755) (end 156.591 128.5755) (width 0.25) (layer F.Cu) (net 58)) + (segment (start 159.639 130.1445) (end 159.639 129.286) (width 0.25) (layer F.Cu) (net 59)) + (segment (start 153.3525 125.5395) (end 153.3525 126.0355) (width 0.25) (layer F.Cu) (net 59) (tstamp 5831708E)) + (segment (start 152.9715 125.1585) (end 153.3525 125.5395) (width 0.25) (layer F.Cu) (net 59) (tstamp 5831708D)) + (segment (start 150.750398 125.1585) (end 152.9715 125.1585) (width 0.25) (layer F.Cu) (net 59) (tstamp 5831708C)) + (segment (start 149.924898 125.984) (end 150.750398 125.1585) (width 0.25) (layer F.Cu) (net 59) (tstamp 5831708B)) + (segment (start 149.2885 125.984) (end 149.924898 125.984) (width 0.25) (layer F.Cu) (net 59) (tstamp 58317085)) + (segment (start 149.098 126.1745) (end 149.2885 125.984) (width 0.25) (layer F.Cu) (net 59) (tstamp 58317084)) + (via (at 149.098 126.1745) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 59)) + (segment (start 148.532002 126.740498) (end 149.098 126.1745) (width 0.25) (layer B.Cu) (net 59) (tstamp 58317081)) + (segment (start 148.532002 128.143) (end 148.532002 126.740498) (width 0.25) (layer B.Cu) (net 59) (tstamp 5831707F)) + (segment (start 149.606 129.216998) (end 148.532002 128.143) (width 0.25) (layer B.Cu) (net 59) (tstamp 5831707D)) + (segment (start 151.632498 129.216998) (end 149.606 129.216998) (width 0.25) (layer B.Cu) (net 59) (tstamp 5831707B)) + (segment (start 152.648498 130.232998) (end 151.632498 129.216998) (width 0.25) (layer B.Cu) (net 59) (tstamp 58317079)) + (segment (start 156.469502 130.232998) (end 152.648498 130.232998) (width 0.25) (layer B.Cu) (net 59) (tstamp 58317078)) + (segment (start 156.6545 130.048) (end 156.469502 130.232998) (width 0.25) (layer B.Cu) (net 59) (tstamp 58317077)) + (via (at 156.6545 130.048) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 59)) + (segment (start 156.845 129.8575) (end 156.6545 130.048) (width 0.25) (layer F.Cu) (net 59) (tstamp 58317073)) + (segment (start 157.351602 129.8575) (end 156.845 129.8575) (width 0.25) (layer F.Cu) (net 59) (tstamp 5831706D)) + (segment (start 157.5435 129.665602) (end 157.351602 129.8575) (width 0.25) (layer F.Cu) (net 59) (tstamp 5831706B)) + (segment (start 157.5435 129.286) (end 157.5435 129.665602) (width 0.25) (layer F.Cu) (net 59) (tstamp 58317069)) + (segment (start 157.7975 129.032) (end 157.5435 129.286) (width 0.25) (layer F.Cu) (net 59) (tstamp 58317067)) + (segment (start 159.385 129.032) (end 157.7975 129.032) (width 0.25) (layer F.Cu) (net 59) (tstamp 58317065)) + (segment (start 159.639 129.286) (end 159.385 129.032) (width 0.25) (layer F.Cu) (net 59) (tstamp 58317063)) + (segment (start 154.94 126.0355) (end 156.464 126.0355) (width 0.25) (layer F.Cu) (net 59)) + (segment (start 153.3525 126.0355) (end 154.94 126.0355) (width 0.25) (layer F.Cu) (net 59)) + (segment (start 157.2895 122.7455) (end 157.2895 123.71) (width 0.25) (layer F.Cu) (net 60)) + (segment (start 157.2895 123.71) (end 156.464 124.5355) (width 0.25) (layer F.Cu) (net 60) (tstamp 58316EB9)) + (segment (start 154.94 124.5355) (end 156.464 124.5355) (width 0.25) (layer F.Cu) (net 60)) + (segment (start 150.1775 124.5115) (end 150.1775 125.095) (width 0.25) (layer F.Cu) (net 61)) + (segment (start 157.701 130.1445) (end 158.369 130.1445) (width 0.25) (layer F.Cu) (net 61) (tstamp 58316FDC)) + (segment (start 157.353 130.4925) (end 157.701 130.1445) (width 0.25) (layer F.Cu) (net 61) (tstamp 58316FDB)) + (via (at 157.353 130.4925) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 61)) + (segment (start 157.1625 130.683) (end 157.353 130.4925) (width 0.25) (layer B.Cu) (net 61) (tstamp 58316FD9)) + (segment (start 152.4 130.683) (end 157.1625 130.683) (width 0.25) (layer B.Cu) (net 61) (tstamp 58316FD7)) + (segment (start 151.384 129.667) (end 152.4 130.683) (width 0.25) (layer B.Cu) (net 61) (tstamp 58316FD6)) + (segment (start 149.352 129.667) (end 151.384 129.667) (width 0.25) (layer B.Cu) (net 61) (tstamp 58316FD4)) + (segment (start 148.082 128.397) (end 149.352 129.667) (width 0.25) (layer B.Cu) (net 61) (tstamp 58316FD2)) + (segment (start 148.082 126.111) (end 148.082 128.397) (width 0.25) (layer B.Cu) (net 61) (tstamp 58316FD1)) + (segment (start 148.2725 125.9205) (end 148.082 126.111) (width 0.25) (layer B.Cu) (net 61) (tstamp 58316FD0)) + (via (at 148.2725 125.9205) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 61)) + (segment (start 148.717 125.476) (end 148.2725 125.9205) (width 0.25) (layer F.Cu) (net 61) (tstamp 58316FCD)) + (segment (start 149.7965 125.476) (end 148.717 125.476) (width 0.25) (layer F.Cu) (net 61) (tstamp 58316FCC)) + (segment (start 150.1775 125.095) (end 149.7965 125.476) (width 0.25) (layer F.Cu) (net 61) (tstamp 58316FCB)) + (segment (start 158.275 130.2385) (end 158.369 130.1445) (width 0.25) (layer F.Cu) (net 61) (tstamp 58316F96)) + (segment (start 151.7015 124.5355) (end 153.3525 124.5355) (width 0.25) (layer F.Cu) (net 61)) + (segment (start 150.1775 124.5115) (end 151.6775 124.5115) (width 0.25) (layer F.Cu) (net 61)) + (segment (start 151.6775 124.5115) (end 151.7015 124.5355) (width 0.25) (layer F.Cu) (net 61) (tstamp 58316DFB)) + (segment (start 150.114 130.3535) (end 151.1815 130.3535) (width 0.25) (layer F.Cu) (net 62)) + (segment (start 167.038 130.1445) (end 165.989 130.1445) (width 0.25) (layer F.Cu) (net 62) (tstamp 58316F61)) + (segment (start 167.1955 130.302) (end 167.038 130.1445) (width 0.25) (layer F.Cu) (net 62) (tstamp 58316F60)) + (segment (start 167.1955 130.7465) (end 167.1955 130.302) (width 0.25) (layer F.Cu) (net 62) (tstamp 58316F5F)) + (segment (start 167.0685 130.8735) (end 167.1955 130.7465) (width 0.25) (layer F.Cu) (net 62) (tstamp 58316F5E)) + (via (at 167.0685 130.8735) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 62)) + (segment (start 166.751 131.191) (end 167.0685 130.8735) (width 0.25) (layer B.Cu) (net 62) (tstamp 58316F5C)) + (segment (start 152.019 131.191) (end 166.751 131.191) (width 0.25) (layer B.Cu) (net 62) (tstamp 58316F5B)) + (segment (start 151.257 130.429) (end 152.019 131.191) (width 0.25) (layer B.Cu) (net 62) (tstamp 58316F5A)) + (via (at 151.257 130.429) (size 0.6) (drill 0.4) (layers F.Cu B.Cu) (net 62)) + (segment (start 151.1815 130.3535) (end 151.257 130.429) (width 0.25) (layer F.Cu) (net 62) (tstamp 58316F58)) + (segment (start 153.3525 128.639) (end 151.7015 128.639) (width 0.25) (layer F.Cu) (net 62)) + (segment (start 150.114 130.3535) (end 150.114 130.2265) (width 0.25) (layer F.Cu) (net 62)) + (segment (start 150.114 130.2265) (end 151.7015 128.639) (width 0.25) (layer F.Cu) (net 62) (tstamp 58316E2C)) + (segment (start 165.735 119.38) (end 163.195 116.84) (width 0.4) (layer F.Cu) (net 64) (status C00000)) + (segment (start 165.735 119.38) (end 165.735 121.28754) (width 1.27) (layer F.Cu) (net 64) (status 400000)) + (segment (start 165.735 121.28754) (end 164.465 122.55754) (width 1.27) (layer F.Cu) (net 64) (tstamp 58336BB6) (status 800000)) + (segment (start 161.0995 119.9395) (end 161.3415 119.9395) (width 0.25) (layer F.Cu) (net 64)) + (segment (start 161.3415 119.9395) (end 162.1155 120.7135) (width 0.25) (layer F.Cu) (net 64) (tstamp 583177F3)) + (segment (start 162.1155 120.7135) (end 164.4015 120.7135) (width 0.25) (layer F.Cu) (net 64) (tstamp 583177F4)) + (segment (start 164.4015 120.7135) (end 165.735 119.38) (width 0.25) (layer F.Cu) (net 64) (tstamp 583177F5)) + (segment (start 167.8305 119.368) (end 165.747 119.368) (width 0.25) (layer F.Cu) (net 64)) + (segment (start 165.747 119.368) (end 165.735 119.38) (width 0.25) (layer F.Cu) (net 64) (tstamp 5831750F)) + (segment (start 168.28804 122.55754) (end 169.545 123.8145) (width 1.27) (layer F.Cu) (net 64) (tstamp 58317215)) + (segment (start 164.465 122.55754) (end 168.28804 122.55754) (width 1.27) (layer F.Cu) (net 64)) + (segment (start 164.52596 122.6185) (end 164.465 122.55754) (width 0.635) (layer F.Cu) (net 64) (tstamp 583171C4)) + (segment (start 163.195 116.84) (end 163.5125 116.84) (width 0.25) (layer B.Cu) (net 64)) + (segment (start 165.735 119.0625) (end 165.735 119.38) (width 0.25) (layer B.Cu) (net 64) (tstamp 583160BE)) + (segment (start 148.971 112.7005) (end 146.9905 112.7005) (width 0.25) (layer F.Cu) (net 66)) + (segment (start 146.9905 112.7005) (end 146.05 111.76) (width 0.25) (layer F.Cu) (net 66) (tstamp 58316E98)) + (segment (start 148.971 115.2405) (end 146.9905 115.2405) (width 0.25) (layer F.Cu) (net 67)) + (segment (start 146.9905 115.2405) (end 146.05 114.3) (width 0.25) (layer F.Cu) (net 67) (tstamp 58316E9B)) + (segment (start 148.971 116.344) (end 146.546 116.344) (width 0.25) (layer F.Cu) (net 68)) + (segment (start 146.546 116.344) (end 146.05 116.84) (width 0.25) (layer F.Cu) (net 68) (tstamp 58316E9E)) + (segment (start 148.971 118.9475) (end 146.4825 118.9475) (width 0.25) (layer F.Cu) (net 69)) + (segment (start 146.4825 118.9475) (end 146.05 119.38) (width 0.25) (layer F.Cu) (net 69) (tstamp 58316EA1)) + (segment (start 148.971 120.4475) (end 150.5585 120.4475) (width 0.25) (layer F.Cu) (net 72)) + (segment (start 148.971 117.844) (end 150.5585 117.844) (width 0.25) (layer F.Cu) (net 73)) + (segment (start 148.971 113.7405) (end 150.5585 113.7405) (width 0.25) (layer F.Cu) (net 74)) + (segment (start 148.971 111.2005) (end 150.5585 111.2005) (width 0.25) (layer F.Cu) (net 75)) + +) diff --git a/PCB/Tinylab_proto1.kicad_pcb.bak.recent.REMOVED.git-id b/PCB/Tinylab_proto1.kicad_pcb.bak.recent.REMOVED.git-id deleted file mode 100644 index bc746999..00000000 --- a/PCB/Tinylab_proto1.kicad_pcb.bak.recent.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f5e295c5ba7765410aae79e08f33e3fe32ac0c7f \ No newline at end of file diff --git a/PCB/Tinylab_proto1.net b/PCB/Tinylab_proto1.net new file mode 100644 index 00000000..b64e45f1 --- /dev/null +++ b/PCB/Tinylab_proto1.net @@ -0,0 +1,1071 @@ +(export (version D) + (design + (source C:/Users/Esposch/Documents/GitHub/Labrador/PCB/Tinylab_proto1.sch) + (date "9/05/2017 4:52:55 PM") + (tool "Eeschema 4.0.4-stable") + (sheet (number 1) (name /) (tstamps /) + (title_block + (title) + (company) + (rev) + (date) + (source Tinylab_proto1.sch) + (comment (number 1) (value "")) + (comment (number 2) (value "")) + (comment (number 3) (value "")) + (comment (number 4) (value ""))))) + (components + (comp (ref U2) + (value LM324) + (footprint Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm) + (libsource (lib Tinylab_proto1-rescue) (part LM324-RESCUE-Tinylab_proto1)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CA87E2)) + (comp (ref IC1) + (value ATXMEGA32A4U-AU) + (footprint Housings_QFP:LQFP-44_10x10mm_Pitch0.8mm) + (libsource (lib atmel) (part ATXMEGA16A4U-A)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CA8F25)) + (comp (ref P2) + (value USB_OTG) + (footprint Connect:USB_Micro-B_WIDE) + (libsource (lib conn) (part USB_OTG)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CA90D2)) + (comp (ref U1) + (value 78L05) + (footprint SMD:SOT-23-3) + (libsource (lib Tinylab_proto1-rescue) (part 78L05-RESCUE-Tinylab_proto1)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CA99FA)) + (comp (ref R1) + (value 1M) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CAAB95)) + (comp (ref R3) + (value 75K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CAABF4)) + (comp (ref R5) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CAAC5F)) + (comp (ref R6) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CAACD2)) + (comp (ref R4) + (value 75K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CAAD11)) + (comp (ref R2) + (value 1M) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CAAD4C)) + (comp (ref C2) + (value C) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C_Small)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CAB4DE)) + (comp (ref C1) + (value C) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C_Small)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CAB611)) + (comp (ref C3) + (value C_Small) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C_Small)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CB13E1)) + (comp (ref C4) + (value C_Small) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C_Small)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CB147C)) + (comp (ref R22) + (value 28R) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CB4680)) + (comp (ref C13) + (value C) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C_Small)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CB630B)) + (comp (ref R24) + (value 28R) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CB9020)) + (comp (ref R11) + (value 28R) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CBCD2A)) + (comp (ref R7) + (value 28R) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CBCDA5)) + (comp (ref R13) + (value 28R) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CBE0F4)) + (comp (ref R9) + (value 28R) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CBE16B)) + (comp (ref R14) + (value 28R) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CBE21C)) + (comp (ref R10) + (value 28R) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CBE2C7)) + (comp (ref R12) + (value 28R) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CBE362)) + (comp (ref R8) + (value 28R) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CBE401)) + (comp (ref P3) + (value DIG_OUT) + (footprint Pin_Headers:Pin_Header_Straight_1x04) + (libsource (lib conn) (part CONN_01X04)) + (sheetpath (names /) (tstamps /)) + (tstamp 55CBF4D5)) + (comp (ref C5) + (value C_Small) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C_Small)) + (sheetpath (names /) (tstamps /)) + (tstamp 55D60181)) + (comp (ref U4) + (value DMN63D8LDW) + (footprint TO_SOT_Packages_SMD:SOT-363) + (libsource (lib ESPO_PART) (part DMN63D8LDW)) + (sheetpath (names /) (tstamps /)) + (tstamp 55D6ACFD)) + (comp (ref P8) + (value DIG_IN) + (footprint Pin_Headers:Pin_Header_Straight_1x02) + (libsource (lib conn) (part CONN_01X02)) + (sheetpath (names /) (tstamps /)) + (tstamp 55D6DB77)) + (comp (ref F1) + (value F_Small) + (footprint Capacitors_SMD:C_1210) + (libsource (lib device) (part F_Small)) + (sheetpath (names /) (tstamps /)) + (tstamp 55D739F3)) + (comp (ref L1) + (value INDUCTOR) + (footprint Special_inductor:SMALL_INDUCTOR) + (libsource (lib device) (part INDUCTOR)) + (sheetpath (names /) (tstamps /)) + (tstamp 5606EE9E)) + (comp (ref D1) + (value D_Schottky) + (footprint Diodes_SMD:SMA_Standard) + (libsource (lib device) (part D_Schottky)) + (sheetpath (names /) (tstamps /)) + (tstamp 5606FDB4)) + (comp (ref C9) + (value CP1) + (footprint Capacitors_SMD:c_elec_4x5.3) + (libsource (lib device) (part CP1)) + (sheetpath (names /) (tstamps /)) + (tstamp 560719D9)) + (comp (ref C10) + (value C) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C)) + (sheetpath (names /) (tstamps /)) + (tstamp 56071A50)) + (comp (ref C16) + (value C) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C)) + (sheetpath (names /) (tstamps /)) + (tstamp 5607355F)) + (comp (ref C15) + (value CP1) + (footprint Capacitors_SMD:c_elec_4x5.3) + (libsource (lib device) (part CP1)) + (sheetpath (names /) (tstamps /)) + (tstamp 560735FE)) + (comp (ref P4) + (value PDI/3V3) + (footprint Pin_Headers:Pin_Header_Straight_2x02) + (libsource (lib conn) (part CONN_02X02)) + (sheetpath (names /) (tstamps /)) + (tstamp 56069A87)) + (comp (ref R23) + (value 28R) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 566DE721)) + (comp (ref R25) + (value 28R) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 566DE7E8)) + (comp (ref C14) + (value C) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C_Small)) + (sheetpath (names /) (tstamps /)) + (tstamp 566DF655)) + (comp (ref P6) + (value DAC_OUT) + (footprint Pin_Headers:Pin_Header_Straight_1x04) + (libsource (lib conn) (part CONN_01X04)) + (sheetpath (names /) (tstamps /)) + (tstamp 566DF832)) + (comp (ref R26) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 566E5C29)) + (comp (ref R27) + (value 100R) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 566E5CBE)) + (comp (ref C6) + (value CP1) + (footprint Capacitors_SMD:c_elec_4x5.3) + (libsource (lib device) (part CP1)) + (sheetpath (names /) (tstamps /)) + (tstamp 566F5A75)) + (comp (ref R19) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 56AECD86)) + (comp (ref C11) + (value C) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C)) + (sheetpath (names /) (tstamps /)) + (tstamp 5608B4BE)) + (comp (ref C8) + (value C) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C)) + (sheetpath (names /) (tstamps /)) + (tstamp 56AF91A3)) + (comp (ref R17) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 56AFE83E)) + (comp (ref R18) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 56AFE8F3)) + (comp (ref U3) + (value DMN63D8LDW) + (footprint TO_SOT_Packages_SMD:SOT-363) + (libsource (lib ESPO_PART) (part DMN63D8LDW)) + (sheetpath (names /) (tstamps /)) + (tstamp 56B012DD)) + (comp (ref R20) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 56B0C682)) + (comp (ref R15) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 56B0C779)) + (comp (ref R16) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 56B0C86E)) + (comp (ref L2) + (value INDUCTOR) + (footprint Resistors_SMD:R_1206) + (libsource (lib device) (part INDUCTOR)) + (sheetpath (names /) (tstamps /)) + (tstamp 56E88440)) + (comp (ref L3) + (value INDUCTOR) + (footprint Resistors_SMD:R_1206) + (libsource (lib device) (part INDUCTOR)) + (sheetpath (names /) (tstamps /)) + (tstamp 56E8DA35)) + (comp (ref C7) + (value C) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C)) + (sheetpath (names /) (tstamps /)) + (tstamp 56E8E263)) + (comp (ref R21) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 56E9851A)) + (comp (ref R28) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 56E985EF)) + (comp (ref R29) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 56E9888A)) + (comp (ref R30) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 56E98921)) + (comp (ref P7) + (value PSU) + (footprint Pin_Headers:Pin_Header_Straight_1x02) + (libsource (lib conn) (part CONN_01X02)) + (sheetpath (names /) (tstamps /)) + (tstamp 56F2A93D)) + (comp (ref L4) + (value INDUCTOR) + (footprint Resistors_SMD:R_1206) + (libsource (lib device) (part INDUCTOR)) + (sheetpath (names /) (tstamps /)) + (tstamp 573254B0)) + (comp (ref C18) + (value C) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C)) + (sheetpath (names /) (tstamps /)) + (tstamp 57564580)) + (comp (ref C17) + (value C) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C)) + (sheetpath (names /) (tstamps /)) + (tstamp 57564635)) + (comp (ref R31) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R)) + (sheetpath (names /) (tstamps /)) + (tstamp 5804605C)) + (comp (ref Q1) + (value Q_NMOS_GSD) + (footprint SMD:SOT-23-3) + (libsource (lib device) (part Q_NMOS_GSD)) + (sheetpath (names /) (tstamps /)) + (tstamp 583120F2)) + (comp (ref D2) + (value LED) + (footprint LEDs:LED_0603) + (libsource (lib device) (part LED)) + (sheetpath (names /) (tstamps /)) + (tstamp 5833E159)) + (comp (ref R32) + (value 1K) + (footprint Resistors_SMD:R_0603) + (libsource (lib device) (part R_Small)) + (sheetpath (names /) (tstamps /)) + (tstamp 5833E34C)) + (comp (ref P10) + (value EXPANSION) + (footprint Pin_Headers:Pin_Header_Straight_1x03) + (libsource (lib conn) (part CONN_01X03)) + (sheetpath (names /) (tstamps /)) + (tstamp 5837847B)) + (comp (ref P11) + (value SWITCH) + (footprint Pin_Headers:Pin_Header_Straight_1x03) + (libsource (lib conn) (part CONN_01X03)) + (sheetpath (names /) (tstamps /)) + (tstamp 58378536)) + (comp (ref P1) + (value SCOPE_OUT) + (footprint Pin_Headers:Pin_Header_Straight_1x04) + (libsource (lib conn) (part CONN_01X04)) + (sheetpath (names /) (tstamps /)) + (tstamp 5832064B)) + (comp (ref P5) + (value SCOPE_OUT) + (footprint Pin_Headers:Pin_Header_Straight_1x04) + (libsource (lib conn) (part CONN_01X04)) + (sheetpath (names /) (tstamps /)) + (tstamp 58320706)) + (comp (ref C12) + (value C) + (footprint Capacitors_SMD:C_0603) + (libsource (lib device) (part C)) + (sheetpath (names /) (tstamps /)) + (tstamp 588029E7)) + (comp (ref F2) + (value F_Small) + (footprint Capacitors_SMD:C_1210) + (libsource (lib device) (part F_Small)) + (sheetpath (names /) (tstamps /)) + (tstamp 58F5AF9C)) + (comp (ref P9) + (value FUSE_BYPASS) + (footprint Pin_Headers:Pin_Header_Straight_1x02) + (libsource (lib conn) (part CONN_01X02)) + (sheetpath (names /) (tstamps /)) + (tstamp 58FEDB8C))) + (libparts + (libpart (lib Tinylab_proto1-rescue) (part 78L05-RESCUE-Tinylab_proto1) + (fields + (field (name Reference) U) + (field (name Value) 78L05-RESCUE-Tinylab_proto1)) + (pins + (pin (num 1) (name GND) (type input)) + (pin (num 2) (name VO) (type power_out)) + (pin (num 3) (name VI) (type input)))) + (libpart (lib atmel) (part ATXMEGA16A4U-A) + (aliases + (alias ATXMEGA32A4U-A) + (alias ATXMEGA64A4U-A) + (alias ATXMEGA128A4U-A)) + (description "TQFP44, 16k Flash, 4k Boot, 2k SRAM, 1k EEPROM, JTAG, USB") + (docs http://www.atmel.com/Images/Atmel-8387-8-and16-bit-AVR-Microcontroller-XMEGA-A4U_Datasheet.pdf) + (fields + (field (name Reference) IC) + (field (name Value) ATXMEGA16A4U-A) + (field (name Footprint) TQFP44)) + (pins + (pin (num 1) (name AC5/ADC5/PA5) (type BiDi)) + (pin (num 2) (name AC1OUT/AC6/ADC6/PA6) (type BiDi)) + (pin (num 3) (name AC0OUT/AC7/ADC7/PA7) (type BiDi)) + (pin (num 4) (name AREFB/ADC8/PB0) (type BiDi)) + (pin (num 5) (name ADC9/PB1) (type BiDi)) + (pin (num 6) (name DAC0/ADC10/PB2) (type BiDi)) + (pin (num 7) (name DAC1/ACD11/PB3) (type BiDi)) + (pin (num 8) (name GND) (type power_in)) + (pin (num 9) (name VCC) (type power_in)) + (pin (num 10) (name SDAIN/SDA/~OC0ALS~/OC0A/PC0) (type BiDi)) + (pin (num 11) (name SCLIN/SCL/XCK0/OC0AHS/OC0B/PC1) (type BiDi)) + (pin (num 12) (name SDAOUT/RXD0/~OC0BLS~/OC0C/PC2) (type BiDi)) + (pin (num 13) (name SCLOUT/TXD0/OC0BHS/OC0D/PC3) (type BiDi)) + (pin (num 14) (name ~SS~/~OC0CLS~/OC1A/PC4) (type BiDi)) + (pin (num 15) (name MOSI/XCK1/OC0CHS/OC1B/PC5) (type BiDi)) + (pin (num 16) (name CLKRTC/MISO/RXD1/~OC0DLS~/PC6) (type BiDi)) + (pin (num 17) (name EVOUT/CLKOUT/SCK/TXD1/OC0DHS/PC7) (type BiDi)) + (pin (num 18) (name GND) (type power_in)) + (pin (num 19) (name VCC) (type power_in)) + (pin (num 20) (name PD0/OC0A) (type BiDi)) + (pin (num 21) (name PD1/OC0B/XCK0) (type BiDi)) + (pin (num 22) (name PD2/OC0C/RXD0) (type BiDi)) + (pin (num 23) (name PD3/OC0D/TXD0) (type BiDi)) + (pin (num 24) (name PD4/OC1A/~SS~) (type BiDi)) + (pin (num 25) (name PD5/OC1B/XCK1/MOSI) (type BiDi)) + (pin (num 26) (name PD6/D-/RXD1/MISO) (type BiDi)) + (pin (num 27) (name PD7/D+/TXD1/SCK/CLKOUT/EVOUT) (type BiDi)) + (pin (num 28) (name PE0/OC0A/SDA) (type BiDi)) + (pin (num 29) (name PE1/OC0B/XCK0/SCL) (type BiDi)) + (pin (num 30) (name GND) (type power_in)) + (pin (num 31) (name VCC) (type power_in)) + (pin (num 32) (name PE2/OC0C/RXD0) (type BiDi)) + (pin (num 33) (name PE3/OC0D/TXD0) (type BiDi)) + (pin (num 34) (name PDI_DATA) (type input)) + (pin (num 35) (name ~RESET~/PDI_CLK) (type input)) + (pin (num 36) (name PR0/XTAL2/TOSC2) (type BiDi)) + (pin (num 37) (name PR1/XTAL1/TOSC1) (type BiDi)) + (pin (num 38) (name GND) (type power_in)) + (pin (num 39) (name AVCC) (type power_in)) + (pin (num 40) (name AREFA/AC0/ADC0/PA0) (type BiDi)) + (pin (num 41) (name AC1/ADC1/PA1) (type BiDi)) + (pin (num 42) (name AC2/ADC2/PA2) (type BiDi)) + (pin (num 43) (name AC3/ADC3/PA3) (type BiDi)) + (pin (num 44) (name AC4/ADC4/PA4) (type BiDi)))) + (libpart (lib device) (part C) + (description "Unpolarized capacitor") + (footprints + (fp C?) + (fp C_????_*) + (fp C_????) + (fp SMD*_c) + (fp Capacitor*)) + (fields + (field (name Reference) C) + (field (name Value) C)) + (pins + (pin (num 1) (name ~) (type passive)) + (pin (num 2) (name ~) (type passive)))) + (libpart (lib conn) (part CONN_01X02) + (description "Connector, single row, 01x02") + (footprints + (fp Pin_Header_Straight_1X02) + (fp Pin_Header_Angled_1X02) + (fp Socket_Strip_Straight_1X02) + (fp Socket_Strip_Angled_1X02)) + (fields + (field (name Reference) P) + (field (name Value) CONN_01X02)) + (pins + (pin (num 1) (name P1) (type passive)) + (pin (num 2) (name P2) (type passive)))) + (libpart (lib conn) (part CONN_01X03) + (description "Connector, single row, 01x03") + (footprints + (fp Pin_Header_Straight_1X03) + (fp Pin_Header_Angled_1X03) + (fp Socket_Strip_Straight_1X03) + (fp Socket_Strip_Angled_1X03)) + (fields + (field (name Reference) P) + (field (name Value) CONN_01X03)) + (pins + (pin (num 1) (name P1) (type passive)) + (pin (num 2) (name P2) (type passive)) + (pin (num 3) (name P3) (type passive)))) + (libpart (lib conn) (part CONN_01X04) + (description "Connector, single row, 01x04") + (footprints + (fp Pin_Header_Straight_1X04) + (fp Pin_Header_Angled_1X04) + (fp Socket_Strip_Straight_1X04) + (fp Socket_Strip_Angled_1X04)) + (fields + (field (name Reference) P) + (field (name Value) CONN_01X04)) + (pins + (pin (num 1) (name P1) (type passive)) + (pin (num 2) (name P2) (type passive)) + (pin (num 3) (name P3) (type passive)) + (pin (num 4) (name P4) (type passive)))) + (libpart (lib conn) (part CONN_02X02) + (description "Connector, double row, 02x02") + (footprints + (fp Pin_Header_Straight_2X02) + (fp Pin_Header_Angled_2X02) + (fp Socket_Strip_Straight_2X02) + (fp Socket_Strip_Angled_2X02)) + (fields + (field (name Reference) P) + (field (name Value) CONN_02X02)) + (pins + (pin (num 1) (name P1) (type passive)) + (pin (num 2) (name P2) (type passive)) + (pin (num 3) (name P3) (type passive)) + (pin (num 4) (name P4) (type passive)))) + (libpart (lib device) (part CP1) + (description "Polarised capacitor") + (footprints + (fp SMD*_Pol) + (fp C_Axial*) + (fp C_Radial*) + (fp c_elec*) + (fp C*elec) + (fp TantalC*) + (fp CP*)) + (fields + (field (name Reference) C) + (field (name Value) CP1)) + (pins + (pin (num 1) (name ~) (type passive)) + (pin (num 2) (name ~) (type passive)))) + (libpart (lib device) (part C_Small) + (description "Unpolarized capacitor") + (footprints + (fp C?) + (fp C_????_*) + (fp C_????) + (fp SMD*_c) + (fp Capacitor*)) + (fields + (field (name Reference) C) + (field (name Value) C_Small)) + (pins + (pin (num 1) (name ~) (type passive)) + (pin (num 2) (name ~) (type passive)))) + (libpart (lib ESPO_PART) (part DMN63D8LDW) + (fields + (field (name Reference) U) + (field (name Value) DMN63D8LDW)) + (pins + (pin (num 1) (name S1) (type input)) + (pin (num 2) (name G1) (type input)) + (pin (num 3) (name D2) (type input)) + (pin (num 4) (name S2) (type input)) + (pin (num 5) (name G2) (type input)) + (pin (num 6) (name D1) (type input)))) + (libpart (lib device) (part D_Schottky) + (description "Diode schottky") + (footprints + (fp D-Pak_TO252AA) + (fp Diode_*) + (fp *SingleDiode) + (fp *SingleDiode*) + (fp *_Diode_*)) + (fields + (field (name Reference) D) + (field (name Value) D_Schottky)) + (pins + (pin (num 1) (name K) (type passive)) + (pin (num 2) (name A) (type passive)))) + (libpart (lib device) (part F_Small) + (description Fuse) + (footprints + (fp CP*) + (fp SM*)) + (fields + (field (name Reference) F) + (field (name Value) F_Small)) + (pins + (pin (num 1) (name ~) (type passive)) + (pin (num 2) (name ~) (type passive)))) + (libpart (lib device) (part INDUCTOR) + (footprints + (fp Choke_*) + (fp *Coil*)) + (fields + (field (name Reference) L) + (field (name Value) INDUCTOR)) + (pins + (pin (num 1) (name 1) (type passive)) + (pin (num 2) (name 2) (type passive)))) + (libpart (lib device) (part LED) + (footprints + (fp LED-*) + (fp LED_*)) + (fields + (field (name Reference) D) + (field (name Value) LED)) + (pins + (pin (num 1) (name K) (type passive)) + (pin (num 2) (name A) (type passive)))) + (libpart (lib Tinylab_proto1-rescue) (part LM324-RESCUE-Tinylab_proto1) + (fields + (field (name Reference) U) + (field (name Value) LM324-RESCUE-Tinylab_proto1)) + (pins + (pin (num 1) (name ~) (type output)) + (pin (num 2) (name -) (type input)) + (pin (num 3) (name +) (type input)) + (pin (num 4) (name V+) (type power_in)) + (pin (num 5) (name +) (type input)) + (pin (num 6) (name -) (type input)) + (pin (num 7) (name ~) (type output)) + (pin (num 8) (name ~) (type output)) + (pin (num 9) (name -) (type input)) + (pin (num 10) (name +) (type input)) + (pin (num 11) (name V-) (type power_in)) + (pin (num 12) (name +) (type input)) + (pin (num 13) (name -) (type input)) + (pin (num 14) (name ~) (type output)))) + (libpart (lib device) (part Q_NMOS_GSD) + (description "Transistor N-MOSFET (general)") + (fields + (field (name Reference) Q) + (field (name Value) Q_NMOS_GSD)) + (pins + (pin (num 1) (name G) (type input)) + (pin (num 2) (name S) (type passive)) + (pin (num 3) (name D) (type passive)))) + (libpart (lib device) (part R) + (description Resistor) + (footprints + (fp R_*) + (fp Resistor_*)) + (fields + (field (name Reference) R) + (field (name Value) R)) + (pins + (pin (num 1) (name ~) (type passive)) + (pin (num 2) (name ~) (type passive)))) + (libpart (lib device) (part R_Small) + (description Resistor) + (footprints + (fp Resistor_*) + (fp R_*)) + (fields + (field (name Reference) R) + (field (name Value) R_Small)) + (pins + (pin (num 1) (name ~) (type passive)) + (pin (num 2) (name ~) (type passive)))) + (libpart (lib conn) (part USB_OTG) + (description "USB micro/mini connector") + (footprints + (fp USB*)) + (fields + (field (name Reference) P) + (field (name Value) USB_OTG)) + (pins + (pin (num 1) (name VCC) (type power_out)) + (pin (num 2) (name D-) (type passive)) + (pin (num 3) (name D+) (type passive)) + (pin (num 4) (name ID) (type power_in)) + (pin (num 5) (name GND) (type power_in)) + (pin (num 6) (name shield) (type passive))))) + (libraries + (library (logical conn) + (uri "C:\\Program Files\\KiCad\\share\\kicad\\library\\conn.lib")) + (library (logical Tinylab_proto1-rescue) + (uri C:\Users\Esposch\Documents\GitHub\Labrador\PCB\Tinylab_proto1-rescue.lib)) + (library (logical atmel) + (uri "C:\\Program Files\\KiCad\\share\\kicad\\library\\atmel.lib")) + (library (logical device) + (uri "C:\\Program Files\\KiCad\\share\\kicad\\library\\device.lib")) + (library (logical ESPO_PART) + (uri C:\Users\Esposch\Documents\KiCAD\ESPO_PART.lib))) + (nets + (net (code 1) (name /VCC_3V3) + (node (ref U1) (pin 2)) + (node (ref C6) (pin 1)) + (node (ref C11) (pin 1)) + (node (ref F1) (pin 2)) + (node (ref IC1) (pin 19)) + (node (ref L2) (pin 1)) + (node (ref IC1) (pin 31)) + (node (ref C4) (pin 1))) + (net (code 2) (name /TO_B1) + (node (ref IC1) (pin 5)) + (node (ref U3) (pin 5))) + (net (code 3) (name /V_minus_dac_out2) + (node (ref R20) (pin 2)) + (node (ref R15) (pin 1)) + (node (ref R16) (pin 1)) + (node (ref U2) (pin 13))) + (net (code 4) (name /S-Gen_Drain_Top_CH1) + (node (ref U3) (pin 3)) + (node (ref R18) (pin 2)) + (node (ref R17) (pin 2))) + (net (code 5) (name /Scope_Buffer_Input_CH1) + (node (ref R3) (pin 1)) + (node (ref R1) (pin 1)) + (node (ref U2) (pin 3))) + (net (code 6) (name /Scope_Buffer_Input_CH2) + (node (ref U2) (pin 5)) + (node (ref R2) (pin 1)) + (node (ref R4) (pin 2))) + (net (code 7) (name /D1_OUT) + (node (ref R8) (pin 2)) + (node (ref P3) (pin 3))) + (net (code 8) (name /PDI_CLK) + (node (ref IC1) (pin 34)) + (node (ref P4) (pin 2))) + (net (code 9) (name /PDI_DATA) + (node (ref P4) (pin 4)) + (node (ref IC1) (pin 35))) + (net (code 10) (name /3V3_OUT) + (node (ref F1) (pin 1)) + (node (ref P4) (pin 1))) + (net (code 11) (name /Switch_OC) + (node (ref P11) (pin 1))) + (net (code 12) (name /Scope_CH2_DC) + (node (ref P5) (pin 3)) + (node (ref P5) (pin 1)) + (node (ref P5) (pin 4)) + (node (ref R2) (pin 2)) + (node (ref C2) (pin 1))) + (net (code 13) (name /Scoe_CH1_AC) + (node (ref C1) (pin 2)) + (node (ref P1) (pin 2))) + (net (code 14) (name /Scope_CH2_AC) + (node (ref P5) (pin 2)) + (node (ref C2) (pin 2))) + (net (code 15) (name /S-Gen_CH1_DC) + (node (ref C13) (pin 2)) + (node (ref R24) (pin 1)) + (node (ref P6) (pin 1))) + (net (code 16) (name /S-Gen_CH1_AC) + (node (ref C13) (pin 1)) + (node (ref P6) (pin 2))) + (net (code 17) (name /S-Gen_CH2_DC) + (node (ref R25) (pin 1)) + (node (ref C14) (pin 2)) + (node (ref P6) (pin 3))) + (net (code 18) (name /S-Gen_CH2_AC) + (node (ref C14) (pin 1)) + (node (ref P6) (pin 4))) + (net (code 19) (name /PSU_FDBK) + (node (ref IC1) (pin 1)) + (node (ref R27) (pin 1)) + (node (ref P10) (pin 2)) + (node (ref R26) (pin 2))) + (net (code 20) (name /QTop) + (node (ref D1) (pin 2)) + (node (ref L1) (pin 1)) + (node (ref Q1) (pin 3))) + (net (code 21) (name /D0_MID) + (node (ref R11) (pin 2)) + (node (ref R7) (pin 1))) + (net (code 22) (name /D1_MID) + (node (ref R8) (pin 1)) + (node (ref R12) (pin 2))) + (net (code 23) (name /D2_MID) + (node (ref R13) (pin 2)) + (node (ref R9) (pin 1))) + (net (code 24) (name /D3_MID) + (node (ref R14) (pin 2)) + (node (ref R10) (pin 1))) + (net (code 25) (name /L-Ana_IN_CH1) + (node (ref P8) (pin 1)) + (node (ref U4) (pin 5))) + (net (code 26) (name /R22-R24) + (node (ref R22) (pin 1)) + (node (ref R24) (pin 2))) + (net (code 27) (name /PSU_OUT) + (node (ref P11) (pin 3)) + (node (ref P7) (pin 1)) + (node (ref R32) (pin 1))) + (net (code 28) (name "Net-(L3-Pad1)") + (node (ref L4) (pin 2)) + (node (ref L3) (pin 1))) + (net (code 29) (name /CH1) + (node (ref R21) (pin 1)) + (node (ref U2) (pin 2)) + (node (ref U2) (pin 1)) + (node (ref IC1) (pin 42))) + (net (code 30) (name /CH2) + (node (ref R28) (pin 2)) + (node (ref IC1) (pin 2)) + (node (ref IC1) (pin 40)) + (node (ref U2) (pin 7)) + (node (ref U2) (pin 6))) + (net (code 31) (name /DAC_OUT) + (node (ref U2) (pin 10)) + (node (ref IC1) (pin 6))) + (net (code 32) (name "Net-(F2-Pad2)") + (node (ref L1) (pin 2)) + (node (ref F2) (pin 2)) + (node (ref P9) (pin 2))) + (net (code 33) (name /L-Ana_IN_CH2) + (node (ref P8) (pin 2)) + (node (ref U4) (pin 2))) + (net (code 34) (name /DIG_CH1) + (node (ref U4) (pin 6)) + (node (ref IC1) (pin 15))) + (net (code 35) (name /AVCC) + (node (ref C5) (pin 1)) + (node (ref R5) (pin 1)) + (node (ref C17) (pin 1)) + (node (ref C8) (pin 1)) + (node (ref L2) (pin 2)) + (node (ref C18) (pin 1)) + (node (ref IC1) (pin 39))) + (net (code 36) (name /D2-prefuse) + (node (ref R13) (pin 1)) + (node (ref IC1) (pin 32))) + (net (code 37) (name /D1-prefuse) + (node (ref IC1) (pin 29)) + (node (ref R12) (pin 1))) + (net (code 38) (name /D0-prefuse) + (node (ref R11) (pin 1)) + (node (ref IC1) (pin 28))) + (net (code 39) (name +5V) + (node (ref C3) (pin 1)) + (node (ref P9) (pin 1)) + (node (ref P2) (pin 1)) + (node (ref F2) (pin 1)) + (node (ref U1) (pin 3)) + (node (ref C10) (pin 1)) + (node (ref C9) (pin 1))) + (net (code 40) (name /D-) + (node (ref IC1) (pin 26)) + (node (ref P2) (pin 2))) + (net (code 41) (name /D+) + (node (ref P2) (pin 3)) + (node (ref IC1) (pin 27))) + (net (code 42) (name /D3-OUT) + (node (ref R10) (pin 2)) + (node (ref P3) (pin 1))) + (net (code 43) (name /D2-OUT) + (node (ref R9) (pin 2)) + (node (ref P3) (pin 2))) + (net (code 44) (name /D0_OUT) + (node (ref R7) (pin 2)) + (node (ref P3) (pin 4))) + (net (code 45) (name /D3-prefuse) + (node (ref IC1) (pin 33)) + (node (ref R14) (pin 1))) + (net (code 46) (name /VGND) + (node (ref R29) (pin 2)) + (node (ref R30) (pin 1)) + (node (ref P7) (pin 2)) + (node (ref D2) (pin 1)) + (node (ref C17) (pin 2)) + (node (ref R31) (pin 2)) + (node (ref Q1) (pin 2)) + (node (ref C18) (pin 2)) + (node (ref P10) (pin 3)) + (node (ref U1) (pin 1)) + (node (ref IC1) (pin 18)) + (node (ref IC1) (pin 38)) + (node (ref C12) (pin 2)) + (node (ref P2) (pin 5)) + (node (ref P2) (pin 6)) + (node (ref R21) (pin 2)) + (node (ref IC1) (pin 14)) + (node (ref R28) (pin 1)) + (node (ref U3) (pin 1)) + (node (ref C6) (pin 2)) + (node (ref C11) (pin 2)) + (node (ref C8) (pin 2)) + (node (ref R27) (pin 2)) + (node (ref C9) (pin 2)) + (node (ref C7) (pin 2)) + (node (ref U3) (pin 4)) + (node (ref C10) (pin 2)) + (node (ref C16) (pin 2)) + (node (ref C15) (pin 2)) + (node (ref P4) (pin 3)) + (node (ref R6) (pin 1)) + (node (ref C5) (pin 2)) + (node (ref IC1) (pin 30)) + (node (ref IC1) (pin 8)) + (node (ref U4) (pin 4)) + (node (ref C4) (pin 2)) + (node (ref C3) (pin 2)) + (node (ref U2) (pin 11)) + (node (ref U4) (pin 1))) + (net (code 47) (name /Disconnected_USB) + (node (ref P2) (pin 4))) + (net (code 48) (name /DIG_CH2) + (node (ref U4) (pin 3)) + (node (ref IC1) (pin 12))) + (net (code 49) (name "Net-(IC1-Pad10)") + (node (ref IC1) (pin 10))) + (net (code 50) (name "Net-(IC1-Pad3)") + (node (ref IC1) (pin 3))) + (net (code 51) (name /DAC_OUT2) + (node (ref U2) (pin 12)) + (node (ref IC1) (pin 7))) + (net (code 52) (name "Net-(IC1-Pad9)") + (node (ref IC1) (pin 9))) + (net (code 53) (name "Net-(IC1-Pad20)") + (node (ref IC1) (pin 20))) + (net (code 54) (name /XCK) + (node (ref IC1) (pin 17)) + (node (ref IC1) (pin 11))) + (net (code 55) (name "Net-(IC1-Pad21)") + (node (ref IC1) (pin 21))) + (net (code 56) (name "Net-(IC1-Pad41)") + (node (ref IC1) (pin 41))) + (net (code 57) (name /OPAMP_VCC) + (node (ref U2) (pin 4)) + (node (ref L4) (pin 1)) + (node (ref C16) (pin 1))) + (net (code 58) (name "Net-(IC1-Pad22)") + (node (ref IC1) (pin 22))) + (net (code 59) (name "Net-(IC1-Pad37)") + (node (ref IC1) (pin 37))) + (net (code 60) (name /Scope_CH1_DC) + (node (ref P1) (pin 3)) + (node (ref P1) (pin 1)) + (node (ref R1) (pin 2)) + (node (ref P1) (pin 4)) + (node (ref C1) (pin 1))) + (net (code 61) (name "Net-(IC1-Pad13)") + (node (ref IC1) (pin 13))) + (net (code 62) (name "Net-(IC1-Pad23)") + (node (ref IC1) (pin 23))) + (net (code 63) (name "Net-(IC1-Pad43)") + (node (ref IC1) (pin 43))) + (net (code 64) (name /AVCC_ON_2) + (node (ref R6) (pin 2)) + (node (ref R4) (pin 1)) + (node (ref IC1) (pin 44)) + (node (ref R5) (pin 2)) + (node (ref R3) (pin 2))) + (net (code 65) (name "Net-(IC1-Pad25)") + (node (ref IC1) (pin 25))) + (net (code 66) (name "Net-(IC1-Pad16)") + (node (ref IC1) (pin 16))) + (net (code 67) (name "Net-(IC1-Pad36)") + (node (ref IC1) (pin 36))) + (net (code 68) (name /PSU_Unfiltered_Raw) + (node (ref R26) (pin 1)) + (node (ref C15) (pin 1)) + (node (ref P10) (pin 1)) + (node (ref D1) (pin 1)) + (node (ref C7) (pin 1)) + (node (ref L3) (pin 2)) + (node (ref P11) (pin 2))) + (net (code 69) (name /Buffered_DAC_CH1) + (node (ref R22) (pin 2)) + (node (ref R29) (pin 1)) + (node (ref R19) (pin 1)) + (node (ref U2) (pin 8))) + (net (code 70) (name /Buffered_DAC_CH2) + (node (ref R20) (pin 1)) + (node (ref U2) (pin 14)) + (node (ref R23) (pin 2)) + (node (ref R30) (pin 2))) + (net (code 71) (name /TO_B0) + (node (ref U3) (pin 2)) + (node (ref IC1) (pin 4))) + (net (code 72) (name /S-Gen_Drain_Top_CH2) + (node (ref U3) (pin 6)) + (node (ref R16) (pin 2)) + (node (ref R15) (pin 2))) + (net (code 73) (name /PSU_PWM) + (node (ref Q1) (pin 1)) + (node (ref R31) (pin 1)) + (node (ref C12) (pin 1)) + (node (ref IC1) (pin 24))) + (net (code 74) (name "Net-(D2-Pad2)") + (node (ref D2) (pin 2)) + (node (ref R32) (pin 2))) + (net (code 75) (name /V_minus_dac_out) + (node (ref R18) (pin 1)) + (node (ref R17) (pin 1)) + (node (ref U2) (pin 9)) + (node (ref R19) (pin 2))) + (net (code 76) (name /R23-R25) + (node (ref R23) (pin 1)) + (node (ref R25) (pin 2))))) \ No newline at end of file diff --git a/PCB/Tinylab_proto1.net.REMOVED.git-id b/PCB/Tinylab_proto1.net.REMOVED.git-id deleted file mode 100644 index f026386e..00000000 --- a/PCB/Tinylab_proto1.net.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b64e45f1190c2f60ed8ba7605e8378e69b3892ff \ No newline at end of file diff --git a/PCB/Tinylab_proto1.pro b/PCB/Tinylab_proto1.pro new file mode 100644 index 00000000..08ce12fa --- /dev/null +++ b/PCB/Tinylab_proto1.pro @@ -0,0 +1,72 @@ +update=23/03/2016 12:02:25 PM +version=1 +last_client=kicad +[pcbnew] +version=1 +LastNetListRead= +UseCmpFile=1 +PadDrill=0.600000000000 +PadDrillOvalY=0.600000000000 +PadSizeH=1.500000000000 +PadSizeV=1.500000000000 +PcbTextSizeV=1.500000000000 +PcbTextSizeH=1.500000000000 +PcbTextThickness=0.300000000000 +ModuleTextSizeV=1.000000000000 +ModuleTextSizeH=1.000000000000 +ModuleTextSizeThickness=0.150000000000 +SolderMaskClearance=0.000000000000 +SolderMaskMinWidth=0.000000000000 +DrawSegmentWidth=0.200000000000 +BoardOutlineThickness=0.100000000000 +ModuleOutlineThickness=0.150000000000 +[cvpcb] +version=1 +NetIExt=net +[general] +version=1 +[schematic_editor] +version=1 +PageLayoutDescrFile= +PlotDirectoryName= +SubpartIdSeparator=0 +SubpartFirstId=65 +NetFmtName= +SpiceForceRefPrefix=0 +SpiceUseNetNumbers=0 +LabSize=60 +[eeschema] +version=1 +LibDir= +[eeschema/libraries] +LibName1=Tinylab_proto1-rescue +LibName2=power +LibName3=device +LibName4=transistors +LibName5=conn +LibName6=linear +LibName7=regul +LibName8=74xx +LibName9=cmos4000 +LibName10=adc-dac +LibName11=memory +LibName12=xilinx +LibName13=microcontrollers +LibName14=dsp +LibName15=microchip +LibName16=analog_switches +LibName17=motorola +LibName18=texas +LibName19=intel +LibName20=audio +LibName21=interface +LibName22=digital-audio +LibName23=philips +LibName24=display +LibName25=cypress +LibName26=siliconi +LibName27=opto +LibName28=atmel +LibName29=contrib +LibName30=valves +LibName31=C:/Users/Esposch/Documents/KiCAD/ESPO_PART diff --git a/PCB/Tinylab_proto1.pro.REMOVED.git-id b/PCB/Tinylab_proto1.pro.REMOVED.git-id deleted file mode 100644 index 41c5a6fa..00000000 --- a/PCB/Tinylab_proto1.pro.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -08ce12fab9b5618d522f0bc15407c921a5a717c0 \ No newline at end of file diff --git a/PCB/Tinylab_proto1.sch b/PCB/Tinylab_proto1.sch new file mode 100644 index 00000000..45ce4042 --- /dev/null +++ b/PCB/Tinylab_proto1.sch @@ -0,0 +1,1600 @@ +EESchema Schematic File Version 2 +LIBS:Tinylab_proto1-rescue +LIBS:power +LIBS:device +LIBS:transistors +LIBS:conn +LIBS:linear +LIBS:regul +LIBS:74xx +LIBS:cmos4000 +LIBS:adc-dac +LIBS:memory +LIBS:xilinx +LIBS:microcontrollers +LIBS:dsp +LIBS:microchip +LIBS:analog_switches +LIBS:motorola +LIBS:texas +LIBS:intel +LIBS:audio +LIBS:interface +LIBS:digital-audio +LIBS:philips +LIBS:display +LIBS:cypress +LIBS:siliconi +LIBS:opto +LIBS:atmel +LIBS:contrib +LIBS:valves +LIBS:ESPO_PART +LIBS:Tinylab_proto1-cache +EELAYER 25 0 +EELAYER END +$Descr A2 23386 16535 +encoding utf-8 +Sheet 1 1 +Title "" +Date "" +Rev "" +Comp "" +Comment1 "" +Comment2 "" +Comment3 "" +Comment4 "" +$EndDescr +$Comp +L LM324-RESCUE-Tinylab_proto1 U2 +U 1 1 55CA87E2 +P 4200 8750 +F 0 "U2" H 4250 8950 60 0000 C CNN +F 1 "LM324" H 4350 8550 50 0000 C CNN +F 2 "Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm" H 4200 8750 60 0001 C CNN +F 3 "" H 4200 8750 60 0000 C CNN + 1 4200 8750 + 1 0 0 -1 +$EndComp +$Comp +L LM324-RESCUE-Tinylab_proto1 U2 +U 2 1 55CA88A1 +P 4200 10550 +F 0 "U2" H 4250 10750 60 0000 C CNN +F 1 "LM324" H 4350 10350 50 0000 C CNN +F 2 "Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm" H 4200 10550 60 0001 C CNN +F 3 "" H 4200 10550 60 0000 C CNN + 2 4200 10550 + 1 0 0 -1 +$EndComp +$Comp +L LM324-RESCUE-Tinylab_proto1 U2 +U 3 1 55CA8924 +P 8450 9250 +F 0 "U2" H 8500 9450 60 0000 C CNN +F 1 "LM324" H 8600 9050 50 0000 C CNN +F 2 "Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm" H 8450 9250 60 0001 C CNN +F 3 "" H 8450 9250 60 0000 C CNN + 3 8450 9250 + 1 0 0 -1 +$EndComp +$Comp +L LM324-RESCUE-Tinylab_proto1 U2 +U 4 1 55CA89A3 +P 8400 11550 +F 0 "U2" H 8450 11750 60 0000 C CNN +F 1 "LM324" H 8550 11350 50 0000 C CNN +F 2 "Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm" H 8400 11550 60 0001 C CNN +F 3 "" H 8400 11550 60 0000 C CNN + 4 8400 11550 + 1 0 0 -1 +$EndComp +$Comp +L ATXMEGA16A4U-A IC1 +U 1 1 55CA8F25 +P 6150 5300 +F 0 "IC1" H 5400 6500 40 0000 L BNN +F 1 "ATXMEGA32A4U-AU" H 6500 4050 40 0000 L BNN +F 2 "Housings_QFP:LQFP-44_10x10mm_Pitch0.8mm" H 6150 5300 35 0000 C CIN +F 3 "" H 6150 5300 60 0000 C CNN + 1 6150 5300 + 1 0 0 -1 +$EndComp +$Comp +L USB_OTG P2 +U 1 1 55CA90D2 +P 1650 6850 +F 0 "P2" H 1975 6725 50 0000 C CNN +F 1 "USB_OTG" H 1650 7050 50 0000 C CNN +F 2 "Connect:USB_Micro-B_WIDE" V 1600 6750 60 0001 C CNN +F 3 "" V 1600 6750 60 0000 C CNN + 1 1650 6850 + 0 -1 1 0 +$EndComp +$Comp +L 78L05-RESCUE-Tinylab_proto1 U1 +U 1 1 55CA99FA +P 3100 6700 +F 0 "U1" H 3250 6504 60 0000 C CNN +F 1 "78L05" H 3100 6900 60 0000 C CNN +F 2 "SMD:SOT-23-3" H 3100 6700 60 0001 C CNN +F 3 "" H 3100 6700 60 0000 C CNN + 1 3100 6700 + 1 0 0 -1 +$EndComp +$Comp +L R R1 +U 1 1 55CAAB95 +P 2000 9250 +F 0 "R1" V 2080 9250 50 0000 C CNN +F 1 "1M" V 2000 9250 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 1930 9250 30 0001 C CNN +F 3 "" H 2000 9250 30 0000 C CNN + 1 2000 9250 + 0 1 1 0 +$EndComp +$Comp +L R R3 +U 1 1 55CAABF4 +P 2350 9400 +F 0 "R3" V 2430 9400 50 0000 C CNN +F 1 "75K" V 2350 9400 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 2280 9400 30 0001 C CNN +F 3 "" H 2350 9400 30 0000 C CNN + 1 2350 9400 + 1 0 0 -1 +$EndComp +$Comp +L R R5 +U 1 1 55CAAC5F +P 3000 9500 +F 0 "R5" V 3080 9500 50 0000 C CNN +F 1 "1K" V 3000 9500 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 2930 9500 30 0001 C CNN +F 3 "" H 3000 9500 30 0000 C CNN + 1 3000 9500 + 0 1 1 0 +$EndComp +$Comp +L R R6 +U 1 1 55CAACD2 +P 3000 9700 +F 0 "R6" V 3080 9700 50 0000 C CNN +F 1 "1K" V 3000 9700 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 2930 9700 30 0001 C CNN +F 3 "" H 3000 9700 30 0000 C CNN + 1 3000 9700 + 0 1 1 0 +$EndComp +$Comp +L R R4 +U 1 1 55CAAD11 +P 2350 9800 +F 0 "R4" V 2430 9800 50 0000 C CNN +F 1 "75K" V 2350 9800 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 2280 9800 30 0001 C CNN +F 3 "" H 2350 9800 30 0000 C CNN + 1 2350 9800 + 1 0 0 -1 +$EndComp +$Comp +L R R2 +U 1 1 55CAAD4C +P 2000 9950 +F 0 "R2" V 2080 9950 50 0000 C CNN +F 1 "1M" V 2000 9950 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 1930 9950 30 0001 C CNN +F 3 "" H 2000 9950 30 0000 C CNN + 1 2000 9950 + 0 1 1 0 +$EndComp +$Comp +L C_Small C2 +U 1 1 55CAB4DE +P 1550 9950 +F 0 "C2" H 1560 10020 50 0000 L CNN +F 1 "C" H 1560 9870 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 1550 9950 60 0001 C CNN +F 3 "" H 1550 9950 60 0000 C CNN + 1 1550 9950 + 0 1 1 0 +$EndComp +$Comp +L C_Small C1 +U 1 1 55CAB611 +P 1450 9300 +F 0 "C1" H 1460 9370 50 0000 L CNN +F 1 "C" H 1460 9220 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 1450 9300 60 0001 C CNN +F 3 "" H 1450 9300 60 0000 C CNN + 1 1450 9300 + 0 1 1 0 +$EndComp +Text Label 3150 9500 0 60 ~ 0 +AVCC +Text Label 4700 8750 0 60 ~ 0 +CH1 +Text Label 4700 10550 0 60 ~ 0 +CH2 +Text Label 7050 4500 0 60 ~ 0 +CH1 +Text Label 7050 4300 0 60 ~ 0 +CH2 +Text Label 2350 9600 0 60 ~ 0 +AVCC_ON_2 +Text Label 7050 4700 0 60 ~ 0 +AVCC_ON_2 +$Comp +L C_Small C3 +U 1 1 55CB13E1 +P 2700 6950 +F 0 "C3" H 2710 7020 50 0000 L CNN +F 1 "C_Small" H 2710 6870 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 2700 6950 60 0001 C CNN +F 3 "" H 2700 6950 60 0000 C CNN + 1 2700 6950 + 1 0 0 -1 +$EndComp +$Comp +L C_Small C4 +U 1 1 55CB147C +P 3500 6950 +F 0 "C4" H 3510 7020 50 0000 L CNN +F 1 "C_Small" H 3510 6870 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 3500 6950 60 0001 C CNN +F 3 "" H 3500 6950 60 0000 C CNN + 1 3500 6950 + 1 0 0 -1 +$EndComp +Text Notes 1450 8500 0 60 ~ 0 +Analog Front End for Scope\n +Text Notes 8950 8600 0 60 ~ 0 +DAC stuff\n +$Comp +L R R22 +U 1 1 55CB4680 +P 10650 9250 +F 0 "R22" V 10730 9250 50 0000 C CNN +F 1 "28R" V 10650 9250 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 10580 9250 30 0001 C CNN +F 3 "" H 10650 9250 30 0000 C CNN + 1 10650 9250 + 0 1 1 0 +$EndComp +$Comp +L C_Small C13 +U 1 1 55CB630B +P 11250 9350 +F 0 "C13" H 11260 9420 50 0000 L CNN +F 1 "C" H 11260 9270 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 11250 9350 60 0001 C CNN +F 3 "" H 11250 9350 60 0000 C CNN + 1 11250 9350 + 0 1 1 0 +$EndComp +Text Label 7400 9150 0 60 ~ 0 +DAC_OUT +Text Label 7050 5350 0 60 ~ 0 +DAC_OUT +$Comp +L R R24 +U 1 1 55CB9020 +P 11000 9250 +F 0 "R24" V 11080 9250 50 0000 C CNN +F 1 "28R" V 11000 9250 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 10930 9250 30 0001 C CNN +F 3 "" H 11000 9250 30 0000 C CNN + 1 11000 9250 + 0 1 1 0 +$EndComp +$Comp +L R R11 +U 1 1 55CBCD2A +P 4700 5000 +F 0 "R11" V 4780 5000 50 0000 C CNN +F 1 "28R" V 4700 5000 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4630 5000 30 0001 C CNN +F 3 "" H 4700 5000 30 0000 C CNN + 1 4700 5000 + 0 1 1 0 +$EndComp +$Comp +L R R7 +U 1 1 55CBCDA5 +P 4350 5000 +F 0 "R7" V 4430 5000 50 0000 C CNN +F 1 "28R" V 4350 5000 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4280 5000 30 0001 C CNN +F 3 "" H 4350 5000 30 0000 C CNN + 1 4350 5000 + 0 1 1 0 +$EndComp +$Comp +L R R13 +U 1 1 55CBE0F4 +P 4700 5400 +F 0 "R13" V 4780 5400 50 0000 C CNN +F 1 "28R" V 4700 5400 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4630 5400 30 0001 C CNN +F 3 "" H 4700 5400 30 0000 C CNN + 1 4700 5400 + 0 1 1 0 +$EndComp +$Comp +L R R9 +U 1 1 55CBE16B +P 4350 5400 +F 0 "R9" V 4430 5400 50 0000 C CNN +F 1 "28R" V 4350 5400 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4280 5400 30 0001 C CNN +F 3 "" H 4350 5400 30 0000 C CNN + 1 4350 5400 + 0 1 1 0 +$EndComp +$Comp +L R R14 +U 1 1 55CBE21C +P 4700 5600 +F 0 "R14" V 4780 5600 50 0000 C CNN +F 1 "28R" V 4700 5600 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4630 5600 30 0001 C CNN +F 3 "" H 4700 5600 30 0000 C CNN + 1 4700 5600 + 0 1 1 0 +$EndComp +$Comp +L R R10 +U 1 1 55CBE2C7 +P 4350 5600 +F 0 "R10" V 4430 5600 50 0000 C CNN +F 1 "28R" V 4350 5600 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4280 5600 30 0001 C CNN +F 3 "" H 4350 5600 30 0000 C CNN + 1 4350 5600 + 0 1 1 0 +$EndComp +$Comp +L R R12 +U 1 1 55CBE362 +P 4700 5200 +F 0 "R12" V 4780 5200 50 0000 C CNN +F 1 "28R" V 4700 5200 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4630 5200 30 0001 C CNN +F 3 "" H 4700 5200 30 0000 C CNN + 1 4700 5200 + 0 1 1 0 +$EndComp +$Comp +L R R8 +U 1 1 55CBE401 +P 4350 5200 +F 0 "R8" V 4430 5200 50 0000 C CNN +F 1 "28R" V 4350 5200 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4280 5200 30 0001 C CNN +F 3 "" H 4350 5200 30 0000 C CNN + 1 4350 5200 + 0 1 1 0 +$EndComp +$Comp +L CONN_01X04 P3 +U 1 1 55CBF4D5 +P 3550 5300 +F 0 "P3" H 3550 5550 50 0000 C CNN +F 1 "DIG_OUT" V 3650 5300 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x04" H 3550 5300 60 0001 C CNN +F 3 "" H 3550 5300 60 0000 C CNN + 1 3550 5300 + -1 0 0 1 +$EndComp +Text Notes 4250 4850 0 60 ~ 0 +Dig Output\n +Text Notes 10050 4650 0 60 ~ 0 +PSU\n +$Comp +L +5V #PWR01 +U 1 1 55CD51C0 +P 2700 6650 +F 0 "#PWR01" H 2700 6500 50 0001 C CNN +F 1 "+5V" H 2700 6790 50 0000 C CNN +F 2 "" H 2700 6650 60 0000 C CNN +F 3 "" H 2700 6650 60 0000 C CNN + 1 2700 6650 + 1 0 0 -1 +$EndComp +Text Label 1950 6850 0 60 ~ 0 +D+ +Text Label 1950 6750 0 60 ~ 0 +D- +Text Label 5100 6200 0 60 ~ 0 +D- +Text Label 5100 6300 0 60 ~ 0 +D+ +NoConn ~ 1950 6950 +$Comp +L C_Small C5 +U 1 1 55D60181 +P 3600 9600 +F 0 "C5" H 3610 9670 50 0000 L CNN +F 1 "C_Small" H 3610 9520 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 3600 9600 60 0001 C CNN +F 3 "" H 3600 9600 60 0000 C CNN + 1 3600 9600 + 1 0 0 -1 +$EndComp +Text Label 6450 4000 0 60 ~ 0 +AVCC +$Comp +L DMN63D8LDW U4 +U 1 1 55D6ACFD +P 14400 3450 +F 0 "U4" H 14400 3150 60 0000 C CNN +F 1 "DMN63D8LDW" H 14400 3800 60 0000 C CNN +F 2 "TO_SOT_Packages_SMD:SOT-363" H 14400 3150 60 0001 C CNN +F 3 "" H 14400 3150 60 0000 C CNN + 1 14400 3450 + 1 0 0 -1 +$EndComp +Text Notes 14250 2450 0 60 ~ 0 +DIG IN +$Comp +L CONN_01X02 P8 +U 1 1 55D6DB77 +P 14400 2750 +F 0 "P8" H 14400 2900 50 0000 C CNN +F 1 "DIG_IN" V 14500 2750 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x02" H 14400 2750 60 0001 C CNN +F 3 "" H 14400 2750 60 0000 C CNN + 1 14400 2750 + 0 -1 -1 0 +$EndComp +Text Label 14850 3300 0 60 ~ 0 +DIG_CH2 +Text Label 13550 3600 0 60 ~ 0 +DIG_CH1 +$Comp +L F_Small F1 +U 1 1 55D739F3 +P 3350 4300 +F 0 "F1" H 3310 4360 50 0000 L CNN +F 1 "F_Small" H 3230 4240 50 0000 L CNN +F 2 "Capacitors_SMD:C_1210" H 3350 4300 60 0001 C CNN +F 3 "" H 3350 4300 60 0000 C CNN + 1 3350 4300 + -1 0 0 1 +$EndComp +Text Label 2500 7250 0 60 ~ 0 +VGND +Text Label 3500 6650 0 60 ~ 0 +VCC_3V3 +NoConn ~ 7050 5000 +NoConn ~ 7050 5600 +NoConn ~ 7050 5900 +Text Label 7050 5700 0 60 ~ 0 +XCK +Text Label 7050 5800 0 60 ~ 0 +DIG_CH2 +Text Label 7050 6100 0 60 ~ 0 +DIG_CH1 +Text Label 7050 6300 0 60 ~ 0 +XCK +NoConn ~ 7050 6200 +NoConn ~ 5250 5600 +Text Label 4750 6000 0 60 ~ 0 +PSU_PWM +NoConn ~ 5250 6100 +NoConn ~ 5250 5000 +NoConn ~ 5250 4900 +NoConn ~ 5250 5800 +NoConn ~ 5250 5700 +Text Label 6150 3800 0 60 ~ 0 +VCC_3V3 +$Comp +L INDUCTOR L1 +U 1 1 5606EE9E +P 10350 5050 +F 0 "L1" V 10300 5050 50 0000 C CNN +F 1 "INDUCTOR" V 10450 5050 50 0000 C CNN +F 2 "Special_inductor:SMALL_INDUCTOR" H 10350 5050 60 0001 C CNN +F 3 "" H 10350 5050 60 0000 C CNN + 1 10350 5050 + 0 1 1 0 +$EndComp +$Comp +L D_Schottky D1 +U 1 1 5606FDB4 +P 11100 5050 +F 0 "D1" H 11100 5150 50 0000 C CNN +F 1 "D_Schottky" H 11100 4950 50 0000 C CNN +F 2 "Diodes_SMD:SMA_Standard" H 11100 5050 60 0001 C CNN +F 3 "" H 11100 5050 60 0000 C CNN + 1 11100 5050 + -1 0 0 1 +$EndComp +$Comp +L CP1 C9 +U 1 1 560719D9 +P 9300 5350 +F 0 "C9" H 9325 5450 50 0000 L CNN +F 1 "CP1" H 9325 5250 50 0000 L CNN +F 2 "Capacitors_SMD:c_elec_4x5.3" H 9300 5350 60 0001 C CNN +F 3 "" H 9300 5350 60 0000 C CNN + 1 9300 5350 + 1 0 0 -1 +$EndComp +$Comp +L C C10 +U 1 1 56071A50 +P 9600 5350 +F 0 "C10" H 9625 5450 50 0000 L CNN +F 1 "C" H 9625 5250 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 9638 5200 30 0001 C CNN +F 3 "" H 9600 5350 60 0000 C CNN + 1 9600 5350 + 1 0 0 -1 +$EndComp +$Comp +L C C16 +U 1 1 5607355F +P 16600 5350 +F 0 "C16" H 16625 5450 50 0000 L CNN +F 1 "C" H 16625 5250 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 16638 5200 30 0001 C CNN +F 3 "" H 16600 5350 60 0000 C CNN + 1 16600 5350 + 1 0 0 -1 +$EndComp +$Comp +L CP1 C15 +U 1 1 560735FE +P 11500 5400 +F 0 "C15" H 11525 5500 50 0000 L CNN +F 1 "CP1" H 11525 5300 50 0000 L CNN +F 2 "Capacitors_SMD:c_elec_4x5.3" H 11500 5400 60 0001 C CNN +F 3 "" H 11500 5400 60 0000 C CNN + 1 11500 5400 + 1 0 0 -1 +$EndComp +NoConn ~ 7050 4400 +NoConn ~ 7050 4600 +Text Label 7050 4900 0 60 ~ 0 +CH2 +$Comp +L CONN_02X02 P4 +U 1 1 56069A87 +P 4600 4350 +F 0 "P4" H 4600 4500 50 0000 C CNN +F 1 "PDI/3V3" H 4600 4200 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_2x02" H 4600 3150 60 0001 C CNN +F 3 "" H 4600 3150 60 0000 C CNN + 1 4600 4350 + 1 0 0 -1 +$EndComp +Text Label 2700 4300 0 60 ~ 0 +VCC_3V3 +NoConn ~ 6050 4000 +Text Label 8900 5650 0 60 ~ 0 +VGND +Text Label 7050 5450 0 60 ~ 0 +DAC_OUT2 +Text Label 7350 11450 0 60 ~ 0 +DAC_OUT2 +$Comp +L R R23 +U 1 1 566DE721 +P 10850 11550 +F 0 "R23" V 10930 11550 50 0000 C CNN +F 1 "28R" V 10850 11550 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 10780 11550 30 0001 C CNN +F 3 "" H 10850 11550 30 0000 C CNN + 1 10850 11550 + 0 1 1 0 +$EndComp +$Comp +L R R25 +U 1 1 566DE7E8 +P 11150 11550 +F 0 "R25" V 11230 11550 50 0000 C CNN +F 1 "28R" V 11150 11550 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 11080 11550 30 0001 C CNN +F 3 "" H 11150 11550 30 0000 C CNN + 1 11150 11550 + 0 1 1 0 +$EndComp +$Comp +L C_Small C14 +U 1 1 566DF655 +P 11400 11650 +F 0 "C14" H 11410 11720 50 0000 L CNN +F 1 "C" H 11410 11570 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 11400 11650 60 0001 C CNN +F 3 "" H 11400 11650 60 0000 C CNN + 1 11400 11650 + 0 1 1 0 +$EndComp +$Comp +L CONN_01X04 P6 +U 1 1 566DF832 +P 12450 10750 +F 0 "P6" H 12450 11000 50 0000 C CNN +F 1 "DAC_OUT" V 12550 10750 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x04" H 12450 10750 60 0001 C CNN +F 3 "" H 12450 10750 60 0000 C CNN + 1 12450 10750 + 1 0 0 -1 +$EndComp +$Comp +L R R26 +U 1 1 566E5C29 +P 12100 5200 +F 0 "R26" V 12180 5200 50 0000 C CNN +F 1 "1K" V 12100 5200 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 12030 5200 30 0001 C CNN +F 3 "" H 12100 5200 30 0000 C CNN + 1 12100 5200 + 1 0 0 -1 +$EndComp +$Comp +L R R27 +U 1 1 566E5CBE +P 12100 5500 +F 0 "R27" V 12180 5500 50 0000 C CNN +F 1 "100R" V 12100 5500 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 12030 5500 30 0001 C CNN +F 3 "" H 12100 5500 30 0000 C CNN + 1 12100 5500 + 1 0 0 -1 +$EndComp +Text Label 7050 4800 0 60 ~ 0 +PSU_FDBK +Text Label 12350 5350 0 60 ~ 0 +PSU_FDBK +$Comp +L CP1 C6 +U 1 1 566F5A75 +P 4050 6900 +F 0 "C6" H 4075 7000 50 0000 L CNN +F 1 "CP1" H 4075 6800 50 0000 L CNN +F 2 "Capacitors_SMD:c_elec_4x5.3" H 4050 6900 60 0001 C CNN +F 3 "" H 4050 6900 60 0000 C CNN + 1 4050 6900 + 1 0 0 -1 +$EndComp +Text Label 6250 3900 0 60 ~ 0 +VCC_3V3 +$Comp +L R R19 +U 1 1 56AECD86 +P 8700 9750 +F 0 "R19" V 8780 9750 50 0000 C CNN +F 1 "1K" V 8700 9750 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 8630 9750 30 0001 C CNN +F 3 "" H 8700 9750 30 0000 C CNN + 1 8700 9750 + 0 1 1 0 +$EndComp +Text Label 10400 3600 0 60 ~ 0 +VCC_3V3 +Text Label 9150 3600 0 60 ~ 0 +AVCC +$Comp +L C C11 +U 1 1 5608B4BE +P 10150 3750 +F 0 "C11" H 10175 3850 50 0000 L CNN +F 1 "C" H 10175 3650 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 10188 3600 30 0001 C CNN +F 3 "" H 10150 3750 60 0000 C CNN + 1 10150 3750 + 1 0 0 -1 +$EndComp +$Comp +L C C8 +U 1 1 56AF91A3 +P 9200 3750 +F 0 "C8" H 9225 3850 50 0000 L CNN +F 1 "C" H 9225 3650 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 9238 3600 30 0001 C CNN +F 3 "" H 9200 3750 60 0000 C CNN + 1 9200 3750 + 1 0 0 -1 +$EndComp +$Comp +L R R17 +U 1 1 56AFE83E +P 7950 9900 +F 0 "R17" V 8030 9900 50 0000 C CNN +F 1 "1K" V 7950 9900 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 7880 9900 30 0001 C CNN +F 3 "" H 7950 9900 30 0000 C CNN + 1 7950 9900 + 1 0 0 -1 +$EndComp +$Comp +L R R18 +U 1 1 56AFE8F3 +P 8150 9900 +F 0 "R18" V 8230 9900 50 0000 C CNN +F 1 "1K" V 8150 9900 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 8080 9900 30 0001 C CNN +F 3 "" H 8150 9900 30 0000 C CNN + 1 8150 9900 + 1 0 0 -1 +$EndComp +$Comp +L DMN63D8LDW U3 +U 1 1 56B012DD +P 9250 10750 +F 0 "U3" H 9250 10450 60 0000 C CNN +F 1 "DMN63D8LDW" H 9250 11100 60 0000 C CNN +F 2 "TO_SOT_Packages_SMD:SOT-363" H 9250 10450 60 0001 C CNN +F 3 "" H 9250 10450 60 0000 C CNN + 1 9250 10750 + 1 0 0 -1 +$EndComp +Text Label 9800 10750 0 60 ~ 0 +TO_B0 +Text Label 7050 5150 0 60 ~ 0 +TO_B0 +Text Label 13950 5050 0 60 ~ 0 +PSU_OUT +$Comp +L R R20 +U 1 1 56B0C682 +P 8700 12050 +F 0 "R20" V 8780 12050 50 0000 C CNN +F 1 "1K" V 8700 12050 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 8630 12050 30 0001 C CNN +F 3 "" H 8700 12050 30 0000 C CNN + 1 8700 12050 + 0 1 1 0 +$EndComp +$Comp +L R R15 +U 1 1 56B0C779 +P 7900 12200 +F 0 "R15" V 7980 12200 50 0000 C CNN +F 1 "1K" V 7900 12200 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 7830 12200 30 0001 C CNN +F 3 "" H 7900 12200 30 0000 C CNN + 1 7900 12200 + 1 0 0 -1 +$EndComp +$Comp +L R R16 +U 1 1 56B0C86E +P 8100 12200 +F 0 "R16" V 8180 12200 50 0000 C CNN +F 1 "1K" V 8100 12200 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 8030 12200 30 0001 C CNN +F 3 "" H 8100 12200 30 0000 C CNN + 1 8100 12200 + 1 0 0 -1 +$EndComp +Text Label 8100 10750 0 60 ~ 0 +TO_B1 +Text Label 7050 5250 0 60 ~ 0 +TO_B1 +$Comp +L +5V #PWR02 +U 1 1 56E7FFFF +P 8900 5050 +F 0 "#PWR02" H 8900 4900 50 0001 C CNN +F 1 "+5V" H 8900 5190 50 0000 C CNN +F 2 "" H 8900 5050 60 0000 C CNN +F 3 "" H 8900 5050 60 0000 C CNN + 1 8900 5050 + 1 0 0 -1 +$EndComp +$Comp +L INDUCTOR L2 +U 1 1 56E88440 +P 9700 3600 +F 0 "L2" V 9650 3600 50 0000 C CNN +F 1 "INDUCTOR" V 9800 3600 50 0000 C CNN +F 2 "Resistors_SMD:R_1206" H 9700 3600 60 0001 C CNN +F 3 "" H 9700 3600 60 0000 C CNN + 1 9700 3600 + 0 1 1 0 +$EndComp +Text Label 4100 8350 0 60 ~ 0 +OPAMP_VCC +Text Label 4100 10150 0 60 ~ 0 +OPAMP_VCC +Text Label 8350 8850 0 60 ~ 0 +OPAMP_VCC +Text Label 8300 11150 0 60 ~ 0 +OPAMP_VCC +$Comp +L INDUCTOR L3 +U 1 1 56E8DA35 +P 15300 5050 +F 0 "L3" V 15250 5050 50 0000 C CNN +F 1 "INDUCTOR" V 15400 5050 50 0000 C CNN +F 2 "Resistors_SMD:R_1206" H 15300 5050 60 0001 C CNN +F 3 "" H 15300 5050 60 0000 C CNN + 1 15300 5050 + 0 1 1 0 +$EndComp +$Comp +L C C7 +U 1 1 56E8E263 +P 15000 5350 +F 0 "C7" H 15025 5450 50 0000 L CNN +F 1 "C" H 15025 5250 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 15038 5200 30 0001 C CNN +F 3 "" H 15000 5350 60 0000 C CNN + 1 15000 5350 + 1 0 0 -1 +$EndComp +Text Label 16250 5050 0 60 ~ 0 +OPAMP_VCC +$Comp +L R R21 +U 1 1 56E9851A +P 4900 8900 +F 0 "R21" V 4980 8900 50 0000 C CNN +F 1 "1K" V 4900 8900 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4830 8900 30 0001 C CNN +F 3 "" H 4900 8900 30 0000 C CNN + 1 4900 8900 + 1 0 0 -1 +$EndComp +$Comp +L R R28 +U 1 1 56E985EF +P 4950 10400 +F 0 "R28" V 5030 10400 50 0000 C CNN +F 1 "1K" V 4950 10400 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 4880 10400 30 0001 C CNN +F 3 "" H 4950 10400 30 0000 C CNN + 1 4950 10400 + 1 0 0 -1 +$EndComp +$Comp +L R R29 +U 1 1 56E9888A +P 9600 9400 +F 0 "R29" V 9680 9400 50 0000 C CNN +F 1 "1K" V 9600 9400 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 9530 9400 30 0001 C CNN +F 3 "" H 9600 9400 30 0000 C CNN + 1 9600 9400 + 1 0 0 -1 +$EndComp +$Comp +L R R30 +U 1 1 56E98921 +P 10000 11400 +F 0 "R30" V 10080 11400 50 0000 C CNN +F 1 "1K" V 10000 11400 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 9930 11400 30 0001 C CNN +F 3 "" H 10000 11400 30 0000 C CNN + 1 10000 11400 + 1 0 0 -1 +$EndComp +$Comp +L CONN_01X02 P7 +U 1 1 56F2A93D +P 14150 5350 +F 0 "P7" H 14150 5500 50 0000 C CNN +F 1 "PSU" V 14250 5350 50 0000 C CIN +F 2 "Pin_Headers:Pin_Header_Straight_1x02" H 14150 5350 50 0001 C CNN +F 3 "" H 14150 5350 50 0000 C CNN + 1 14150 5350 + 1 0 0 -1 +$EndComp +Text Label 6300 6700 0 60 ~ 0 +VGND +Text Label 6200 6950 0 60 ~ 0 +VGND +Text Label 6100 6800 0 60 ~ 0 +VGND +Text Label 6000 7100 0 60 ~ 0 +VGND +Text Label 7600 6000 0 60 ~ 0 +VGND +Text Label 4750 9750 0 60 ~ 0 +VGND +Text Label 4100 9150 0 60 ~ 0 +VGND +Text Label 4100 10950 0 60 ~ 0 +VGND +Text Label 7900 3900 0 60 ~ 0 +VGND +Text Label 10800 3900 0 60 ~ 0 +VGND +Text Label 10300 10900 0 60 ~ 0 +VGND +Text Label 8500 10600 0 60 ~ 0 +VGND +Text Label 8350 9650 0 60 ~ 0 +VGND +Text Label 8300 11950 0 60 ~ 0 +VGND +$Comp +L INDUCTOR L4 +U 1 1 573254B0 +P 15950 5050 +F 0 "L4" V 15900 5050 50 0000 C CNN +F 1 "INDUCTOR" V 16050 5050 50 0000 C CNN +F 2 "Resistors_SMD:R_1206" H 15950 5050 60 0001 C CNN +F 3 "" H 15950 5050 60 0000 C CNN + 1 15950 5050 + 0 1 1 0 +$EndComp +Text Label 13700 3300 0 60 ~ 0 +VGND +Text Label 14850 3600 0 60 ~ 0 +VGND +Text Label 3900 4400 0 60 ~ 0 +VGND +$Comp +L C C18 +U 1 1 57564580 +P 8700 3750 +F 0 "C18" H 8725 3850 50 0000 L CNN +F 1 "C" H 8725 3650 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 8738 3600 50 0001 C CNN +F 3 "" H 8700 3750 50 0000 C CNN + 1 8700 3750 + 1 0 0 -1 +$EndComp +$Comp +L C C17 +U 1 1 57564635 +P 8450 3750 +F 0 "C17" H 8475 3850 50 0000 L CNN +F 1 "C" H 8475 3650 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 8488 3600 50 0001 C CNN +F 3 "" H 8450 3750 50 0000 C CNN + 1 8450 3750 + 1 0 0 -1 +$EndComp +$Comp +L R R31 +U 1 1 5804605C +P 10300 5500 +F 0 "R31" V 10380 5500 50 0000 C CNN +F 1 "1K" V 10300 5500 50 0000 C CNN +F 2 "Resistors_SMD:R_0603" V 10230 5500 50 0001 C CNN +F 3 "" H 10300 5500 50 0000 C CNN + 1 10300 5500 + 1 0 0 -1 +$EndComp +Text Label 10150 5350 0 60 ~ 0 +PSU_PWM +$Comp +L Q_NMOS_GSD Q1 +U 1 1 583120F2 +P 10650 5350 +F 0 "Q1" H 10950 5400 50 0000 R CNN +F 1 "Q_NMOS_GSD" H 11300 5300 50 0000 R CNN +F 2 "SMD:SOT-23-3" H 10850 5450 50 0001 C CNN +F 3 "" H 10650 5350 50 0000 C CNN + 1 10650 5350 + 1 0 0 -1 +$EndComp +NoConn ~ 5250 5900 +$Comp +L LED D2 +U 1 1 5833E159 +P 14450 5450 +F 0 "D2" H 14450 5550 50 0000 C CNN +F 1 "LED" H 14450 5350 50 0000 C CNN +F 2 "LEDs:LED_0603" H 14450 5450 50 0001 C CNN +F 3 "" H 14450 5450 50 0000 C CNN + 1 14450 5450 + 0 -1 -1 0 +$EndComp +$Comp +L R_Small R32 +U 1 1 5833E34C +P 14450 5150 +F 0 "R32" H 14480 5170 50 0000 L CNN +F 1 "1K" H 14480 5110 50 0000 L CNN +F 2 "Resistors_SMD:R_0603" H 14450 5150 50 0001 C CNN +F 3 "" H 14450 5150 50 0000 C CNN + 1 14450 5150 + 1 0 0 -1 +$EndComp +$Comp +L CONN_01X03 P10 +U 1 1 5837847B +P 12800 4950 +F 0 "P10" H 12800 5150 50 0000 C CNN +F 1 "EXPANSION" V 12900 4950 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x03" H 12800 4950 50 0001 C CNN +F 3 "" H 12800 4950 50 0000 C CNN + 1 12800 4950 + 1 0 0 -1 +$EndComp +$Comp +L CONN_01X03 P11 +U 1 1 58378536 +P 13400 4950 +F 0 "P11" H 13400 5150 50 0000 C CNN +F 1 "SWITCH" V 13500 4950 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x03" H 13400 4950 50 0001 C CNN +F 3 "" H 13400 4950 50 0000 C CNN + 1 13400 4950 + 1 0 0 -1 +$EndComp +NoConn ~ 13200 4850 +$Comp +L CONN_01X04 P1 +U 1 1 5832064B +P 1050 9250 +F 0 "P1" H 1050 9500 50 0000 C CNN +F 1 "SCOPE_OUT" V 1150 9250 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x04" H 1050 9250 50 0001 C CNN +F 3 "" H 1050 9250 50 0000 C CNN + 1 1050 9250 + -1 0 0 1 +$EndComp +$Comp +L CONN_01X04 P5 +U 1 1 58320706 +P 1050 9900 +F 0 "P5" H 1050 10150 50 0000 C CNN +F 1 "SCOPE_OUT" V 1150 9900 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x04" H 1050 9900 50 0001 C CNN +F 3 "" H 1050 9900 50 0000 C CNN + 1 1050 9900 + -1 0 0 1 +$EndComp +Text Label 10650 5050 0 60 ~ 0 +QTop +Text Label 1300 9100 0 60 ~ 0 +Scope_CH1_DC +Text Label 1300 9300 0 60 ~ 0 +Scoe_CH1_AC +Text Label 1300 9750 0 60 ~ 0 +Scope_CH2_DC +Text Label 1300 9950 0 60 ~ 0 +Scope_CH2_AC +Text Label 12250 10400 0 60 ~ 0 +S-Gen_CH1_DC +Text Label 12150 10050 0 60 ~ 0 +S-Gen_CH1_AC +Text Label 11950 11100 0 60 ~ 0 +S-Gen_CH2_DC +Text Label 12100 11350 0 60 ~ 0 +S-Gen_CH2_AC +Text Label 7950 9650 0 60 ~ 0 +V_minus_dac_out +Text Label 7900 11900 0 60 ~ 0 +V_minus_dac_out2 +Text Label 9300 9250 0 60 ~ 0 +Buffered_DAC_CH1 +Text Label 9050 11550 0 60 ~ 0 +Buffered_DAC_CH2 +Text Label 8150 10350 0 60 ~ 0 +S-Gen_Drain_Top_CH1 +Text Label 7150 12350 0 60 ~ 0 +S-Gen_Drain_Top_CH2 +Text Label 2650 8650 0 60 ~ 0 +Scope_Buffer_Input_CH1 +Text Label 2500 10450 0 60 ~ 0 +Scope_Buffer_Input_CH2 +Text Label 3800 5150 0 60 ~ 0 +D0_OUT +Text Label 3800 5250 0 60 ~ 0 +D1_OUT +Text Label 3800 5350 0 60 ~ 0 +D2-OUT +Text Label 3800 5450 0 60 ~ 0 +D3-OUT +Text Label 4950 5000 0 60 ~ 0 +D0-prefuse +Text Label 4900 5200 0 60 ~ 0 +D1-prefuse +Text Label 4900 5400 0 60 ~ 0 +D2-prefuse +Text Label 4900 5600 0 60 ~ 0 +D3-prefuse +Text Label 4300 4000 0 60 ~ 0 +PDI_CLK +Text Label 4950 4400 0 60 ~ 0 +PDI_DATA +Text Label 3750 4300 0 60 ~ 0 +3V3_OUT +Text Label 13200 4850 0 60 ~ 0 +Switch_OC +Text Label 1950 6950 0 60 ~ 0 +Disconnected_USB +Text Label 4500 5000 0 60 ~ 0 +D0_MID +Text Label 4550 5200 0 60 ~ 0 +D1_MID +Text Label 4500 5400 0 60 ~ 0 +D2_MID +Text Label 4550 5600 0 60 ~ 0 +D3_MID +Text Label 12250 4600 0 60 ~ 0 +PSU_Unfiltered_Raw +Text Label 13650 2950 0 60 ~ 0 +L-Ana_IN_CH1 +Text Label 14950 2950 0 60 ~ 0 +L-Ana_IN_CH2 +Text Label 10800 9250 0 60 ~ 0 +R22-R24 +Text Label 11000 11550 0 60 ~ 0 +R23-R25 +$Comp +L C C12 +U 1 1 588029E7 +P 10100 5500 +F 0 "C12" H 10125 5600 50 0000 L CNN +F 1 "C" H 10125 5400 50 0000 L CNN +F 2 "Capacitors_SMD:C_0603" H 10138 5350 50 0001 C CNN +F 3 "" H 10100 5500 50 0000 C CNN + 1 10100 5500 + 1 0 0 -1 +$EndComp +Connection ~ 13950 5050 +Connection ~ 14450 5650 +Wire Wire Line + 13200 5050 14450 5050 +Connection ~ 16350 5050 +Connection ~ 13950 5650 +Wire Wire Line + 15600 5050 15650 5050 +Wire Wire Line + 11900 5050 11250 5050 +Wire Wire Line + 16600 5650 16600 5500 +Wire Wire Line + 16600 5050 16600 5200 +Wire Wire Line + 12100 5350 12350 5350 +Connection ~ 10300 5350 +Connection ~ 10300 5650 +Wire Wire Line + 10100 5350 10450 5350 +Wire Wire Line + 10750 5650 10750 5550 +Wire Wire Line + 10750 5150 10750 5050 +Wire Wire Line + 13950 5650 13950 5400 +Wire Wire Line + 8450 3600 8950 3600 +Connection ~ 8450 3600 +Connection ~ 8700 3600 +Connection ~ 8950 3600 +Connection ~ 8950 3900 +Connection ~ 8700 3900 +Connection ~ 8450 3900 +Connection ~ 8200 3900 +Wire Wire Line + 2550 4000 4850 4000 +Wire Wire Line + 2550 4600 2550 4000 +Wire Wire Line + 5200 4600 2550 4600 +Wire Wire Line + 5200 4400 5200 4600 +Wire Wire Line + 5200 4400 5250 4400 +Wire Wire Line + 3250 4300 2700 4300 +Wire Wire Line + 8200 3900 8950 3900 +Wire Wire Line + 3100 6950 3100 7050 +Connection ~ 2500 7050 +Wire Wire Line + 2500 7250 2500 7050 +Wire Wire Line + 1950 7050 4050 7050 +Connection ~ 9600 9250 +Connection ~ 10000 11550 +Wire Wire Line + 6000 6600 6000 7100 +Wire Wire Line + 6300 6700 6300 6600 +Connection ~ 10000 10900 +Wire Wire Line + 10000 11250 10000 10900 +Connection ~ 10150 10900 +Wire Wire Line + 10150 11100 10150 10900 +Wire Wire Line + 10950 11100 10150 11100 +Wire Wire Line + 10950 10150 10950 11100 +Wire Wire Line + 9600 10150 10950 10150 +Wire Wire Line + 9600 9550 9600 10150 +Connection ~ 4400 9750 +Wire Wire Line + 4400 9950 4400 9750 +Wire Wire Line + 4950 9950 4400 9950 +Wire Wire Line + 4950 10250 4950 9950 +Wire Wire Line + 4700 10550 4950 10550 +Wire Wire Line + 4150 9250 4150 9750 +Wire Wire Line + 4150 9250 4900 9250 +Wire Wire Line + 4900 9250 4900 9050 +Wire Wire Line + 4700 8750 4900 8750 +Connection ~ 8100 12050 +Wire Wire Line + 8100 12050 8600 12050 +Connection ~ 7900 12350 +Wire Wire Line + 7150 12350 7150 10900 +Wire Wire Line + 7150 12350 8100 12350 +Connection ~ 8150 9750 +Wire Wire Line + 7950 10050 7950 10350 +Wire Wire Line + 8150 10050 7950 10050 +Wire Wire Line + 12100 10900 12250 10900 +Wire Wire Line + 12100 11650 12100 10900 +Wire Wire Line + 11500 11650 12100 11650 +Wire Wire Line + 11950 10800 12250 10800 +Wire Wire Line + 11950 11550 11950 10800 +Wire Wire Line + 12150 10700 12250 10700 +Wire Wire Line + 12150 9350 12150 10700 +Wire Wire Line + 12250 9250 12250 10600 +Wire Wire Line + 11150 9250 12250 9250 +Wire Wire Line + 8950 9250 10500 9250 +Wire Wire Line + 8900 11550 10700 11550 +Wire Wire Line + 8800 10600 8500 10600 +Wire Wire Line + 8800 10750 8100 10750 +Wire Wire Line + 7150 10900 8800 10900 +Wire Wire Line + 8550 12050 7900 12050 +Wire Wire Line + 8900 12050 8900 11550 +Wire Wire Line + 8850 12050 8900 12050 +Wire Wire Line + 7900 12050 7900 11650 +Wire Wire Line + 9700 10750 10350 10750 +Wire Wire Line + 9700 10900 10300 10900 +Wire Wire Line + 9700 10350 9700 10600 +Wire Wire Line + 7950 10350 9700 10350 +Wire Wire Line + 8950 9750 8950 9250 +Wire Wire Line + 8850 9750 8950 9750 +Wire Wire Line + 7950 9750 8550 9750 +Wire Wire Line + 7950 9350 7950 9750 +Wire Wire Line + 7900 3900 9200 3900 +Connection ~ 9200 3600 +Connection ~ 10150 3600 +Wire Wire Line + 10000 3600 10400 3600 +Wire Wire Line + 9150 3600 9400 3600 +Wire Wire Line + 6250 4000 6250 3900 +Wire Wire Line + 6200 6600 6200 6950 +Wire Wire Line + 4050 6650 3500 6650 +Wire Wire Line + 4050 6750 4050 6650 +Connection ~ 3500 7050 +Connection ~ 4150 9750 +Wire Wire Line + 11300 11550 11950 11550 +Wire Wire Line + 11300 11650 11300 11550 +Wire Wire Line + 7900 11450 7350 11450 +Wire Wire Line + 3600 9750 4750 9750 +Wire Wire Line + 3600 9700 3600 9750 +Wire Wire Line + 4850 4000 4850 4300 +Wire Wire Line + 5050 4400 4850 4400 +Wire Wire Line + 5050 4300 5050 4400 +Wire Wire Line + 5250 4300 5050 4300 +Wire Wire Line + 10150 3900 10800 3900 +Wire Wire Line + 4350 4400 3900 4400 +Wire Wire Line + 3450 4300 4350 4300 +Connection ~ 10750 5650 +Connection ~ 9600 5650 +Wire Wire Line + 9600 5500 9600 5650 +Connection ~ 9300 5650 +Wire Wire Line + 9300 5500 9300 5650 +Connection ~ 9300 5050 +Wire Wire Line + 9300 5200 9300 5050 +Connection ~ 9600 5050 +Wire Wire Line + 9600 4850 9600 5200 +Connection ~ 10750 5050 +Wire Wire Line + 9650 5050 8900 5050 +Wire Wire Line + 1950 7250 1950 7050 +Wire Wire Line + 1550 7250 1950 7250 +Wire Wire Line + 5250 6000 4750 6000 +Wire Wire Line + 7050 6000 7600 6000 +Wire Wire Line + 15250 3450 14850 3450 +Wire Wire Line + 15250 2950 15250 3450 +Wire Wire Line + 14450 2950 15250 2950 +Wire Wire Line + 13550 2950 14350 2950 +Wire Wire Line + 13550 3450 13550 2950 +Wire Wire Line + 13950 3450 13550 3450 +Wire Wire Line + 13950 3600 13550 3600 +Wire Wire Line + 13950 3300 13700 3300 +Wire Wire Line + 6150 4000 6150 3800 +Wire Wire Line + 6100 6600 6100 6800 +Wire Wire Line + 3600 9500 3150 9500 +Wire Wire Line + 3600 9700 3150 9700 +Wire Wire Line + 5250 6200 5100 6200 +Wire Wire Line + 5250 6300 5100 6300 +Wire Wire Line + 4000 5600 4200 5600 +Wire Wire Line + 4000 5450 4000 5600 +Wire Wire Line + 3750 5450 4000 5450 +Wire Wire Line + 4000 5400 4200 5400 +Wire Wire Line + 4000 5350 4000 5400 +Wire Wire Line + 3750 5350 4000 5350 +Wire Wire Line + 4000 5250 3750 5250 +Wire Wire Line + 4000 5200 4000 5250 +Wire Wire Line + 4200 5200 4000 5200 +Wire Wire Line + 4000 5000 4200 5000 +Wire Wire Line + 4000 5150 4000 5000 +Wire Wire Line + 3750 5150 4000 5150 +Wire Wire Line + 5050 5450 5250 5450 +Wire Wire Line + 5050 5600 5050 5450 +Wire Wire Line + 4850 5600 5050 5600 +Wire Wire Line + 5050 5350 5250 5350 +Wire Wire Line + 5050 5400 5050 5350 +Wire Wire Line + 4850 5400 5050 5400 +Wire Wire Line + 5050 5250 5250 5250 +Wire Wire Line + 5050 5200 5050 5250 +Wire Wire Line + 4850 5200 5050 5200 +Wire Wire Line + 5050 5150 5250 5150 +Wire Wire Line + 5050 5000 5050 5150 +Wire Wire Line + 4850 5000 5050 5000 +Wire Wire Line + 4500 5600 4550 5600 +Wire Wire Line + 4500 5400 4550 5400 +Wire Wire Line + 4500 5200 4550 5200 +Wire Wire Line + 4500 5000 4550 5000 +Wire Wire Line + 10800 9250 10850 9250 +Wire Wire Line + 1950 6650 2700 6650 +Wire Wire Line + 2700 6650 2700 6850 +Connection ~ 2700 7050 +Connection ~ 3100 7050 +Wire Wire Line + 3500 6650 3500 6850 +Wire Wire Line + 2150 9250 2350 9250 +Wire Wire Line + 2850 9500 2850 9700 +Wire Wire Line + 2350 9550 2350 9650 +Wire Wire Line + 2350 9600 2850 9600 +Connection ~ 2850 9600 +Connection ~ 2350 9600 +Wire Wire Line + 3700 8850 3700 9000 +Wire Wire Line + 3700 9000 4700 9000 +Wire Wire Line + 4700 9000 4700 8750 +Wire Wire Line + 2350 9250 2350 8650 +Wire Wire Line + 2350 8650 3700 8650 +Wire Wire Line + 3700 10650 3700 10800 +Wire Wire Line + 3700 10800 4700 10800 +Wire Wire Line + 4700 10800 4700 10550 +Wire Wire Line + 2350 10450 3700 10450 +Wire Wire Line + 2350 9950 2350 10450 +Wire Wire Line + 2150 9950 2350 9950 +Wire Wire Line + 11350 9350 12150 9350 +Wire Wire Line + 7950 9150 7400 9150 +Wire Wire Line + 11150 9250 11150 9350 +Wire Wire Line + 11500 5050 11500 5250 +Wire Wire Line + 11500 5650 11500 5550 +Connection ~ 11500 5650 +Connection ~ 11500 5050 +Wire Wire Line + 16600 5050 16250 5050 +Connection ~ 12100 5650 +Wire Wire Line + 12600 5050 12600 5650 +Connection ~ 12600 5650 +Wire Wire Line + 11900 5050 11900 4850 +Wire Wire Line + 13050 4600 13050 4950 +Wire Wire Line + 12100 4600 15000 4600 +Wire Wire Line + 15000 4600 15000 5200 +Wire Wire Line + 12100 4600 12100 5050 +Wire Wire Line + 11900 4850 12600 4850 +Connection ~ 12100 4850 +Wire Wire Line + 12350 5350 12350 4950 +Wire Wire Line + 12350 4950 12600 4950 +Connection ~ 13050 4600 +Wire Wire Line + 13950 5300 13950 5050 +Wire Wire Line + 13050 4950 13200 4950 +Wire Wire Line + 1850 9100 1850 9400 +Wire Wire Line + 1850 9100 1250 9100 +Wire Wire Line + 1250 9200 1850 9200 +Connection ~ 1850 9200 +Wire Wire Line + 1850 9400 1250 9400 +Connection ~ 1850 9250 +Wire Wire Line + 1250 9300 1350 9300 +Wire Wire Line + 1550 9300 1850 9300 +Connection ~ 1850 9300 +Wire Wire Line + 1850 9950 1650 9950 +Wire Wire Line + 1450 9950 1250 9950 +Wire Wire Line + 1850 9750 1850 10050 +Wire Wire Line + 1850 10050 1250 10050 +Wire Wire Line + 1250 9850 1850 9850 +Connection ~ 1850 9950 +Wire Wire Line + 1250 9750 1850 9750 +Connection ~ 1850 9850 +Connection ~ 15000 5050 +Wire Wire Line + 15000 5500 15000 5650 +Connection ~ 15000 5650 +Wire Wire Line + 16350 5200 16350 5050 +Wire Wire Line + 8200 3600 9200 3600 +Connection ~ 10100 5650 +Wire Wire Line + 10950 5050 10650 5050 +$Comp +L F_Small F2 +U 1 1 58F5AF9C +P 9750 5050 +F 0 "F2" H 9710 5110 50 0000 L CNN +F 1 "F_Small" H 9630 4990 50 0000 L CNN +F 2 "Capacitors_SMD:C_1210" H 9750 5050 50 0001 C CNN +F 3 "" H 9750 5050 50 0000 C CNN + 1 9750 5050 + 1 0 0 -1 +$EndComp +Wire Wire Line + 9850 5050 10050 5050 +$Comp +L CONN_01X02 P9 +U 1 1 58FEDB8C +P 9750 4650 +F 0 "P9" H 9750 4800 50 0000 C CNN +F 1 "FUSE_BYPASS" V 9850 4650 50 0000 C CNN +F 2 "Pin_Headers:Pin_Header_Straight_1x02" H 9750 4650 60 0001 C CNN +F 3 "" H 9750 4650 60 0000 C CNN + 1 9750 4650 + 0 -1 -1 0 +$EndComp +Wire Wire Line + 9700 4850 9600 4850 +Wire Wire Line + 9800 4850 9950 4850 +Wire Wire Line + 9950 4850 9950 5050 +Connection ~ 9950 5050 +Wire Wire Line + 8900 5650 16600 5650 +Wire Wire Line + 16350 5650 16350 5500 +Connection ~ 16350 5650 +$EndSCHEMATC diff --git a/PCB/Tinylab_proto1.sch.REMOVED.git-id b/PCB/Tinylab_proto1.sch.REMOVED.git-id deleted file mode 100644 index ca783bb0..00000000 --- a/PCB/Tinylab_proto1.sch.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -45ce40429f68ff9f30a230b3cf3f742c9aac7287 \ No newline at end of file diff --git a/PCB/Tinylab_proto1.xml b/PCB/Tinylab_proto1.xml new file mode 100644 index 00000000..4d7e19fa --- /dev/null +++ b/PCB/Tinylab_proto1.xml @@ -0,0 +1,1310 @@ + + + + C:/Users/Esposch/Documents/GitHub/Labrador/PCB/Tinylab_proto1.sch + 25/04/2017 11:21:47 AM + Eeschema 4.0.4-stable + + + + <company/> + <rev/> + <date/> + <source>Tinylab_proto1.sch</source> + <comment number="1" value=""/> + <comment number="2" value=""/> + <comment number="3" value=""/> + <comment number="4" value=""/> + </title_block> + </sheet> + </design> + <components> + <comp ref="U2"> + <value>LM324</value> + <footprint>Housings_SOIC:SOIC-14_3.9x8.7mm_Pitch1.27mm</footprint> + <libsource lib="Tinylab_proto1-rescue" part="LM324-RESCUE-Tinylab_proto1"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CA87E2</tstamp> + </comp> + <comp ref="IC1"> + <value>ATXMEGA32A4U-AU</value> + <footprint>Housings_QFP:LQFP-44_10x10mm_Pitch0.8mm</footprint> + <libsource lib="atmel" part="ATXMEGA16A4U-A"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CA8F25</tstamp> + </comp> + <comp ref="P2"> + <value>USB_OTG</value> + <footprint>Connect:USB_Micro-B_WIDE</footprint> + <libsource lib="conn" part="USB_OTG"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CA90D2</tstamp> + </comp> + <comp ref="U1"> + <value>78L05</value> + <footprint>SMD:SOT-23-3</footprint> + <libsource lib="Tinylab_proto1-rescue" part="78L05-RESCUE-Tinylab_proto1"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CA99FA</tstamp> + </comp> + <comp ref="R1"> + <value>1M</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CAAB95</tstamp> + </comp> + <comp ref="R3"> + <value>75K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CAABF4</tstamp> + </comp> + <comp ref="R5"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CAAC5F</tstamp> + </comp> + <comp ref="R6"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CAACD2</tstamp> + </comp> + <comp ref="R4"> + <value>75K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CAAD11</tstamp> + </comp> + <comp ref="R2"> + <value>1M</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CAAD4C</tstamp> + </comp> + <comp ref="C2"> + <value>C</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C_Small"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CAB4DE</tstamp> + </comp> + <comp ref="C1"> + <value>C</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C_Small"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CAB611</tstamp> + </comp> + <comp ref="C3"> + <value>C_Small</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C_Small"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CB13E1</tstamp> + </comp> + <comp ref="C4"> + <value>C_Small</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C_Small"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CB147C</tstamp> + </comp> + <comp ref="R22"> + <value>28R</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CB4680</tstamp> + </comp> + <comp ref="C13"> + <value>C</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C_Small"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CB630B</tstamp> + </comp> + <comp ref="R24"> + <value>28R</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CB9020</tstamp> + </comp> + <comp ref="R11"> + <value>28R</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CBCD2A</tstamp> + </comp> + <comp ref="R7"> + <value>28R</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CBCDA5</tstamp> + </comp> + <comp ref="R13"> + <value>28R</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CBE0F4</tstamp> + </comp> + <comp ref="R9"> + <value>28R</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CBE16B</tstamp> + </comp> + <comp ref="R14"> + <value>28R</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CBE21C</tstamp> + </comp> + <comp ref="R10"> + <value>28R</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CBE2C7</tstamp> + </comp> + <comp ref="R12"> + <value>28R</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CBE362</tstamp> + </comp> + <comp ref="R8"> + <value>28R</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CBE401</tstamp> + </comp> + <comp ref="P3"> + <value>DIG_OUT</value> + <footprint>Pin_Headers:Pin_Header_Straight_1x04</footprint> + <libsource lib="conn" part="CONN_01X04"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55CBF4D5</tstamp> + </comp> + <comp ref="C5"> + <value>C_Small</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C_Small"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55D60181</tstamp> + </comp> + <comp ref="U4"> + <value>DMN63D8LDW</value> + <footprint>TO_SOT_Packages_SMD:SOT-363</footprint> + <libsource lib="ESPO_PART" part="DMN63D8LDW"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55D6ACFD</tstamp> + </comp> + <comp ref="P8"> + <value>DIG_IN</value> + <footprint>Pin_Headers:Pin_Header_Straight_1x02</footprint> + <libsource lib="conn" part="CONN_01X02"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55D6DB77</tstamp> + </comp> + <comp ref="F1"> + <value>F_Small</value> + <footprint>Capacitors_SMD:C_1210</footprint> + <libsource lib="device" part="F_Small"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>55D739F3</tstamp> + </comp> + <comp ref="L1"> + <value>INDUCTOR</value> + <footprint>Special_inductor:SMALL_INDUCTOR</footprint> + <libsource lib="device" part="INDUCTOR"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>5606EE9E</tstamp> + </comp> + <comp ref="D1"> + <value>D_Schottky</value> + <footprint>Diodes_SMD:SMA_Standard</footprint> + <libsource lib="device" part="D_Schottky"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>5606FDB4</tstamp> + </comp> + <comp ref="C9"> + <value>CP1</value> + <footprint>Capacitors_SMD:c_elec_4x5.3</footprint> + <libsource lib="device" part="CP1"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>560719D9</tstamp> + </comp> + <comp ref="C10"> + <value>C</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56071A50</tstamp> + </comp> + <comp ref="C16"> + <value>C</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>5607355F</tstamp> + </comp> + <comp ref="C15"> + <value>CP1</value> + <footprint>Capacitors_SMD:c_elec_4x5.3</footprint> + <libsource lib="device" part="CP1"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>560735FE</tstamp> + </comp> + <comp ref="P4"> + <value>PDI/3V3</value> + <footprint>Pin_Headers:Pin_Header_Straight_2x02</footprint> + <libsource lib="conn" part="CONN_02X02"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56069A87</tstamp> + </comp> + <comp ref="R23"> + <value>28R</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>566DE721</tstamp> + </comp> + <comp ref="R25"> + <value>28R</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>566DE7E8</tstamp> + </comp> + <comp ref="C14"> + <value>C</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C_Small"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>566DF655</tstamp> + </comp> + <comp ref="P6"> + <value>DAC_OUT</value> + <footprint>Pin_Headers:Pin_Header_Straight_1x04</footprint> + <libsource lib="conn" part="CONN_01X04"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>566DF832</tstamp> + </comp> + <comp ref="R26"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>566E5C29</tstamp> + </comp> + <comp ref="R27"> + <value>100R</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>566E5CBE</tstamp> + </comp> + <comp ref="C6"> + <value>CP1</value> + <footprint>Capacitors_SMD:c_elec_4x5.3</footprint> + <libsource lib="device" part="CP1"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>566F5A75</tstamp> + </comp> + <comp ref="R19"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56AECD86</tstamp> + </comp> + <comp ref="C11"> + <value>C</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>5608B4BE</tstamp> + </comp> + <comp ref="C8"> + <value>C</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56AF91A3</tstamp> + </comp> + <comp ref="R17"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56AFE83E</tstamp> + </comp> + <comp ref="R18"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56AFE8F3</tstamp> + </comp> + <comp ref="U3"> + <value>DMN63D8LDW</value> + <footprint>TO_SOT_Packages_SMD:SOT-363</footprint> + <libsource lib="ESPO_PART" part="DMN63D8LDW"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56B012DD</tstamp> + </comp> + <comp ref="R20"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56B0C682</tstamp> + </comp> + <comp ref="R15"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56B0C779</tstamp> + </comp> + <comp ref="R16"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56B0C86E</tstamp> + </comp> + <comp ref="L2"> + <value>INDUCTOR</value> + <footprint>Resistors_SMD:R_1206</footprint> + <libsource lib="device" part="INDUCTOR"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56E88440</tstamp> + </comp> + <comp ref="L3"> + <value>INDUCTOR</value> + <footprint>Resistors_SMD:R_1206</footprint> + <libsource lib="device" part="INDUCTOR"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56E8DA35</tstamp> + </comp> + <comp ref="C7"> + <value>C</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56E8E263</tstamp> + </comp> + <comp ref="R21"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56E9851A</tstamp> + </comp> + <comp ref="R28"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56E985EF</tstamp> + </comp> + <comp ref="R29"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56E9888A</tstamp> + </comp> + <comp ref="R30"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56E98921</tstamp> + </comp> + <comp ref="P7"> + <value>PSU</value> + <footprint>Pin_Headers:Pin_Header_Straight_1x02</footprint> + <libsource lib="conn" part="CONN_01X02"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>56F2A93D</tstamp> + </comp> + <comp ref="L4"> + <value>INDUCTOR</value> + <footprint>Resistors_SMD:R_1206</footprint> + <libsource lib="device" part="INDUCTOR"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>573254B0</tstamp> + </comp> + <comp ref="C18"> + <value>C</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>57564580</tstamp> + </comp> + <comp ref="C17"> + <value>C</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>57564635</tstamp> + </comp> + <comp ref="R31"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>5804605C</tstamp> + </comp> + <comp ref="Q1"> + <value>Q_NMOS_GSD</value> + <footprint>SMD:SOT-23-3</footprint> + <libsource lib="device" part="Q_NMOS_GSD"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>583120F2</tstamp> + </comp> + <comp ref="D2"> + <value>LED</value> + <footprint>LEDs:LED_0603</footprint> + <libsource lib="device" part="LED"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>5833E159</tstamp> + </comp> + <comp ref="R32"> + <value>1K</value> + <footprint>Resistors_SMD:R_0603</footprint> + <libsource lib="device" part="R_Small"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>5833E34C</tstamp> + </comp> + <comp ref="P10"> + <value>EXPANSION</value> + <footprint>Pin_Headers:Pin_Header_Straight_1x03</footprint> + <libsource lib="conn" part="CONN_01X03"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>5837847B</tstamp> + </comp> + <comp ref="P11"> + <value>SWITCH</value> + <footprint>Pin_Headers:Pin_Header_Straight_1x03</footprint> + <libsource lib="conn" part="CONN_01X03"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>58378536</tstamp> + </comp> + <comp ref="P1"> + <value>SCOPE_OUT</value> + <footprint>Pin_Headers:Pin_Header_Straight_1x04</footprint> + <libsource lib="conn" part="CONN_01X04"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>5832064B</tstamp> + </comp> + <comp ref="P5"> + <value>SCOPE_OUT</value> + <footprint>Pin_Headers:Pin_Header_Straight_1x04</footprint> + <libsource lib="conn" part="CONN_01X04"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>58320706</tstamp> + </comp> + <comp ref="C12"> + <value>C</value> + <footprint>Capacitors_SMD:C_0603</footprint> + <libsource lib="device" part="C"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>588029E7</tstamp> + </comp> + <comp ref="F2"> + <value>F_Small</value> + <footprint>Capacitors_SMD:C_1210</footprint> + <libsource lib="device" part="F_Small"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>58F5AF9C</tstamp> + </comp> + <comp ref="P9"> + <value>FUSE_BYPASS</value> + <footprint>Pin_Headers:Pin_Header_Straight_1x02</footprint> + <libsource lib="conn" part="CONN_01X02"/> + <sheetpath names="/" tstamps="/"/> + <tstamp>58FEDB8C</tstamp> + </comp> + </components> + <libparts> + <libpart lib="Tinylab_proto1-rescue" part="78L05-RESCUE-Tinylab_proto1"> + <fields> + <field name="Reference">U</field> + <field name="Value">78L05-RESCUE-Tinylab_proto1</field> + </fields> + <pins> + <pin num="1" name="GND" type="input"/> + <pin num="2" name="VO" type="power_out"/> + <pin num="3" name="VI" type="input"/> + </pins> + </libpart> + <libpart lib="atmel" part="ATXMEGA16A4U-A"> + <aliases> + <alias>ATXMEGA32A4U-A</alias> + <alias>ATXMEGA64A4U-A</alias> + <alias>ATXMEGA128A4U-A</alias> + </aliases> + <description>TQFP44, 16k Flash, 4k Boot, 2k SRAM, 1k EEPROM, JTAG, USB</description> + <docs>http://www.atmel.com/Images/Atmel-8387-8-and16-bit-AVR-Microcontroller-XMEGA-A4U_Datasheet.pdf</docs> + <fields> + <field name="Reference">IC</field> + <field name="Value">ATXMEGA16A4U-A</field> + <field name="Footprint">TQFP44</field> + </fields> + <pins> + <pin num="1" name="AC5/ADC5/PA5" type="BiDi"/> + <pin num="2" name="AC1OUT/AC6/ADC6/PA6" type="BiDi"/> + <pin num="3" name="AC0OUT/AC7/ADC7/PA7" type="BiDi"/> + <pin num="4" name="AREFB/ADC8/PB0" type="BiDi"/> + <pin num="5" name="ADC9/PB1" type="BiDi"/> + <pin num="6" name="DAC0/ADC10/PB2" type="BiDi"/> + <pin num="7" name="DAC1/ACD11/PB3" type="BiDi"/> + <pin num="8" name="GND" type="power_in"/> + <pin num="9" name="VCC" type="power_in"/> + <pin num="10" name="SDAIN/SDA/~OC0ALS~/OC0A/PC0" type="BiDi"/> + <pin num="11" name="SCLIN/SCL/XCK0/OC0AHS/OC0B/PC1" type="BiDi"/> + <pin num="12" name="SDAOUT/RXD0/~OC0BLS~/OC0C/PC2" type="BiDi"/> + <pin num="13" name="SCLOUT/TXD0/OC0BHS/OC0D/PC3" type="BiDi"/> + <pin num="14" name="~SS~/~OC0CLS~/OC1A/PC4" type="BiDi"/> + <pin num="15" name="MOSI/XCK1/OC0CHS/OC1B/PC5" type="BiDi"/> + <pin num="16" name="CLKRTC/MISO/RXD1/~OC0DLS~/PC6" type="BiDi"/> + <pin num="17" name="EVOUT/CLKOUT/SCK/TXD1/OC0DHS/PC7" type="BiDi"/> + <pin num="18" name="GND" type="power_in"/> + <pin num="19" name="VCC" type="power_in"/> + <pin num="20" name="PD0/OC0A" type="BiDi"/> + <pin num="21" name="PD1/OC0B/XCK0" type="BiDi"/> + <pin num="22" name="PD2/OC0C/RXD0" type="BiDi"/> + <pin num="23" name="PD3/OC0D/TXD0" type="BiDi"/> + <pin num="24" name="PD4/OC1A/~SS~" type="BiDi"/> + <pin num="25" name="PD5/OC1B/XCK1/MOSI" type="BiDi"/> + <pin num="26" name="PD6/D-/RXD1/MISO" type="BiDi"/> + <pin num="27" name="PD7/D+/TXD1/SCK/CLKOUT/EVOUT" type="BiDi"/> + <pin num="28" name="PE0/OC0A/SDA" type="BiDi"/> + <pin num="29" name="PE1/OC0B/XCK0/SCL" type="BiDi"/> + <pin num="30" name="GND" type="power_in"/> + <pin num="31" name="VCC" type="power_in"/> + <pin num="32" name="PE2/OC0C/RXD0" type="BiDi"/> + <pin num="33" name="PE3/OC0D/TXD0" type="BiDi"/> + <pin num="34" name="PDI_DATA" type="input"/> + <pin num="35" name="~RESET~/PDI_CLK" type="input"/> + <pin num="36" name="PR0/XTAL2/TOSC2" type="BiDi"/> + <pin num="37" name="PR1/XTAL1/TOSC1" type="BiDi"/> + <pin num="38" name="GND" type="power_in"/> + <pin num="39" name="AVCC" type="power_in"/> + <pin num="40" name="AREFA/AC0/ADC0/PA0" type="BiDi"/> + <pin num="41" name="AC1/ADC1/PA1" type="BiDi"/> + <pin num="42" name="AC2/ADC2/PA2" type="BiDi"/> + <pin num="43" name="AC3/ADC3/PA3" type="BiDi"/> + <pin num="44" name="AC4/ADC4/PA4" type="BiDi"/> + </pins> + </libpart> + <libpart lib="device" part="C"> + <description>Unpolarized capacitor</description> + <footprints> + <fp>C?</fp> + <fp>C_????_*</fp> + <fp>C_????</fp> + <fp>SMD*_c</fp> + <fp>Capacitor*</fp> + </footprints> + <fields> + <field name="Reference">C</field> + <field name="Value">C</field> + </fields> + <pins> + <pin num="1" name="~" type="passive"/> + <pin num="2" name="~" type="passive"/> + </pins> + </libpart> + <libpart lib="conn" part="CONN_01X02"> + <description>Connector, single row, 01x02</description> + <footprints> + <fp>Pin_Header_Straight_1X02</fp> + <fp>Pin_Header_Angled_1X02</fp> + <fp>Socket_Strip_Straight_1X02</fp> + <fp>Socket_Strip_Angled_1X02</fp> + </footprints> + <fields> + <field name="Reference">P</field> + <field name="Value">CONN_01X02</field> + </fields> + <pins> + <pin num="1" name="P1" type="passive"/> + <pin num="2" name="P2" type="passive"/> + </pins> + </libpart> + <libpart lib="conn" part="CONN_01X03"> + <description>Connector, single row, 01x03</description> + <footprints> + <fp>Pin_Header_Straight_1X03</fp> + <fp>Pin_Header_Angled_1X03</fp> + <fp>Socket_Strip_Straight_1X03</fp> + <fp>Socket_Strip_Angled_1X03</fp> + </footprints> + <fields> + <field name="Reference">P</field> + <field name="Value">CONN_01X03</field> + </fields> + <pins> + <pin num="1" name="P1" type="passive"/> + <pin num="2" name="P2" type="passive"/> + <pin num="3" name="P3" type="passive"/> + </pins> + </libpart> + <libpart lib="conn" part="CONN_01X04"> + <description>Connector, single row, 01x04</description> + <footprints> + <fp>Pin_Header_Straight_1X04</fp> + <fp>Pin_Header_Angled_1X04</fp> + <fp>Socket_Strip_Straight_1X04</fp> + <fp>Socket_Strip_Angled_1X04</fp> + </footprints> + <fields> + <field name="Reference">P</field> + <field name="Value">CONN_01X04</field> + </fields> + <pins> + <pin num="1" name="P1" type="passive"/> + <pin num="2" name="P2" type="passive"/> + <pin num="3" name="P3" type="passive"/> + <pin num="4" name="P4" type="passive"/> + </pins> + </libpart> + <libpart lib="conn" part="CONN_02X02"> + <description>Connector, double row, 02x02</description> + <footprints> + <fp>Pin_Header_Straight_2X02</fp> + <fp>Pin_Header_Angled_2X02</fp> + <fp>Socket_Strip_Straight_2X02</fp> + <fp>Socket_Strip_Angled_2X02</fp> + </footprints> + <fields> + <field name="Reference">P</field> + <field name="Value">CONN_02X02</field> + </fields> + <pins> + <pin num="1" name="P1" type="passive"/> + <pin num="2" name="P2" type="passive"/> + <pin num="3" name="P3" type="passive"/> + <pin num="4" name="P4" type="passive"/> + </pins> + </libpart> + <libpart lib="device" part="CP1"> + <description>Polarised capacitor</description> + <footprints> + <fp>SMD*_Pol</fp> + <fp>C_Axial*</fp> + <fp>C_Radial*</fp> + <fp>c_elec*</fp> + <fp>C*elec</fp> + <fp>TantalC*</fp> + <fp>CP*</fp> + </footprints> + <fields> + <field name="Reference">C</field> + <field name="Value">CP1</field> + </fields> + <pins> + <pin num="1" name="~" type="passive"/> + <pin num="2" name="~" type="passive"/> + </pins> + </libpart> + <libpart lib="device" part="C_Small"> + <description>Unpolarized capacitor</description> + <footprints> + <fp>C?</fp> + <fp>C_????_*</fp> + <fp>C_????</fp> + <fp>SMD*_c</fp> + <fp>Capacitor*</fp> + </footprints> + <fields> + <field name="Reference">C</field> + <field name="Value">C_Small</field> + </fields> + <pins> + <pin num="1" name="~" type="passive"/> + <pin num="2" name="~" type="passive"/> + </pins> + </libpart> + <libpart lib="ESPO_PART" part="DMN63D8LDW"> + <fields> + <field name="Reference">U</field> + <field name="Value">DMN63D8LDW</field> + </fields> + <pins> + <pin num="1" name="S1" type="input"/> + <pin num="2" name="G1" type="input"/> + <pin num="3" name="D2" type="input"/> + <pin num="4" name="S2" type="input"/> + <pin num="5" name="G2" type="input"/> + <pin num="6" name="D1" type="input"/> + </pins> + </libpart> + <libpart lib="device" part="D_Schottky"> + <description>Diode schottky</description> + <footprints> + <fp>D-Pak_TO252AA</fp> + <fp>Diode_*</fp> + <fp>*SingleDiode</fp> + <fp>*SingleDiode*</fp> + <fp>*_Diode_*</fp> + </footprints> + <fields> + <field name="Reference">D</field> + <field name="Value">D_Schottky</field> + </fields> + <pins> + <pin num="1" name="K" type="passive"/> + <pin num="2" name="A" type="passive"/> + </pins> + </libpart> + <libpart lib="device" part="F_Small"> + <description>Fuse</description> + <footprints> + <fp>CP*</fp> + <fp>SM*</fp> + </footprints> + <fields> + <field name="Reference">F</field> + <field name="Value">F_Small</field> + </fields> + <pins> + <pin num="1" name="~" type="passive"/> + <pin num="2" name="~" type="passive"/> + </pins> + </libpart> + <libpart lib="device" part="INDUCTOR"> + <footprints> + <fp>Choke_*</fp> + <fp>*Coil*</fp> + </footprints> + <fields> + <field name="Reference">L</field> + <field name="Value">INDUCTOR</field> + </fields> + <pins> + <pin num="1" name="1" type="passive"/> + <pin num="2" name="2" type="passive"/> + </pins> + </libpart> + <libpart lib="device" part="LED"> + <footprints> + <fp>LED-*</fp> + <fp>LED_*</fp> + </footprints> + <fields> + <field name="Reference">D</field> + <field name="Value">LED</field> + </fields> + <pins> + <pin num="1" name="K" type="passive"/> + <pin num="2" name="A" type="passive"/> + </pins> + </libpart> + <libpart lib="Tinylab_proto1-rescue" part="LM324-RESCUE-Tinylab_proto1"> + <fields> + <field name="Reference">U</field> + <field name="Value">LM324-RESCUE-Tinylab_proto1</field> + </fields> + <pins> + <pin num="1" name="~" type="output"/> + <pin num="2" name="-" type="input"/> + <pin num="3" name="+" type="input"/> + <pin num="4" name="V+" type="power_in"/> + <pin num="5" name="+" type="input"/> + <pin num="6" name="-" type="input"/> + <pin num="7" name="~" type="output"/> + <pin num="8" name="~" type="output"/> + <pin num="9" name="-" type="input"/> + <pin num="10" name="+" type="input"/> + <pin num="11" name="V-" type="power_in"/> + <pin num="12" name="+" type="input"/> + <pin num="13" name="-" type="input"/> + <pin num="14" name="~" type="output"/> + </pins> + </libpart> + <libpart lib="device" part="Q_NMOS_GSD"> + <description>Transistor N-MOSFET (general)</description> + <fields> + <field name="Reference">Q</field> + <field name="Value">Q_NMOS_GSD</field> + </fields> + <pins> + <pin num="1" name="G" type="input"/> + <pin num="2" name="S" type="passive"/> + <pin num="3" name="D" type="passive"/> + </pins> + </libpart> + <libpart lib="device" part="R"> + <description>Resistor</description> + <footprints> + <fp>R_*</fp> + <fp>Resistor_*</fp> + </footprints> + <fields> + <field name="Reference">R</field> + <field name="Value">R</field> + </fields> + <pins> + <pin num="1" name="~" type="passive"/> + <pin num="2" name="~" type="passive"/> + </pins> + </libpart> + <libpart lib="device" part="R_Small"> + <description>Resistor</description> + <footprints> + <fp>Resistor_*</fp> + <fp>R_*</fp> + </footprints> + <fields> + <field name="Reference">R</field> + <field name="Value">R_Small</field> + </fields> + <pins> + <pin num="1" name="~" type="passive"/> + <pin num="2" name="~" type="passive"/> + </pins> + </libpart> + <libpart lib="conn" part="USB_OTG"> + <description>USB micro/mini connector</description> + <footprints> + <fp>USB*</fp> + </footprints> + <fields> + <field name="Reference">P</field> + <field name="Value">USB_OTG</field> + </fields> + <pins> + <pin num="1" name="VCC" type="power_out"/> + <pin num="2" name="D-" type="passive"/> + <pin num="3" name="D+" type="passive"/> + <pin num="4" name="ID" type="power_in"/> + <pin num="5" name="GND" type="power_in"/> + <pin num="6" name="shield" type="passive"/> + </pins> + </libpart> + </libparts> + <libraries> + <library logical="Tinylab_proto1-rescue"> + <uri>C:\Users\Esposch\Documents\GitHub\Labrador\PCB\Tinylab_proto1-rescue.lib</uri> + </library> + <library logical="device"> + <uri>C:\Program Files\KiCad\share\kicad\library\device.lib</uri> + </library> + <library logical="conn"> + <uri>C:\Program Files\KiCad\share\kicad\library\conn.lib</uri> + </library> + <library logical="atmel"> + <uri>C:\Program Files\KiCad\share\kicad\library\atmel.lib</uri> + </library> + <library logical="ESPO_PART"> + <uri>C:\Users\Esposch\Documents\KiCAD\ESPO_PART.lib</uri> + </library> + </libraries> + <nets> + <net code="1" name="/VCC_3V3"> + <node ref="C6" pin="1"/> + <node ref="L2" pin="1"/> + <node ref="C11" pin="1"/> + <node ref="IC1" pin="31"/> + <node ref="F1" pin="2"/> + <node ref="C4" pin="1"/> + <node ref="U1" pin="2"/> + <node ref="IC1" pin="19"/> + </net> + <net code="2" name="/TO_B1"> + <node ref="IC1" pin="5"/> + <node ref="U3" pin="5"/> + </net> + <net code="3" name="/V_minus_dac_out2"> + <node ref="U2" pin="13"/> + <node ref="R20" pin="2"/> + <node ref="R15" pin="1"/> + <node ref="R16" pin="1"/> + </net> + <net code="4" name="/S-Gen_Drain_Top_CH1"> + <node ref="U3" pin="3"/> + <node ref="R18" pin="2"/> + <node ref="R17" pin="2"/> + </net> + <net code="5" name="/Scope_Buffer_Input_CH2"> + <node ref="R2" pin="1"/> + <node ref="U2" pin="5"/> + <node ref="R4" pin="2"/> + </net> + <net code="6" name="/D1_OUT"> + <node ref="R8" pin="2"/> + <node ref="P3" pin="3"/> + </net> + <net code="7" name="/PDI_CLK"> + <node ref="IC1" pin="34"/> + <node ref="P4" pin="2"/> + </net> + <net code="8" name="/PDI_DATA"> + <node ref="IC1" pin="35"/> + <node ref="P4" pin="4"/> + </net> + <net code="9" name="/3V3_OUT"> + <node ref="P4" pin="1"/> + <node ref="F1" pin="1"/> + </net> + <net code="10" name="/Switch_OC"> + <node ref="P11" pin="1"/> + </net> + <net code="11" name="/Scoe_CH1_AC"> + <node ref="P1" pin="2"/> + <node ref="C1" pin="2"/> + </net> + <net code="12" name="/Scope_CH2_AC"> + <node ref="P5" pin="2"/> + <node ref="C2" pin="2"/> + </net> + <net code="13" name="/S-Gen_CH1_DC"> + <node ref="R24" pin="1"/> + <node ref="C13" pin="2"/> + <node ref="P6" pin="1"/> + </net> + <net code="14" name="/S-Gen_CH1_AC"> + <node ref="C13" pin="1"/> + <node ref="P6" pin="2"/> + </net> + <net code="15" name="/S-Gen_CH2_DC"> + <node ref="P6" pin="3"/> + <node ref="C14" pin="2"/> + <node ref="R25" pin="1"/> + </net> + <net code="16" name="/S-Gen_CH2_AC"> + <node ref="P6" pin="4"/> + <node ref="C14" pin="1"/> + </net> + <net code="17" name="Net-(C16-Pad2)"> + <node ref="C16" pin="2"/> + </net> + <net code="18" name="/PSU_FDBK"> + <node ref="IC1" pin="1"/> + <node ref="R27" pin="1"/> + <node ref="P10" pin="2"/> + <node ref="R26" pin="2"/> + </net> + <net code="19" name="/QTop"> + <node ref="D1" pin="2"/> + <node ref="Q1" pin="3"/> + <node ref="L1" pin="1"/> + </net> + <net code="20" name="Net-(L3-Pad1)"> + <node ref="L3" pin="1"/> + <node ref="L4" pin="2"/> + </net> + <net code="21" name="/D0_MID"> + <node ref="R11" pin="2"/> + <node ref="R7" pin="1"/> + </net> + <net code="22" name="/D1_MID"> + <node ref="R12" pin="2"/> + <node ref="R8" pin="1"/> + </net> + <net code="23" name="/D2_MID"> + <node ref="R13" pin="2"/> + <node ref="R9" pin="1"/> + </net> + <net code="24" name="/D3_MID"> + <node ref="R10" pin="1"/> + <node ref="R14" pin="2"/> + </net> + <net code="25" name="/L-Ana_IN_CH1"> + <node ref="U4" pin="5"/> + <node ref="P8" pin="1"/> + </net> + <net code="26" name="/R22-R24"> + <node ref="R24" pin="2"/> + <node ref="R22" pin="1"/> + </net> + <net code="27" name="/PSU_OUT"> + <node ref="P11" pin="3"/> + <node ref="P7" pin="1"/> + <node ref="R32" pin="1"/> + </net> + <net code="28" name="/DAC_OUT"> + <node ref="U2" pin="10"/> + <node ref="IC1" pin="6"/> + </net> + <net code="29" name="/Scope_Buffer_Input_CH1"> + <node ref="R1" pin="1"/> + <node ref="R3" pin="1"/> + <node ref="U2" pin="3"/> + </net> + <net code="30" name="/CH1"> + <node ref="IC1" pin="42"/> + <node ref="R21" pin="1"/> + <node ref="U2" pin="1"/> + <node ref="U2" pin="2"/> + </net> + <net code="31" name="/CH2"> + <node ref="R28" pin="2"/> + <node ref="IC1" pin="2"/> + <node ref="IC1" pin="40"/> + <node ref="U2" pin="6"/> + <node ref="U2" pin="7"/> + </net> + <net code="32" name="Net-(F2-Pad2)"> + <node ref="L1" pin="2"/> + <node ref="P9" pin="2"/> + <node ref="F2" pin="2"/> + </net> + <net code="33" name="/Scope_CH2_DC"> + <node ref="P5" pin="3"/> + <node ref="P5" pin="4"/> + <node ref="R2" pin="2"/> + <node ref="P5" pin="1"/> + <node ref="C2" pin="1"/> + </net> + <net code="34" name="/L-Ana_IN_CH2"> + <node ref="P8" pin="2"/> + <node ref="U4" pin="2"/> + </net> + <net code="35" name="/DIG_CH1"> + <node ref="IC1" pin="15"/> + <node ref="U4" pin="6"/> + </net> + <net code="36" name="/AVCC"> + <node ref="C18" pin="1"/> + <node ref="C5" pin="1"/> + <node ref="IC1" pin="39"/> + <node ref="C17" pin="1"/> + <node ref="C8" pin="1"/> + <node ref="R5" pin="1"/> + <node ref="L2" pin="2"/> + </net> + <net code="37" name="/D2-prefuse"> + <node ref="R13" pin="1"/> + <node ref="IC1" pin="32"/> + </net> + <net code="38" name="/D1-prefuse"> + <node ref="IC1" pin="29"/> + <node ref="R12" pin="1"/> + </net> + <net code="39" name="/D0-prefuse"> + <node ref="R11" pin="1"/> + <node ref="IC1" pin="28"/> + </net> + <net code="40" name="+5V"> + <node ref="C10" pin="1"/> + <node ref="F2" pin="1"/> + <node ref="C3" pin="1"/> + <node ref="P9" pin="1"/> + <node ref="P2" pin="1"/> + <node ref="U1" pin="3"/> + <node ref="C9" pin="1"/> + </net> + <net code="41" name="/D-"> + <node ref="P2" pin="2"/> + <node ref="IC1" pin="26"/> + </net> + <net code="42" name="/D+"> + <node ref="IC1" pin="27"/> + <node ref="P2" pin="3"/> + </net> + <net code="43" name="/D3-OUT"> + <node ref="R10" pin="2"/> + <node ref="P3" pin="1"/> + </net> + <net code="44" name="/D2-OUT"> + <node ref="P3" pin="2"/> + <node ref="R9" pin="2"/> + </net> + <net code="45" name="/D0_OUT"> + <node ref="R7" pin="2"/> + <node ref="P3" pin="4"/> + </net> + <net code="46" name="/D3-prefuse"> + <node ref="R14" pin="1"/> + <node ref="IC1" pin="33"/> + </net> + <net code="47" name="/VGND"> + <node ref="IC1" pin="38"/> + <node ref="C12" pin="2"/> + <node ref="P2" pin="5"/> + <node ref="P2" pin="6"/> + <node ref="U1" pin="1"/> + <node ref="U2" pin="11"/> + <node ref="P4" pin="3"/> + <node ref="IC1" pin="18"/> + <node ref="C15" pin="2"/> + <node ref="C10" pin="2"/> + <node ref="C9" pin="2"/> + <node ref="R30" pin="1"/> + <node ref="C7" pin="2"/> + <node ref="R21" pin="2"/> + <node ref="P10" pin="3"/> + <node ref="C18" pin="2"/> + <node ref="R29" pin="2"/> + <node ref="Q1" pin="2"/> + <node ref="P7" pin="2"/> + <node ref="R31" pin="2"/> + <node ref="C17" pin="2"/> + <node ref="D2" pin="1"/> + <node ref="IC1" pin="14"/> + <node ref="U3" pin="4"/> + <node ref="R28" pin="1"/> + <node ref="U4" pin="4"/> + <node ref="U3" pin="1"/> + <node ref="C8" pin="2"/> + <node ref="C11" pin="2"/> + <node ref="U4" pin="1"/> + <node ref="C5" pin="2"/> + <node ref="C4" pin="2"/> + <node ref="C3" pin="2"/> + <node ref="R27" pin="2"/> + <node ref="IC1" pin="30"/> + <node ref="IC1" pin="8"/> + <node ref="C6" pin="2"/> + <node ref="R6" pin="1"/> + </net> + <net code="48" name="/Disconnected_USB"> + <node ref="P2" pin="4"/> + </net> + <net code="49" name="/DIG_CH2"> + <node ref="IC1" pin="12"/> + <node ref="U4" pin="3"/> + </net> + <net code="50" name="Net-(IC1-Pad10)"> + <node ref="IC1" pin="10"/> + </net> + <net code="51" name="Net-(IC1-Pad3)"> + <node ref="IC1" pin="3"/> + </net> + <net code="52" name="/DAC_OUT2"> + <node ref="IC1" pin="7"/> + <node ref="U2" pin="12"/> + </net> + <net code="53" name="Net-(IC1-Pad9)"> + <node ref="IC1" pin="9"/> + </net> + <net code="54" name="Net-(IC1-Pad20)"> + <node ref="IC1" pin="20"/> + </net> + <net code="55" name="/XCK"> + <node ref="IC1" pin="11"/> + <node ref="IC1" pin="17"/> + </net> + <net code="56" name="Net-(IC1-Pad21)"> + <node ref="IC1" pin="21"/> + </net> + <net code="57" name="Net-(IC1-Pad41)"> + <node ref="IC1" pin="41"/> + </net> + <net code="58" name="/OPAMP_VCC"> + <node ref="U2" pin="4"/> + <node ref="L4" pin="1"/> + <node ref="C16" pin="1"/> + </net> + <net code="59" name="Net-(IC1-Pad22)"> + <node ref="IC1" pin="22"/> + </net> + <net code="60" name="Net-(IC1-Pad37)"> + <node ref="IC1" pin="37"/> + </net> + <net code="61" name="/Scope_CH1_DC"> + <node ref="R1" pin="2"/> + <node ref="P1" pin="1"/> + <node ref="C1" pin="1"/> + <node ref="P1" pin="3"/> + <node ref="P1" pin="4"/> + </net> + <net code="62" name="Net-(IC1-Pad13)"> + <node ref="IC1" pin="13"/> + </net> + <net code="63" name="Net-(IC1-Pad23)"> + <node ref="IC1" pin="23"/> + </net> + <net code="64" name="Net-(IC1-Pad43)"> + <node ref="IC1" pin="43"/> + </net> + <net code="65" name="/AVCC_ON_2"> + <node ref="R3" pin="2"/> + <node ref="IC1" pin="44"/> + <node ref="R5" pin="2"/> + <node ref="R6" pin="2"/> + <node ref="R4" pin="1"/> + </net> + <net code="66" name="Net-(IC1-Pad25)"> + <node ref="IC1" pin="25"/> + </net> + <net code="67" name="Net-(IC1-Pad16)"> + <node ref="IC1" pin="16"/> + </net> + <net code="68" name="Net-(IC1-Pad36)"> + <node ref="IC1" pin="36"/> + </net> + <net code="69" name="/PSU_Unfiltered_Raw"> + <node ref="R26" pin="1"/> + <node ref="P10" pin="1"/> + <node ref="D1" pin="1"/> + <node ref="P11" pin="2"/> + <node ref="C15" pin="1"/> + <node ref="C7" pin="1"/> + <node ref="L3" pin="2"/> + </net> + <net code="70" name="/Buffered_DAC_CH1"> + <node ref="R19" pin="1"/> + <node ref="R22" pin="2"/> + <node ref="R29" pin="1"/> + <node ref="U2" pin="8"/> + </net> + <net code="71" name="/Buffered_DAC_CH2"> + <node ref="R20" pin="1"/> + <node ref="R30" pin="2"/> + <node ref="R23" pin="2"/> + <node ref="U2" pin="14"/> + </net> + <net code="72" name="/TO_B0"> + <node ref="U3" pin="2"/> + <node ref="IC1" pin="4"/> + </net> + <net code="73" name="/S-Gen_Drain_Top_CH2"> + <node ref="R16" pin="2"/> + <node ref="R15" pin="2"/> + <node ref="U3" pin="6"/> + </net> + <net code="74" name="/PSU_PWM"> + <node ref="R31" pin="1"/> + <node ref="Q1" pin="1"/> + <node ref="C12" pin="1"/> + <node ref="IC1" pin="24"/> + </net> + <net code="75" name="Net-(D2-Pad2)"> + <node ref="D2" pin="2"/> + <node ref="R32" pin="2"/> + </net> + <net code="76" name="/V_minus_dac_out"> + <node ref="U2" pin="9"/> + <node ref="R19" pin="2"/> + <node ref="R17" pin="1"/> + <node ref="R18" pin="1"/> + </net> + <net code="77" name="/R23-R25"> + <node ref="R25" pin="2"/> + <node ref="R23" pin="1"/> + </net> + </nets> +</export> diff --git a/PCB/Tinylab_proto1.xml.REMOVED.git-id b/PCB/Tinylab_proto1.xml.REMOVED.git-id deleted file mode 100644 index 247aa448..00000000 --- a/PCB/Tinylab_proto1.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4d7e19faca785f7b7840739888809040ee9cf2b5 \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1-B_Cu.gbr.REMOVED.git-id b/PCB/WOT/Tinylab_proto1-B_Cu.gbr.REMOVED.git-id deleted file mode 100644 index 49ff8422..00000000 --- a/PCB/WOT/Tinylab_proto1-B_Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -95c142f0a1f0ff5f4dcca3327a66b19bc68b77b3 \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1-B_Mask.gbr.REMOVED.git-id b/PCB/WOT/Tinylab_proto1-B_Mask.gbr.REMOVED.git-id deleted file mode 100644 index 0872d6f6..00000000 --- a/PCB/WOT/Tinylab_proto1-B_Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d4760890f803f3e98b89bd567f58b427a615a3d1 \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1-B_Paste.gbr.REMOVED.git-id b/PCB/WOT/Tinylab_proto1-B_Paste.gbr.REMOVED.git-id deleted file mode 100644 index 8d1be32c..00000000 --- a/PCB/WOT/Tinylab_proto1-B_Paste.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -850ea99ee3757e0e37275ad3552084ddcd1c2c27 \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1-B_SilkS.gbr.REMOVED.git-id b/PCB/WOT/Tinylab_proto1-B_SilkS.gbr.REMOVED.git-id deleted file mode 100644 index c6b38fe7..00000000 --- a/PCB/WOT/Tinylab_proto1-B_SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5cb45898974e8f4930587871d95e4d41a8fe8bc9 \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1-Edge_Cuts.gbr.REMOVED.git-id b/PCB/WOT/Tinylab_proto1-Edge_Cuts.gbr.REMOVED.git-id deleted file mode 100644 index be80fd70..00000000 --- a/PCB/WOT/Tinylab_proto1-Edge_Cuts.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -7b87d719f8f9ff7e3b995348eab254eca0768cf4 \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1-F_Cu.gbr.REMOVED.git-id b/PCB/WOT/Tinylab_proto1-F_Cu.gbr.REMOVED.git-id deleted file mode 100644 index 415110dc..00000000 --- a/PCB/WOT/Tinylab_proto1-F_Cu.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -bd5bebef691494c1d95977e50cb7066c1f9c6579 \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1-F_Mask.gbr.REMOVED.git-id b/PCB/WOT/Tinylab_proto1-F_Mask.gbr.REMOVED.git-id deleted file mode 100644 index 39ee940a..00000000 --- a/PCB/WOT/Tinylab_proto1-F_Mask.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0aa4682c216012d199f4bfc78e507a98bc81dd4d \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1-F_Paste.gbr.REMOVED.git-id b/PCB/WOT/Tinylab_proto1-F_Paste.gbr.REMOVED.git-id deleted file mode 100644 index 73d3f6ba..00000000 --- a/PCB/WOT/Tinylab_proto1-F_Paste.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1b6fefc9cef7aa808100b64c22aaf26ccc11e98a \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1-F_SilkS.gbr.REMOVED.git-id b/PCB/WOT/Tinylab_proto1-F_SilkS.gbr.REMOVED.git-id deleted file mode 100644 index 20ba1eb3..00000000 --- a/PCB/WOT/Tinylab_proto1-F_SilkS.gbr.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -0e44114702ef3bcbd32e5b9d7ea394f86007061e \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1-cache.lib.REMOVED.git-id b/PCB/WOT/Tinylab_proto1-cache.lib.REMOVED.git-id deleted file mode 100644 index 03395dc6..00000000 --- a/PCB/WOT/Tinylab_proto1-cache.lib.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -2cb7db295d2e1c5feaabcb3292c1129faffa6419 \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1.drl.REMOVED.git-id b/PCB/WOT/Tinylab_proto1.drl.REMOVED.git-id deleted file mode 100644 index b5faf2d2..00000000 --- a/PCB/WOT/Tinylab_proto1.drl.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b339f5055689f653eb175af0c7844fe786a85513 \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1.kicad_pcb-bak.REMOVED.git-id b/PCB/WOT/Tinylab_proto1.kicad_pcb-bak.REMOVED.git-id deleted file mode 100644 index 4321d50b..00000000 --- a/PCB/WOT/Tinylab_proto1.kicad_pcb-bak.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b595887b77427943b9e85f866e77fc15d39c5265 \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1.kicad_pcb.REMOVED.git-id b/PCB/WOT/Tinylab_proto1.kicad_pcb.REMOVED.git-id deleted file mode 100644 index 5ab9fb99..00000000 --- a/PCB/WOT/Tinylab_proto1.kicad_pcb.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -f9131c405fe06cfce957de76b1e167cfc7db4050 \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1.kicad_pcb.bak.REMOVED.git-id b/PCB/WOT/Tinylab_proto1.kicad_pcb.bak.REMOVED.git-id deleted file mode 100644 index af3b0ddc..00000000 --- a/PCB/WOT/Tinylab_proto1.kicad_pcb.bak.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -6c7db377f161ff701b70db87bd2441935661b066 \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1.kicad_pcb_bak.REMOVED.git-id b/PCB/WOT/Tinylab_proto1.kicad_pcb_bak.REMOVED.git-id deleted file mode 100644 index 9f6d7f71..00000000 --- a/PCB/WOT/Tinylab_proto1.kicad_pcb_bak.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ba9a943c74b3aab6d6232690332e6bdbdb957855 \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1.xml.REMOVED.git-id b/PCB/WOT/Tinylab_proto1.xml.REMOVED.git-id deleted file mode 100644 index 5c93e96b..00000000 --- a/PCB/WOT/Tinylab_proto1.xml.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e7f4ba84a12e13ff79bbcd22b60807353c345749 \ No newline at end of file diff --git a/PCB/WOT/Tinylab_proto1.zip.REMOVED.git-id b/PCB/WOT/Tinylab_proto1.zip.REMOVED.git-id deleted file mode 100644 index 3f6e3481..00000000 --- a/PCB/WOT/Tinylab_proto1.zip.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -78824db3d2e0c0b39b64c5b3f9211982b668f959 \ No newline at end of file diff --git a/PCB/____BOM.csv b/PCB/____BOM.csv new file mode 100644 index 00000000..324b9652 --- /dev/null +++ b/PCB/____BOM.csv @@ -0,0 +1,27 @@ +Id,Designator,Package,Quantity,Designation,Description,Notes +1,"C6,C9,C15",c_elec_4x5.3,3,CP1,"SMD Electrolytic Capacitor, 33uH 16V", +2,IC1,LQFP-44_10x10mm_Pitch0.8mm,1,ATXMEGA32A4U-A,ATXMEGA32A4U-AU, +3,P2,USB_Micro-B_WIDE,1,USB_OTG,Micro USB-B connector, +5,"C1,C2,C7,C8,C10,C11,C13,C14,C16,C17,C18",C_0603,11,C,1uF 0603 Ceramic Cap, +6,"C3,C4,C5",C_0603,3,C_Small,1uF 0603 Ceramic Cap, +7,D1,SMA_Standard,1,D_Schottky,"SMA Schottky Diode, 1.5V 1A", +8,D2,LED_0603,1,LED,0603 LED, +9,F1,C_1210,1,F_Small,PTC Fuse, +10,L1,SELF-WE-PD-XXL,1,INDUCTOR,SMD Inductor (self-wound package), +11,"L2,L3,L4",R_1206,3,INDUCTOR,SMD Inductor 1206, +4,"P1,P5",Pin_Header_Straight_1x04,2,SCOPE_OUT,Female 1x4 header, +12,P3,Pin_Header_Straight_1x04,1,DIG_OUT,Stackable 1x10 Header,"P3, P4 and P4 share a single header. Please do not use flimsy/weak pins!" +14,P6,Pin_Header_Straight_1x04,1,DAC_OUT,Stackable 1x10 Header,"P3, P4 and P4 share a single header. Please do not use flimsy/weak pins!" +13,P4,Pin_Header_Straight_2x02,1,PDI/3V3,Stackable 1x10 Header,"P3, P4 and P4 share a single header. Please do not use flimsy/weak pins!" +,P7,Pin_Header_Straight_1x02,1,PSU,Stackable 1x2 Header,"Stackable refers to the pins that are female on one side and male on the other, like on many Arduino shields." +16,P8,Pin_Header_Straight_1x02,1,DIG_IN,Female 1x2 Header, +17,P10,Pin_Header_Straight_1x03,1,EXPANSION,-,Unpopulated +18,P11,Pin_Header_Straight_1x03,1,SWITCH,Male 1x3 Header, +26,REF**,Pin_Header_Straight_1x02,1,Pin_Header_Straight_1x02,Male 1x2 Header,This will need to be soldered on upside down +19,Q1,SOT-23-3,1,Q_NMOS_GSD,, +20,"R1,R2,R3,R4,R5,R6,R15,R16,R17,R18,R19,R20,R21,R22,R23,R24,R25,R26,R27,R28,R29,R30,R31",R_0603,23,R,, +21,"R7,R8,R9,R10,R11,R12,R13,R14",R_0603,8,28R,, +22,R32,R_0603,1,R_Small,, +23,U1,SOT-23-3,1,78L05,, +24,U2,SOIC-14_3.9x8.7mm_Pitch1.27mm,1,LM324,, +25,"U3,U4",SOT-363,2,DMN63D8LDW,, diff --git a/PCB/____BOM.csv.REMOVED.git-id b/PCB/____BOM.csv.REMOVED.git-id deleted file mode 100644 index 2289e42f..00000000 --- a/PCB/____BOM.csv.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -324b9652afcc7d61548a05dff46d3e78990d96aa \ No newline at end of file diff --git a/PCB/fp-lib-table b/PCB/fp-lib-table new file mode 100644 index 00000000..da98408f --- /dev/null +++ b/PCB/fp-lib-table @@ -0,0 +1,14 @@ +(fp_lib_table + (lib (name Capacitors_SMD)(type KiCad)(uri C:\Users\Esposch\Documents\KICAD_LIB\Capacitors_SMD.pretty)(options "")(descr "")) + (lib (name Capacitors_ThroughHole)(type KiCad)(uri C:\Users\Esposch\Documents\KICAD_LIB\Capacitors_ThroughHole.pretty)(options "")(descr "")) + (lib (name Connect)(type KiCad)(uri C:\Users\Esposch\Documents\KICAD_LIB\Connect.pretty)(options "")(descr "")) + (lib (name Diodes_ThroughHole)(type KiCad)(uri C:\Users\Esposch\Documents\KICAD_LIB\Diodes_ThroughHole.pretty)(options "")(descr "")) + (lib (name Housings_QFP)(type KiCad)(uri C:\Users\Esposch\Documents\KICAD_LIB\Housings_QFP.pretty)(options "")(descr "")) + (lib (name Housings_SOIC)(type KiCad)(uri C:\Users\Esposch\Documents\KICAD_LIB\Housings_SOIC.pretty)(options "")(descr "")) + (lib (name Inductors)(type KiCad)(uri C:\Users\Esposch\Documents\KICAD_LIB\Inductors.pretty)(options "")(descr "")) + (lib (name Pin_Headers)(type KiCad)(uri C:\Users\Esposch\Documents\KICAD_LIB\Pin_Headers.pretty)(options "")(descr "")) + (lib (name Resistors_SMD)(type KiCad)(uri C:\Users\Esposch\Documents\KICAD_LIB\Resistors_SMD.pretty)(options "")(descr "")) + (lib (name TO_SOT_Packages_SMD)(type KiCad)(uri C:\Users\Esposch\Documents\KICAD_LIB\TO_SOT_Packages_SMD.pretty)(options "")(descr "")) + (lib (name SMD)(type KiCad)(uri C:\Users\Esposch\Documents\KiCAD\KiCad-Libraries-master\modules\SMD.pretty)(options "")(descr "")) + (lib (name labralogo)(type KiCad)(uri "$(KIPRJMOD)\\labralogo.pretty")(options "")(descr "")) +) diff --git a/PCB/fp-lib-table.REMOVED.git-id b/PCB/fp-lib-table.REMOVED.git-id deleted file mode 100644 index 32a7b306..00000000 --- a/PCB/fp-lib-table.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -da98408fbef966bbc19ba1e8d3a05f219fbf8124 \ No newline at end of file diff --git a/PCB/labralogo.pretty/Product_Logo_Transparent.png b/PCB/labralogo.pretty/Product_Logo_Transparent.png new file mode 100644 index 00000000..8e79ba18 Binary files /dev/null and b/PCB/labralogo.pretty/Product_Logo_Transparent.png differ diff --git a/PCB/labralogo.pretty/Product_Logo_Transparent.png.REMOVED.git-id b/PCB/labralogo.pretty/Product_Logo_Transparent.png.REMOVED.git-id deleted file mode 100644 index be59bd91..00000000 --- a/PCB/labralogo.pretty/Product_Logo_Transparent.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -8e79ba18da4e8de4b9edd2174a2f24a479337f12 \ No newline at end of file diff --git a/PCB/labralogo.pretty/Thumbs.db b/PCB/labralogo.pretty/Thumbs.db new file mode 100644 index 00000000..37fd76e6 Binary files /dev/null and b/PCB/labralogo.pretty/Thumbs.db differ diff --git a/PCB/labralogo.pretty/Thumbs.db.REMOVED.git-id b/PCB/labralogo.pretty/Thumbs.db.REMOVED.git-id deleted file mode 100644 index db4698d8..00000000 --- a/PCB/labralogo.pretty/Thumbs.db.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -37fd76e6e33596eacd0f1ab8dc70a224f6083cb8 \ No newline at end of file diff --git a/PCB/labralogo.pretty/logo100dpi.kicad_mod b/PCB/labralogo.pretty/logo100dpi.kicad_mod new file mode 100644 index 00000000..5f4f091c --- /dev/null +++ b/PCB/labralogo.pretty/logo100dpi.kicad_mod @@ -0,0 +1,34 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy 6.887956 -10.360785) (xy 7.663703 -10.180194) (xy 8.470333 -9.870620) (xy 9.211901 -9.480878) (xy 9.792461 -9.059782) (xy 10.071854 -8.740887) (xy 10.266997 -8.263336) (xy 10.449505 -7.522396) + (xy 10.601590 -6.591061) (xy 10.608192 -6.539905) (xy 10.707993 -5.164422) (xy 10.641267 -3.802170) (xy 10.396348 -2.381476) (xy 9.961573 -0.830668) (xy 9.442992 0.620109) (xy 9.026802 1.711505) + (xy 8.717463 2.565875) (xy 8.496627 3.258454) (xy 8.345946 3.864478) (xy 8.247071 4.459180) (xy 8.181653 5.117795) (xy 8.131346 5.915557) (xy 8.125572 6.021992) (xy 8.085255 6.855776) + (xy 8.076332 7.428410) (xy 8.107252 7.814383) (xy 8.186462 8.088185) (xy 8.322412 8.324307) (xy 8.398753 8.430552) (xy 8.662127 8.910549) (xy 8.628731 9.233990) (xy 8.299586 9.398241) + (xy 8.014692 9.419867) (xy 7.514362 9.330918) (xy 7.178352 9.020295) (xy 7.167465 9.003900) (xy 6.950835 8.539388) (xy 6.735952 7.860078) (xy 6.552298 7.086448) (xy 6.429355 6.338980) + (xy 6.394540 5.845364) (xy 6.353310 5.439796) (xy 6.254197 5.224903) (xy 6.223841 5.214569) (xy 6.118643 5.366273) (xy 6.066596 5.764620) (xy 6.065195 6.324468) (xy 6.111936 6.960673) + (xy 6.204313 7.588091) (xy 6.306271 8.016054) (xy 6.516870 8.567257) (xy 6.770256 9.018861) (xy 6.895013 9.166032) (xy 7.213914 9.594298) (xy 7.243428 9.975942) (xy 7.030522 10.257381) + (xy 6.622161 10.385032) (xy 6.065311 10.305310) (xy 5.937381 10.258611) (xy 5.452906 9.899693) (xy 4.993977 9.245294) (xy 4.580428 8.336310) (xy 4.232096 7.213635) (xy 4.043568 6.354197) + (xy 3.924662 5.756530) (xy 3.812417 5.410068) (xy 3.653528 5.234980) (xy 3.394694 5.151435) (xy 3.219825 5.120496) (xy 2.589906 4.992680) (xy 1.958783 4.809166) (xy 1.242129 4.539927) + (xy 0.355616 4.154935) (xy -0.168212 3.914061) (xy -1.766225 3.170227) (xy -2.186755 3.709925) (xy -2.498713 4.092105) (xy -2.950690 4.623927) (xy -3.457308 5.205274) (xy -3.582567 5.346697) + (xy -4.098008 5.956983) (xy -4.580810 6.580785) (xy -4.941196 7.101031) (xy -4.992177 7.184895) (xy -5.426504 7.926020) (xy -4.951580 8.421734) (xy -4.657087 8.780732) (xy -4.607563 9.014451) + (xy -4.672001 9.112796) (xy -4.955963 9.195495) (xy -5.398226 9.147125) (xy -5.865119 9.003752) (xy -6.222972 8.801442) (xy -6.330277 8.665378) (xy -6.352377 8.386264) (xy -6.321243 7.890736) + (xy -6.255737 7.371152) (xy -6.179402 6.814852) (xy -6.140747 6.409055) (xy -6.146459 6.249593) (xy -6.254317 6.328443) (xy -6.430359 6.634657) (xy -6.633845 7.077296) (xy -6.824037 7.565421) + (xy -6.960195 8.008093) (xy -6.984963 8.121342) (xy -7.012259 8.673669) (xy -6.830235 9.193347) (xy -6.744743 9.345968) (xy -6.510266 9.839294) (xy -6.525433 10.130915) (xy -6.797667 10.252601) + (xy -6.958571 10.260927) (xy -7.476975 10.145617) (xy -7.832304 9.779642) (xy -8.049487 9.132936) (xy -8.088898 8.897741) (xy -8.211369 7.776375) (xy -8.213660 6.857559) (xy -8.085472 6.025867) + (xy -7.816505 5.165878) (xy -7.737748 4.962251) (xy -7.437601 4.109692) (xy -7.281240 3.369506) (xy -7.233320 2.569300) (xy -7.233112 2.500803) (xy -7.241257 1.883482) (xy -7.277202 1.539811) + (xy -7.358216 1.407182) (xy -7.501564 1.422987) (xy -7.527483 1.433435) (xy -8.289016 1.627062) (xy -9.120250 1.639461) (xy -9.895170 1.481290) (xy -10.461213 1.185336) (xy -10.844208 0.875204) + (xy -10.089985 0.674505) (xy -8.878051 0.215210) (xy -7.647849 -0.500877) (xy -6.497881 -1.415039) (xy -6.348808 -1.555570) (xy -5.852489 -2.030251) (xy -5.436327 -2.396532) (xy -5.046894 -2.669589) + (xy -4.630757 -2.864598) (xy -4.134485 -2.996737) (xy -3.504648 -3.081182) (xy -2.687814 -3.133111) (xy -1.630552 -3.167699) (xy -0.584534 -3.192876) (xy 3.120336 -3.280133) (xy 4.215430 -3.819576) + (xy 4.827580 -4.153063) (xy 5.368000 -4.502886) (xy 5.710743 -4.785032) (xy 5.967049 -5.085730) (xy 6.003331 -5.283439) (xy 5.838746 -5.511754) (xy 5.818218 -5.534522) (xy 5.531006 -5.777332) + (xy 5.049162 -6.113466) (xy 4.472558 -6.473616) (xy 4.422762 -6.502890) (xy 3.488228 -7.159840) (xy 2.861413 -7.852426) (xy 2.554129 -8.565894) (xy 2.523179 -8.875453) (xy 2.572072 -9.275034) + (xy 2.624573 -9.335762) (xy 5.887418 -9.335762) (xy 5.972768 -9.126410) (xy 6.068245 -9.115685) (xy 6.242036 -9.289344) (xy 6.249073 -9.335762) (xy 6.118117 -9.532996) (xy 6.068245 -9.555839) + (xy 5.914863 -9.474640) (xy 5.887418 -9.335762) (xy 2.624573 -9.335762) (xy 2.757891 -9.489971) (xy 3.139346 -9.545588) (xy 3.775150 -9.467208) (xy 3.860026 -9.452059) (xy 4.377731 -9.373115) + (xy 4.724304 -9.400135) (xy 5.046937 -9.573197) (xy 5.429467 -9.879402) (xy 5.871285 -10.221071) (xy 6.214055 -10.376766) (xy 6.601129 -10.393802) (xy 6.887956 -10.360785) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/logo100dpi.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/logo100dpi.kicad_mod.REMOVED.git-id deleted file mode 100644 index d23410b9..00000000 --- a/PCB/labralogo.pretty/logo100dpi.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5f4f091cbecbfd9f204df8a1efaa3bd03e327e02 \ No newline at end of file diff --git a/PCB/labralogo.pretty/logo151dpi.kicad_mod b/PCB/labralogo.pretty/logo151dpi.kicad_mod new file mode 100644 index 00000000..5f4f091c --- /dev/null +++ b/PCB/labralogo.pretty/logo151dpi.kicad_mod @@ -0,0 +1,34 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy 6.887956 -10.360785) (xy 7.663703 -10.180194) (xy 8.470333 -9.870620) (xy 9.211901 -9.480878) (xy 9.792461 -9.059782) (xy 10.071854 -8.740887) (xy 10.266997 -8.263336) (xy 10.449505 -7.522396) + (xy 10.601590 -6.591061) (xy 10.608192 -6.539905) (xy 10.707993 -5.164422) (xy 10.641267 -3.802170) (xy 10.396348 -2.381476) (xy 9.961573 -0.830668) (xy 9.442992 0.620109) (xy 9.026802 1.711505) + (xy 8.717463 2.565875) (xy 8.496627 3.258454) (xy 8.345946 3.864478) (xy 8.247071 4.459180) (xy 8.181653 5.117795) (xy 8.131346 5.915557) (xy 8.125572 6.021992) (xy 8.085255 6.855776) + (xy 8.076332 7.428410) (xy 8.107252 7.814383) (xy 8.186462 8.088185) (xy 8.322412 8.324307) (xy 8.398753 8.430552) (xy 8.662127 8.910549) (xy 8.628731 9.233990) (xy 8.299586 9.398241) + (xy 8.014692 9.419867) (xy 7.514362 9.330918) (xy 7.178352 9.020295) (xy 7.167465 9.003900) (xy 6.950835 8.539388) (xy 6.735952 7.860078) (xy 6.552298 7.086448) (xy 6.429355 6.338980) + (xy 6.394540 5.845364) (xy 6.353310 5.439796) (xy 6.254197 5.224903) (xy 6.223841 5.214569) (xy 6.118643 5.366273) (xy 6.066596 5.764620) (xy 6.065195 6.324468) (xy 6.111936 6.960673) + (xy 6.204313 7.588091) (xy 6.306271 8.016054) (xy 6.516870 8.567257) (xy 6.770256 9.018861) (xy 6.895013 9.166032) (xy 7.213914 9.594298) (xy 7.243428 9.975942) (xy 7.030522 10.257381) + (xy 6.622161 10.385032) (xy 6.065311 10.305310) (xy 5.937381 10.258611) (xy 5.452906 9.899693) (xy 4.993977 9.245294) (xy 4.580428 8.336310) (xy 4.232096 7.213635) (xy 4.043568 6.354197) + (xy 3.924662 5.756530) (xy 3.812417 5.410068) (xy 3.653528 5.234980) (xy 3.394694 5.151435) (xy 3.219825 5.120496) (xy 2.589906 4.992680) (xy 1.958783 4.809166) (xy 1.242129 4.539927) + (xy 0.355616 4.154935) (xy -0.168212 3.914061) (xy -1.766225 3.170227) (xy -2.186755 3.709925) (xy -2.498713 4.092105) (xy -2.950690 4.623927) (xy -3.457308 5.205274) (xy -3.582567 5.346697) + (xy -4.098008 5.956983) (xy -4.580810 6.580785) (xy -4.941196 7.101031) (xy -4.992177 7.184895) (xy -5.426504 7.926020) (xy -4.951580 8.421734) (xy -4.657087 8.780732) (xy -4.607563 9.014451) + (xy -4.672001 9.112796) (xy -4.955963 9.195495) (xy -5.398226 9.147125) (xy -5.865119 9.003752) (xy -6.222972 8.801442) (xy -6.330277 8.665378) (xy -6.352377 8.386264) (xy -6.321243 7.890736) + (xy -6.255737 7.371152) (xy -6.179402 6.814852) (xy -6.140747 6.409055) (xy -6.146459 6.249593) (xy -6.254317 6.328443) (xy -6.430359 6.634657) (xy -6.633845 7.077296) (xy -6.824037 7.565421) + (xy -6.960195 8.008093) (xy -6.984963 8.121342) (xy -7.012259 8.673669) (xy -6.830235 9.193347) (xy -6.744743 9.345968) (xy -6.510266 9.839294) (xy -6.525433 10.130915) (xy -6.797667 10.252601) + (xy -6.958571 10.260927) (xy -7.476975 10.145617) (xy -7.832304 9.779642) (xy -8.049487 9.132936) (xy -8.088898 8.897741) (xy -8.211369 7.776375) (xy -8.213660 6.857559) (xy -8.085472 6.025867) + (xy -7.816505 5.165878) (xy -7.737748 4.962251) (xy -7.437601 4.109692) (xy -7.281240 3.369506) (xy -7.233320 2.569300) (xy -7.233112 2.500803) (xy -7.241257 1.883482) (xy -7.277202 1.539811) + (xy -7.358216 1.407182) (xy -7.501564 1.422987) (xy -7.527483 1.433435) (xy -8.289016 1.627062) (xy -9.120250 1.639461) (xy -9.895170 1.481290) (xy -10.461213 1.185336) (xy -10.844208 0.875204) + (xy -10.089985 0.674505) (xy -8.878051 0.215210) (xy -7.647849 -0.500877) (xy -6.497881 -1.415039) (xy -6.348808 -1.555570) (xy -5.852489 -2.030251) (xy -5.436327 -2.396532) (xy -5.046894 -2.669589) + (xy -4.630757 -2.864598) (xy -4.134485 -2.996737) (xy -3.504648 -3.081182) (xy -2.687814 -3.133111) (xy -1.630552 -3.167699) (xy -0.584534 -3.192876) (xy 3.120336 -3.280133) (xy 4.215430 -3.819576) + (xy 4.827580 -4.153063) (xy 5.368000 -4.502886) (xy 5.710743 -4.785032) (xy 5.967049 -5.085730) (xy 6.003331 -5.283439) (xy 5.838746 -5.511754) (xy 5.818218 -5.534522) (xy 5.531006 -5.777332) + (xy 5.049162 -6.113466) (xy 4.472558 -6.473616) (xy 4.422762 -6.502890) (xy 3.488228 -7.159840) (xy 2.861413 -7.852426) (xy 2.554129 -8.565894) (xy 2.523179 -8.875453) (xy 2.572072 -9.275034) + (xy 2.624573 -9.335762) (xy 5.887418 -9.335762) (xy 5.972768 -9.126410) (xy 6.068245 -9.115685) (xy 6.242036 -9.289344) (xy 6.249073 -9.335762) (xy 6.118117 -9.532996) (xy 6.068245 -9.555839) + (xy 5.914863 -9.474640) (xy 5.887418 -9.335762) (xy 2.624573 -9.335762) (xy 2.757891 -9.489971) (xy 3.139346 -9.545588) (xy 3.775150 -9.467208) (xy 3.860026 -9.452059) (xy 4.377731 -9.373115) + (xy 4.724304 -9.400135) (xy 5.046937 -9.573197) (xy 5.429467 -9.879402) (xy 5.871285 -10.221071) (xy 6.214055 -10.376766) (xy 6.601129 -10.393802) (xy 6.887956 -10.360785) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/logo151dpi.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/logo151dpi.kicad_mod.REMOVED.git-id deleted file mode 100644 index d23410b9..00000000 --- a/PCB/labralogo.pretty/logo151dpi.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -5f4f091cbecbfd9f204df8a1efaa3bd03e327e02 \ No newline at end of file diff --git a/PCB/labralogo.pretty/logo175dpi.kicad_mod b/PCB/labralogo.pretty/logo175dpi.kicad_mod new file mode 100644 index 00000000..67e02527 --- /dev/null +++ b/PCB/labralogo.pretty/logo175dpi.kicad_mod @@ -0,0 +1,34 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy 5.943322 -8.939877) (xy 6.612681 -8.784053) (xy 7.308687 -8.516935) (xy 7.948554 -8.180643) (xy 8.449495 -7.817298) (xy 8.690571 -7.542137) (xy 8.858951 -7.130078) (xy 9.016430 -6.490753) + (xy 9.147658 -5.687144) (xy 9.153354 -5.643004) (xy 9.239469 -4.456159) (xy 9.181893 -3.280729) (xy 8.970563 -2.054874) (xy 8.595414 -0.716748) (xy 8.147953 0.535066) (xy 7.788840 1.476784) + (xy 7.521925 2.213983) (xy 7.331375 2.811581) (xy 7.201359 3.334492) (xy 7.116044 3.847635) (xy 7.059598 4.415926) (xy 7.016190 5.104281) (xy 7.011208 5.196118) (xy 6.976420 5.915555) + (xy 6.968721 6.409656) (xy 6.995400 6.742696) (xy 7.063747 6.978949) (xy 7.181053 7.182688) (xy 7.246924 7.274362) (xy 7.474178 7.688530) (xy 7.445362 7.967614) (xy 7.161357 8.109340) + (xy 6.915534 8.128000) (xy 6.483821 8.051249) (xy 6.193892 7.783226) (xy 6.184498 7.769080) (xy 5.997578 7.368272) (xy 5.812164 6.782124) (xy 5.653697 6.114593) (xy 5.547615 5.469634) + (xy 5.517574 5.043714) (xy 5.481999 4.693767) (xy 5.396478 4.508345) (xy 5.370286 4.499428) (xy 5.279515 4.630327) (xy 5.234606 4.974044) (xy 5.233397 5.457113) (xy 5.273728 6.006067) + (xy 5.353435 6.547439) (xy 5.441411 6.916709) (xy 5.623128 7.392319) (xy 5.841763 7.781988) (xy 5.949411 7.908977) (xy 6.224577 8.278508) (xy 6.250044 8.607813) (xy 6.066336 8.850655) + (xy 5.713979 8.960799) (xy 5.233497 8.892011) (xy 5.123111 8.851716) (xy 4.705079 8.542021) (xy 4.309089 7.977368) (xy 3.952255 7.193044) (xy 3.651694 6.224337) (xy 3.489022 5.482764) + (xy 3.386423 4.967063) (xy 3.289571 4.668116) (xy 3.152473 4.517040) (xy 2.929136 4.444952) (xy 2.778249 4.418257) (xy 2.234719 4.307969) (xy 1.690150 4.149623) (xy 1.071780 3.917309) + (xy 0.306846 3.585116) (xy -0.145142 3.377276) (xy -1.524000 2.735453) (xy -1.886857 3.201135) (xy -2.156032 3.530902) (xy -2.546024 3.989788) (xy -2.983163 4.491408) (xy -3.091243 4.613435) + (xy -3.535995 5.140025) (xy -3.952585 5.678277) (xy -4.263547 6.127175) (xy -4.307535 6.199538) (xy -4.682298 6.839023) (xy -4.272506 7.266754) (xy -4.018400 7.576517) (xy -3.975669 7.778183) + (xy -4.031269 7.863041) (xy -4.276288 7.934398) (xy -4.657898 7.892662) (xy -5.060760 7.768952) (xy -5.369536 7.594387) (xy -5.462125 7.476983) (xy -5.481194 7.236147) (xy -5.454329 6.808578) + (xy -5.397807 6.360251) (xy -5.331941 5.880244) (xy -5.298587 5.530099) (xy -5.303516 5.392506) (xy -5.396582 5.460542) (xy -5.548481 5.724761) (xy -5.724061 6.106695) (xy -5.888169 6.527878) + (xy -6.005654 6.909840) (xy -6.027025 7.007558) (xy -6.050578 7.484137) (xy -5.893517 7.932545) (xy -5.819749 8.064235) (xy -5.617430 8.489905) (xy -5.630516 8.741532) (xy -5.865415 8.846530) + (xy -6.004253 8.853714) (xy -6.451562 8.754218) (xy -6.758159 8.438434) (xy -6.945557 7.880419) (xy -6.979563 7.677479) (xy -7.085238 6.709901) (xy -7.087215 5.917093) (xy -6.976607 5.199463) + (xy -6.744528 4.457415) (xy -6.676571 4.281714) (xy -6.417588 3.546077) (xy -6.282670 2.907403) (xy -6.241322 2.216939) (xy -6.241143 2.157836) (xy -6.248170 1.625176) (xy -6.279186 1.328637) + (xy -6.349089 1.214197) (xy -6.472778 1.227834) (xy -6.495142 1.236850) (xy -7.152236 1.403922) (xy -7.869473 1.414621) (xy -8.538118 1.278142) (xy -9.026532 1.022775) (xy -9.357003 0.755176) + (xy -8.706216 0.582001) (xy -7.660490 0.185695) (xy -6.599001 -0.432186) (xy -5.606743 -1.220977) (xy -5.478115 -1.342235) (xy -5.049862 -1.751817) (xy -4.690774 -2.067865) (xy -4.354748 -2.303474) + (xy -3.995682 -2.471739) (xy -3.567470 -2.585756) (xy -3.024011 -2.658620) (xy -2.319199 -2.703427) (xy -1.406933 -2.733272) (xy -0.504369 -2.754996) (xy 2.692404 -2.830286) (xy 3.637314 -3.295749) + (xy 4.165512 -3.583500) (xy 4.631817 -3.885347) (xy 4.927556 -4.128799) (xy 5.148711 -4.388259) (xy 5.180017 -4.558853) (xy 5.038004 -4.755856) (xy 5.020291 -4.775502) (xy 4.772468 -4.985013) + (xy 4.356705 -5.275048) (xy 3.859178 -5.585806) (xy 3.816212 -5.611065) (xy 3.009842 -6.177919) (xy 2.468991 -6.775522) (xy 2.203849 -7.391143) (xy 2.177143 -7.658248) (xy 2.219331 -8.003029) + (xy 2.264632 -8.055429) (xy 5.080000 -8.055429) (xy 5.153646 -7.874788) (xy 5.236029 -7.865534) (xy 5.385985 -8.015377) (xy 5.392058 -8.055429) (xy 5.279061 -8.225614) (xy 5.236029 -8.245324) + (xy 5.103682 -8.175261) (xy 5.080000 -8.055429) (xy 2.264632 -8.055429) (xy 2.379666 -8.188489) (xy 2.708807 -8.236479) (xy 3.257415 -8.168848) (xy 3.330651 -8.155776) (xy 3.777356 -8.087659) + (xy 4.076399 -8.110973) (xy 4.354785 -8.260301) (xy 4.684854 -8.524512) (xy 5.066080 -8.819324) (xy 5.361842 -8.953667) (xy 5.695831 -8.968366) (xy 5.943322 -8.939877) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/logo175dpi.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/logo175dpi.kicad_mod.REMOVED.git-id deleted file mode 100644 index 3d3bee5d..00000000 --- a/PCB/labralogo.pretty/logo175dpi.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -67e02527c64fe586329a7ea82b49f798817bd573 \ No newline at end of file diff --git a/PCB/labralogo.pretty/logo200dpi.kicad_mod b/PCB/labralogo.pretty/logo200dpi.kicad_mod new file mode 100644 index 00000000..154ae8c1 --- /dev/null +++ b/PCB/labralogo.pretty/logo200dpi.kicad_mod @@ -0,0 +1,34 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy 5.200406 -7.822393) (xy 5.786095 -7.686046) (xy 6.395101 -7.452318) (xy 6.954984 -7.158063) (xy 7.393307 -6.840136) (xy 7.604249 -6.599370) (xy 7.751582 -6.238819) (xy 7.889375 -5.679409) + (xy 8.004200 -4.976251) (xy 8.009184 -4.937628) (xy 8.084534 -3.899139) (xy 8.034155 -2.870638) (xy 7.849242 -1.798015) (xy 7.520987 -0.627155) (xy 7.129458 0.468182) (xy 6.815235 1.292186) + (xy 6.581684 1.937235) (xy 6.414953 2.460133) (xy 6.301188 2.917681) (xy 6.226538 3.366681) (xy 6.177148 3.863935) (xy 6.139165 4.466246) (xy 6.134806 4.546603) (xy 6.104367 5.176111) + (xy 6.097630 5.608449) (xy 6.120974 5.899859) (xy 6.180778 6.106580) (xy 6.283420 6.284852) (xy 6.341058 6.365067) (xy 6.539905 6.727464) (xy 6.514691 6.971662) (xy 6.266187 7.095672) + (xy 6.051092 7.112000) (xy 5.673342 7.044843) (xy 5.419655 6.810322) (xy 5.411435 6.797945) (xy 5.247880 6.447238) (xy 5.085643 5.934358) (xy 4.946984 5.350268) (xy 4.854162 4.785930) + (xy 4.827877 4.413250) (xy 4.796748 4.107046) (xy 4.721918 3.944801) (xy 4.699000 3.937000) (xy 4.619574 4.051536) (xy 4.580279 4.352288) (xy 4.579222 4.774973) (xy 4.614511 5.255308) + (xy 4.684255 5.729009) (xy 4.761234 6.052120) (xy 4.920236 6.468279) (xy 5.111542 6.809240) (xy 5.205734 6.920354) (xy 5.446504 7.243695) (xy 5.468788 7.531836) (xy 5.308044 7.744323) + (xy 4.999731 7.840699) (xy 4.579309 7.780509) (xy 4.482722 7.745251) (xy 4.116944 7.474268) (xy 3.770452 6.980197) (xy 3.458222 6.293914) (xy 3.195232 5.446294) (xy 3.052893 4.797419) + (xy 2.963119 4.346180) (xy 2.878374 4.084601) (xy 2.758413 3.952410) (xy 2.562993 3.889333) (xy 2.430967 3.865974) (xy 1.955378 3.769473) (xy 1.478880 3.630920) (xy 0.937806 3.427645) + (xy 0.268489 3.136976) (xy -0.127000 2.955116) (xy -1.333500 2.393521) (xy -1.651000 2.800993) (xy -1.886529 3.089539) (xy -2.227771 3.491064) (xy -2.610269 3.929982) (xy -2.704839 4.036756) + (xy -3.093997 4.497522) (xy -3.458512 4.968493) (xy -3.730604 5.361278) (xy -3.769094 5.424596) (xy -4.097012 5.984145) (xy -3.738443 6.358409) (xy -3.516101 6.629453) (xy -3.478711 6.805910) + (xy -3.527362 6.880161) (xy -3.741753 6.942598) (xy -4.075662 6.906079) (xy -4.428166 6.797833) (xy -4.698345 6.645088) (xy -4.779360 6.542360) (xy -4.796046 6.331629) (xy -4.772539 5.957505) + (xy -4.723082 5.565219) (xy -4.665449 5.145213) (xy -4.636265 4.838836) (xy -4.640577 4.718443) (xy -4.722010 4.777974) (xy -4.854922 5.009166) (xy -5.008554 5.343358) (xy -5.152149 5.711893) + (xy -5.254948 6.046110) (xy -5.273648 6.131613) (xy -5.294257 6.548620) (xy -5.156828 6.940977) (xy -5.092282 7.056205) (xy -4.915252 7.428667) (xy -4.926702 7.648841) (xy -5.132239 7.740714) + (xy -5.253722 7.747000) (xy -5.645117 7.659941) (xy -5.913390 7.383630) (xy -6.077363 6.895367) (xy -6.107119 6.717794) (xy -6.199584 5.871163) (xy -6.201314 5.177457) (xy -6.104532 4.549530) + (xy -5.901462 3.900238) (xy -5.842001 3.746500) (xy -5.615390 3.102817) (xy -5.497337 2.543977) (xy -5.461158 1.939821) (xy -5.461000 1.888106) (xy -5.467150 1.422029) (xy -5.494289 1.162557) + (xy -5.555454 1.062423) (xy -5.663681 1.074355) (xy -5.683250 1.082244) (xy -6.258208 1.228432) (xy -6.885790 1.237793) (xy -7.470854 1.118374) (xy -7.898216 0.894928) (xy -8.187378 0.660779) + (xy -7.617940 0.509251) (xy -6.702930 0.162483) (xy -5.774127 -0.378163) (xy -4.905901 -1.068355) (xy -4.793351 -1.174456) (xy -4.418630 -1.532840) (xy -4.104428 -1.809382) (xy -3.810406 -2.015540) + (xy -3.496222 -2.162772) (xy -3.121537 -2.262537) (xy -2.646010 -2.326293) (xy -2.029300 -2.365499) (xy -1.231068 -2.391613) (xy -0.441324 -2.410622) (xy 2.355853 -2.476500) (xy 3.182649 -2.883780) + (xy 3.644822 -3.135563) (xy 4.052839 -3.399679) (xy 4.311610 -3.612699) (xy 4.505121 -3.839727) (xy 4.532514 -3.988996) (xy 4.408253 -4.161374) (xy 4.392754 -4.178564) (xy 4.175909 -4.361886) + (xy 3.812116 -4.615667) (xy 3.376780 -4.887580) (xy 3.339185 -4.909682) (xy 2.633611 -5.405679) (xy 2.160366 -5.928582) (xy 1.928367 -6.467250) (xy 1.905000 -6.700967) (xy 1.941913 -7.002651) + (xy 1.981551 -7.048500) (xy 4.445000 -7.048500) (xy 4.509439 -6.890440) (xy 4.581525 -6.882342) (xy 4.712736 -7.013455) (xy 4.718050 -7.048500) (xy 4.619177 -7.197412) (xy 4.581525 -7.214659) + (xy 4.465721 -7.153353) (xy 4.445000 -7.048500) (xy 1.981551 -7.048500) (xy 2.082207 -7.164928) (xy 2.370206 -7.206919) (xy 2.850237 -7.147742) (xy 2.914319 -7.136304) (xy 3.305186 -7.076702) + (xy 3.566848 -7.097102) (xy 3.810436 -7.227764) (xy 4.099246 -7.458948) (xy 4.432819 -7.716909) (xy 4.691611 -7.834459) (xy 4.983852 -7.847321) (xy 5.200406 -7.822393) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/logo200dpi.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/logo200dpi.kicad_mod.REMOVED.git-id deleted file mode 100644 index 6da52e77..00000000 --- a/PCB/labralogo.pretty/logo200dpi.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -154ae8c13cd167913ecbecaddd04fc2c99efd823 \ No newline at end of file diff --git a/PCB/labralogo.pretty/logo300dpi.kicad_mod b/PCB/labralogo.pretty/logo300dpi.kicad_mod new file mode 100644 index 00000000..9024a1f3 --- /dev/null +++ b/PCB/labralogo.pretty/logo300dpi.kicad_mod @@ -0,0 +1,34 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy 3.466938 -5.214928) (xy 3.857397 -5.124031) (xy 4.263401 -4.968212) (xy 4.636657 -4.772042) (xy 4.928872 -4.560090) (xy 5.069500 -4.399580) (xy 5.167722 -4.159212) (xy 5.259584 -3.786272) + (xy 5.336134 -3.317501) (xy 5.339456 -3.291752) (xy 5.389690 -2.599426) (xy 5.356104 -1.913759) (xy 5.232828 -1.198676) (xy 5.013992 -0.418103) (xy 4.752972 0.312122) (xy 4.543490 0.861457) + (xy 4.387790 1.291490) (xy 4.276636 1.640089) (xy 4.200793 1.945121) (xy 4.151026 2.244454) (xy 4.118099 2.575957) (xy 4.092777 2.977497) (xy 4.089871 3.031069) (xy 4.069579 3.450741) + (xy 4.065087 3.738966) (xy 4.080650 3.933239) (xy 4.120519 4.071053) (xy 4.188947 4.189901) (xy 4.227372 4.243378) (xy 4.359937 4.484976) (xy 4.343128 4.647775) (xy 4.177458 4.730448) + (xy 4.034062 4.741333) (xy 3.782229 4.696562) (xy 3.613104 4.540215) (xy 3.607624 4.531963) (xy 3.498587 4.298159) (xy 3.390429 3.956239) (xy 3.297990 3.566846) (xy 3.236109 3.190620) + (xy 3.218585 2.942167) (xy 3.197833 2.738031) (xy 3.147946 2.629868) (xy 3.132667 2.624667) (xy 3.079717 2.701024) (xy 3.053520 2.901526) (xy 3.052815 3.183316) (xy 3.076341 3.503539) + (xy 3.122837 3.819339) (xy 3.174157 4.034747) (xy 3.280158 4.312186) (xy 3.407695 4.539493) (xy 3.470490 4.613570) (xy 3.631003 4.829130) (xy 3.645859 5.021224) (xy 3.538696 5.162882) + (xy 3.333154 5.227133) (xy 3.052873 5.187006) (xy 2.988482 5.163501) (xy 2.744630 4.982845) (xy 2.513635 4.653465) (xy 2.305482 4.195943) (xy 2.130155 3.630863) (xy 2.035263 3.198279) + (xy 1.975413 2.897453) (xy 1.918916 2.723068) (xy 1.838943 2.634940) (xy 1.708662 2.592889) (xy 1.620645 2.577316) (xy 1.303586 2.512982) (xy 0.985921 2.420614) (xy 0.625205 2.285097) + (xy 0.178993 2.091317) (xy -0.084666 1.970077) (xy -0.889000 1.595681) (xy -1.100666 1.867329) (xy -1.257686 2.059693) (xy -1.485180 2.327376) (xy -1.740179 2.619988) (xy -1.803225 2.691171) + (xy -2.062664 2.998348) (xy -2.305674 3.312329) (xy -2.487069 3.574185) (xy -2.512729 3.616397) (xy -2.731341 3.989430) (xy -2.492295 4.238940) (xy -2.344067 4.419635) (xy -2.319140 4.537274) + (xy -2.351574 4.586774) (xy -2.494502 4.628399) (xy -2.717107 4.604053) (xy -2.952110 4.531889) (xy -3.132229 4.430059) (xy -3.186240 4.361573) (xy -3.197363 4.221086) (xy -3.181692 3.971670) + (xy -3.148721 3.710146) (xy -3.110299 3.430142) (xy -3.090843 3.225891) (xy -3.093718 3.145629) (xy -3.148006 3.185316) (xy -3.236614 3.339444) (xy -3.339035 3.562239) (xy -3.434765 3.807929) + (xy -3.503298 4.030740) (xy -3.515765 4.087742) (xy -3.529504 4.365747) (xy -3.437885 4.627318) (xy -3.394854 4.704137) (xy -3.276834 4.952445) (xy -3.284468 5.099227) (xy -3.421492 5.160476) + (xy -3.502481 5.164667) (xy -3.763411 5.106627) (xy -3.942260 4.922420) (xy -4.051575 4.596911) (xy -4.071412 4.478530) (xy -4.133056 3.914109) (xy -4.134209 3.451638) (xy -4.069688 3.033020) + (xy -3.934308 2.600159) (xy -3.894667 2.497667) (xy -3.743593 2.068545) (xy -3.664891 1.695985) (xy -3.640771 1.293214) (xy -3.640666 1.258737) (xy -3.644766 0.948019) (xy -3.662859 0.775038) + (xy -3.703635 0.708282) (xy -3.775787 0.716237) (xy -3.788833 0.721496) (xy -4.172138 0.818955) (xy -4.590526 0.825196) (xy -4.980569 0.745583) (xy -5.265477 0.596619) (xy -5.458251 0.440519) + (xy -5.078626 0.339501) (xy -4.468619 0.108322) (xy -3.849417 -0.252108) (xy -3.270600 -0.712236) (xy -3.195567 -0.782970) (xy -2.945753 -1.021893) (xy -2.736285 -1.206254) (xy -2.540270 -1.343693) + (xy -2.330814 -1.441848) (xy -2.081024 -1.508358) (xy -1.764006 -1.550862) (xy -1.352866 -1.576999) (xy -0.820711 -1.594408) (xy -0.294215 -1.607081) (xy 1.570569 -1.651000) (xy 2.121767 -1.922520) + (xy 2.429882 -2.090375) (xy 2.701893 -2.266452) (xy 2.874407 -2.408466) (xy 3.003415 -2.559818) (xy 3.021677 -2.659331) (xy 2.938836 -2.774249) (xy 2.928503 -2.785709) (xy 2.783940 -2.907924) + (xy 2.541411 -3.077111) (xy 2.251187 -3.258387) (xy 2.226124 -3.273121) (xy 1.755741 -3.603786) (xy 1.440244 -3.952388) (xy 1.285578 -4.311500) (xy 1.270000 -4.467311) (xy 1.294609 -4.668434) + (xy 1.321034 -4.699000) (xy 2.963334 -4.699000) (xy 3.006293 -4.593627) (xy 3.054350 -4.588228) (xy 3.141825 -4.675636) (xy 3.145367 -4.699000) (xy 3.079452 -4.798275) (xy 3.054350 -4.809772) + (xy 2.977148 -4.768902) (xy 2.963334 -4.699000) (xy 1.321034 -4.699000) (xy 1.388138 -4.776619) (xy 1.580138 -4.804613) (xy 1.900159 -4.765161) (xy 1.942880 -4.757536) (xy 2.203458 -4.717801) + (xy 2.377899 -4.731401) (xy 2.540291 -4.818509) (xy 2.732831 -4.972632) (xy 2.955213 -5.144606) (xy 3.127741 -5.222972) (xy 3.322568 -5.231547) (xy 3.466938 -5.214928) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/logo300dpi.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/logo300dpi.kicad_mod.REMOVED.git-id deleted file mode 100644 index 2ec86eac..00000000 --- a/PCB/labralogo.pretty/logo300dpi.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -9024a1f3f56b9e65f23b90e911cf8ea41f767e04 \ No newline at end of file diff --git a/PCB/labralogo.pretty/logo50dpi.kicad_mod b/PCB/labralogo.pretty/logo50dpi.kicad_mod new file mode 100644 index 00000000..720b14a8 --- /dev/null +++ b/PCB/labralogo.pretty/logo50dpi.kicad_mod @@ -0,0 +1,46 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy -31.169646 3.904122) (xy -29.837180 4.407326) (xy -27.907979 4.723572) (xy -25.788049 4.829482) (xy -23.883401 4.701679) (xy -22.733001 4.389890) (xy -22.270334 4.258237) (xy -22.002864 4.552010) + (xy -21.878336 5.457101) (xy -21.844494 7.159402) (xy -21.844001 7.552425) (xy -21.968091 10.004299) (xy -22.411521 12.235139) (xy -23.281030 14.765580) (xy -23.368000 14.985999) (xy -24.277593 17.648454) + (xy -24.755220 20.149065) (xy -24.831985 22.836414) (xy -24.538990 26.059080) (xy -24.428473 26.871178) (xy -23.875787 29.077594) (xy -22.926961 30.410805) (xy -21.506704 30.961613) (xy -21.014887 30.988000) + (xy -19.910096 30.780511) (xy -19.589657 30.094081) (xy -20.031145 28.832759) (xy -20.369125 28.224823) (xy -21.100586 26.584159) (xy -21.169755 24.998574) (xy -21.094591 24.526452) (xy -20.758553 23.287344) + (xy -20.221386 21.826256) (xy -19.606120 20.417823) (xy -19.035787 19.336684) (xy -18.633418 18.857473) (xy -18.562307 18.873772) (xy -18.549357 19.426862) (xy -18.675816 20.697359) (xy -18.892327 22.260879) + (xy -19.110363 24.044822) (xy -19.185032 25.477350) (xy -19.117439 26.169441) (xy -18.432822 26.835287) (xy -17.174218 27.389160) (xy -15.745311 27.722142) (xy -14.549786 27.725315) (xy -14.109445 27.520644) + (xy -13.897678 26.929922) (xy -14.379453 26.075217) (xy -14.953772 25.433639) (xy -16.388045 23.936580) (xy -15.076375 21.698385) (xy -14.098213 20.235956) (xy -12.694327 18.387722) (xy -11.135839 16.507239) + (xy -10.819353 16.147025) (xy -9.288402 14.401217) (xy -7.857972 12.729347) (xy -6.785902 11.433763) (xy -6.604000 11.203974) (xy -5.334000 9.574087) (xy -0.508000 11.820465) (xy 2.514860 13.188264) + (xy 4.899537 14.161903) (xy 6.900701 14.832066) (xy 8.773020 15.289439) (xy 9.723870 15.463899) (xy 10.707019 15.669192) (xy 11.311268 16.035532) (xy 11.697596 16.804011) (xy 12.026977 18.215717) + (xy 12.211575 19.189676) (xy 13.096437 22.946489) (xy 14.218754 26.141457) (xy 15.518623 28.651076) (xy 16.936137 30.351844) (xy 17.930888 30.981006) (xy 17.689838 31.080507) (xy 16.491305 31.171142) + (xy 14.393778 31.251766) (xy 11.455744 31.321233) (xy 7.735693 31.378399) (xy 3.292111 31.422120) (xy -1.816514 31.451249) (xy -6.731000 31.463799) (xy -32.512000 31.496000) (xy -32.512000 3.024578) + (xy -31.169646 3.904122) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 32.228763 -9.810715) (xy 32.300567 -8.958286) (xy 32.354964 -7.491927) (xy 32.394942 -5.340618) (xy 32.423491 -2.433339) (xy 32.443599 1.300929) (xy 32.458257 5.933206) (xy 32.466413 9.525000) + (xy 32.512000 31.496000) (xy 26.543000 31.455894) (xy 24.290473 31.420495) (xy 22.535293 31.353484) (xy 21.448654 31.264369) (xy 21.201751 31.162664) (xy 21.209000 31.159561) (xy 21.761396 30.471811) + (xy 21.758014 29.344452) (xy 21.241219 28.159146) (xy 20.822938 27.681419) (xy 20.082717 26.657890) (xy 19.349782 25.095404) (xy 19.044938 24.208483) (xy 18.663855 22.512487) (xy 18.414700 20.589675) + (xy 18.305039 18.697182) (xy 18.342436 17.092142) (xy 18.534459 16.031689) (xy 18.796000 15.748000) (xy 19.124386 16.196823) (xy 19.301833 17.309690) (xy 19.311508 17.653000) (xy 19.474534 19.589830) + (xy 19.891386 21.893671) (xy 20.473027 24.200673) (xy 21.130420 26.146986) (xy 21.645743 27.191780) (xy 22.650007 28.158083) (xy 24.135759 28.447683) (xy 24.204368 28.448000) (xy 25.657644 28.202920) + (xy 26.219354 27.472985) (xy 25.886408 26.266151) (xy 25.364233 25.460268) (xy 24.873797 24.727754) (xy 24.565469 23.976260) (xy 24.413735 22.980828) (xy 24.393079 21.516498) (xy 24.477986 19.358309) + (xy 24.539227 18.186415) (xy 24.689905 15.707040) (xy 24.880020 13.676310) (xy 25.165177 11.865898) (xy 25.600980 10.047480) (xy 26.243034 7.992731) (xy 27.146944 5.473326) (xy 28.368315 2.260939) + (xy 28.502465 1.912494) (xy 29.523091 -0.901199) (xy 30.466286 -3.796788) (xy 31.227907 -6.435901) (xy 31.703810 -8.480167) (xy 31.707687 -8.501506) (xy 31.879013 -9.394608) (xy 32.020975 -9.957856) + (xy 32.136562 -10.120231) (xy 32.228763 -9.810715) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 16.332762 -29.782134) (xy 15.069834 -28.788823) (xy 14.107221 -28.345726) (xy 12.983479 -28.330764) (xy 11.657276 -28.545216) (xy 9.645167 -28.820405) (xy 8.420018 -28.699043) (xy 7.804520 -28.104655) + (xy 7.621367 -26.960766) (xy 7.619999 -26.803868) (xy 8.122054 -24.635774) (xy 9.604434 -22.511584) (xy 12.031468 -20.475855) (xy 13.356740 -19.638727) (xy 15.108430 -18.554527) (xy 16.599385 -17.525204) + (xy 17.527992 -16.760062) (xy 17.571018 -16.714256) (xy 18.112534 -16.000807) (xy 18.051904 -15.410969) (xy 17.331271 -14.541281) (xy 17.246443 -14.450796) (xy 16.170888 -13.569872) (xy 14.527575 -12.511572) + (xy 12.730598 -11.535119) (xy 9.423412 -9.906000) (xy -1.765294 -9.642485) (xy -5.647840 -9.547307) (xy -8.676846 -9.436229) (xy -11.014309 -9.262644) (xy -12.822223 -8.979943) (xy -14.262585 -8.541516) + (xy -15.497390 -7.900755) (xy -16.688636 -7.011051) (xy -17.998317 -5.825795) (xy -19.267994 -4.606690) (xy -21.690903 -2.577112) (xy -24.528233 -0.675661) (xy -27.459656 0.912120) (xy -30.164848 2.000687) + (xy -31.115000 2.255464) (xy -32.512000 2.559356) (xy -32.512000 -31.496000) (xy 18.384127 -31.496000) (xy 16.332762 -29.782134) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 32.512000 -24.892000) (xy 32.497941 -22.435280) (xy 32.459476 -20.392956) (xy 32.402167 -18.953653) (xy 32.331581 -18.305994) (xy 32.317180 -18.288000) (xy 32.167657 -18.749055) (xy 31.968389 -19.953292) + (xy 31.777573 -21.507573) (xy 31.436189 -23.505324) (xy 30.911038 -25.332139) (xy 30.468321 -26.313082) (xy 29.080444 -27.812884) (xy 26.861893 -29.241351) (xy 23.997176 -30.486321) (xy 23.114000 -30.783711) + (xy 22.303491 -31.060737) (xy 22.021705 -31.246238) (xy 22.376603 -31.360095) (xy 23.476147 -31.422192) (xy 25.428297 -31.452413) (xy 26.797000 -31.462017) (xy 32.512000 -31.496000) (xy 32.512000 -24.892000) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 18.850946 -28.334184) (xy 18.872200 -28.194000) (xy 18.476711 -27.598354) (xy 18.326100 -27.529367) (xy 17.862885 -27.774589) (xy 17.780000 -28.194000) (xy 18.037759 -28.826242) (xy 18.326100 -28.858634) + (xy 18.850946 -28.334184) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/logo50dpi.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/logo50dpi.kicad_mod.REMOVED.git-id deleted file mode 100644 index 4883861f..00000000 --- a/PCB/labralogo.pretty/logo50dpi.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -720b14a887504152f00e48edfa698bfbb4bf542e \ No newline at end of file diff --git a/PCB/labralogo.pretty/logo600dpi.kicad_mod b/PCB/labralogo.pretty/logo600dpi.kicad_mod new file mode 100644 index 00000000..d1268323 --- /dev/null +++ b/PCB/labralogo.pretty/logo600dpi.kicad_mod @@ -0,0 +1,34 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy 1.733469 -2.607464) (xy 1.928698 -2.562015) (xy 2.131700 -2.484106) (xy 2.318328 -2.386021) (xy 2.464436 -2.280045) (xy 2.534750 -2.199790) (xy 2.583861 -2.079606) (xy 2.629792 -1.893136) + (xy 2.668067 -1.658750) (xy 2.669728 -1.645876) (xy 2.694845 -1.299713) (xy 2.678052 -0.956879) (xy 2.616414 -0.599338) (xy 2.506996 -0.209051) (xy 2.376486 0.156061) (xy 2.271745 0.430729) + (xy 2.193895 0.645745) (xy 2.138318 0.820045) (xy 2.100396 0.972561) (xy 2.075513 1.122227) (xy 2.059049 1.287979) (xy 2.046388 1.488749) (xy 2.044935 1.515535) (xy 2.034789 1.725371) + (xy 2.032543 1.869483) (xy 2.040325 1.966620) (xy 2.060259 2.035527) (xy 2.094473 2.094951) (xy 2.113686 2.121689) (xy 2.179968 2.242488) (xy 2.171564 2.323888) (xy 2.088729 2.365224) + (xy 2.017031 2.370667) (xy 1.891114 2.348281) (xy 1.806552 2.270108) (xy 1.803812 2.265982) (xy 1.749293 2.149080) (xy 1.695214 1.978120) (xy 1.648995 1.783423) (xy 1.618054 1.595310) + (xy 1.609292 1.471084) (xy 1.598916 1.369016) (xy 1.573973 1.314934) (xy 1.566333 1.312334) (xy 1.539858 1.350512) (xy 1.526760 1.450763) (xy 1.526407 1.591658) (xy 1.538170 1.751770) + (xy 1.561418 1.909670) (xy 1.587078 2.017374) (xy 1.640079 2.156093) (xy 1.703847 2.269747) (xy 1.735245 2.306785) (xy 1.815501 2.414565) (xy 1.822929 2.510612) (xy 1.769348 2.581441) + (xy 1.666577 2.613567) (xy 1.526436 2.593503) (xy 1.494241 2.581751) (xy 1.372315 2.491423) (xy 1.256817 2.326733) (xy 1.152741 2.097972) (xy 1.065077 1.815432) (xy 1.017631 1.599140) + (xy 0.987706 1.448727) (xy 0.959458 1.361534) (xy 0.919471 1.317470) (xy 0.854331 1.296445) (xy 0.810322 1.288658) (xy 0.651793 1.256491) (xy 0.492960 1.210307) (xy 0.312602 1.142549) + (xy 0.089496 1.045659) (xy -0.042333 0.985039) (xy -0.444500 0.797841) (xy -0.550333 0.933665) (xy -0.628843 1.029847) (xy -0.742590 1.163688) (xy -0.870090 1.309994) (xy -0.901613 1.345586) + (xy -1.031332 1.499174) (xy -1.152837 1.656165) (xy -1.243535 1.787093) (xy -1.256365 1.808199) (xy -1.365671 1.994715) (xy -1.246148 2.119470) (xy -1.172034 2.209818) (xy -1.159570 2.268637) + (xy -1.175787 2.293387) (xy -1.247251 2.314200) (xy -1.358554 2.302027) (xy -1.476055 2.265945) (xy -1.566115 2.215030) (xy -1.593120 2.180787) (xy -1.598682 2.110543) (xy -1.590846 1.985835) + (xy -1.574361 1.855073) (xy -1.555150 1.715071) (xy -1.545422 1.612946) (xy -1.546859 1.572815) (xy -1.574003 1.592658) (xy -1.618307 1.669722) (xy -1.669518 1.781120) (xy -1.717383 1.903965) + (xy -1.751649 2.015370) (xy -1.757883 2.043871) (xy -1.764752 2.182874) (xy -1.718943 2.313659) (xy -1.697427 2.352069) (xy -1.638417 2.476223) (xy -1.642234 2.549614) (xy -1.710746 2.580238) + (xy -1.751241 2.582334) (xy -1.881706 2.553314) (xy -1.971130 2.461210) (xy -2.025788 2.298456) (xy -2.035706 2.239265) (xy -2.066528 1.957055) (xy -2.067105 1.725819) (xy -2.034844 1.516510) + (xy -1.967154 1.300080) (xy -1.947334 1.248834) (xy -1.871797 1.034273) (xy -1.832446 0.847993) (xy -1.820386 0.646607) (xy -1.820333 0.629369) (xy -1.822383 0.474010) (xy -1.831430 0.387519) + (xy -1.851818 0.354141) (xy -1.887894 0.358119) (xy -1.894417 0.360748) (xy -2.086069 0.409478) (xy -2.295263 0.412598) (xy -2.490285 0.372792) (xy -2.632739 0.298310) (xy -2.729125 0.220260) + (xy -2.539313 0.169751) (xy -2.234310 0.054161) (xy -1.924709 -0.126054) (xy -1.635300 -0.356118) (xy -1.597784 -0.391485) (xy -1.472877 -0.510946) (xy -1.368143 -0.603127) (xy -1.270135 -0.671846) + (xy -1.165407 -0.720924) (xy -1.040512 -0.754179) (xy -0.882003 -0.775431) (xy -0.676433 -0.788499) (xy -0.410356 -0.797204) (xy -0.147108 -0.803540) (xy 0.785284 -0.825500) (xy 1.060883 -0.961260) + (xy 1.214941 -1.045187) (xy 1.350946 -1.133226) (xy 1.437203 -1.204233) (xy 1.501707 -1.279909) (xy 1.510838 -1.329665) (xy 1.469418 -1.387124) (xy 1.464251 -1.392854) (xy 1.391970 -1.453962) + (xy 1.270705 -1.538555) (xy 1.125593 -1.629193) (xy 1.113062 -1.636560) (xy 0.877870 -1.801893) (xy 0.720122 -1.976194) (xy 0.642789 -2.155750) (xy 0.635000 -2.233655) (xy 0.647304 -2.334217) + (xy 0.660516 -2.349500) (xy 1.481667 -2.349500) (xy 1.503146 -2.296813) (xy 1.527175 -2.294114) (xy 1.570912 -2.337818) (xy 1.572683 -2.349500) (xy 1.539726 -2.399137) (xy 1.527175 -2.404886) + (xy 1.488574 -2.384451) (xy 1.481667 -2.349500) (xy 0.660516 -2.349500) (xy 0.694069 -2.388309) (xy 0.790069 -2.402306) (xy 0.950079 -2.382580) (xy 0.971440 -2.378768) (xy 1.101729 -2.358900) + (xy 1.188949 -2.365700) (xy 1.270145 -2.409254) (xy 1.366415 -2.486316) (xy 1.477606 -2.572303) (xy 1.563870 -2.611486) (xy 1.661284 -2.615773) (xy 1.733469 -2.607464) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/logo600dpi.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/logo600dpi.kicad_mod.REMOVED.git-id deleted file mode 100644 index 90900aa2..00000000 --- a/PCB/labralogo.pretty/logo600dpi.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -d126832310a6fe78c235e9aefafc5ade33710815 \ No newline at end of file diff --git a/PCB/labralogo.pretty/logo800dpi.kicad_mod b/PCB/labralogo.pretty/logo800dpi.kicad_mod new file mode 100644 index 00000000..b04e973c --- /dev/null +++ b/PCB/labralogo.pretty/logo800dpi.kicad_mod @@ -0,0 +1,34 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy 1.300101 -1.955599) (xy 1.446523 -1.921512) (xy 1.598775 -1.863080) (xy 1.738746 -1.789516) (xy 1.848326 -1.710034) (xy 1.901062 -1.649843) (xy 1.937895 -1.559705) (xy 1.972343 -1.419853) + (xy 2.001050 -1.244063) (xy 2.002296 -1.234407) (xy 2.021133 -0.974785) (xy 2.008538 -0.717660) (xy 1.962310 -0.449504) (xy 1.880246 -0.156789) (xy 1.782364 0.117045) (xy 1.703808 0.323046) + (xy 1.645421 0.484308) (xy 1.603738 0.615033) (xy 1.575297 0.729420) (xy 1.556634 0.841670) (xy 1.544287 0.965983) (xy 1.534791 1.116561) (xy 1.533701 1.136650) (xy 1.526091 1.294027) + (xy 1.524407 1.402112) (xy 1.530243 1.474964) (xy 1.545194 1.526645) (xy 1.570855 1.571213) (xy 1.585264 1.591266) (xy 1.634976 1.681866) (xy 1.628672 1.742915) (xy 1.566546 1.773918) + (xy 1.512773 1.778000) (xy 1.418335 1.761210) (xy 1.354913 1.702580) (xy 1.352858 1.699486) (xy 1.311970 1.611809) (xy 1.271410 1.483589) (xy 1.236746 1.337567) (xy 1.213540 1.196482) + (xy 1.206969 1.103312) (xy 1.199187 1.026761) (xy 1.180479 0.986200) (xy 1.174750 0.984250) (xy 1.154893 1.012884) (xy 1.145069 1.088072) (xy 1.144805 1.193743) (xy 1.153627 1.313827) + (xy 1.171063 1.432252) (xy 1.190308 1.513030) (xy 1.230059 1.617069) (xy 1.277885 1.702310) (xy 1.301433 1.730088) (xy 1.361626 1.810923) (xy 1.367197 1.882959) (xy 1.327011 1.936080) + (xy 1.249932 1.960174) (xy 1.144827 1.945127) (xy 1.120680 1.936312) (xy 1.029236 1.868567) (xy 0.942613 1.745049) (xy 0.864555 1.573478) (xy 0.798808 1.361573) (xy 0.763223 1.199354) + (xy 0.740779 1.086545) (xy 0.719593 1.021150) (xy 0.689603 0.988102) (xy 0.640748 0.972333) (xy 0.607741 0.966493) (xy 0.488844 0.942368) (xy 0.369720 0.907730) (xy 0.234451 0.856911) + (xy 0.067122 0.784244) (xy -0.031750 0.738779) (xy -0.333375 0.598380) (xy -0.412750 0.700248) (xy -0.471633 0.772384) (xy -0.556943 0.872766) (xy -0.652568 0.982495) (xy -0.676210 1.009189) + (xy -0.773500 1.124380) (xy -0.864628 1.242123) (xy -0.932651 1.340319) (xy -0.942274 1.356149) (xy -1.024253 1.496036) (xy -0.934611 1.589602) (xy -0.879026 1.657363) (xy -0.869678 1.701477) + (xy -0.881841 1.720040) (xy -0.935439 1.735649) (xy -1.018916 1.726519) (xy -1.107042 1.699458) (xy -1.174587 1.661272) (xy -1.194840 1.635590) (xy -1.199012 1.582907) (xy -1.193135 1.489376) + (xy -1.180771 1.391304) (xy -1.166363 1.286303) (xy -1.159067 1.209709) (xy -1.160145 1.179610) (xy -1.180503 1.194493) (xy -1.213731 1.252291) (xy -1.252139 1.335839) (xy -1.288038 1.427973) + (xy -1.313737 1.511527) (xy -1.318412 1.532903) (xy -1.323565 1.637155) (xy -1.289207 1.735244) (xy -1.273071 1.764051) (xy -1.228813 1.857166) (xy -1.231676 1.912210) (xy -1.283060 1.935178) + (xy -1.313431 1.936750) (xy -1.411280 1.914985) (xy -1.478348 1.845907) (xy -1.519341 1.723841) (xy -1.526780 1.679448) (xy -1.549896 1.467790) (xy -1.550329 1.294364) (xy -1.526133 1.137382) + (xy -1.475366 0.975059) (xy -1.460501 0.936625) (xy -1.403848 0.775704) (xy -1.374335 0.635994) (xy -1.365290 0.484955) (xy -1.365250 0.472026) (xy -1.366788 0.355507) (xy -1.373573 0.290639) + (xy -1.388864 0.265605) (xy -1.415921 0.268588) (xy -1.420813 0.270561) (xy -1.564552 0.307108) (xy -1.721448 0.309448) (xy -1.867714 0.279593) (xy -1.974554 0.223732) (xy -2.046844 0.165194) + (xy -1.904485 0.127312) (xy -1.675733 0.040620) (xy -1.443532 -0.094541) (xy -1.226476 -0.267089) (xy -1.198338 -0.293614) (xy -1.104658 -0.383210) (xy -1.026107 -0.452346) (xy -0.952602 -0.503885) + (xy -0.874056 -0.540693) (xy -0.780385 -0.565635) (xy -0.661503 -0.581574) (xy -0.507325 -0.591375) (xy -0.307767 -0.597904) (xy -0.110331 -0.602656) (xy 0.588963 -0.619125) (xy 0.795662 -0.720945) + (xy 0.911205 -0.783891) (xy 1.013209 -0.849920) (xy 1.077902 -0.903175) (xy 1.126280 -0.959932) (xy 1.133128 -0.997249) (xy 1.102063 -1.040344) (xy 1.098188 -1.044641) (xy 1.043977 -1.090472) + (xy 0.953029 -1.153917) (xy 0.844195 -1.221895) (xy 0.834796 -1.227421) (xy 0.658402 -1.351420) (xy 0.540091 -1.482146) (xy 0.482091 -1.616813) (xy 0.476250 -1.675242) (xy 0.485478 -1.750663) + (xy 0.495387 -1.762125) (xy 1.111250 -1.762125) (xy 1.127359 -1.722610) (xy 1.145381 -1.720586) (xy 1.178184 -1.753364) (xy 1.179512 -1.762125) (xy 1.154794 -1.799353) (xy 1.145381 -1.803665) + (xy 1.116430 -1.788339) (xy 1.111250 -1.762125) (xy 0.495387 -1.762125) (xy 0.520551 -1.791232) (xy 0.592551 -1.801730) (xy 0.712559 -1.786936) (xy 0.728579 -1.784076) (xy 0.826296 -1.769176) + (xy 0.891712 -1.774276) (xy 0.952609 -1.806941) (xy 1.024811 -1.864737) (xy 1.108204 -1.929228) (xy 1.172902 -1.958615) (xy 1.245963 -1.961831) (xy 1.300101 -1.955599) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/logo800dpi.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/logo800dpi.kicad_mod.REMOVED.git-id deleted file mode 100644 index df45c42a..00000000 --- a/PCB/labralogo.pretty/logo800dpi.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -b04e973c0c79ab9719bd2a467a1994ef255ab8ad \ No newline at end of file diff --git a/PCB/labralogo.pretty/logo_edit.png b/PCB/labralogo.pretty/logo_edit.png new file mode 100644 index 00000000..e9c498a4 Binary files /dev/null and b/PCB/labralogo.pretty/logo_edit.png differ diff --git a/PCB/labralogo.pretty/logo_edit.png.REMOVED.git-id b/PCB/labralogo.pretty/logo_edit.png.REMOVED.git-id deleted file mode 100644 index a148c8fc..00000000 --- a/PCB/labralogo.pretty/logo_edit.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e9c498a44eb279e3aa8dc1f0d19dc887af0eac8a \ No newline at end of file diff --git a/PCB/labralogo.pretty/logo_edit_wit_128.png b/PCB/labralogo.pretty/logo_edit_wit_128.png new file mode 100644 index 00000000..1476e774 Binary files /dev/null and b/PCB/labralogo.pretty/logo_edit_wit_128.png differ diff --git a/PCB/labralogo.pretty/logo_edit_wit_128.png.REMOVED.git-id b/PCB/labralogo.pretty/logo_edit_wit_128.png.REMOVED.git-id deleted file mode 100644 index e913f445..00000000 --- a/PCB/labralogo.pretty/logo_edit_wit_128.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -1476e774e092a2753bd37d3935e03a86ab73e2bd \ No newline at end of file diff --git a/PCB/labralogo.pretty/logorush.kicad_mod b/PCB/labralogo.pretty/logorush.kicad_mod new file mode 100644 index 00000000..36851429 --- /dev/null +++ b/PCB/labralogo.pretty/logorush.kicad_mod @@ -0,0 +1,46 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy -7.792412 0.976030) (xy -7.459295 1.101831) (xy -6.976995 1.180893) (xy -6.447013 1.207370) (xy -5.970851 1.175419) (xy -5.683251 1.097472) (xy -5.567584 1.064559) (xy -5.500716 1.138002) + (xy -5.469584 1.364275) (xy -5.461124 1.789850) (xy -5.461001 1.888106) (xy -5.492023 2.501074) (xy -5.602881 3.058784) (xy -5.820258 3.691395) (xy -5.842000 3.746499) (xy -6.069399 4.412113) + (xy -6.188805 5.037266) (xy -6.207997 5.709103) (xy -6.134748 6.514770) (xy -6.107119 6.717794) (xy -5.968947 7.269398) (xy -5.731741 7.602701) (xy -5.376676 7.740403) (xy -5.253722 7.747000) + (xy -4.977524 7.695127) (xy -4.897415 7.523520) (xy -5.007787 7.208189) (xy -5.092282 7.056205) (xy -5.275147 6.646039) (xy -5.292439 6.249643) (xy -5.273648 6.131613) (xy -5.189639 5.821836) + (xy -5.055347 5.456564) (xy -4.901530 5.104455) (xy -4.758947 4.834171) (xy -4.658355 4.714368) (xy -4.640577 4.718443) (xy -4.637340 4.856715) (xy -4.668954 5.174339) (xy -4.723082 5.565219) + (xy -4.777591 6.011205) (xy -4.796258 6.369337) (xy -4.779360 6.542360) (xy -4.608206 6.708821) (xy -4.293555 6.847290) (xy -3.936328 6.930535) (xy -3.637447 6.931328) (xy -3.527362 6.880161) + (xy -3.474420 6.732480) (xy -3.594864 6.518804) (xy -3.738443 6.358409) (xy -4.097012 5.984145) (xy -3.769094 5.424596) (xy -3.524554 5.058989) (xy -3.173582 4.596930) (xy -2.783960 4.126809) + (xy -2.704839 4.036756) (xy -2.322101 3.600304) (xy -1.964493 3.182336) (xy -1.696476 2.858440) (xy -1.651000 2.800993) (xy -1.333500 2.393521) (xy -0.127000 2.955116) (xy 0.628715 3.297066) + (xy 1.224884 3.540475) (xy 1.725175 3.708016) (xy 2.193255 3.822359) (xy 2.430967 3.865974) (xy 2.676754 3.917298) (xy 2.827817 4.008883) (xy 2.924399 4.201002) (xy 3.006744 4.553929) + (xy 3.052893 4.797419) (xy 3.274109 5.736622) (xy 3.554688 6.535364) (xy 3.879655 7.162769) (xy 4.234034 7.587961) (xy 4.482722 7.745251) (xy 4.422459 7.770126) (xy 4.122826 7.792785) + (xy 3.598444 7.812941) (xy 2.863936 7.830308) (xy 1.933923 7.844599) (xy 0.823027 7.855530) (xy -0.454129 7.862812) (xy -1.682750 7.865949) (xy -8.128000 7.874000) (xy -8.128000 0.756144) + (xy -7.792412 0.976030) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 8.057190 -2.452679) (xy 8.075141 -2.239572) (xy 8.088741 -1.872982) (xy 8.098735 -1.335155) (xy 8.105872 -0.608335) (xy 8.110899 0.325232) (xy 8.114564 1.483301) (xy 8.116603 2.381250) + (xy 8.128000 7.874000) (xy 6.635750 7.863973) (xy 6.072618 7.855123) (xy 5.633823 7.838371) (xy 5.362163 7.816092) (xy 5.300437 7.790666) (xy 5.302250 7.789890) (xy 5.440349 7.617952) + (xy 5.439503 7.336113) (xy 5.310304 7.039786) (xy 5.205734 6.920354) (xy 5.020679 6.664472) (xy 4.837445 6.273851) (xy 4.761234 6.052120) (xy 4.665963 5.628121) (xy 4.603675 5.147418) + (xy 4.576259 4.674295) (xy 4.585609 4.273035) (xy 4.633614 4.007922) (xy 4.699000 3.937000) (xy 4.781096 4.049205) (xy 4.825458 4.327422) (xy 4.827877 4.413250) (xy 4.868633 4.897457) + (xy 4.972846 5.473417) (xy 5.118256 6.050168) (xy 5.282605 6.536746) (xy 5.411435 6.797945) (xy 5.662501 7.039520) (xy 6.033939 7.111920) (xy 6.051092 7.112000) (xy 6.414411 7.050730) + (xy 6.554838 6.868246) (xy 6.471602 6.566537) (xy 6.341058 6.365067) (xy 6.218449 6.181938) (xy 6.141367 5.994065) (xy 6.103433 5.745207) (xy 6.098269 5.379124) (xy 6.119496 4.839577) + (xy 6.134806 4.546603) (xy 6.172476 3.926760) (xy 6.220005 3.419077) (xy 6.291294 2.966474) (xy 6.400245 2.511870) (xy 6.560758 1.998182) (xy 6.786736 1.368331) (xy 7.092078 0.565234) + (xy 7.125616 0.478123) (xy 7.380772 -0.225300) (xy 7.616571 -0.949197) (xy 7.806976 -1.608976) (xy 7.925952 -2.120042) (xy 7.926921 -2.125377) (xy 7.969753 -2.348652) (xy 8.005243 -2.489464) + (xy 8.034140 -2.530058) (xy 8.057190 -2.452679) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 4.083190 -7.445534) (xy 3.767458 -7.197206) (xy 3.526805 -7.086432) (xy 3.245869 -7.082691) (xy 2.914319 -7.136304) (xy 2.411291 -7.205102) (xy 2.105004 -7.174761) (xy 1.951130 -7.026164) + (xy 1.905341 -6.740192) (xy 1.904999 -6.700967) (xy 2.030513 -6.158944) (xy 2.401108 -5.627896) (xy 3.007867 -5.118964) (xy 3.339185 -4.909682) (xy 3.777107 -4.638632) (xy 4.149846 -4.381301) + (xy 4.381998 -4.190016) (xy 4.392754 -4.178564) (xy 4.528133 -4.000202) (xy 4.512976 -3.852743) (xy 4.332817 -3.635321) (xy 4.311610 -3.612699) (xy 4.042722 -3.392468) (xy 3.631893 -3.127893) + (xy 3.182649 -2.883780) (xy 2.355853 -2.476500) (xy -0.441324 -2.410622) (xy -1.411960 -2.386827) (xy -2.169212 -2.359058) (xy -2.753578 -2.315661) (xy -3.205556 -2.244986) (xy -3.565647 -2.135379) + (xy -3.874348 -1.975189) (xy -4.172159 -1.752763) (xy -4.499580 -1.456449) (xy -4.816999 -1.151673) (xy -5.422726 -0.644278) (xy -6.132059 -0.168916) (xy -6.864914 0.228030) (xy -7.541212 0.500171) + (xy -7.778750 0.563866) (xy -8.128000 0.639839) (xy -8.128000 -7.874000) (xy 4.596031 -7.874000) (xy 4.083190 -7.445534) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 8.128000 -6.223000) (xy 8.124485 -5.608820) (xy 8.114869 -5.098239) (xy 8.100541 -4.738414) (xy 8.082895 -4.576499) (xy 8.079295 -4.572000) (xy 8.041914 -4.687264) (xy 7.992097 -4.988323) + (xy 7.944393 -5.376894) (xy 7.859047 -5.876331) (xy 7.727759 -6.333035) (xy 7.617080 -6.578271) (xy 7.270111 -6.953221) (xy 6.715473 -7.310338) (xy 5.999294 -7.621581) (xy 5.778500 -7.695928) + (xy 5.575872 -7.765185) (xy 5.505426 -7.811560) (xy 5.594150 -7.840024) (xy 5.869036 -7.855548) (xy 6.357074 -7.863104) (xy 6.699250 -7.865505) (xy 8.128000 -7.874000) (xy 8.128000 -6.223000) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 4.712736 -7.083546) (xy 4.718050 -7.048500) (xy 4.619177 -6.899589) (xy 4.581525 -6.882342) (xy 4.465721 -6.943648) (xy 4.445000 -7.048500) (xy 4.509439 -7.206561) (xy 4.581525 -7.214659) + (xy 4.712736 -7.083546) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/logorush.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/logorush.kicad_mod.REMOVED.git-id deleted file mode 100644 index 0f5b96a2..00000000 --- a/PCB/labralogo.pretty/logorush.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -36851429e5deb59cbe1ba461566b6ad0d1752f61 \ No newline at end of file diff --git a/PCB/labralogo.pretty/oshw-logo-100-px - Notext.png b/PCB/labralogo.pretty/oshw-logo-100-px - Notext.png new file mode 100644 index 00000000..ee98837d Binary files /dev/null and b/PCB/labralogo.pretty/oshw-logo-100-px - Notext.png differ diff --git a/PCB/labralogo.pretty/oshw-logo-100-px - Notext.png.REMOVED.git-id b/PCB/labralogo.pretty/oshw-logo-100-px - Notext.png.REMOVED.git-id deleted file mode 100644 index 5e2ad964..00000000 --- a/PCB/labralogo.pretty/oshw-logo-100-px - Notext.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ee98837db702ce260984d30f8205f727d13de5fe \ No newline at end of file diff --git a/PCB/labralogo.pretty/oshw-logo-100-px.png b/PCB/labralogo.pretty/oshw-logo-100-px.png new file mode 100644 index 00000000..421001fa Binary files /dev/null and b/PCB/labralogo.pretty/oshw-logo-100-px.png differ diff --git a/PCB/labralogo.pretty/oshw-logo-100-px.png.REMOVED.git-id b/PCB/labralogo.pretty/oshw-logo-100-px.png.REMOVED.git-id deleted file mode 100644 index a2ff28c4..00000000 --- a/PCB/labralogo.pretty/oshw-logo-100-px.png.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -421001fabedb5b539a8e04a157f7de454805e213 \ No newline at end of file diff --git a/PCB/labralogo.pretty/oshw600dpi.kicad_mod b/PCB/labralogo.pretty/oshw600dpi.kicad_mod new file mode 100644 index 00000000..03f98d5f --- /dev/null +++ b/PCB/labralogo.pretty/oshw600dpi.kicad_mod @@ -0,0 +1,100 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy -1.428750 1.024149) (xy -1.315511 1.036901) (xy -1.261371 1.068620) (xy -1.240856 1.142338) (xy -1.235518 1.198871) (xy -1.244812 1.347000) (xy -1.295460 1.442146) (xy -1.379519 1.471695) + (xy -1.404626 1.467407) (xy -1.459905 1.469677) (xy -1.480267 1.529233) (xy -1.481666 1.572795) (xy -1.470061 1.654110) (xy -1.441201 1.673289) (xy -1.440208 1.672708) (xy -1.374023 1.670300) + (xy -1.313208 1.692865) (xy -1.260980 1.755202) (xy -1.229862 1.856738) (xy -1.221321 1.969274) (xy -1.236823 2.064616) (xy -1.277834 2.114564) (xy -1.291166 2.116667) (xy -1.337622 2.085331) + (xy -1.354436 1.984563) (xy -1.354666 1.964972) (xy -1.370387 1.860154) (xy -1.406480 1.829080) (xy -1.446342 1.869328) (xy -1.473370 1.978478) (xy -1.473765 1.982344) (xy -1.501246 2.082833) + (xy -1.547849 2.116667) (xy -1.577040 2.099800) (xy -1.596232 2.040335) (xy -1.607542 1.924972) (xy -1.613087 1.740414) (xy -1.613577 1.703917) (xy -1.617401 1.538526) (xy -1.623821 1.419883) + (xy -1.631831 1.362034) (xy -1.637842 1.365221) (xy -1.693834 1.435181) (xy -1.791995 1.469145) (xy -1.894095 1.457665) (xy -1.928812 1.437138) (xy -1.976323 1.345695) (xy -1.979783 1.249112) + (xy -1.861271 1.249112) (xy -1.841912 1.316896) (xy -1.833808 1.327081) (xy -1.794143 1.329079) (xy -1.764285 1.279414) (xy -1.763203 1.249437) (xy -1.465511 1.249437) (xy -1.437179 1.322379) + (xy -1.392471 1.354667) (xy -1.364044 1.318412) (xy -1.354666 1.248834) (xy -1.373204 1.164987) (xy -1.416624 1.143686) (xy -1.458139 1.181513) (xy -1.465511 1.249437) (xy -1.763203 1.249437) + (xy -1.761806 1.210734) (xy -1.765279 1.199756) (xy -1.807339 1.148072) (xy -1.824862 1.143000) (xy -1.854887 1.176734) (xy -1.861271 1.249112) (xy -1.979783 1.249112) (xy -1.981179 1.210161) + (xy -1.967195 1.099085) (xy -1.933056 1.046629) (xy -1.857705 1.026749) (xy -1.830555 1.023874) (xy -1.726352 1.027102) (xy -1.669921 1.073754) (xy -1.653321 1.108541) (xy -1.614033 1.206500) + (xy -1.611350 1.108816) (xy -1.600900 1.047963) (xy -1.558507 1.022628) (xy -1.460830 1.021989) (xy -1.428750 1.024149) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy -0.878777 1.712101) (xy -0.836731 1.753746) (xy -0.816030 1.823533) (xy -0.805343 1.936428) (xy -0.804981 1.957917) (xy -0.809018 2.059261) (xy -0.838412 2.104495) (xy -0.917411 2.116260) + (xy -0.974995 2.116667) (xy -1.110739 2.099966) (xy -1.170024 2.053167) (xy -1.175163 1.967246) (xy -1.040557 1.967246) (xy -1.037166 1.989667) (xy -1.000956 2.030008) (xy -0.994833 2.032000) + (xy -0.961176 2.002474) (xy -0.952500 1.989667) (xy -0.962553 1.953802) (xy -0.994833 1.947334) (xy -1.040557 1.967246) (xy -1.175163 1.967246) (xy -1.176369 1.947092) (xy -1.113423 1.878375) + (xy -1.035997 1.862667) (xy -0.961802 1.849050) (xy -0.953564 1.818611) (xy -1.010843 1.792958) (xy -1.058333 1.799167) (xy -1.138129 1.801037) (xy -1.162838 1.760033) (xy -1.119752 1.704408) + (xy -1.104919 1.695609) (xy -0.989569 1.673709) (xy -0.878777 1.712101) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy -0.150720 1.508246) (xy -0.134135 1.586702) (xy -0.127362 1.736885) (xy -0.127000 1.798195) (xy -0.127000 2.121778) (xy -0.285750 2.108639) (xy -0.390646 2.093085) (xy -0.438213 2.052275) + (xy -0.455778 1.959567) (xy -0.457367 1.941311) (xy -0.463056 1.905000) (xy -0.338666 1.905000) (xy -0.320938 1.973790) (xy -0.296333 1.989667) (xy -0.261938 1.954211) (xy -0.254000 1.905000) + (xy -0.271728 1.836210) (xy -0.296333 1.820334) (xy -0.330728 1.855790) (xy -0.338666 1.905000) (xy -0.463056 1.905000) (xy -0.473220 1.840143) (xy -0.506643 1.804201) (xy -0.552617 1.808665) + (xy -0.613312 1.850894) (xy -0.634540 1.947991) (xy -0.635000 1.973438) (xy -0.649770 2.081054) (xy -0.696365 2.116631) (xy -0.698500 2.116667) (xy -0.737000 2.095552) (xy -0.756696 2.021579) + (xy -0.762000 1.886665) (xy -0.759916 1.754654) (xy -0.745854 1.686675) (xy -0.708099 1.662094) (xy -0.634935 1.660276) (xy -0.633490 1.660317) (xy -0.535613 1.673617) (xy -0.482754 1.699933) + (xy -0.433488 1.711298) (xy -0.378431 1.691959) (xy -0.312842 1.670187) (xy -0.292113 1.681261) (xy -0.279775 1.672566) (xy -0.259196 1.611805) (xy -0.218503 1.526766) (xy -0.178749 1.491861) + (xy -0.150720 1.508246) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 0.504720 1.669709) (xy 0.508000 1.694823) (xy 0.534045 1.717007) (xy 0.589600 1.694975) (xy 0.704266 1.673644) (xy 0.814838 1.712338) (xy 0.856602 1.753746) (xy 0.877168 1.823342) + (xy 0.887931 1.936563) (xy 0.888352 1.960351) (xy 0.889000 2.121535) (xy 0.709084 2.108518) (xy 0.595234 2.094506) (xy 0.542995 2.064401) (xy 0.529317 2.003027) (xy 0.529167 1.990083) + (xy 0.534647 1.967246) (xy 0.652776 1.967246) (xy 0.656167 1.989667) (xy 0.692377 2.030008) (xy 0.698500 2.032000) (xy 0.732157 2.002474) (xy 0.740834 1.989667) (xy 0.730781 1.953802) + (xy 0.698500 1.947334) (xy 0.652776 1.967246) (xy 0.534647 1.967246) (xy 0.548781 1.908359) (xy 0.623091 1.865634) (xy 0.656167 1.857508) (xy 0.744130 1.834124) (xy 0.750276 1.817574) + (xy 0.673412 1.805844) (xy 0.623538 1.802312) (xy 0.543032 1.809235) (xy 0.494540 1.857417) (xy 0.458088 1.955937) (xy 0.404689 2.066639) (xy 0.339223 2.117021) (xy 0.278715 2.101946) + (xy 0.241152 2.021417) (xy 0.222415 1.926167) (xy 0.190937 2.021417) (xy 0.140286 2.105964) (xy 0.078156 2.113778) (xy 0.015830 2.049678) (xy -0.033553 1.925559) (xy -0.070294 1.777889) + (xy -0.081761 1.694135) (xy -0.068424 1.657555) (xy -0.041285 1.651000) (xy 0.003631 1.686070) (xy 0.048427 1.767417) (xy 0.094759 1.883834) (xy 0.136280 1.765300) (xy 0.187175 1.678774) + (xy 0.242487 1.674246) (xy 0.290559 1.750588) (xy 0.299809 1.781139) (xy 0.326786 1.883834) (xy 0.374012 1.767417) (xy 0.422320 1.686155) (xy 0.472586 1.649958) (xy 0.504720 1.669709) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 1.059843 1.660317) (xy 1.157721 1.673617) (xy 1.210579 1.699933) (xy 1.259845 1.711298) (xy 1.314903 1.691959) (xy 1.423353 1.674670) (xy 1.523641 1.723257) (xy 1.592190 1.820344) + (xy 1.608667 1.908463) (xy 1.571578 1.936652) (xy 1.481266 1.953101) (xy 1.471084 1.953676) (xy 1.384543 1.958876) (xy 1.378880 1.965478) (xy 1.449917 1.977655) (xy 1.537548 2.011299) + (xy 1.566334 2.058534) (xy 1.542636 2.100422) (xy 1.460592 2.111612) (xy 1.407584 2.108639) (xy 1.302688 2.093085) (xy 1.255121 2.052275) (xy 1.237555 1.959567) (xy 1.235967 1.941311) + (xy 1.220113 1.840143) (xy 1.201693 1.820334) (xy 1.375834 1.820334) (xy 1.379190 1.859343) (xy 1.394502 1.862667) (xy 1.437611 1.831937) (xy 1.439334 1.820334) (xy 1.424890 1.779101) + (xy 1.420665 1.778000) (xy 1.384522 1.807665) (xy 1.375834 1.820334) (xy 1.201693 1.820334) (xy 1.186690 1.804201) (xy 1.140717 1.808665) (xy 1.080021 1.850894) (xy 1.058794 1.947991) + (xy 1.058334 1.973438) (xy 1.043563 2.081054) (xy 0.996968 2.116631) (xy 0.994834 2.116667) (xy 0.956334 2.095552) (xy 0.936637 2.021579) (xy 0.931334 1.886665) (xy 0.933417 1.754654) + (xy 0.947479 1.686675) (xy 0.985234 1.662094) (xy 1.058398 1.660276) (xy 1.059843 1.660317) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy -0.931710 1.030047) (xy -0.851808 1.091525) (xy -0.848156 1.097884) (xy -0.808373 1.200576) (xy -0.833277 1.254069) (xy -0.928650 1.269981) (xy -0.933832 1.270000) (xy -1.016201 1.280523) + (xy -1.040803 1.306083) (xy -1.039623 1.308359) (xy -0.984870 1.330261) (xy -0.931291 1.324589) (xy -0.860933 1.328006) (xy -0.846666 1.366367) (xy -0.881509 1.437206) (xy -0.964408 1.474544) + (xy -1.062919 1.471110) (xy -1.134533 1.430867) (xy -1.170969 1.354417) (xy -1.185333 1.248834) (xy -1.172373 1.157111) (xy -1.044222 1.157111) (xy -1.038411 1.182278) (xy -1.016000 1.185334) + (xy -0.981155 1.169844) (xy -0.987778 1.157111) (xy -1.038017 1.152045) (xy -1.044222 1.157111) (xy -1.172373 1.157111) (xy -1.169844 1.139218) (xy -1.134533 1.066800) (xy -1.039224 1.020364) + (xy -0.931710 1.030047) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy -0.444500 1.037167) (xy -0.431704 1.259417) (xy -0.428976 1.392977) (xy -0.443513 1.460976) (xy -0.479628 1.481525) (xy -0.484621 1.481667) (xy -0.529776 1.456187) (xy -0.548746 1.369549) + (xy -0.550333 1.312334) (xy -0.561823 1.196898) (xy -0.590872 1.145108) (xy -0.629349 1.165178) (xy -0.651637 1.209963) (xy -0.672312 1.305606) (xy -0.677333 1.379296) (xy -0.692270 1.457181) + (xy -0.719666 1.481667) (xy -0.742741 1.443368) (xy -0.758117 1.344477) (xy -0.762000 1.246278) (xy -0.762000 1.010889) (xy -0.444500 1.037167) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 0.695311 1.052767) (xy 0.725324 1.152599) (xy 0.727695 1.174750) (xy 0.746132 1.276870) (xy 0.775362 1.330925) (xy 0.783167 1.333500) (xy 0.813498 1.296054) (xy 0.835596 1.203221) + (xy 0.838639 1.174750) (xy 0.863862 1.056629) (xy 0.912430 1.016001) (xy 0.912722 1.016000) (xy 0.949934 1.039558) (xy 0.968960 1.119873) (xy 0.973667 1.248834) (xy 0.971457 1.381951) + (xy 0.957431 1.451240) (xy 0.920496 1.477533) (xy 0.849691 1.481667) (xy 0.728091 1.454769) (xy 0.632600 1.387748) (xy 0.592103 1.301118) (xy 0.592043 1.298726) (xy 0.576276 1.294222) + (xy 0.539108 1.352610) (xy 0.538066 1.354667) (xy 0.460166 1.444395) (xy 0.363681 1.473495) (xy 0.275288 1.437222) (xy 0.249763 1.405947) (xy 0.208290 1.350887) (xy 0.168774 1.358340) + (xy 0.120732 1.403269) (xy 0.021152 1.471541) (xy -0.081959 1.463549) (xy -0.137583 1.435943) (xy -0.206183 1.376965) (xy -0.197588 1.335800) (xy -0.119078 1.324556) (xy -0.074083 1.330345) + (xy 0.011895 1.344327) (xy 0.020358 1.338519) (xy -0.041138 1.310433) (xy -0.148386 1.243928) (xy 0.315806 1.243928) (xy 0.327473 1.287028) (xy 0.385907 1.311248) (xy 0.420253 1.261947) + (xy 0.423334 1.227667) (xy 0.407484 1.158848) (xy 0.385529 1.143000) (xy 0.339109 1.176774) (xy 0.315806 1.243928) (xy -0.148386 1.243928) (xy -0.153541 1.240732) (xy -0.185664 1.157955) + (xy -0.163567 1.089892) (xy -0.099070 1.031804) (xy 0.013396 1.024111) (xy 0.112368 1.049712) (xy 0.134564 1.090572) (xy 0.077546 1.132461) (xy 0.034249 1.145775) (xy -0.028333 1.163947) + (xy -0.016599 1.177488) (xy 0.055974 1.193406) (xy 0.148922 1.197408) (xy 0.199918 1.148059) (xy 0.214697 1.113863) (xy 0.259452 1.041515) (xy 0.336741 1.020909) (xy 0.389893 1.023899) + (xy 0.496721 1.052893) (xy 0.549495 1.125088) (xy 0.555033 1.143000) (xy 0.584227 1.248834) (xy 0.588447 1.132417) (xy 0.609351 1.037349) (xy 0.650813 1.012575) (xy 0.695311 1.052767) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 1.513417 1.027910) (xy 2.010834 1.037167) (xy 2.024229 1.153584) (xy 2.022559 1.238033) (xy 1.975425 1.267586) (xy 1.928979 1.270000) (xy 1.848083 1.283983) (xy 1.820334 1.311834) + (xy 1.855486 1.340950) (xy 1.910917 1.343584) (xy 1.990722 1.356152) (xy 2.019758 1.384856) (xy 2.001683 1.431453) (xy 1.931765 1.461849) (xy 1.842324 1.469069) (xy 1.765680 1.446139) + (xy 1.758990 1.441123) (xy 1.680566 1.413231) (xy 1.614156 1.436396) (xy 1.528979 1.472803) (xy 1.487474 1.481667) (xy 1.409308 1.445177) (xy 1.343043 1.357393) (xy 1.312518 1.250841) + (xy 1.312334 1.242706) (xy 1.308337 1.223443) (xy 1.439334 1.223443) (xy 1.455927 1.308140) (xy 1.519724 1.339246) (xy 1.584779 1.339454) (xy 1.661672 1.312414) (xy 1.677603 1.244398) + (xy 1.642883 1.179299) (xy 1.591941 1.157111) (xy 1.834445 1.157111) (xy 1.840256 1.182278) (xy 1.862667 1.185334) (xy 1.897512 1.169844) (xy 1.890889 1.157111) (xy 1.840649 1.152045) + (xy 1.834445 1.157111) (xy 1.591941 1.157111) (xy 1.570478 1.147763) (xy 1.493214 1.152676) (xy 1.443915 1.196925) (xy 1.439334 1.223443) (xy 1.308337 1.223443) (xy 1.295987 1.163939) + (xy 1.239351 1.150627) (xy 1.238250 1.150832) (xy 1.180381 1.195938) (xy 1.152202 1.310367) (xy 1.151028 1.323269) (xy 1.125776 1.441142) (xy 1.077173 1.481666) (xy 1.076945 1.481667) + (xy 1.039638 1.458000) (xy 1.020622 1.377372) (xy 1.016000 1.250160) (xy 1.016000 1.018654) (xy 1.513417 1.027910) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 0.148235 -2.114193) (xy 0.223703 -2.094515) (xy 0.266964 -2.039249) (xy 0.297409 -1.930009) (xy 0.316419 -1.836764) (xy 0.377283 -1.709813) (xy 0.448571 -1.656848) (xy 0.541379 -1.620257) + (xy 0.614473 -1.617033) (xy 0.698539 -1.652688) (xy 0.806884 -1.721212) (xy 0.976952 -1.833758) (xy 1.123476 -1.691741) (xy 1.225463 -1.580564) (xy 1.261715 -1.491991) (xy 1.234913 -1.398747) + (xy 1.162655 -1.292948) (xy 1.096743 -1.199804) (xy 1.078397 -1.133393) (xy 1.102698 -1.054010) (xy 1.126686 -1.002536) (xy 1.181050 -0.908963) (xy 1.248879 -0.858425) (xy 1.361552 -0.830746) + (xy 1.403364 -0.824625) (xy 1.608667 -0.796388) (xy 1.608667 -0.304278) (xy 1.402139 -0.275873) (xy 1.274554 -0.252471) (xy 1.201834 -0.213890) (xy 1.154353 -0.139531) (xy 1.133363 -0.089001) + (xy 1.097065 0.018189) (xy 1.100898 0.089969) (xy 1.150340 0.168176) (xy 1.170348 0.193483) (xy 1.246871 0.309607) (xy 1.259405 0.405187) (xy 1.205105 0.504349) (xy 1.123476 0.591075) + (xy 0.976952 0.733092) (xy 0.805233 0.619454) (xy 0.687307 0.550932) (xy 0.606689 0.532589) (xy 0.552160 0.549356) (xy 0.511259 0.570707) (xy 0.480578 0.574068) (xy 0.451137 0.547080) + (xy 0.413952 0.477386) (xy 0.360043 0.352626) (xy 0.294933 0.195436) (xy 0.228801 0.033520) (xy 0.192705 -0.068835) (xy 0.184227 -0.130265) (xy 0.200949 -0.169410) (xy 0.240451 -0.204906) + (xy 0.242744 -0.206731) (xy 0.364184 -0.346707) (xy 0.419063 -0.508009) (xy 0.404904 -0.670036) (xy 0.319231 -0.812182) (xy 0.315920 -0.815534) (xy 0.157347 -0.926361) (xy -0.007911 -0.954092) + (xy -0.171517 -0.898956) (xy -0.292268 -0.798944) (xy -0.367256 -0.661832) (xy -0.374564 -0.502056) (xy -0.317770 -0.342679) (xy -0.200450 -0.206763) (xy -0.200410 -0.206731) (xy -0.159932 -0.170959) + (xy -0.142124 -0.132383) (xy -0.149407 -0.072367) (xy -0.184198 0.027728) (xy -0.248915 0.186538) (xy -0.252600 0.195436) (xy -0.327604 0.376270) (xy -0.378318 0.491605) (xy -0.413750 0.553783) + (xy -0.442909 0.575148) (xy -0.474802 0.568043) (xy -0.510599 0.548942) (xy -0.581173 0.531323) (xy -0.666870 0.560272) (xy -0.750690 0.612328) (xy -0.850681 0.676938) (xy -0.919362 0.715189) + (xy -0.932856 0.719667) (xy -0.974168 0.691936) (xy -1.050828 0.621775) (xy -1.092362 0.580068) (xy -1.189729 0.464322) (xy -1.220277 0.371159) (xy -1.186418 0.274425) (xy -1.128014 0.193483) + (xy -1.066383 0.107184) (xy -1.051723 0.037715) (xy -1.078556 -0.056765) (xy -1.091030 -0.089001) (xy -1.136817 -0.186141) (xy -1.194533 -0.238247) (xy -1.293804 -0.265920) (xy -1.359805 -0.275873) + (xy -1.566333 -0.304278) (xy -1.566333 -0.796388) (xy -1.361030 -0.824625) (xy -1.231022 -0.849608) (xy -1.154260 -0.892046) (xy -1.099367 -0.972116) (xy -1.084352 -1.002536) (xy -1.042183 -1.101086) + (xy -1.040412 -1.168504) (xy -1.083957 -1.244493) (xy -1.120322 -1.292948) (xy -1.199656 -1.412341) (xy -1.218261 -1.503399) (xy -1.173456 -1.593399) (xy -1.081142 -1.691741) (xy -0.934618 -1.833758) + (xy -0.764550 -1.721212) (xy -0.645114 -1.646495) (xy -0.563843 -1.615542) (xy -0.490053 -1.622841) (xy -0.406238 -1.656848) (xy -0.308855 -1.745340) (xy -0.274085 -1.836764) (xy -0.242276 -1.984908) + (xy -0.208683 -2.068621) (xy -0.153914 -2.106288) (xy -0.058576 -2.116294) (xy 0.021167 -2.116666) (xy 0.148235 -2.114193) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/oshw600dpi.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/oshw600dpi.kicad_mod.REMOVED.git-id deleted file mode 100644 index 1959d2fe..00000000 --- a/PCB/labralogo.pretty/oshw600dpi.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -03f98d5fbdf938673f46a5801d336be60940e87d \ No newline at end of file diff --git a/PCB/labralogo.pretty/oshw700dpi.kicad_mod b/PCB/labralogo.pretty/oshw700dpi.kicad_mod new file mode 100644 index 00000000..4fdd1b3b --- /dev/null +++ b/PCB/labralogo.pretty/oshw700dpi.kicad_mod @@ -0,0 +1,100 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy -1.224643 0.877842) (xy -1.127581 0.888773) (xy -1.081175 0.915960) (xy -1.063591 0.979147) (xy -1.059016 1.027604) (xy -1.066981 1.154571) (xy -1.110394 1.236125) (xy -1.182445 1.261453) + (xy -1.203965 1.257777) (xy -1.251347 1.259723) (xy -1.268800 1.310771) (xy -1.270000 1.348110) (xy -1.260053 1.417809) (xy -1.235315 1.434248) (xy -1.234464 1.433749) (xy -1.177734 1.431686) + (xy -1.125607 1.451027) (xy -1.080840 1.504459) (xy -1.054167 1.591490) (xy -1.046846 1.687950) (xy -1.060134 1.769671) (xy -1.095286 1.812484) (xy -1.106714 1.814286) (xy -1.146533 1.787426) + (xy -1.160945 1.701054) (xy -1.161143 1.684262) (xy -1.174618 1.594418) (xy -1.205555 1.567783) (xy -1.239722 1.602282) (xy -1.262889 1.695838) (xy -1.263228 1.699152) (xy -1.286783 1.785286) + (xy -1.326728 1.814286) (xy -1.351749 1.799829) (xy -1.368199 1.748858) (xy -1.377893 1.649976) (xy -1.382646 1.491784) (xy -1.383066 1.460500) (xy -1.386344 1.318737) (xy -1.391847 1.217043) + (xy -1.398713 1.167458) (xy -1.403865 1.170190) (xy -1.451858 1.230155) (xy -1.535996 1.259267) (xy -1.623510 1.249427) (xy -1.653268 1.231833) (xy -1.693991 1.153453) (xy -1.696956 1.070668) + (xy -1.595375 1.070668) (xy -1.578782 1.128768) (xy -1.571836 1.137498) (xy -1.537837 1.139211) (xy -1.512244 1.096641) (xy -1.511317 1.070946) (xy -1.256152 1.070946) (xy -1.231868 1.133468) + (xy -1.193546 1.161143) (xy -1.169181 1.130068) (xy -1.161143 1.070429) (xy -1.177032 0.998560) (xy -1.214249 0.980303) (xy -1.249833 1.012726) (xy -1.256152 1.070946) (xy -1.511317 1.070946) + (xy -1.510120 1.037772) (xy -1.513096 1.028362) (xy -1.549148 0.984062) (xy -1.564168 0.979714) (xy -1.589904 1.008630) (xy -1.595375 1.070668) (xy -1.696956 1.070668) (xy -1.698153 1.037281) + (xy -1.686167 0.942073) (xy -1.656905 0.897111) (xy -1.592318 0.880071) (xy -1.569047 0.877607) (xy -1.479730 0.880373) (xy -1.431361 0.920361) (xy -1.417133 0.950178) (xy -1.383457 1.034143) + (xy -1.381157 0.950414) (xy -1.372200 0.898254) (xy -1.335863 0.876538) (xy -1.252140 0.875991) (xy -1.224643 0.877842) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy -0.753237 1.467515) (xy -0.717198 1.503211) (xy -0.699454 1.563029) (xy -0.690294 1.659796) (xy -0.689984 1.678214) (xy -0.693444 1.765081) (xy -0.718639 1.803853) (xy -0.786353 1.813937) + (xy -0.835710 1.814286) (xy -0.952062 1.799971) (xy -1.002878 1.759857) (xy -1.007283 1.686211) (xy -0.891906 1.686211) (xy -0.889000 1.705429) (xy -0.857963 1.740007) (xy -0.852714 1.741714) + (xy -0.823865 1.716407) (xy -0.816429 1.705429) (xy -0.825045 1.674688) (xy -0.852714 1.669143) (xy -0.891906 1.686211) (xy -1.007283 1.686211) (xy -1.008317 1.668936) (xy -0.954363 1.610036) + (xy -0.887997 1.596572) (xy -0.824402 1.584900) (xy -0.817341 1.558810) (xy -0.866437 1.536821) (xy -0.907143 1.542143) (xy -0.975539 1.543746) (xy -0.996719 1.508600) (xy -0.959788 1.460921) + (xy -0.947073 1.453379) (xy -0.848202 1.434608) (xy -0.753237 1.467515) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy -0.129189 1.292783) (xy -0.114973 1.360030) (xy -0.109168 1.488759) (xy -0.108857 1.541310) (xy -0.108857 1.818667) (xy -0.244929 1.807405) (xy -0.334839 1.794073) (xy -0.375611 1.759093) + (xy -0.390667 1.679629) (xy -0.392029 1.663981) (xy -0.396905 1.632857) (xy -0.290286 1.632857) (xy -0.275090 1.691820) (xy -0.254000 1.705429) (xy -0.224518 1.675038) (xy -0.217714 1.632857) + (xy -0.232910 1.573894) (xy -0.254000 1.560286) (xy -0.283481 1.590677) (xy -0.290286 1.632857) (xy -0.396905 1.632857) (xy -0.405617 1.577265) (xy -0.434266 1.546458) (xy -0.473672 1.550284) + (xy -0.525696 1.586481) (xy -0.543891 1.669707) (xy -0.544286 1.691518) (xy -0.556946 1.783760) (xy -0.596884 1.814256) (xy -0.598714 1.814286) (xy -0.631714 1.796188) (xy -0.648597 1.732782) + (xy -0.653143 1.617141) (xy -0.651357 1.503989) (xy -0.639304 1.445722) (xy -0.606942 1.424652) (xy -0.544230 1.423094) (xy -0.542992 1.423129) (xy -0.459097 1.434529) (xy -0.413789 1.457086) + (xy -0.371561 1.466827) (xy -0.324369 1.450250) (xy -0.268150 1.431589) (xy -0.250383 1.441081) (xy -0.239807 1.433628) (xy -0.222168 1.381548) (xy -0.187288 1.308657) (xy -0.153213 1.278738) + (xy -0.129189 1.292783) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 0.432617 1.431179) (xy 0.435429 1.452705) (xy 0.457753 1.471721) (xy 0.505371 1.452836) (xy 0.603656 1.434552) (xy 0.698432 1.467718) (xy 0.734230 1.503211) (xy 0.751858 1.562865) + (xy 0.761084 1.659911) (xy 0.761444 1.680301) (xy 0.762000 1.818459) (xy 0.607786 1.807301) (xy 0.510200 1.795291) (xy 0.465425 1.769486) (xy 0.453701 1.716881) (xy 0.453572 1.705785) + (xy 0.458269 1.686211) (xy 0.559523 1.686211) (xy 0.562429 1.705429) (xy 0.593466 1.740007) (xy 0.598714 1.741714) (xy 0.627563 1.716407) (xy 0.635000 1.705429) (xy 0.626383 1.674688) + (xy 0.598714 1.669143) (xy 0.559523 1.686211) (xy 0.458269 1.686211) (xy 0.470383 1.635737) (xy 0.534078 1.599115) (xy 0.562429 1.592150) (xy 0.637826 1.572106) (xy 0.643093 1.557921) + (xy 0.577210 1.547866) (xy 0.534461 1.544839) (xy 0.465456 1.550773) (xy 0.423891 1.592072) (xy 0.392646 1.676518) (xy 0.346876 1.771405) (xy 0.290763 1.814589) (xy 0.238898 1.801668) + (xy 0.206702 1.732643) (xy 0.190642 1.651000) (xy 0.163660 1.732643) (xy 0.120245 1.805112) (xy 0.066991 1.811810) (xy 0.013569 1.756867) (xy -0.028760 1.650479) (xy -0.060252 1.523905) + (xy -0.070081 1.452116) (xy -0.058649 1.420761) (xy -0.035388 1.415143) (xy 0.003113 1.445203) (xy 0.041509 1.514929) (xy 0.081222 1.614714) (xy 0.116811 1.513115) (xy 0.160436 1.438949) + (xy 0.207846 1.435068) (xy 0.249051 1.500504) (xy 0.256979 1.526690) (xy 0.280102 1.614714) (xy 0.320582 1.514929) (xy 0.361989 1.445276) (xy 0.405074 1.414250) (xy 0.432617 1.431179) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 0.908437 1.423129) (xy 0.992332 1.434529) (xy 1.037639 1.457086) (xy 1.079867 1.466827) (xy 1.127059 1.450250) (xy 1.220016 1.435431) (xy 1.305978 1.477077) (xy 1.364735 1.560295) + (xy 1.378857 1.635825) (xy 1.347067 1.659988) (xy 1.269657 1.674086) (xy 1.260929 1.674580) (xy 1.186751 1.679037) (xy 1.181897 1.684696) (xy 1.242786 1.695133) (xy 1.317898 1.723970) + (xy 1.342571 1.764458) (xy 1.322259 1.800362) (xy 1.251936 1.809953) (xy 1.206500 1.807405) (xy 1.116589 1.794073) (xy 1.075818 1.759093) (xy 1.060762 1.679629) (xy 1.059400 1.663981) + (xy 1.045811 1.577265) (xy 1.030022 1.560286) (xy 1.179286 1.560286) (xy 1.182163 1.593723) (xy 1.195287 1.596572) (xy 1.232238 1.570231) (xy 1.233714 1.560286) (xy 1.221334 1.524944) + (xy 1.217713 1.524000) (xy 1.186733 1.549427) (xy 1.179286 1.560286) (xy 1.030022 1.560286) (xy 1.017163 1.546458) (xy 0.977757 1.550284) (xy 0.925733 1.586481) (xy 0.907537 1.669707) + (xy 0.907143 1.691518) (xy 0.894482 1.783760) (xy 0.854544 1.814256) (xy 0.852714 1.814286) (xy 0.819715 1.796188) (xy 0.802832 1.732782) (xy 0.798286 1.617141) (xy 0.800072 1.503989) + (xy 0.812125 1.445722) (xy 0.844487 1.424652) (xy 0.907198 1.423094) (xy 0.908437 1.423129) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy -0.798609 0.882897) (xy -0.730121 0.935593) (xy -0.726991 0.941043) (xy -0.692891 1.029065) (xy -0.714237 1.074916) (xy -0.795986 1.088555) (xy -0.800427 1.088572) (xy -0.871030 1.097591) + (xy -0.892117 1.119500) (xy -0.891105 1.121451) (xy -0.844174 1.140224) (xy -0.798250 1.135362) (xy -0.737942 1.138291) (xy -0.725714 1.171172) (xy -0.755580 1.231891) (xy -0.826636 1.263895) + (xy -0.911074 1.260951) (xy -0.972457 1.226457) (xy -1.003688 1.160929) (xy -1.016000 1.070429) (xy -1.004891 0.991810) (xy -0.895048 0.991810) (xy -0.890067 1.013382) (xy -0.870857 1.016000) + (xy -0.840990 1.002724) (xy -0.846667 0.991810) (xy -0.889729 0.987467) (xy -0.895048 0.991810) (xy -1.004891 0.991810) (xy -1.002723 0.976473) (xy -0.972457 0.914400) (xy -0.890763 0.874598) + (xy -0.798609 0.882897) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy -0.517071 0.877738) (xy -0.381000 0.889000) (xy -0.370032 1.079500) (xy -0.367693 1.193980) (xy -0.380154 1.252266) (xy -0.411110 1.269878) (xy -0.415389 1.270000) (xy -0.454094 1.248161) + (xy -0.470354 1.173899) (xy -0.471714 1.124857) (xy -0.481563 1.025913) (xy -0.506461 0.981521) (xy -0.539442 0.998724) (xy -0.558546 1.037111) (xy -0.576268 1.119091) (xy -0.580571 1.182254) + (xy -0.593374 1.249013) (xy -0.616857 1.270000) (xy -0.636635 1.237173) (xy -0.649814 1.152409) (xy -0.653143 1.068238) (xy -0.653143 0.866477) (xy -0.517071 0.877738) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 0.595981 0.902372) (xy 0.621706 0.987942) (xy 0.623738 1.006929) (xy 0.639542 1.094460) (xy 0.664596 1.140793) (xy 0.671286 1.143000) (xy 0.697284 1.110904) (xy 0.716225 1.031332) + (xy 0.718833 1.006929) (xy 0.740453 0.905682) (xy 0.782083 0.870858) (xy 0.782333 0.870857) (xy 0.814229 0.891049) (xy 0.830537 0.959891) (xy 0.834572 1.070429) (xy 0.832677 1.184530) + (xy 0.820655 1.243920) (xy 0.788996 1.266457) (xy 0.728306 1.270000) (xy 0.624078 1.246945) (xy 0.542228 1.189499) (xy 0.507517 1.115244) (xy 0.507465 1.113194) (xy 0.493951 1.109333) + (xy 0.462093 1.159380) (xy 0.461200 1.161143) (xy 0.394428 1.238053) (xy 0.311727 1.262996) (xy 0.235961 1.231905) (xy 0.214082 1.205097) (xy 0.178534 1.157903) (xy 0.144663 1.164291) + (xy 0.103484 1.202802) (xy 0.018130 1.261321) (xy -0.070251 1.254470) (xy -0.117929 1.230808) (xy -0.176728 1.180255) (xy -0.169361 1.144972) (xy -0.102067 1.135334) (xy -0.063500 1.140296) + (xy 0.010196 1.152280) (xy 0.017450 1.147302) (xy -0.035261 1.123229) (xy -0.127189 1.066224) (xy 0.270691 1.066224) (xy 0.280691 1.103167) (xy 0.330777 1.123927) (xy 0.360217 1.081669) + (xy 0.362857 1.052286) (xy 0.349272 0.993298) (xy 0.330454 0.979714) (xy 0.290665 1.008663) (xy 0.270691 1.066224) (xy -0.127189 1.066224) (xy -0.131606 1.063485) (xy -0.159141 0.992533) + (xy -0.140200 0.934193) (xy -0.084917 0.884404) (xy 0.011482 0.877810) (xy 0.096315 0.899753) (xy 0.115341 0.934776) (xy 0.066468 0.970681) (xy 0.029356 0.982093) (xy -0.024286 0.997669) + (xy -0.014228 1.009275) (xy 0.047978 1.022919) (xy 0.127647 1.026350) (xy 0.171358 0.984051) (xy 0.184026 0.954740) (xy 0.222388 0.892727) (xy 0.288635 0.875065) (xy 0.334194 0.877628) + (xy 0.425760 0.902480) (xy 0.470996 0.964361) (xy 0.475743 0.979714) (xy 0.500766 1.070429) (xy 0.504383 0.970643) (xy 0.522301 0.889157) (xy 0.557839 0.867922) (xy 0.595981 0.902372) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 1.723571 0.889000) (xy 1.735053 0.988786) (xy 1.733622 1.061171) (xy 1.693222 1.086502) (xy 1.653410 1.088572) (xy 1.584071 1.100557) (xy 1.560286 1.124430) (xy 1.590416 1.149386) + (xy 1.637929 1.151644) (xy 1.706333 1.162416) (xy 1.731221 1.187019) (xy 1.715728 1.226960) (xy 1.655798 1.253014) (xy 1.579135 1.259202) (xy 1.513440 1.239548) (xy 1.507705 1.235248) + (xy 1.440485 1.211341) (xy 1.383562 1.231196) (xy 1.310553 1.262403) (xy 1.274977 1.270000) (xy 1.207978 1.238724) (xy 1.151180 1.163480) (xy 1.125015 1.072149) (xy 1.124857 1.065176) + (xy 1.121431 1.048665) (xy 1.233714 1.048665) (xy 1.247937 1.121263) (xy 1.302620 1.147925) (xy 1.358382 1.148104) (xy 1.424290 1.124926) (xy 1.437945 1.066627) (xy 1.408185 1.010828) + (xy 1.364522 0.991810) (xy 1.572381 0.991810) (xy 1.577362 1.013382) (xy 1.596571 1.016000) (xy 1.626439 1.002724) (xy 1.620762 0.991810) (xy 1.577699 0.987467) (xy 1.572381 0.991810) + (xy 1.364522 0.991810) (xy 1.346124 0.983797) (xy 1.279898 0.988008) (xy 1.237641 1.025936) (xy 1.233714 1.048665) (xy 1.121431 1.048665) (xy 1.110846 0.997662) (xy 1.062301 0.986252) + (xy 1.061357 0.986427) (xy 1.011755 1.025090) (xy 0.987602 1.123171) (xy 0.986595 1.134231) (xy 0.964951 1.235265) (xy 0.923291 1.270000) (xy 0.923095 1.270000) (xy 0.891118 1.249714) + (xy 0.874819 1.180605) (xy 0.870857 1.071566) (xy 0.870857 0.873132) (xy 1.723571 0.889000) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 0.127059 -1.812165) (xy 0.191746 -1.795298) (xy 0.228826 -1.747927) (xy 0.254922 -1.654294) (xy 0.271216 -1.574369) (xy 0.323386 -1.465554) (xy 0.384490 -1.420155) (xy 0.464039 -1.388791) + (xy 0.526691 -1.386028) (xy 0.598748 -1.416589) (xy 0.691614 -1.475325) (xy 0.837387 -1.571793) (xy 0.962979 -1.450064) (xy 1.050396 -1.354769) (xy 1.081470 -1.278850) (xy 1.058497 -1.198926) + (xy 0.996562 -1.108241) (xy 0.940066 -1.028403) (xy 0.924340 -0.971479) (xy 0.945170 -0.903437) (xy 0.965731 -0.859317) (xy 1.012328 -0.779111) (xy 1.070468 -0.735793) (xy 1.167044 -0.712068) + (xy 1.202883 -0.706821) (xy 1.378857 -0.682618) (xy 1.378857 -0.260810) (xy 1.201833 -0.236463) (xy 1.092474 -0.216404) (xy 1.030143 -0.183334) (xy 0.989445 -0.119598) (xy 0.971454 -0.076287) + (xy 0.940341 0.015591) (xy 0.943626 0.077116) (xy 0.986006 0.144151) (xy 1.003155 0.165843) (xy 1.068747 0.265377) (xy 1.079490 0.347303) (xy 1.032947 0.432299) (xy 0.962979 0.506636) + (xy 0.837387 0.628364) (xy 0.690200 0.530961) (xy 0.589120 0.472227) (xy 0.520019 0.456505) (xy 0.473280 0.470877) (xy 0.438222 0.489178) (xy 0.411924 0.492059) (xy 0.386688 0.468926) + (xy 0.354816 0.409188) (xy 0.308608 0.302251) (xy 0.252800 0.167516) (xy 0.196115 0.028731) (xy 0.165175 -0.059001) (xy 0.157909 -0.111656) (xy 0.172242 -0.145209) (xy 0.206101 -0.175634) + (xy 0.208066 -0.177198) (xy 0.312158 -0.297177) (xy 0.359197 -0.435437) (xy 0.347061 -0.574316) (xy 0.273626 -0.696156) (xy 0.270789 -0.699029) (xy 0.134869 -0.794024) (xy -0.006781 -0.817793) + (xy -0.147015 -0.770533) (xy -0.250515 -0.684809) (xy -0.314791 -0.567284) (xy -0.321055 -0.430334) (xy -0.272374 -0.293725) (xy -0.171814 -0.177225) (xy -0.171780 -0.177198) (xy -0.137084 -0.146536) + (xy -0.121821 -0.113471) (xy -0.128063 -0.062029) (xy -0.157884 0.023767) (xy -0.213356 0.159890) (xy -0.216514 0.167516) (xy -0.280804 0.322518) (xy -0.324273 0.421376) (xy -0.354643 0.474671) + (xy -0.379636 0.492984) (xy -0.406974 0.486894) (xy -0.437657 0.470522) (xy -0.498148 0.455420) (xy -0.571603 0.480234) (xy -0.643449 0.524853) (xy -0.729155 0.580233) (xy -0.788025 0.613020) + (xy -0.799591 0.616857) (xy -0.835001 0.593088) (xy -0.900710 0.532950) (xy -0.936310 0.497201) (xy -1.019768 0.397990) (xy -1.045952 0.318137) (xy -1.016929 0.235222) (xy -0.966869 0.165843) + (xy -0.914042 0.091872) (xy -0.901477 0.032327) (xy -0.924477 -0.048656) (xy -0.935168 -0.076287) (xy -0.974415 -0.159549) (xy -1.023885 -0.204212) (xy -1.108975 -0.227932) (xy -1.165547 -0.236463) + (xy -1.342571 -0.260810) (xy -1.342571 -0.682618) (xy -1.166597 -0.706821) (xy -1.055162 -0.728235) (xy -0.989366 -0.764611) (xy -0.942314 -0.833242) (xy -0.929445 -0.859317) (xy -0.893299 -0.943788) + (xy -0.891782 -1.001574) (xy -0.929106 -1.066708) (xy -0.960276 -1.108241) (xy -1.028277 -1.210578) (xy -1.044224 -1.288628) (xy -1.005819 -1.365770) (xy -0.926693 -1.450064) (xy -0.801101 -1.571793) + (xy -0.655329 -1.475325) (xy -0.552955 -1.411282) (xy -0.483294 -1.384751) (xy -0.420045 -1.391007) (xy -0.348204 -1.420155) (xy -0.264733 -1.496006) (xy -0.234930 -1.574369) (xy -0.207665 -1.701350) + (xy -0.178872 -1.773104) (xy -0.131927 -1.805390) (xy -0.050208 -1.813966) (xy 0.018143 -1.814285) (xy 0.127059 -1.812165) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/oshw700dpi.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/oshw700dpi.kicad_mod.REMOVED.git-id deleted file mode 100644 index 30f06529..00000000 --- a/PCB/labralogo.pretty/oshw700dpi.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4fdd1b3b63a1cbd81168b04090d08136a145ec3c \ No newline at end of file diff --git a/PCB/labralogo.pretty/oshw800dpi.kicad_mod b/PCB/labralogo.pretty/oshw800dpi.kicad_mod new file mode 100644 index 00000000..e96d7f79 --- /dev/null +++ b/PCB/labralogo.pretty/oshw800dpi.kicad_mod @@ -0,0 +1,100 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy -1.071563 0.768111) (xy -0.986634 0.777675) (xy -0.946029 0.801465) (xy -0.930643 0.856753) (xy -0.926639 0.899153) (xy -0.933609 1.010249) (xy -0.971596 1.081609) (xy -1.034640 1.103771) + (xy -1.053470 1.100554) (xy -1.094929 1.102257) (xy -1.110201 1.146924) (xy -1.111250 1.179596) (xy -1.102547 1.240582) (xy -1.080901 1.254966) (xy -1.080157 1.254530) (xy -1.030518 1.252725) + (xy -0.984907 1.269648) (xy -0.945736 1.316401) (xy -0.922397 1.392553) (xy -0.915991 1.476955) (xy -0.927618 1.548461) (xy -0.958376 1.585922) (xy -0.968375 1.587500) (xy -1.003217 1.563997) + (xy -1.015828 1.488422) (xy -1.016000 1.473729) (xy -1.027791 1.395115) (xy -1.054861 1.371809) (xy -1.084757 1.401996) (xy -1.105028 1.483858) (xy -1.105325 1.486757) (xy -1.125935 1.562124) + (xy -1.160887 1.587500) (xy -1.182781 1.574849) (xy -1.197175 1.530250) (xy -1.205657 1.443728) (xy -1.209816 1.305310) (xy -1.210184 1.277937) (xy -1.213051 1.153894) (xy -1.217866 1.064912) + (xy -1.223874 1.021525) (xy -1.228382 1.023915) (xy -1.270376 1.076385) (xy -1.343997 1.101858) (xy -1.420572 1.093248) (xy -1.446610 1.077853) (xy -1.482243 1.009270) (xy -1.484838 0.936833) + (xy -1.395954 0.936833) (xy -1.381435 0.987671) (xy -1.375357 0.995310) (xy -1.345608 0.996809) (xy -1.323214 0.959560) (xy -1.322403 0.937077) (xy -1.099134 0.937077) (xy -1.077885 0.991784) + (xy -1.044354 1.016000) (xy -1.023034 0.988809) (xy -1.016000 0.936625) (xy -1.029903 0.873739) (xy -1.062468 0.857764) (xy -1.093605 0.886134) (xy -1.099134 0.937077) (xy -1.322403 0.937077) + (xy -1.321355 0.908050) (xy -1.323960 0.899816) (xy -1.355505 0.861054) (xy -1.368647 0.857250) (xy -1.391166 0.882550) (xy -1.395954 0.936833) (xy -1.484838 0.936833) (xy -1.485885 0.907620) + (xy -1.475397 0.824313) (xy -1.449793 0.784971) (xy -1.393279 0.770061) (xy -1.372917 0.767905) (xy -1.294765 0.770326) (xy -1.252442 0.805315) (xy -1.239992 0.831405) (xy -1.210526 0.904875) + (xy -1.208513 0.831611) (xy -1.200676 0.785971) (xy -1.168881 0.766970) (xy -1.095623 0.766491) (xy -1.071563 0.768111) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy -0.659083 1.284075) (xy -0.627549 1.315309) (xy -0.612023 1.367649) (xy -0.604008 1.452321) (xy -0.603737 1.468437) (xy -0.606764 1.544445) (xy -0.628810 1.578370) (xy -0.688059 1.587194) + (xy -0.731247 1.587500) (xy -0.833055 1.574974) (xy -0.877519 1.539875) (xy -0.881373 1.475434) (xy -0.780418 1.475434) (xy -0.777875 1.492250) (xy -0.750718 1.522505) (xy -0.746125 1.524000) + (xy -0.720883 1.501855) (xy -0.714375 1.492250) (xy -0.721915 1.465351) (xy -0.746125 1.460500) (xy -0.780418 1.475434) (xy -0.881373 1.475434) (xy -0.882278 1.460319) (xy -0.835068 1.408780) + (xy -0.776998 1.397000) (xy -0.721352 1.386787) (xy -0.715174 1.363958) (xy -0.758133 1.344718) (xy -0.793750 1.349375) (xy -0.853597 1.350777) (xy -0.872129 1.320024) (xy -0.839815 1.278306) + (xy -0.828690 1.271706) (xy -0.742177 1.255281) (xy -0.659083 1.284075) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy -0.113041 1.131184) (xy -0.100602 1.190026) (xy -0.095522 1.302663) (xy -0.095250 1.348645) (xy -0.095250 1.591333) (xy -0.214313 1.581479) (xy -0.292985 1.569813) (xy -0.328660 1.539206) + (xy -0.341834 1.469674) (xy -0.343026 1.455982) (xy -0.347293 1.428750) (xy -0.254000 1.428750) (xy -0.240704 1.480342) (xy -0.222250 1.492250) (xy -0.196454 1.465657) (xy -0.190500 1.428750) + (xy -0.203797 1.377157) (xy -0.222250 1.365250) (xy -0.248047 1.391842) (xy -0.254000 1.428750) (xy -0.347293 1.428750) (xy -0.354916 1.380106) (xy -0.379983 1.353150) (xy -0.414463 1.356498) + (xy -0.459985 1.388170) (xy -0.475905 1.460993) (xy -0.476250 1.480078) (xy -0.487328 1.560790) (xy -0.522274 1.587473) (xy -0.523875 1.587500) (xy -0.552750 1.571663) (xy -0.567523 1.516184) + (xy -0.571500 1.414998) (xy -0.569938 1.315990) (xy -0.559391 1.265006) (xy -0.531075 1.246570) (xy -0.476202 1.245206) (xy -0.475118 1.245237) (xy -0.401710 1.255212) (xy -0.362066 1.274949) + (xy -0.325117 1.283473) (xy -0.283824 1.268968) (xy -0.234632 1.252640) (xy -0.219086 1.260945) (xy -0.209832 1.254424) (xy -0.194397 1.208853) (xy -0.163878 1.145074) (xy -0.134062 1.118895) + (xy -0.113041 1.131184) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 0.378540 1.252281) (xy 0.381000 1.271117) (xy 0.400533 1.287755) (xy 0.442199 1.271230) (xy 0.528199 1.255232) (xy 0.611128 1.284253) (xy 0.642451 1.315309) (xy 0.657875 1.367506) + (xy 0.665948 1.452421) (xy 0.666263 1.470263) (xy 0.666750 1.591151) (xy 0.531812 1.581388) (xy 0.446425 1.570879) (xy 0.407246 1.548300) (xy 0.396987 1.502270) (xy 0.396875 1.492561) + (xy 0.400985 1.475434) (xy 0.489582 1.475434) (xy 0.492125 1.492250) (xy 0.519282 1.522505) (xy 0.523875 1.524000) (xy 0.549117 1.501855) (xy 0.555625 1.492250) (xy 0.548085 1.465351) + (xy 0.523875 1.460500) (xy 0.489582 1.475434) (xy 0.400985 1.475434) (xy 0.411585 1.431269) (xy 0.467318 1.399225) (xy 0.492125 1.393130) (xy 0.558097 1.375592) (xy 0.562706 1.363180) + (xy 0.505058 1.354382) (xy 0.467653 1.351733) (xy 0.407273 1.356925) (xy 0.370904 1.393062) (xy 0.343565 1.466952) (xy 0.303516 1.549978) (xy 0.254417 1.587765) (xy 0.209036 1.576459) + (xy 0.180863 1.516062) (xy 0.166811 1.444625) (xy 0.143202 1.516062) (xy 0.105214 1.579472) (xy 0.058616 1.585333) (xy 0.011872 1.537258) (xy -0.025165 1.444169) (xy -0.052721 1.333416) + (xy -0.061321 1.270601) (xy -0.051319 1.243165) (xy -0.030965 1.238250) (xy 0.002723 1.264552) (xy 0.036320 1.325562) (xy 0.071069 1.412875) (xy 0.102209 1.323975) (xy 0.140381 1.259080) + (xy 0.181864 1.255684) (xy 0.217919 1.312940) (xy 0.224856 1.335853) (xy 0.245089 1.412875) (xy 0.280508 1.325562) (xy 0.316740 1.264616) (xy 0.354439 1.237468) (xy 0.378540 1.252281) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 0.794882 1.245237) (xy 0.868290 1.255212) (xy 0.907934 1.274949) (xy 0.944883 1.283473) (xy 0.986176 1.268968) (xy 1.067514 1.256002) (xy 1.142730 1.292442) (xy 1.194142 1.365258) + (xy 1.206500 1.431346) (xy 1.178683 1.452489) (xy 1.110949 1.464825) (xy 1.103312 1.465257) (xy 1.038406 1.469157) (xy 1.034159 1.474108) (xy 1.087437 1.483241) (xy 1.153160 1.508473) + (xy 1.174750 1.543900) (xy 1.156976 1.575316) (xy 1.095444 1.583708) (xy 1.055687 1.581479) (xy 0.977015 1.569813) (xy 0.941340 1.539206) (xy 0.928166 1.469674) (xy 0.926974 1.455982) + (xy 0.915084 1.380106) (xy 0.901270 1.365250) (xy 1.031875 1.365250) (xy 1.034392 1.394507) (xy 1.045876 1.397000) (xy 1.078207 1.373952) (xy 1.079500 1.365250) (xy 1.068667 1.334325) + (xy 1.065498 1.333500) (xy 1.038391 1.355748) (xy 1.031875 1.365250) (xy 0.901270 1.365250) (xy 0.890017 1.353150) (xy 0.855537 1.356498) (xy 0.810015 1.388170) (xy 0.794095 1.460993) + (xy 0.793750 1.480078) (xy 0.782672 1.560790) (xy 0.747726 1.587473) (xy 0.746125 1.587500) (xy 0.717250 1.571663) (xy 0.702477 1.516184) (xy 0.698500 1.414998) (xy 0.700062 1.315990) + (xy 0.710609 1.265006) (xy 0.738925 1.246570) (xy 0.793798 1.245206) (xy 0.794882 1.245237) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy -0.698783 0.772534) (xy -0.638857 0.818643) (xy -0.636118 0.823412) (xy -0.606281 0.900432) (xy -0.624958 0.940551) (xy -0.696488 0.952485) (xy -0.700374 0.952500) (xy -0.762152 0.960392) + (xy -0.780603 0.979561) (xy -0.779718 0.981269) (xy -0.738653 0.997695) (xy -0.698469 0.993441) (xy -0.645700 0.996004) (xy -0.635000 1.024775) (xy -0.661133 1.077904) (xy -0.723307 1.105907) + (xy -0.797190 1.103332) (xy -0.850900 1.073150) (xy -0.878227 1.015812) (xy -0.889000 0.936625) (xy -0.879280 0.867833) (xy -0.783167 0.867833) (xy -0.778809 0.886708) (xy -0.762000 0.889000) + (xy -0.735867 0.877383) (xy -0.740834 0.867833) (xy -0.778514 0.864033) (xy -0.783167 0.867833) (xy -0.879280 0.867833) (xy -0.877383 0.854413) (xy -0.850900 0.800100) (xy -0.779418 0.765273) + (xy -0.698783 0.772534) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy -0.452438 0.768020) (xy -0.333375 0.777875) (xy -0.323779 0.944562) (xy -0.321732 1.044732) (xy -0.332636 1.095732) (xy -0.359722 1.111143) (xy -0.363466 1.111250) (xy -0.397333 1.092140) + (xy -0.411560 1.027161) (xy -0.412750 0.984250) (xy -0.421368 0.897673) (xy -0.443154 0.858830) (xy -0.472012 0.873883) (xy -0.488729 0.907471) (xy -0.504235 0.979204) (xy -0.508000 1.034471) + (xy -0.519203 1.092885) (xy -0.539750 1.111250) (xy -0.557056 1.082526) (xy -0.568588 1.008357) (xy -0.571500 0.934708) (xy -0.571500 0.758166) (xy -0.452438 0.768020) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 0.521483 0.789575) (xy 0.543992 0.864449) (xy 0.545770 0.881062) (xy 0.559598 0.957652) (xy 0.581521 0.998193) (xy 0.587375 1.000125) (xy 0.610123 0.972040) (xy 0.626696 0.902415) + (xy 0.628979 0.881062) (xy 0.647896 0.792471) (xy 0.684322 0.762000) (xy 0.684541 0.762000) (xy 0.712450 0.779668) (xy 0.726719 0.839904) (xy 0.730250 0.936625) (xy 0.728592 1.036463) + (xy 0.718073 1.088429) (xy 0.690371 1.108149) (xy 0.637267 1.111250) (xy 0.546068 1.091076) (xy 0.474449 1.040811) (xy 0.444076 0.975838) (xy 0.444031 0.974044) (xy 0.432207 0.970666) + (xy 0.404330 1.014457) (xy 0.403549 1.016000) (xy 0.345124 1.083296) (xy 0.272760 1.105121) (xy 0.206465 1.077916) (xy 0.187322 1.054459) (xy 0.156217 1.013164) (xy 0.126580 1.018754) + (xy 0.090548 1.052451) (xy 0.015863 1.103655) (xy -0.061470 1.097661) (xy -0.103188 1.076956) (xy -0.154638 1.032723) (xy -0.148191 1.001850) (xy -0.089309 0.993416) (xy -0.055563 0.997758) + (xy 0.008921 1.008245) (xy 0.015268 1.003889) (xy -0.030854 0.982824) (xy -0.111292 0.932945) (xy 0.236854 0.932945) (xy 0.245604 0.965270) (xy 0.289429 0.983436) (xy 0.315189 0.946460) + (xy 0.317500 0.920750) (xy 0.305613 0.869135) (xy 0.289146 0.857250) (xy 0.254331 0.882580) (xy 0.236854 0.932945) (xy -0.111292 0.932945) (xy -0.115156 0.930549) (xy -0.139249 0.868466) + (xy -0.122676 0.817418) (xy -0.074303 0.773852) (xy 0.010046 0.768083) (xy 0.084275 0.787283) (xy 0.100922 0.817929) (xy 0.058159 0.849345) (xy 0.025686 0.859331) (xy -0.021251 0.872960) + (xy -0.012450 0.883115) (xy 0.041980 0.895054) (xy 0.111691 0.898055) (xy 0.149938 0.861044) (xy 0.161022 0.835397) (xy 0.194589 0.781135) (xy 0.252555 0.765681) (xy 0.292419 0.767924) + (xy 0.372540 0.789669) (xy 0.412121 0.843815) (xy 0.416274 0.857250) (xy 0.438170 0.936625) (xy 0.441335 0.849312) (xy 0.457013 0.778011) (xy 0.488109 0.759431) (xy 0.521483 0.789575) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 1.135062 0.770932) (xy 1.508125 0.777875) (xy 1.518171 0.865187) (xy 1.516919 0.928524) (xy 1.481568 0.950689) (xy 1.446733 0.952500) (xy 1.386062 0.962987) (xy 1.365250 0.983875) + (xy 1.391614 1.005712) (xy 1.433187 1.007688) (xy 1.493041 1.017113) (xy 1.514818 1.038641) (xy 1.501261 1.073589) (xy 1.448823 1.096386) (xy 1.381743 1.101801) (xy 1.324260 1.084604) + (xy 1.319242 1.080842) (xy 1.260424 1.059923) (xy 1.210616 1.077296) (xy 1.146733 1.104602) (xy 1.115605 1.111250) (xy 1.056980 1.083882) (xy 1.007282 1.018044) (xy 0.984388 0.938130) + (xy 0.984250 0.932029) (xy 0.981252 0.917581) (xy 1.079500 0.917581) (xy 1.091945 0.981104) (xy 1.139792 1.004434) (xy 1.188584 1.004590) (xy 1.246253 0.984310) (xy 1.258201 0.933298) + (xy 1.232161 0.884474) (xy 1.193955 0.867833) (xy 1.375833 0.867833) (xy 1.380191 0.886708) (xy 1.397000 0.889000) (xy 1.423133 0.877383) (xy 1.418166 0.867833) (xy 1.380486 0.864033) + (xy 1.375833 0.867833) (xy 1.193955 0.867833) (xy 1.177858 0.860822) (xy 1.119910 0.864507) (xy 1.082936 0.897693) (xy 1.079500 0.917581) (xy 0.981252 0.917581) (xy 0.971989 0.872953) + (xy 0.929513 0.862969) (xy 0.928687 0.863123) (xy 0.885285 0.896953) (xy 0.864151 0.982774) (xy 0.863270 0.992451) (xy 0.844332 1.080856) (xy 0.807879 1.111249) (xy 0.807708 1.111250) + (xy 0.779728 1.093499) (xy 0.765466 1.033028) (xy 0.762000 0.937620) (xy 0.762000 0.763990) (xy 1.135062 0.770932) )(layer F.SilkS) (width 0.010000) + ) + (fp_poly (pts (xy 0.111176 -1.585645) (xy 0.167777 -1.570887) (xy 0.200222 -1.529437) (xy 0.223056 -1.447508) (xy 0.237314 -1.377574) (xy 0.282962 -1.282361) (xy 0.336428 -1.242636) (xy 0.406033 -1.215193) + (xy 0.460854 -1.212775) (xy 0.523904 -1.239516) (xy 0.605162 -1.290910) (xy 0.732713 -1.375319) (xy 0.842606 -1.268807) (xy 0.919096 -1.185424) (xy 0.946286 -1.118994) (xy 0.926184 -1.049061) + (xy 0.871991 -0.969711) (xy 0.822557 -0.899853) (xy 0.808797 -0.850045) (xy 0.827023 -0.790508) (xy 0.845014 -0.751903) (xy 0.885787 -0.681723) (xy 0.936659 -0.643820) (xy 1.021163 -0.623060) + (xy 1.052522 -0.618469) (xy 1.206500 -0.597292) (xy 1.206500 -0.228209) (xy 1.051604 -0.206906) (xy 0.955915 -0.189354) (xy 0.901375 -0.160418) (xy 0.865764 -0.104649) (xy 0.850022 -0.066752) + (xy 0.822798 0.013641) (xy 0.825673 0.067476) (xy 0.862755 0.126131) (xy 0.877760 0.145112) (xy 0.935153 0.232205) (xy 0.944553 0.303889) (xy 0.903828 0.378261) (xy 0.842606 0.443306) + (xy 0.732713 0.549818) (xy 0.603924 0.464590) (xy 0.515479 0.413198) (xy 0.455016 0.399441) (xy 0.414119 0.412016) (xy 0.383443 0.428030) (xy 0.360433 0.430551) (xy 0.338352 0.410310) + (xy 0.310463 0.358039) (xy 0.270031 0.264469) (xy 0.221199 0.146576) (xy 0.171600 0.025139) (xy 0.144528 -0.051627) (xy 0.138170 -0.097700) (xy 0.150711 -0.127058) (xy 0.180338 -0.153680) + (xy 0.182057 -0.155049) (xy 0.273137 -0.260031) (xy 0.314297 -0.381008) (xy 0.303677 -0.502527) (xy 0.239423 -0.609137) (xy 0.236939 -0.611651) (xy 0.118010 -0.694771) (xy -0.005934 -0.715570) + (xy -0.128638 -0.674217) (xy -0.219202 -0.599209) (xy -0.275442 -0.496375) (xy -0.280924 -0.376543) (xy -0.238328 -0.257010) (xy -0.150338 -0.155073) (xy -0.150308 -0.155049) (xy -0.119949 -0.128220) + (xy -0.106594 -0.099288) (xy -0.112056 -0.054276) (xy -0.138149 0.020795) (xy -0.186687 0.139903) (xy -0.189450 0.146576) (xy -0.245704 0.282202) (xy -0.283739 0.368703) (xy -0.310313 0.415337) + (xy -0.332182 0.431361) (xy -0.356102 0.426032) (xy -0.382950 0.411706) (xy -0.435880 0.398491) (xy -0.500153 0.420204) (xy -0.563018 0.459245) (xy -0.638012 0.507703) (xy -0.689522 0.536391) + (xy -0.699642 0.539750) (xy -0.730626 0.518951) (xy -0.788122 0.466331) (xy -0.819272 0.435050) (xy -0.892297 0.348241) (xy -0.915208 0.278369) (xy -0.889814 0.205818) (xy -0.846011 0.145112) + (xy -0.799788 0.080388) (xy -0.788793 0.028285) (xy -0.808918 -0.042574) (xy -0.818273 -0.066752) (xy -0.852614 -0.139606) (xy -0.895900 -0.178686) (xy -0.970354 -0.199441) (xy -1.019855 -0.206906) + (xy -1.174751 -0.228209) (xy -1.174750 -0.412750) (xy -1.174750 -0.597292) (xy -1.020773 -0.618469) (xy -0.923267 -0.637206) (xy -0.865696 -0.669035) (xy -0.824526 -0.729088) (xy -0.813265 -0.751903) + (xy -0.781638 -0.825815) (xy -0.780309 -0.876378) (xy -0.812969 -0.933370) (xy -0.840242 -0.969711) (xy -0.899743 -1.059256) (xy -0.913696 -1.127550) (xy -0.880093 -1.195050) (xy -0.810857 -1.268807) + (xy -0.700964 -1.375319) (xy -0.573413 -1.290910) (xy -0.483836 -1.234872) (xy -0.422883 -1.211657) (xy -0.367540 -1.217131) (xy -0.304679 -1.242636) (xy -0.231642 -1.309006) (xy -0.205565 -1.377574) + (xy -0.181708 -1.488682) (xy -0.156513 -1.551467) (xy -0.115436 -1.579717) (xy -0.043932 -1.587221) (xy 0.015874 -1.587500) (xy 0.111176 -1.585645) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/oshw800dpi.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/oshw800dpi.kicad_mod.REMOVED.git-id deleted file mode 100644 index bcf322e3..00000000 --- a/PCB/labralogo.pretty/oshw800dpi.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e96d7f790b5b0a6f27ebafe57c2529d69d03ef7e \ No newline at end of file diff --git a/PCB/labralogo.pretty/oshwnotext400dpi.kicad_mod b/PCB/labralogo.pretty/oshwnotext400dpi.kicad_mod new file mode 100644 index 00000000..448a2280 --- /dev/null +++ b/PCB/labralogo.pretty/oshwnotext400dpi.kicad_mod @@ -0,0 +1,27 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy 0.222352 -2.218790) (xy 0.335554 -2.189273) (xy 0.400445 -2.106374) (xy 0.446113 -1.942515) (xy 0.474628 -1.802647) (xy 0.565924 -1.612221) (xy 0.672856 -1.532772) (xy 0.812067 -1.477886) + (xy 0.921709 -1.473050) (xy 1.047808 -1.526532) (xy 1.210325 -1.629319) (xy 1.465427 -1.798138) (xy 1.685213 -1.585113) (xy 1.838193 -1.418347) (xy 1.892572 -1.285488) (xy 1.852369 -1.145621) + (xy 1.743982 -0.986922) (xy 1.645114 -0.847206) (xy 1.617594 -0.747590) (xy 1.654046 -0.628515) (xy 1.690028 -0.551305) (xy 1.771574 -0.410946) (xy 1.873318 -0.335139) (xy 2.042327 -0.293619) + (xy 2.105045 -0.284438) (xy 2.413000 -0.242083) (xy 2.413000 0.496082) (xy 2.103208 0.538689) (xy 1.911830 0.573792) (xy 1.802750 0.631664) (xy 1.731528 0.743203) (xy 1.700044 0.818997) + (xy 1.645596 0.979783) (xy 1.651346 1.087452) (xy 1.725510 1.204763) (xy 1.755521 1.242724) (xy 1.870306 1.416910) (xy 1.889107 1.560279) (xy 1.807657 1.709022) (xy 1.685213 1.839112) + (xy 1.465427 2.052137) (xy 1.207849 1.881680) (xy 1.030959 1.778897) (xy 0.910033 1.751383) (xy 0.828239 1.776533) (xy 0.766887 1.808560) (xy 0.720866 1.813602) (xy 0.676704 1.773120) + (xy 0.620927 1.668578) (xy 0.540063 1.481438) (xy 0.442399 1.245653) (xy 0.343200 1.002779) (xy 0.289056 0.849247) (xy 0.276340 0.757101) (xy 0.301422 0.698384) (xy 0.360676 0.645140) + (xy 0.364115 0.642403) (xy 0.546275 0.432439) (xy 0.628594 0.190485) (xy 0.607355 -0.052554) (xy 0.478846 -0.265774) (xy 0.473879 -0.270802) (xy 0.236020 -0.437042) (xy -0.011868 -0.478639) + (xy -0.257276 -0.395934) (xy -0.438403 -0.245917) (xy -0.550884 -0.040249) (xy -0.561847 0.199415) (xy -0.476655 0.438481) (xy -0.300676 0.642355) (xy -0.300616 0.642403) (xy -0.239898 0.696061) + (xy -0.213187 0.753925) (xy -0.224111 0.843949) (xy -0.276297 0.994091) (xy -0.373374 1.232307) (xy -0.378900 1.245653) (xy -0.491407 1.516905) (xy -0.567478 1.689907) (xy -0.620626 1.783174) + (xy -0.664364 1.815222) (xy -0.712204 1.804564) (xy -0.765900 1.775913) (xy -0.871760 1.749483) (xy -1.000306 1.792908) (xy -1.126036 1.870991) (xy -1.276023 1.967907) (xy -1.379044 2.025283) + (xy -1.399284 2.032000) (xy -1.461252 1.990403) (xy -1.576243 1.885162) (xy -1.638544 1.822601) (xy -1.784594 1.648982) (xy -1.830416 1.509238) (xy -1.779627 1.364137) (xy -1.692022 1.242724) + (xy -1.599575 1.113276) (xy -1.577585 1.009071) (xy -1.617835 0.867352) (xy -1.636545 0.818997) (xy -1.705227 0.673288) (xy -1.791800 0.595129) (xy -1.940707 0.553619) (xy -2.039709 0.538689) + (xy -2.349501 0.496082) (xy -2.349500 0.127000) (xy -2.349500 -0.242083) (xy -2.041546 -0.284438) (xy -1.846534 -0.321912) (xy -1.731391 -0.385570) (xy -1.649051 -0.505675) (xy -1.626529 -0.551305) + (xy -1.563275 -0.699130) (xy -1.560618 -0.800256) (xy -1.625937 -0.914240) (xy -1.680483 -0.986922) (xy -1.799485 -1.166012) (xy -1.827392 -1.302599) (xy -1.760185 -1.437599) (xy -1.621714 -1.585113) + (xy -1.401928 -1.798138) (xy -1.146826 -1.629319) (xy -0.967672 -1.517244) (xy -0.845766 -1.470814) (xy -0.735080 -1.481762) (xy -0.609357 -1.532772) (xy -0.463283 -1.665511) (xy -0.411129 -1.802647) + (xy -0.363415 -2.024863) (xy -0.313026 -2.150433) (xy -0.230872 -2.206933) (xy -0.087864 -2.221941) (xy 0.031749 -2.222500) (xy 0.222352 -2.218790) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/oshwnotext400dpi.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/oshwnotext400dpi.kicad_mod.REMOVED.git-id deleted file mode 100644 index fac2361b..00000000 --- a/PCB/labralogo.pretty/oshwnotext400dpi.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -448a2280b00fae71bc72e3a57a492719c2fbbe9c \ No newline at end of file diff --git a/PCB/labralogo.pretty/oshwnotext500dpi.kicad_mod b/PCB/labralogo.pretty/oshwnotext500dpi.kicad_mod new file mode 100644 index 00000000..4e1f1a06 --- /dev/null +++ b/PCB/labralogo.pretty/oshwnotext500dpi.kicad_mod @@ -0,0 +1,27 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy 0.177882 -1.775032) (xy 0.268443 -1.751419) (xy 0.320356 -1.685099) (xy 0.356890 -1.554012) (xy 0.379702 -1.442118) (xy 0.452739 -1.289777) (xy 0.538285 -1.226218) (xy 0.649654 -1.182309) + (xy 0.737367 -1.178440) (xy 0.838246 -1.221226) (xy 0.968260 -1.303455) (xy 1.172341 -1.438510) (xy 1.348170 -1.268090) (xy 1.470554 -1.134678) (xy 1.514057 -1.028390) (xy 1.481895 -0.916497) + (xy 1.395186 -0.789538) (xy 1.316091 -0.677765) (xy 1.294075 -0.598072) (xy 1.323237 -0.502812) (xy 1.352022 -0.441044) (xy 1.417259 -0.328757) (xy 1.498654 -0.268111) (xy 1.633861 -0.234896) + (xy 1.684036 -0.227550) (xy 1.930400 -0.193667) (xy 1.930400 0.396866) (xy 1.682566 0.430951) (xy 1.529464 0.459034) (xy 1.442200 0.505331) (xy 1.385223 0.594563) (xy 1.360035 0.655198) + (xy 1.316477 0.783826) (xy 1.321076 0.869962) (xy 1.380408 0.963810) (xy 1.404417 0.994179) (xy 1.496245 1.133528) (xy 1.511285 1.248223) (xy 1.446126 1.367218) (xy 1.348170 1.471289) + (xy 1.172341 1.641709) (xy 0.966279 1.505344) (xy 0.824767 1.423117) (xy 0.728026 1.401106) (xy 0.662591 1.421226) (xy 0.613510 1.446848) (xy 0.576693 1.450881) (xy 0.541363 1.418496) + (xy 0.496742 1.334862) (xy 0.432051 1.185150) (xy 0.353919 0.996522) (xy 0.274560 0.802223) (xy 0.231245 0.679398) (xy 0.221072 0.605681) (xy 0.241138 0.558707) (xy 0.288540 0.516112) + (xy 0.291292 0.513922) (xy 0.437020 0.345951) (xy 0.502875 0.152388) (xy 0.485884 -0.042043) (xy 0.383076 -0.212619) (xy 0.379103 -0.216642) (xy 0.188816 -0.349634) (xy -0.009494 -0.382911) + (xy -0.205821 -0.316747) (xy -0.350722 -0.196734) (xy -0.440708 -0.032199) (xy -0.449477 0.159532) (xy -0.381324 0.350785) (xy -0.240541 0.513884) (xy -0.240493 0.513922) (xy -0.191919 0.556849) + (xy -0.170550 0.603140) (xy -0.179289 0.675159) (xy -0.221038 0.795273) (xy -0.298699 0.985845) (xy -0.303120 0.996522) (xy -0.393126 1.213524) (xy -0.453983 1.351926) (xy -0.496501 1.426539) + (xy -0.531491 1.452177) (xy -0.569764 1.443651) (xy -0.612720 1.420730) (xy -0.697408 1.399587) (xy -0.800245 1.434326) (xy -0.900829 1.496793) (xy -1.020818 1.574325) (xy -1.103235 1.620227) + (xy -1.119428 1.625600) (xy -1.169002 1.592323) (xy -1.260994 1.508130) (xy -1.310835 1.458081) (xy -1.427675 1.319186) (xy -1.464333 1.207391) (xy -1.423702 1.091310) (xy -1.353618 0.994179) + (xy -1.279660 0.890621) (xy -1.262068 0.807257) (xy -1.294268 0.693881) (xy -1.309236 0.655198) (xy -1.364181 0.538631) (xy -1.433440 0.476103) (xy -1.552566 0.442895) (xy -1.631767 0.430951) + (xy -1.879601 0.396866) (xy -1.879600 0.101600) (xy -1.879600 -0.193667) (xy -1.633237 -0.227550) (xy -1.477228 -0.257530) (xy -1.385113 -0.308456) (xy -1.319241 -0.404540) (xy -1.301223 -0.441044) + (xy -1.250620 -0.559304) (xy -1.248495 -0.640205) (xy -1.300749 -0.731392) (xy -1.344387 -0.789538) (xy -1.439588 -0.932809) (xy -1.461914 -1.042080) (xy -1.408148 -1.150079) (xy -1.297371 -1.268090) + (xy -1.121542 -1.438510) (xy -0.917461 -1.303455) (xy -0.774137 -1.213795) (xy -0.676613 -1.176652) (xy -0.588064 -1.185410) (xy -0.487486 -1.226218) (xy -0.370626 -1.332409) (xy -0.328903 -1.442118) + (xy -0.290732 -1.619890) (xy -0.250421 -1.720346) (xy -0.184698 -1.765547) (xy -0.070291 -1.777553) (xy 0.025399 -1.778000) (xy 0.177882 -1.775032) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/oshwnotext500dpi.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/oshwnotext500dpi.kicad_mod.REMOVED.git-id deleted file mode 100644 index e5b3af5c..00000000 --- a/PCB/labralogo.pretty/oshwnotext500dpi.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4e1f1a06d80bbcc1ce5f394668e77c4e5a2102cf \ No newline at end of file diff --git a/PCB/labralogo.pretty/oshwnotext600dpi.kicad_mod b/PCB/labralogo.pretty/oshwnotext600dpi.kicad_mod new file mode 100644 index 00000000..3265a8e8 --- /dev/null +++ b/PCB/labralogo.pretty/oshwnotext600dpi.kicad_mod @@ -0,0 +1,27 @@ +(module LOGO (layer F.Cu) + (at 0 0) + (fp_text reference "G***" (at 0 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_text value "LOGO" (at 0.75 0) (layer F.SilkS) hide + (effects (font (thickness 0.3))) + ) + (fp_poly (pts (xy 0.148235 -1.479193) (xy 0.223703 -1.459515) (xy 0.266964 -1.404249) (xy 0.297409 -1.295009) (xy 0.316419 -1.201764) (xy 0.377283 -1.074813) (xy 0.448571 -1.021848) (xy 0.541379 -0.985257) + (xy 0.614473 -0.982033) (xy 0.698539 -1.017688) (xy 0.806884 -1.086212) (xy 0.976952 -1.198758) (xy 1.123476 -1.056741) (xy 1.225463 -0.945564) (xy 1.261715 -0.856991) (xy 1.234913 -0.763747) + (xy 1.162655 -0.657948) (xy 1.096743 -0.564804) (xy 1.078397 -0.498393) (xy 1.102698 -0.419010) (xy 1.126686 -0.367536) (xy 1.181050 -0.273963) (xy 1.248879 -0.223425) (xy 1.361552 -0.195746) + (xy 1.403364 -0.189625) (xy 1.608667 -0.161388) (xy 1.608667 0.330722) (xy 1.402139 0.359127) (xy 1.274554 0.382529) (xy 1.201834 0.421110) (xy 1.154353 0.495469) (xy 1.133363 0.545999) + (xy 1.097065 0.653189) (xy 1.100898 0.724969) (xy 1.150340 0.803176) (xy 1.170348 0.828483) (xy 1.246871 0.944607) (xy 1.259405 1.040187) (xy 1.205105 1.139349) (xy 1.123476 1.226075) + (xy 0.976952 1.368092) (xy 0.805233 1.254454) (xy 0.687307 1.185932) (xy 0.606689 1.167589) (xy 0.552160 1.184356) (xy 0.511259 1.205707) (xy 0.480578 1.209068) (xy 0.451137 1.182080) + (xy 0.413952 1.112386) (xy 0.360043 0.987626) (xy 0.294933 0.830436) (xy 0.228801 0.668520) (xy 0.192705 0.566165) (xy 0.184227 0.504735) (xy 0.200949 0.465590) (xy 0.240451 0.430094) + (xy 0.242744 0.428269) (xy 0.364184 0.288293) (xy 0.419063 0.126991) (xy 0.404904 -0.035036) (xy 0.319231 -0.177182) (xy 0.315920 -0.180534) (xy 0.157347 -0.291361) (xy -0.007911 -0.319092) + (xy -0.171517 -0.263956) (xy -0.292268 -0.163944) (xy -0.367256 -0.026832) (xy -0.374564 0.132944) (xy -0.317770 0.292321) (xy -0.200450 0.428237) (xy -0.200410 0.428269) (xy -0.159932 0.464041) + (xy -0.142124 0.502617) (xy -0.149407 0.562633) (xy -0.184198 0.662728) (xy -0.248915 0.821538) (xy -0.252600 0.830436) (xy -0.327604 1.011270) (xy -0.378318 1.126605) (xy -0.413750 1.188783) + (xy -0.442909 1.210148) (xy -0.474802 1.203043) (xy -0.510599 1.183942) (xy -0.581173 1.166323) (xy -0.666870 1.195272) (xy -0.750690 1.247328) (xy -0.850681 1.311938) (xy -0.919362 1.350189) + (xy -0.932856 1.354667) (xy -0.974168 1.326936) (xy -1.050828 1.256775) (xy -1.092362 1.215068) (xy -1.189729 1.099322) (xy -1.220277 1.006159) (xy -1.186418 0.909425) (xy -1.128014 0.828483) + (xy -1.066383 0.742184) (xy -1.051723 0.672715) (xy -1.078556 0.578235) (xy -1.091030 0.545999) (xy -1.136817 0.448859) (xy -1.194533 0.396753) (xy -1.293804 0.369080) (xy -1.359805 0.359127) + (xy -1.566333 0.330722) (xy -1.566333 -0.161388) (xy -1.361030 -0.189625) (xy -1.231022 -0.214608) (xy -1.154260 -0.257046) (xy -1.099367 -0.337116) (xy -1.084352 -0.367536) (xy -1.042183 -0.466086) + (xy -1.040412 -0.533504) (xy -1.083957 -0.609493) (xy -1.120322 -0.657948) (xy -1.199656 -0.777341) (xy -1.218261 -0.868399) (xy -1.173456 -0.958399) (xy -1.081142 -1.056741) (xy -0.934618 -1.198758) + (xy -0.764550 -1.086212) (xy -0.645114 -1.011495) (xy -0.563843 -0.980542) (xy -0.490053 -0.987841) (xy -0.406238 -1.021848) (xy -0.308855 -1.110340) (xy -0.274085 -1.201764) (xy -0.242276 -1.349908) + (xy -0.208683 -1.433621) (xy -0.153914 -1.471288) (xy -0.058576 -1.481294) (xy 0.021167 -1.481666) (xy 0.148235 -1.479193) )(layer F.SilkS) (width 0.010000) + ) +) diff --git a/PCB/labralogo.pretty/oshwnotext600dpi.kicad_mod.REMOVED.git-id b/PCB/labralogo.pretty/oshwnotext600dpi.kicad_mod.REMOVED.git-id deleted file mode 100644 index 932eee89..00000000 --- a/PCB/labralogo.pretty/oshwnotext600dpi.kicad_mod.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3265a8e89e0a9dd589bfab10977138c1f122ee1e \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..7800acb1 --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +This is the project page for the EspoTek Labrador. + +http://espotek.com/labrador + +https://www.crowdsupply.com/espotek/labrador + +# Documentation and Binary +All documentation and binary files are currently hosted here: +https://drive.google.com/drive/u/0/folders/0B7U0ulRLHf8cRVBkeFc2SHpUOGs + +# Licence +All software files are licenced under GNU GPL v3. https://www.gnu.org/licenses/gpl.html + +All hardware files (schematics, PCB) are licenced under Creative Commons 4.0 (CC BY-NC-SA). https://creativecommons.org/licenses/by-nc-sa/4.0/ + +The intention is to move to a less restrictive licence in future, where commercial hardware derivatives are allowed but the use of the Labrador name or any branding is not. If anyone knows how to implement such a licence, I'm all ears. + +# Known bugs. +Most of the main bugs have now been fixed, including all synchronisation issues. +There are still a few small bugs, most notably a crash when you disconnect and reconnect the board on a non-Windows platform, and the issue with the logic analyzer still persists. Both will hopefully be cleaned up before launch. + +# Collaboration +Mailing list is here and open to all who wish to collaborate on the project: +https://groups.google.com/forum/#!forum/labrador-devel + +Thanks to all. + +~Chris diff --git a/README.md.REMOVED.git-id.REMOVED.git-id b/README.md.REMOVED.git-id.REMOVED.git-id deleted file mode 100644 index eee5eac5..00000000 --- a/README.md.REMOVED.git-id.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -3571796c73ab43bb218819e64dacd5a7b2cc147b \ No newline at end of file