From d3e9ebef72570c0d9b16565d37e124adf488e523 Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Sat, 9 Jul 2022 15:54:39 +0200 Subject: [PATCH] removed broken SDDC source --- source_modules/sddc_source/CMakeLists.txt | 45 - .../sddc_source/res/firmwares/SDDC_FX3.img | Bin 145388 -> 0 bytes .../sddc_source/src/libsddc/CMakeLists.txt | 78 - .../src/libsddc/Core/CMakeLists.txt | 35 - .../sddc_source/src/libsddc/Core/FX3Class.h | 37 - .../src/libsddc/Core/PScope_uti.cpp | 35 - .../sddc_source/src/libsddc/Core/PScope_uti.h | 9 - .../src/libsddc/Core/RadioHandler.cpp | 440 --- .../src/libsddc/Core/RadioHandler.h | 341 -- .../libsddc/Core/arch/linux/FX3handler.cpp | 95 - .../src/libsddc/Core/arch/linux/FX3handler.h | 44 - .../src/libsddc/Core/arch/linux/ezusb.c | 815 ---- .../src/libsddc/Core/arch/linux/ezusb.h | 114 - .../src/libsddc/Core/arch/linux/logging.c | 47 - .../src/libsddc/Core/arch/linux/logging.h | 43 - .../src/libsddc/Core/arch/linux/streaming.c | 387 -- .../src/libsddc/Core/arch/linux/streaming.h | 63 - .../src/libsddc/Core/arch/linux/usb_device.c | 574 --- .../src/libsddc/Core/arch/linux/usb_device.h | 60 - .../Core/arch/linux/usb_device_internals.h | 52 - .../libsddc/Core/arch/win32/CyAPI/CyAPI.cpp | 3359 ----------------- .../src/libsddc/Core/arch/win32/CyAPI/CyAPI.h | 602 --- .../Core/arch/win32/CyAPI/CyUSB30_def.h | 90 - .../Core/arch/win32/CyAPI/UsbdStatus.h | 46 - .../libsddc/Core/arch/win32/CyAPI/VersionNo.h | 26 - .../libsddc/Core/arch/win32/CyAPI/cyioctl.h | 213 -- .../libsddc/Core/arch/win32/CyAPI/devioctl.h | 184 - .../libsddc/Core/arch/win32/CyAPI/usb100.h | 270 -- .../libsddc/Core/arch/win32/CyAPI/usb200.h | 111 - .../libsddc/Core/arch/win32/FX3handler.cpp | 456 --- .../src/libsddc/Core/arch/win32/FX3handler.h | 73 - .../src/libsddc/Core/dsp/ringbuffer.h | 191 - .../src/libsddc/Core/fft_mt_r2iq.cpp | 263 -- .../src/libsddc/Core/fft_mt_r2iq.h | 127 - .../src/libsddc/Core/fft_mt_r2iq_avx.cpp | 9 - .../src/libsddc/Core/fft_mt_r2iq_avx2.cpp | 9 - .../src/libsddc/Core/fft_mt_r2iq_avx512.cpp | 9 - .../src/libsddc/Core/fft_mt_r2iq_def.cpp | 9 - .../src/libsddc/Core/fft_mt_r2iq_impl.hpp | 171 - .../sddc_source/src/libsddc/Core/fir.cpp | 105 - .../sddc_source/src/libsddc/Core/fir.h | 3 - .../sddc_source/src/libsddc/Core/license.txt | 28 - .../src/libsddc/Core/pffft/LICENSE.txt | 38 - .../src/libsddc/Core/pffft/bench_mixers.c | 733 ---- .../sddc_source/src/libsddc/Core/pffft/fmv.h | 20 - .../src/libsddc/Core/pffft/pf_mixer.cpp | 1148 ------ .../src/libsddc/Core/pffft/pf_mixer.h | 283 -- .../sddc_source/src/libsddc/Core/r2iq.h | 50 - .../src/libsddc/Core/radio/BBRF103Radio.cpp | 145 - .../src/libsddc/Core/radio/HF103Radio.cpp | 50 - .../src/libsddc/Core/radio/RX888R2Radio.cpp | 178 - .../src/libsddc/Core/radio/RX888R3Radio.cpp | 210 -- .../src/libsddc/Core/radio/RX888Radio.cpp | 1 - .../src/libsddc/Core/radio/RX999Radio.cpp | 118 - .../src/libsddc/Core/radio/RXLucy.cpp | 120 - .../src/libsddc/Core/radio/RadioHardware.cpp | 22 - .../src/libsddc/Core/sddc_config.cpp | 8 - .../src/libsddc/Core/sddc_config.h | 94 - .../sddc_source/src/libsddc/HWSDRtable.h | 44 - .../sddc_source/src/libsddc/Interface.h | 154 - .../sddc_source/src/libsddc/LICENSE.txt | 23 - .../src/libsddc/libsddc/CMakeLists.txt | 37 - .../src/libsddc/libsddc/libsddc.cpp | 396 -- .../sddc_source/src/libsddc/libsddc/libsddc.h | 171 - .../sddc_source/src/libsddc/libsddc/wavehdr.h | 102 - .../src/libsddc/libsddc/wavewrite.c | 232 -- .../src/libsddc/libsddc/wavewrite.h | 55 - source_modules/sddc_source/src/main.cpp | 247 -- 68 files changed, 14347 deletions(-) delete mode 100644 source_modules/sddc_source/CMakeLists.txt delete mode 100644 source_modules/sddc_source/res/firmwares/SDDC_FX3.img delete mode 100644 source_modules/sddc_source/src/libsddc/CMakeLists.txt delete mode 100644 source_modules/sddc_source/src/libsddc/Core/CMakeLists.txt delete mode 100644 source_modules/sddc_source/src/libsddc/Core/FX3Class.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/PScope_uti.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/PScope_uti.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/RadioHandler.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/RadioHandler.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/linux/FX3handler.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/linux/FX3handler.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/linux/ezusb.c delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/linux/ezusb.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/linux/logging.c delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/linux/logging.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/linux/streaming.c delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/linux/streaming.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/linux/usb_device.c delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/linux/usb_device.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/linux/usb_device_internals.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/CyAPI.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/CyAPI.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/CyUSB30_def.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/UsbdStatus.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/VersionNo.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/cyioctl.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/devioctl.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/usb100.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/usb200.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/win32/FX3handler.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/arch/win32/FX3handler.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/dsp/ringbuffer.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_avx.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_avx2.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_avx512.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_def.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_impl.hpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/fir.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/fir.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/license.txt delete mode 100644 source_modules/sddc_source/src/libsddc/Core/pffft/LICENSE.txt delete mode 100644 source_modules/sddc_source/src/libsddc/Core/pffft/bench_mixers.c delete mode 100644 source_modules/sddc_source/src/libsddc/Core/pffft/fmv.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/pffft/pf_mixer.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/pffft/pf_mixer.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/r2iq.h delete mode 100644 source_modules/sddc_source/src/libsddc/Core/radio/BBRF103Radio.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/radio/HF103Radio.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/radio/RX888R2Radio.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/radio/RX888R3Radio.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/radio/RX888Radio.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/radio/RX999Radio.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/radio/RXLucy.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/radio/RadioHardware.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/sddc_config.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/Core/sddc_config.h delete mode 100644 source_modules/sddc_source/src/libsddc/HWSDRtable.h delete mode 100644 source_modules/sddc_source/src/libsddc/Interface.h delete mode 100644 source_modules/sddc_source/src/libsddc/LICENSE.txt delete mode 100644 source_modules/sddc_source/src/libsddc/libsddc/CMakeLists.txt delete mode 100644 source_modules/sddc_source/src/libsddc/libsddc/libsddc.cpp delete mode 100644 source_modules/sddc_source/src/libsddc/libsddc/libsddc.h delete mode 100644 source_modules/sddc_source/src/libsddc/libsddc/wavehdr.h delete mode 100644 source_modules/sddc_source/src/libsddc/libsddc/wavewrite.c delete mode 100644 source_modules/sddc_source/src/libsddc/libsddc/wavewrite.h delete mode 100644 source_modules/sddc_source/src/main.cpp diff --git a/source_modules/sddc_source/CMakeLists.txt b/source_modules/sddc_source/CMakeLists.txt deleted file mode 100644 index 0882a1f..0000000 --- a/source_modules/sddc_source/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -cmake_minimum_required(VERSION 3.13) -project(sddc_source) - -if (MSVC) - # What the fuck? - file(GLOB SRC "src/*.cpp" "src/*.c" "src/libsddc/libsddc/*.c" "src/libsddc/libsddc/*.cpp" "src/libsddc/Core/*.c" "src/libsddc/Core/*.cpp" "src/libsddc/Core/radio/*.cpp" "src/libsddc/Core/pffft/*.c" "src/libsddc/Core/pffft/*.cpp" "src/libsddc/Core/arch/win32/*.c" "src/libsddc/Core/arch/win32/*.cpp" "src/libsddc/Core/arch/win32/CyAPI/*.cpp") -else (MSVC) - file(GLOB SRC "src/*.cpp" "src/*.c" "src/libsddc/libsddc/*.c" "src/libsddc/libsddc/*.cpp" "src/libsddc/Core/*.c" "src/libsddc/Core/*.cpp" "src/libsddc/Core/radio/*.cpp" "src/libsddc/Core/pffft/*.c" "src/libsddc/Core/pffft/*.cpp" "src/libsddc/Core/arch/linux/*.c" "src/libsddc/Core/arch/linux/*.cpp") -endif () - -add_library(sddc_source SHARED ${SRC}) -target_link_libraries(sddc_source PRIVATE sdrpp_core) -set_target_properties(sddc_source PROPERTIES PREFIX "") - -target_include_directories(sddc_source PRIVATE "src/" "src/libsddc/" "src/libsddc/Core/" "src/libsddc/Core/pffft/" "src/libsddc/libsddc/") - -if (MSVC) - target_compile_options(sddc_source PRIVATE /O2 /Ob2 /std:c++17 /EHsc) -elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - target_compile_options(sddc_source PRIVATE -O3 -std=c++17 -Wno-unused-command-line-argument -undefined dynamic_lookup) -else () - target_compile_options(sddc_source PRIVATE -O3 -std=c++17) -endif () - -if (MSVC) - # Lib path - target_link_directories(sddc_source PRIVATE "C:/Program Files/PothosSDR/lib/") - - # Misc headers - target_include_directories(sddc_source PRIVATE "C:/Program Files/PothosSDR/include/libusb-1.0/") - - target_link_libraries(sddc_source PRIVATE libusb-1.0) - target_link_libraries(sddc_source PRIVATE Setupapi.lib) -else (MSVC) - find_package(PkgConfig) - - pkg_check_modules(LIBUSB REQUIRED libusb-1.0) - - target_include_directories(sddc_source PRIVATE ${LIBUSB_INCLUDE_DIRS}) - target_link_directories(sddc_source PRIVATE ${LIBUSB_LIBRARY_DIRS}) - target_link_libraries(sddc_source PRIVATE ${LIBUSB_LIBRARIES}) -endif () - -# Install directives -install(TARGETS sddc_source DESTINATION lib/sdrpp/plugins) \ No newline at end of file diff --git a/source_modules/sddc_source/res/firmwares/SDDC_FX3.img b/source_modules/sddc_source/res/firmwares/SDDC_FX3.img deleted file mode 100644 index 8b3b08abd7d120c817defbd4286d510ae7c4b73e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145388 zcmc${3zS?{mH&V4t*Y)yr%9?`p=nxkJKaDCiBv*>01=8LXv8R$2M;l$1w_p#qb)`a zBTDrnAwq%;NgzTnmzN?&Z5|F7gH}R7)S%&^Fp59#tx8Qo2gf+*Ohll5pYN?(aHkE< z@Bdr>wSK+US?BC?_Sxs0efHjGpU179`+?43FKLXij7eptz1VEr(yx=|Kq~Xd{=C^z zHjZ1$q}kU_+v4D02ocQ^Icj*Deh5)Pg{?Zu@Z+fr^cHe^Pm)N59k8=Z~xWl_nb+!o8Y zO*80=4W0T34f0#4*Ctxgx^eKxYfBQ>fj^2?i)b~3ZKl9UjKZ;@D;#K)9m;1$%6n2b zwZ+16(&Zld+~eF-uC!alu6Eb2G@4?p$1YBqI_x`f*SFJdX)N_)jAfxQ9S@m>rAFcy zJUGgjDJ!8-N$n`DOsy^}ZJE3epGHVni<9hZ`$B~0$%*MQn?mBw84j#ACX78Y&GUf+bfk33%*;9>r>a?6-UOAXVj_VrFzMo z8Hoq-mo268kF-m#?gB@8Wzp8}>&?ia^QOJHVab+qtJzp?Pi;i5Q{JJkJd(6>ZmD<0 zmhx2_wv_F>TZ+4GDK$(z`aK@LwOhz9bSiOEw8rG&U7opESI$8H2>SAGLHpTKjJ~8J zZSEnzHMgoPS#K5pQ#Ydr3ri`pvCV08o2E-A=}V1vB0_s_tV;VA5!%m^R~ygwMLWNW zIc^PP^1-l7{V_x9$~z+UHb?4xOZD7U*oW%aqU|3MX@6PR{&ypEmPF`$Rdj||1v-^t zY*9K*5jveAo!cUG8Y6VBA>T1B{8<&q@Mv0X5n6lfDo?JB&?=Bu+-O=y zMQ9C%v_2o9wIV|667usQEvxZwX}v8%YgR~WS%lW)2(9;%Z#7oOXdi}FSA^C}R&|UE zBeY&1uQtXr$hSjUnYpmPCTm<&^2xwnk!$sb+q$OWdB7Mt*<XWYaIkrA1mu$x> zm7}$0$QGXadL`(W>S``kcTL!qL%;v6t~x&|*BasEM8`BNi>!~o1t*@X%BafbN6LN` zmW{JpOTGC=lA5c@lxLv*3(As=cbr|o2CpKn_7Oa6pyj=kh-IdxVwt7mV;PgNym-bo z@eJHBmRG2YWyG^yXe~(%mEV4DzGz!brN-2THj{NrdDGOQ`CpR4re*ue$(|d^P0r3z zvZpV=x0`m9mZb9Kcy_R?HF6t$nF_5&Q-%KpSUi1ce4?!WC@s7E(s--9zRrvoC+3+{ z%&V|y9Q^RK7ngqvIW)JFf^|%F zj-mX@u+JOJHRU8YtfdVbjO=PQSmQQ@Y38`2mwp632z52KP1I5SV@ZFExD(ovSJA#` z=o)a^O0faAbPP0?QrBusu?Dy;^UXDFG0SbydcC4yOL;!HCiJh=&b+YAZ2r0g>rq3D zInFXxwJF-7Wm3N?S6F*l?|tc2kY^r;&ac4BN{??*x>8-6r&RMZMcdAoa?sHFmfLV$ z*>0?k+0@+%UkW8tM_D3FC#r4sGR`IRaX!97E9qThLi^F_mQG;YN%5r-d4#S#woSfE z!@Qx@!F+U5R+r3|I>Wj7&xAR!^`b4{2fm2^0;Vh@;I*x2p;KZS((J35w zetSEZt3mfFE*hz2cpp%mfMt1 zpj>?3j6C;*bFzfA_`U!<@jU^~>{^`;^cEPq6U<*bcvC6cKpUF~?Z}H6m-jn~5w($Q z*sryr4O08s|Ndv3cA*1rN0z}e*~4Y%&$FQqZXfNI{s4~jL%dJIbJ8cX7dl;gTg?Gu zP7ueS*|E9iyVF0PdUmqC)J|J(WotKw{nFg#!n%3Jx|uONrFJ!s=m4}wYSo}3 zdtyzn9&4WyEsxe)fZxBKw&xSyKs;Of0Qz_>X~|DJ?W`g#n#qvn+2mhEp8SDsXs4*N z1UH@yo#8&7ViVE~Z`voC}Ck^h^4pKBvMy&!Ox*%JP(v-IUW6~GYqLIzhqGx%Yw#J=x2dl+P-~Lx4*TNJ$GWgD;-C6r(_hK)cWL*vShb(xkID{(ez(=)mJU&-y@Tj^ zwfuIs^dDgz&3!;G#MvI=*xzTcRb=d{K$m$MHrd6Qp2JbOYc zlfWp-FHa&IvzlU=y#)E{^3#n;c$p)GAM><#Sis(3rnv#xxuLuyGm*WM@m4q+h*N&B zSIN4iS+^ z=}y{;r*0sw!m-XBr9@c%<(SsQg!eFG7;mP%Xv}$j+2^m9(lELpkkwIk^Cc|H=54-N6~qqmGhjC&LQeQ4xQf%<3(3vud&I0gLVSk>b{*;Gma>-_-_^vaNdCIR(E0f&Ixk?`?GvhWR#LVFI{!p0 zn_tWS!eQuaA4O*a_|}vvosUxXkTC~7NPPKW>VA7v-HX&#SocE8hN-)N_#X~a_iLl- zcB=02)pqAocIYpa1Meh$|6%HWWmH|Si9S!R);*1~KT`J{#Ah9*ZhlnVyQpi2b*E5v zkh&9z(}$`1=}~o;tKH+O?H*0pqts0icO9ngrK9RjRl8x`M#^?m*CK9@UWrXyNgFF2 zLV8PiMTU^wQocO5rQF*~$ZsjXZn^s}2j_BdmVmPyoaNvw2WK8Q%R-zSI5}`~;N-x` zfs+Hr0jCq3FBx}#W#Ezhtp_WW6e0aHlQDm+R1BMr`Ghq%M9&jDM;f!7U~pugC!S9{ zMA%J8;(*U1y5@OO^3HSOV@dp?6cPE4(34RM^JuzSe^{a<#RMs zo@wVEiSzaz_D!vO-d8lAVtx1=G+1w1hjq5jUNL@#ZoA)(>V-Kz0HzuF-6esaPnyewsYf;*aPKLi(2M_ZvAwwc_hu z)R=Ajp14_8NCdCI*}Zu6E?iEk%O9E zNCx)wb9NPxf&Uje@wVFhPkJjpytPg^>~(57VXmOQxgg-f>7icKY=m^8aTGsd@FO;g zAB8^lb`gI3ztV~4S#M+~W_JC3o}@yZ=+s{5!$XY!{8CLfWCP#Sjkdr}rbg*TJO|F$ zztxS0SszmHA*vg7|A)F!7wU%a|8I3;Q*HdtTaCY}8>vycVGbIvmHol?L@bjcHU}-w z9JC2BLfjk29@LoeexCijIe4OPvo1|!ztkMUEu5>>aFjps4ZLYDYG0)~!ZB&l7zp5l ztgpsdU$&e%MdJ*VWz)5XwwAE}I`}Dnym@5*xP!y~?i6_JqjY98h4MmJFU0S7FoZeR z^{L-6x_%ORea#0!gdO<1nj!OjV{MqfM9_`!+g{XeoYLHsY(csPt- zeXa^SJF0Q^e^uklZ!iJ=@{Lt^>oe6j`H^Zo^yg~1Gp-6xJy?ae-cf}Q4OQW_Kdi!g zpRdOAX%|n)n6%08CI)%J_A;JUWYsncS?Bv^zREiF9`3)!9dtQ+k7b5?Vwp7lj=RY9 zC+ZF-o%bBGxCGaxTLs3Pal0o1cg}Qgu)Mi9b|R-s3&@M-4P*+N%U1fbVq(WyziWfpIZ}k=b2txZkrCh3?V)DMw9jiXlEc^SX)$| ze~<4vlfKD^t%cp^Vsns*dirWo>yg!kx@+mE?xhFHGm$5gW({Yot%mWQ=9cdK824?= zS^VH_d!K+F=LVTI#P>kwRM9~cHl*Da z`M>8wPjW#YTW~i!OnM{zSj;;l?!4f0JbfE7dINWm1N32F{{re*h5q7v`eX`y@B_ap z-Cv$9nEoeI1DvZ3l;fEJuQA=%=A;LTaVHL)b)3`PR#xBP<^JvTS^drv-gnYP@7kq! z-uutl$~d@_@R7;scaheah)Kg6^iKU^?S|w28p@q)rpWsqKSAF+)2VVSy~>L_ zE#=;TPLSWQoOD2g`WAILFZ54BmX@f`=^L5v0eI36pIaHjqEdUhwJn+MZzB$P(dZ1c zO%*OmTh92I7S>JjuXd;6T}JPI^sIwdg6NGWcDh;W#yvAl383%a%PmwEGXBL zt|zV|t|LwmCy3+3apD+pjMyf&i7jG_xZZrIlthP;%n|@eNS+au$+-0i8nx_9`k zbRwHAs%+d5Zs|DAeWW89&eN#dp?TMN+S`_6bEaYcQ?5SA~_ibaghd z2hDlJ(AqEk$GT?JpO-Jwon^LYQeMjvXmu|S^$3mePxhBlTnE^Xv^r?}ts>(G%phmd#ucK|2N2PC`K zT25b)a}IwJK{`(#TDa0|cpm;);kfl~rO~=&-_dr;>!A;_8CI^}mX5EzbhU|@4{1&4 zm|x&+3G;5H&Mwx$uPbP=lRhv{%0HHS4ja}m6kEJ=Ui_qC`pXVHQD?1wl0 z#gRGI`Tez_t^X5k_GsQ@SK&`0Q?sdU!-McuGT}%*Qhh}$GiZzdTBpTFc!ar$Wu!mieU0Zmq-(mAg7;(5Ptk1r zDDPo{v1`rlFLws%{&IU5YYkU^3Ok^6?+Jp|zS=r5&P;pp)vhh&gPd>atYRf+4|+ej zf%SJbnM9B;4^&cC@j=@7Cr+0%Q9zfc{u$`KS*n= z#{7DjaZ9Hl8@2q)$nQ4hr-IiYCvivmmG@fl6+SW{#A7{=&v*SE!f@s>A75eQ67-vk zt!s~=pH}Yx=P0IOCFcwlx*pHuX?tGT3hTsr(fRZ>#b*P)KT}>to9_T$dVLY;GfAr- zlZcNYW*iMG@f8lvMW2b~qkfirojMKt)4w2S9gVz5S zkcmA6P6o|x;*}2Pa>!ZxqHyn>{$-#)^t&O+eq3wMmzg82PYLG!5c+$lNwTsYy>d&- zkx%y3Bm0?G;eJWDnQUI3|k#bu=kzLx^ffkVZTRo9xdJ;7xI?- z){d><2sa7NU12&wdKq~a!fVR>-<-tV1oc&S5E@5@W4bD}r7hvOP1gr~_ISs%uGpD= zvV7Ya%pJJ;zTn)L`2XATMbO6g7)c^058rDt$?jNY8}VNV*0)TiozO`5I^m^>vCOf= zQwd&IEb|BcJnEecyqNF-!li^O2)7bGPq>DVM*bu-Is?-lVJ+>yIPJ~-#8tq5IRO}3 zwSxYb>@&gG8H4`>>*^7llZ>UF_7e>=-O@$iOU6vPue=kxIUD#C>Ra&UcRjpQMn=-| zmmJ-NLXY)?wG%r%P}IIHmM!cvss6H+Dcp=rUBx~1NQSX}i@tKNn%T?PG*vHdy;gTyt^mU9`dgKEhm3x(AE;h#``|t z)238qZWg@N8Waald|$^r*6NAZ4^mHS-*?2zot9boPLtVA`WJ*}u}Axe|3XL^%dozl zCB8RpHJRfH6XErM_<^k8mvyKO*){GR{OycqDq~QdbWM5ekxQ~G(!uTNC;h9At@cH_ zkqY~n@2E4PYdrAHq9W_O4RB2uZD~Ce{eZvlxRKDBd9r+r+R9etq?0=5t1b8`{GUQE z5w_clj2yOI>h^+X<=$*}UN}y*tNOthX*4hRMN3x z#j!QdrE9S#wR0N1v#2EP@9!&w&T?OlCIm zJi-#fQo;hl$-K=oxolByv}ZyyPdg_Qe~FlTm7?Rw z+1s+ermdQf^m}L+v$1@Z_?;Ona?Lz)WXc?n&wUZGe9n(Gaj#B%cC$I~bK)%`;8^REbVhdI~% zF0w^1J%2JEBVJEgH6C%OgUuxsmB(&#|Kc_R|fCu>WQ|YT@>I(SXLz~B* zRvnvc>SJo3vFrZdV%{D(&5XQ+jd=(3m)vhM?w36){Ok3b>;PQs_lBT`wiM{bhPeB-q#g(z}wyQS?ht; z0DPcwA2f7kmCUi;X4jRsWuEl+ox^+n9PLw2KF~(!2+x1FIk1^Jn;GlFGoJMA*#pHN z63f@gKu_nsO=FM;2YIuf^zokqIh{w@nXGZIXgAVp7WrvU=OeRbvqzN+#ru1g+<_^Dgk2Iqqzbix&8RkIcLOs$M0Tcj?b9f7Lm=>&w@hoZ;**jh-_O z-K9xCZv3m}qiWy3LRx!w`N!X+E$zd8Ks+zfChfJTUA32np4t}uowC&-ZTShJ{e=ka zl@Z!Cy39Q~KJCTXT{@F={SEJ}%7bjtRMw$K)o03tM|o-O8|8z3E9F0+JQbGLQ$83e ze--{cK=~o3THmJpsz~`>%D+Xq7nY+_r4^C#-IU)+`4eHe#&db3{6WfZrF=LnXC6z- zBITPYUr+g_uslKe(n$Fr<=0W3r`%$EDqj*Qznt;`%9m4ahvf?*Q100&suNfvs^>?17)3&vICrB|Azc2*p~g2X&t(YzRDJCLyshr`u%`d&h=%p@6BY2 z>aX4F`UTpJhwH(wXm=d_iQ`KjgU^+GKYSqc5ca;W8Y``!{Pr-d_z>k!gg7eGTRN?| zbzL{^!^aAIq#r_`bGs4aY~*{Ysvdlwycl_VoX7lmVcvt}>3j59Aw2vFel&G@fO$^G znJ(vJ&M$+v%^L4g?DxZr*CpOg{5au9gx!Rlgfx2eV5a)MNBeK-jA8tekAK2fdY-&Z znmh9U5m|G*>Kz?tryYEdM1T4A>by_+cg=DAvE;qh zt1(>2?>F$f54~}$@rCq-Z;MWq?5;2C9G~;Hh7Ym+B#;k%zhIdU#H=AVW`^{=Wh-`= zZ)=1f-VN~dy`j%sB%9u`pdQ_Rr@ph{3)L z@u9(;jb7+|p3ci`;G-ye0Ul(+KI<&_-t>El`!7I#hPh|D2OWoZ+W+0l`%&k7lUYW1 zf-sn6&$G~EHV|IAz+^U&*BPdtCqA?YonBlm+e}(Gvj`@&G0@`%+W(E#VRVSaqye6l z@J+efq1>!5FF&O!7t#Hf&J;Y_eTncV!mETv+G-`l3H*LVFxKtR877VHkDPUcIq(vk#HnNBi}?uwVZwe?9C^Cvx}7c)lI@2Xml23jdoS{*%JT zUR9h1_MRL0ZHzeIztt7L#u}vk=5yGR4ZP`>O)s8c4g_~u><8k^pY&typd6`L2tS~s<#n-ETA-_J1~J z4saX0`9qVfuWnO^m!?^B0#`r#iB6)?;*C`?D0`xgH{_%Eb7sh&ODT^BW0O2ST^?iB@2^8Y@nx>%z6^cgz6?E?PXGQf zpt%TNl6xfHqSvAL;Gj#~}Iq2!W zLg|yKR|?Z($k+M7{0I%z6%EcaJ0w%@1|MAus~!=P7?$=UC9K>GVzH4TfhLKfxX>1Mg_+iPu}EaqkNL0{NcU7s>7Xvq?LT zmX|1x{tu_04*Y>`tzqdM0p76lv~Po>^DWhjDGly3_%yojv7Gl7n@{|df5#-`i9JyD z+)Mhtt9);8&bB1@KCP08b1uE4q&tk4SZ{R~u|M?7bQiHD$9j@uU+?@1Uw=_>2RWSi zRq&P&8%N&8au@ct+IO8f40yxN$LyT}Z(Zt9+Spcu<= zcae722lp50>ivZe-!1H?*0g1;hhL=r7~0Fx$2feuhO>L|xQ6pVa4rQ$KAiS=9LZeS*wpV@l*bkME;9#oF0Q?Ow5VNAemtIv2>$*603k)f^_I#MHZ*8r^EwzJJiS zLmGC^0CrXHQ@GD?o+Pb12YgZdOO0RWAV;tVzenHt$fxS#T`v5wTlkB)6Z&Mba|0Xc(@ndXi0IPXC48!79VOCIU(adx>v z^cdTpNM9bNH{z!s39oZi*xwNA^DZLYH32_3WfeP^vm5aZDo$Nd@;e3ihrkYW#Gm_s zuVxJA0qY%=@+2Go%sgl2utR(Cu9FL|-fF#GIq~e>Kf3bl+s?hpu2jaG{|{rmr8d^j z|DCaZJ2KXPj*RvDk+ELPSYIH#)mSId?+YViJsnv4W9H+HvCd;hxNn!gZ=4H?7H^nzPR$$d>y}T>^no840X(f;9Ow6 zH|-7_$$FwYRQn`%06kr=vvBF_ymY>N_eAQL9q7x2@ZtjNCj7$Th0pp^hjj zbK)Ym=@^1^L1WjMXga^4JQmnoL~yG%Yd8Kz7C!`B+CQH+eAo4(p95w{_IgnBa;?>n zE%DxlxjnyxuiWs}x<1ch|M%4+yF62H*INa5pwSF*$9+5R12vG z$7$(!)<4v}%YPo*@WKw>J2m!s&s$r{w;zcf^II!JmgVgRwo>yw&6AZ~)nCab`p24! zeCGZnEAMto=19j3eLxmtv+{$9j5Cq5pZA^_?s!^K&z1+eY)|hZ#8=*t z`1bMrr3KDlxfx$Z=kMyD-Ggq>H_1`MsWH#G3)ppI4e0^jCba7N@6!iLrJkLo%H*A; zaZ`4d&f<5YRFy3=N z&gv~qHN4Sg->tJZ5I59#-xIHx!~eV706jNkfqbh-Zhq^G2RTdux=TI`=d zI^nri#&cWPC-_qZ7hEe}sKROH9(}WJyzClpCUmcXw{M>vE86cI@MrO^hi?y%%K_i& z6h80R9oMRxgbgDvkO}&68Z|l9;cUw8ec&>-8 z#-Mh%KYOF^vNN5~-iYkQk+F5e&zoKT>Hy{rj``a5XM9U!MrVCGldsLw(RZEQ@gaOV z`E#?+-BO<2Asrf&ewDsW9gDbfQT6Ub_qsMT*5cFB2k0`Fl&=A93E>XlLEyz9d^T_% z_|_1f1$-57TL_;9yb>5$4CtK>ydnah0o)6$`!KaP8~AeIVhHOS-Q~ca3gLGEFH?Q= zX2tQW2k^NE+w{=!{l%lF^%n)7VDl|TSoVI~bjX(z?JKBzzUqeXXMh(1=RtfA0bQ9dK=i3z~p0M>jc&tg9A1lIYx@-!b?fTxDA=Hpi2 z*&%#6@XZnUlfdhNuL{eL2L1~0BO&}Y;OiprMBr|r5S|1)7r4fc9^kVg@Ug&WMBvH5 zrvm@NskT1__$1)ph46#GCjyTT;eP=>0k|!M9|ArO`0^0`K5#d1O@4m>JQ4Wfu>29= zqa*N-fR6+|KP=w?+!BEw1s)Il?y&qZ;IY6p8-FKoJ@9#9`Q5-V;P;2{H-IawB{le) zz<&i^5|)1p_`iUshw!(7Uk08V!ruk{1Mrp*z7Lo~`!~k>Fz`O$8^iK#z&vC>aBT>0 z2mW0I{vq&hfcwMp0`POd>qB@a@H4=xLU;BK7YA{xR^ELj11-KMMTC z5WWZaN5G#7;d_C90Q`{<-U|E>aBaNb0e%3uHr`?2?*iB4{eIwY0oTUc2mB4-2c4?? z^aI}s{6Gi~0B-@_8p4CXw*qeq;Z?vl18)!E)xhh4zZ=5W0DlGeju2i0d>wF&-j{)| z0sdxKel73-aBa=M4)|)|8b8(oe*t(!h`$c_^T4(7UJv{k;M#b<0{ki9n!FDIe**Y4 zr#jvnfIkMD4&fVtF9SXO}HF>`c_*CH9{C^GjBw(G3HIUwN zff=cDs$;zZcq(PN5dIACWZ;j6@Cx7_;6w<27T5uHL-=#RoxooR;m-rN1II%6O5j%D zLJ0pea0=Lj@E3p^LzrF0hb_rfmT|7#O1&K+ZRP#>Pn823L-+*XKLTg)?KA8PbzUj|ZR{w2E^ZI<8DQR+IfHsb z-OvuM@Md#fkYX>%PG_W%cqq=97k!A+ZqU|$@aAhOcOR^g^|bXX+Ul9iUYIwh%1e^> zl=3*QtL2R$Z#Q`rCm!Hvex3ln2K*Zm32!U>*w{7T-NT--8=w7^GY5+6ZN6~^uZwdw zotaPOOlES%?bg{$Jma2};XGUYT1nkK^hs&8KbAW8LHkjsI`^XSZQz?jSp4}WaDsTk z1>AKK2WPwCoIC<8_+8q;-tHUBgXX3-FXx|cndK*1<|*;JkPLDTR~J)! zkJ8HCh_e>n2A}W8vu;;IYQRg-9z63K^4EAhy^oh0M1$}DdO|v5hd6i1ulDpNQSaTy zaNnSFmu9}z675PpQ8cM%bXHQ*IcyKVM?4nUO+t4%IoLJ8Ddo@Pha5Wh7ujQ`7Mcl;~*t>Cd!0+<}`{2}1*!%Lma;o}%-Ab+7 zFI^JPG|%sc@7B$uIMck=F66zq^Fq14@LR^d6CUv`b-LfL=R92F(|DFg#%MT~ z49@%bKF`V%da*4>>fDccgYNQgFc#Nss&GEFrk^;UY|iK1ScUu6)t3V2>Y8&o&W47x zmt9oqgjbwN`0h}?yaQg`!Z{~*g1+X?qiyW2-<;wt0)5cA`z^W0?nZX+)tyy4_Gk>a zhbC-k>!dF8=68x;oZF~;@3C9TdnfQtWoUgMQ?VR+z&Xy5v3}0*f^ST3;T)jEopguF z)ZS{&fMSmA={JDTYkxRwH`=DoV7dQnSPN~*%ApEJ~kN2%Z7uJ%k$?<6lJi@wgMt+lju4{aTb-JcNRJ8yyC34R{@&ERW1vWvCxoc$JcUTWRa_8IDY zg*p~v(Hy$DRpq;v=*4u9^Q6Cm-%(WCCm}zwd9e)N{c|6%Kw}wR&%11XTNT_G zvM}x~`ZANgWa!IM>NJM<9jWSkT5nN@-*0R?i8|*|=N8_VCD9?h-IM&w*4FqJd~+b3 z%RhGaXqnp8vZZYjG|q&Ee#h~P{Eq%m*MO)01Jd1sYzzf5Qo3P`?KN=TXBFI&Od&YG z_K8n2W~qLkxnisv@*4g%5dPm`G<(09w_ zekN%5V({nApf9HrZjtQj8<+ub#G9yH;2!?4y0)F~MqZ%(L)>S7^*GkIc6gE0x;W%b zYVQl~1g;Cle0%YGdLPAa$>kk4mcd>)oL#ED;I{ziJL6(qtlBw^jrF@B*Uay$P+xL$ z_d(VuWTrq{N2C@P8=SdwEXQ3qhx1#j`@h?U>|69#-?9@e=d)u}l@VA0ramKu1A9~&bzZd*L z@Llk=Hi-`|I`c1!(cPh{oYeHU<1J{Uq461Ld<7cPU-^l3+_5m(MWR^{A#Fb@0B%gX7#>2ol!){(J6!JwANqQ=}VyXfp32Tu+eynX->IPm^x@5#O*7t|UB6c$x5yg30_N z;d_L?5MF-wv==9HF0Qp(cUZcw;v4s0@4@%yLIl|v;NBEIW`a5Lb>@BWnn(6O$X+7X zi*KECOGAu1mDe|jRlC!Ws@kn*^i30beGYo9@2+d*n(O_4s044;R?v=qFDdY2)t(tB zYfWAf(w`F2*PEpUVgKI1rEknf!>kbZ6CtkNPE7{)m8+4X3?a|CDtg#j7%I2txR1qV z9rbhcq2RXM{P?jRzhS>Wjy%}t@KN6(AA9oEty4YS$<`Itdb{Z#JlNL6KBJZ2$ie<} z2w&^@aJr40}$j0Z$KUHqZJymY*eG316p!{9>m`w9qMc{Bp;tj=Oo_MD3 zy#4^sB#Zb7rG(+mBjg$F-K*d4sFmLbZU$W0jJJolUkJV#3%(`0S7q`|XR%+JMZNlT z)wWy@pNBFV%UUA~zxcS(Til@^oMX<~fvm0jpmFY;GU#dF za!)E>?qeN@IhM!wT%`}uW?{TxjF0U9uiAaF?znTbmtSALvvyyM-9+|eLw&oAHQFD-5<-;>=?Zrt&;eH*xoX~dTv z;w}PPraM7@9yTdcL_cZqU^d0Ppuy^il3Eeg0%QWm^eb!p|#96NYUftQd z^m7ujO&?VDF69;2i+k`7JoMOaL>D&xdza@SL;4LAey?p`b!}UWJzZqs51rnM49OP~ z?!(Bi*6j7iO!AI|M>ct~198?UWZiGlJPl`ylaQeVZ@?d=O!h%#4PhDkp>1`P9UbQX zO7D=U!|zyZTgCU1?CVMxGqz&7&My;sqeNUzu;w0uXOa>2_MYY3;eDTUJ!MI! zzr@~)@1?5k{d-7PYproMa7U~4c2VgN_K4rG=+M4T`ylz=N$PWVK7u}Lo$~(})@A(L zHd9yiI78^z<2>naPKEdRL&q0&w<$hZ&X|69x?Xs)o$S2=Uu$IzS9kv@(Yb(skt1Dk z2Xf$J4@z3+zsfzeYyx5su-j&aSe)+ZKQLcJRNAH-`DyNd9v2 z$A|gnM)G6iH--80BKdzJU-BvXXGZb`H&Ui^vZE+J^;O-Aa}<>3JQ;qhN*4mXlg=EP zT;P2dyve$yXL-k=?+#4P^=|>kfd>5XH)QkW0$~^73Bqo|9>O`;&NCCdjSTTV!anJA z;34$!XlRPJb@b(jyq~)oy0@_JO*p*8r|fNESDAbd)n)Y`UijjX=$@!CQ+Gaf*YN*Tl;?tXMwmZGa?SaL{3O0bXprBo`m)W! zofzWr9ql%i8OBj7YY)rNp>1kcWwmyj!m=rp8U9}gV=C$YpYg+LL4SIJI=^Loj1|@P zc(b@=6Jy7Ib?CbX>_!K9*mpNZeqxjJtMWwJz?Tc;MSVLI(&BraZJMWHcn~9g5IPT& z*11e8`|Q96gr4RvN4fZ0M+z)$__?<)spVr#5k&dIS0 z8S0Ba(iQdLxv(yJe(xVBmkkvCTKO-+a=s7Qra4tvZC;-U%Y4d2H(GB;SjIPR+tQS& zP1#Sixh*VXPaM!}hqpDF4}@jA!+MgtTD`4dSt8@!zKilWv;w=wx@Nv~0n0B8z&>bg z?7=>K4%?u!*K}5E$1lsWarhw(R)#f${*0$z($Skl7kgnck0o@5XiW7i@h@?{^GRgk(ksm`auGHiBGR!3Ql-tw>vnG-Mgjb`SZ@-H#x8bggYhZsjMd|5|W z723;#v_FS7V&GkfzaiNdYy&R_u7q#~_`C>wHt>6ag{wLieSCMM{#?rEM&NnCXGQ9t z1AIoL{5;@Ofn~>PeSl_Z#via}j79ATeh0A2Z@$UaTfDn88TJC?Kg4^X9(*0;H32^W zd{+pI=G(~oPIL7)%Y}aoZ3(ZNSY=(rrw~shZX{Tso4AVM#%H0Qjk zFZ`>32cc8Rw(q-K^wjF;nTG3@WF zCmQ0J#y&5cC-w6O_yOwQ_lec7hltgm?-8pX4-l*E`-s)vcZt=`w~0mnTg0OIO=8in z=R5sv*tf&+N!4Y0G2tUG$ zI>DoOVMTbck}-%EpCeX(RuGF9R}hOAy~N_hCyCYG<;3E}$BD&@<;3E}M~Q2^*e+g- z(kIa_@%}eD*53g~$NC$UN5=Y`$|GZaMsQ@TzYrYqR&96F#!s87`l$BKrcWBnS;QL4 zJBc-xGl(^o(}*>eQ;AjgWMb*>NyL(q>BQpAiNwbePa|$8K7n`=@$tms!Ewam!7;?A z5_c1yLfl0>gLopbjf~)f2fD2`T>38E6aCx5wA#FdwDeBx-5lnN=7umWx;K#4cvWBY z*D+?TMKxO>`fEab(O*S6Y75j(o;0w2y6i0&1X$rdQxOCLTts%`Z< z`2IAc{Za6fS?mxpt#&U}TVdIUm5#LgLEvb+yh9FbkZ3NUOznz>+RcXTik4xm)O@@b zoSHqGAEq@g=Y(nD%ptAc4AGkQvje>S$!M+QeR0ZtfVy`I|1@w!S95!c(!7b*I?-|- z@AY_(U2B8?{(V62vsKnenck1DqA%Rd1pQWf$ATkYLTmqHtdUilX@WII^ZItm?_ylC zRhrul(QK;1n%fD$S|hZ-KAcXC6Mn>gG>Bfre$=TvqEoiYBRcguZ}g)&^$KtgXPY$} zEP4O4a7O9b!PJ|2_Az_{>Dfn!rDvBBOV2JLmY#i>SbFvk#L}}55{vE!h$TlC5^G-1 zCzkvzCf1xUB$jP0MD*rq`Xc@d?-yZOb$652oT=VVNJ~EitDVQ_>uCKbMCd$1dbEB# z9MV%e`hFuSr}qIz<+Qd|YAp9s7S)fhk7`@}yB(a`7`{e2svoxitKVw(W~C$gu^u?u zZd5?O^--yb~=Tsh%mn#HEZ15+AKT2NyQ8=UIW!We` zh*uv5uf~U^q({%eh2+(Eu|(+zFS5Wwi}&;6DW($!Ev-3)pzOhBygho{&wJ+zRMnTsJzJw?7?xs6M$>_FIrmH zu6wDfZ(k;szFk8seOpB=eH$Q_zV#7H->xQ>9(<8leE$NmbmmH8$=T{%_@5WB)05HTl+99|x|anRDB`(^sX*LVBgE{($>d<|MOs+@qXUyEb0GY=(jOy|JMSXj-m1O|E}+r)rNjULcdQPcQ}9N ztXRJ>9p`^csLkXa==1x-F{8aQzgckbQ%#lMz1Dv4JnT7j^}b&JSEAPD?ywz;vn0_h zsQ=D-=r7_tfc<#n|8LO$j=Lz=daZkf&0$?bKZG9xf33=$sywitABjWvs*tA5+X9V6 zzsDsWsl6p(Sy;bgLF&zMj}6WP`2C_t9>)j`KfHwBw2IVI-rM-5*J5rozRe*&?;;*1 zJV@9|xQC!~q8`=d{}%+m*Uwmf#P1Wt`Mp2Y<+r)$7xNazE2y)H&`3xz&U(JbSpZM0 zG-HI%hM4~$zWli(0~2$Km@360EEnpkya63-&cCS+3me8WRNvb2T& zwcV2LE5(76%&Gb`9^RfD+`HzvH)$#H8_FGeQQ-ypn zm1`+CW?RtBmKRg{K8LfFRIZV{M)De8OmPO!Z%cGog*C;-ot)E{=F)i2F6uY-$MFqE zBX3`HuV=BJ)&GKg2mf1O+$C%IzG*=*p53rFp1m`;`{P^A4$Hf~I8No<>x|R?8sNS- zIG+}eoc?Az-IubQ1LH9UAoND|@%@iAeR`iBBu4)QHgbE$FX zfHxi;+bh>=D!r5H|WRb6AE*nx5&2(yRE@krv;t3=rHyM zyOI3^ciOxi;(tG7ySit(7CdgyoxRg|nHSGgbxU(qwJCe{TIr|u>UVUY*(Dk=Gsn|- z(uOmnXuI?`mbHpO-|3%zi-zy|8@i-f z@qFHe@dgSy{{dgJ9ojOAhFhueWNVk1sRQ_{6ZUw|K+pr~FCOB|V~Vuaxd4rtc$_tX=G;Uw^mXjH^aB z=r`YtGY)=dqB*d$nyX1m=yvQaq@jxb#cv-|sx-i68en>|UJRiArO0%P*iI9$1k&qN}`E3LP*h>{G6& zvBa^Jl6~WNr5Upanydo*&|Pc&#wQ5DIClDLyPE@fVjZ&snWnF-mCcpLmX;t+R^w`$ z3j_OweDO{u%br^QtEI{BhG*mKrcz&%YjK7jW9?|MY<`!{ESzpNyVGMc-07_Cr`uLF zuP^0JA4pg8jH5GFt(zH#?@GIFCw)8VJ4tt0S-;E5INe?3lfIqwouswych4AZ>S}hI zxHssq4R_q)iE&}4tKX;dt>nT|SG(Jla@=m(ILT@RZgso3-^9fx-ORVor1_r>CED%3 z-RU1n+f_Qjc|314(KqC7VTrys#IU3Kw!RL#b)(^}B>y`}?I_qyUGN;8n%-TMz3t1m z{y>&d*I2sC zGiDODvilAA6l?%hz-C+X&s~2;qWb-E%eWzLaoc^8nsdZ+gggHwnTSCl@%|G}`W zr6sp8OqYj?@s8U){on4|IUteuaP&tK^ZdE6wmwew`*gc4t^9i zW@gDcrMqZN=(6FVjUV5v_ZY~JFZt2`Tdc_zeQrR$(0$iJ53Cx^n3=9~s21r1dF}MM z>8_s+Ym6Ov=Eq7gpG|$;HGJ!w4Yb!c19%p=(>2#ux2`IUpU{UMV|&B(T796cCfbrL zTj+Wd`qgB;YsimXaHB=LmVIQO+6;Z4bcue%ph@3Y``*i$Bz)pbPWdIil|{!6k7F+k zY}p*)T?Jm=8TNN__H_xov&U&|Xl|~=Pih(0($%c-ReGMT`V#SzO7!84Hpjh>yCunP z(~i=|p<_8i(%Yav>WAb$nrAO;LjIBSP_Jrz?)urVKS#Czo3(Yvu#eqnek1Pc_nh>l z#nhwBtL8Yy{3Am)dVMl&YA;v8{?_kaTk1Nu)9b#tGu3EjHZ_`)oA|xfvC{uouFG57 zvBO_``lG&eLBP)@<^)+72>$Qv(9Y|z7o6`F@AmAjy5dmjZqMX^7k?d_F}sAX+EPKs z?ZyjAu?4%Nt5dG`hW$kLdtP1c>)z_Ne*f-{K7Uoh^}o}Q_pdLz{%eIL#rnpj1Ka~& zYg->Gx!#-l*&EKGeMw!>O7X_m;Gd_uyshX%V|GOWo!9}+6Yz3}`e{6DIXdwV=)x&x zh2-WLyUBVQoae!LieIfNI+XJ+CD0kx)T+*8mlabd!#C+oBJbN>)w#NJ{E#=j^$u^q z`@<$~*JOzBk(Wd-C|9Kpy9LF|W%*r+uwA3+RW|7Hbjr z7c*A*lV|W^&fTKcE? z9|-*(=H9=CI?9u6*L?BaMgwvoJMHsEexxRI^QqI98S+;U4`grj^=^Ho%8}m&tj7Yx%b2AlLXr z_(rnZed*z*n3>TuXZOLTxrBE!50m%?tb6tq_}cviE9Df7>8i%*%kDpl_bbrH-$|A1 zM7~ss7qBO}X8AvMTVJWtx`Vm6gnjo6pZ!dO_Q4BdL)hTUicQ>a*wanbhNnJFKfI!y z2!50QbSs`M!Kc$*GaRfV+Ka!ApTHX({F8;H{;{rSnL;dvt<(7W@Mjp4XE}>RqnmSu zDbC~M)p3sC%&{v;e%mRI-%EOY9ckOO;-q5<(iUqnX|Idv5>QeoPlo1-?1L6-Y*W66d73$FS@^70 zA|LqC?7L}8zHPV`7ly?b>%B7vw0;M2fDbfMTR(-Lh`{#rQEMsn*^{X~$hxr)LdTjh z*S1fdTRhUCt>n_u)F)j0_Br@(|>^ghqF8sYE4QXhMoJ16!9`x*<`x!T!T zd=0sRH>|6R-;gV{XYhCI9gW4lR@ZXlYyI09$sm+~((R*m@*>Z|v>{)gq75m?`y$gI*)t&df z_PIa^k(`jAG19t0sA#D@TvVjAo{$8H<#I@ZV(Sb+h(bk3Ayn+x=>Y>GN{hE@t(K!> zXMAQl(=!a?+Q>+Vu_F2;MP7WQr=2`-^R6lk&w20Ad90`PKlTCHteNPbSyj-pJoNNY z^1oQk_XLSCbLqFSXPMZ(IB~{`X$N1uI^@i--!fEL66(ZLW4Ka}c()GzB0XItT@}>x z=}2mjCv_jD@28{7TuYbvmM+jFm%^5_2dvzg$#@8wxHGX!&_wZ88e@LSeLNp}Ry^FA zqmQm^%VXR>#=UIGB&RhuX-0!9+wmCpk8%HH?!z-PvIkX~Cl?(b)tOL~3-p8F6AeYb zPcxo49qr_||EY8!&TNnl(7@vIDc}(8)AXy2{`yN#_sO_p9N~N zJ^xDFp=k+=z8X6llMEZa4NAW1S*$7Od?M4XZ#~*MY3B2FMv*sG(A+8WInD|87?_0B zEwh{?Jf3=#x#RQWZGsCWnkm+X=CT&PvRfTM~N{e)Lx}Y@YdtBMZ9eY9PY&tY=1QQ zrL5jDM^!f)xF!J4rN9yE-J1uj)}b-1SF9tgd9nm2ZC?eYMy^-f)58g5-N zE4gCz=C0$`@YT06QLHf_9N{f$FOZQDqkzhTpwn^xY?vDxr?%ccz-%eHnkZCri* zhK{vEIa`M11c_Z8jUCr-y|HCm+0y0)bE&z^%rTAiZL?;mxT$ZPGi!Eyl?o<> zti??Ys_yDV3rcHmZL4o-Td;DLX>D7U)U~at)jor|WqNL&*>H`2ZP7KpZGPNCzMgFH z`o;z&Q+CDDrk3WV&28SD9t~8gZ&~Pxv~!UNfp;Rl~BS3z`?MXsK^&UbfVbsj1PXH!p2#YFSXQ(w640kesOc7ciYmmWZBi! zx@cKz+Y-Q0lS@I_P(ovKYmm0AZQ-hhMfFP;HW}U8x*8TOv=6NT2SA-*tE7(_KF>|DQT z*(W+SZ(hH)!%J5RjM%#V=FSZrr97$^mWj_QZ~8W+p$6XiQBY!GnKB{w6e#@}hPoKAC<(xTlPOf!MzXwkTejS=b%Pau(mb}94m0t(;o4Oo&98gv7V@;NXlQ6^Z8eQpl{RXb zU*EVYxop{D|Hf)%6Toy$J?cz3TAM%8WN(_TM&Yem*s^RzQefK0R{LgI(kgi6UcRDf zMU%1ruWDM7Y`fOKU$A1a*G_BGlKSMLWi3r+Ar@lrX_eKis-bO>tcwRzOY^dpX6jgi zns2$*>x&P*EkGwcqZ2#@&^OdCUfk3YSf=2ut-g5)FTA^k51aaiw&ts`Jtt)Wg4RXL z7GtbD%ZBP-AcP4gtLo=3YdQI$wCs`s@_phnMj%WN)fTD+=(riYLfq&DJxv@E+e=$9M@yvKVa6p(wvw&(q%__m(wA5p2`e)zGU%ag0!-J46#(A#&83T(-2e$*fq~x+0mh#9O8J zrX&+><6Sf?X|xax<}(c~4TBh|Z)|KCd{`lWDQLT~>FPnMB=O9eB@Xmby(@hdVg{e# zTpq8151NK}%04AqmbKx-P(f?+e8?ofLj4h5NF2N$#F0%|u&kw_2@$EMs{vpZl~#a* zlm#o6!tr=xZ7cAoY;PAV!|O54%Lbv~)@OWLYlbEZ>!JJ-z-i>wilrZ3y6l>zmT`nI z7#7qD%4Ynsk2E!|8f?SDB_voWg9DqcZU#ntxND_B;JA7`-+He{D-eqM#chiu?TyVt ztSUzmAImRm`N}$xi$+Kz-~44thxu$KN-bXj^g}7uU6Wf{l15b?yO*Rb7$FTVXXp|y z$>pWYI3;DKpMs(<`5W)V7!vXwzsN7RI3Y7Qg7Y$scMQXCGv;*fqm^fy(CAo5m6XTA zW}FF^4>0Hr{>n!gTmP_XgV$zE=v>37F*S1xvjENj>7%3DLy1$~f9|CBwoaR8Zg`7X zYc`wrnNI%SWV-C{R-QV{7ITTY-fSS{M(#W9n@h|Zt~U?XKR&$3EHE=n+{~i<8tzX1 z8xuO;!ngM1_9JFgoas9Dv4+P)aFLVlij8Y=tha7-aij2@rfwOdA9wL>Q@4%Le|RCd zKQq_dvUxp2O3%ri%DFEZJZiAuq85fmqOPo?)Q`)M!@c?vY%gB5axcYGY1`D&u~B}A zMyD9oTNkX}u%*NIU+|FJ#?3hEo8>Ra&BIUJvS#!8&aO?Hw`im&??B#PedB`Jvo4Lh zTL$g+hFeQq@wJyQJZ`MVF}>7x+sYX?->_!GO&U>e+S=uAy20JN`o@kRmztZpR@VMB z8OzNUvV3CohOHg)`h^xR>H1rgdTU9l-*D@?tzBz3-LkRVZ1P7gt`I0!baTgz>$hl< z!8#Y)rp9Nk^sDyn-Rp04*RJkb?Rt+luikQ#fBV4?xf?rdi@;&u0`Hue+qSI&yj7hW zHcY!{t_wLCh6IgW_=z=}+%;P_Z)PxbAvn^QW#$^eKrd#@99DkSt!qZ8qI2EqEgkL_ z{OvBlKDCzk8P&2D=X|8nX9mOOO7Z5D@EnQqk%)E=W7I zo-+e!%i5dW4Vz9aed!rNq0;NtpIZ8|Gb-I-r(6EiE@(naoOmIJmpH=T`UGzx}wA_{j?$jIH zC5t{eX;^1QU@io6?fOs5JQWecxoU*60)O?^u1#GGD%}|~=iIdDlc(0R`VYfUA|vk2 z>o=ZS$8d%if@Khur^TRq$t8$dd^m3oRWT^4;9(Wo@zmx)MSy>X&?ubsYb_zHLSnE2 z$}RHG0NoqczjxY}_4DRkcG0QLoDqm;Cd4E3?o1i}G(|^}v@;;fALekMKBup1kUl4| z$?9#VBJd3AIEiIX%dmDB>!Q@H!C(q<$Y{Vy^|C>pF|x+PPJ380p~rIb&ZX!7fzngA z%yr+fh8azNpoSrnBwam3Pn5;btDCoOn|4vDXr7!mKsst?PUD4J+zZ!h+8UH>zz1N? z=M?0}QM&@&8@Yeb^H5|KS8v#`>c-XUH)<~3n6gMksC?8oXH4|0@YvCnauO%w;{{b{+qXBZ1Kj6S&RG%zl|OH{Z6s)O1Mu0hcX|1KK-xC)5ocp6zw6~wACzYE zeZ|Z77-_GQ_HO0-td~#ls!p5lvtGU)HhCQN+lcsSyIBqUC4ngV8%tp15Z$k5S>=}X zYrEF@X_~b3@|A^t5(1ruIA&88I%4lHxA%A1d(PY?{V(i&y}e&=?-$tnmG=I_+?!CN zy-$|hf5hI;whKLQ0eQUpjrM+uP2W~>f49A_vFQixJsslj^^*JlviC%l@mDLrHDciJ zGTjS6{=Qanzu1l_y!1UK_g;$kzp|J9o$<5dghJtPBod8|8Z~-!S=pE|<>h0?R#cpI z);JvgcX*qs?(9wc=%(YXTi0#)*VK$k(;Hv(X1kg4<8cYs^Rs8TErG{6Z4-tT=NTj5 z-hiimk-MT3SG5DbnN{)`GiS}d^s>w6Tv0#2p|MG1F$15z@_g6F%TT|7$p72Hb%)P8 zLE8U~tIwilfT05ooc#q&0Phb6lR^zXR-PL=31C%>ir{_PjIy8IAP#*N0H4s3Nl*OfB5c60p-SFIkS z&dkeP{})$PulHPIs34W|u0*-$nR2mz;7YmJF|L%0J;_z1zeQK-(N*$5tcQ7ttH!Ln zkA1>>Z?C+Mah{IVp`RzuA~HP6btMgcp8G{yAJr8-^eFc{#~$ICzt|V~&*l0VuAN+W zb8RNy&&cAaK=Tly1v1`wOA%6Zb;#WB9bNr?3{d2W;9b29c_A;DFxext` z<>vm0pvAvy-umD$I4b-+#4F{LFVtH>zA7XSWSbNu-PdCBwZ@ck1IziL!R-6-%H<(<-1j<}P;ld=89FO{T` zzZi0QDc4;r=lv6WYt~Ck*)-i#Ujh7-<1_Ue=lDPi)C^glA&1^B)8be6hLucD!J@y#x+hkJ(8dh%rv_z4>T3f$q!he%>S$ zXVZAk{$k^H`j{j}q@CZB*}}2#=h^=l%PFoZ8oD!U*wY)T-cGzE36pm@6N4D5xsljI z#nF_X0sVHhmuDTbGoOMU1AO28hXVr-XMu@Wpn`A?@0AlDR8ZQ4NKElKf&tDGS#JL)rCs5b*22eQYCd+_&E`Cczr(yew}eDyb8bK zG4ark5>{nsztYd&=+{vJ z|BmL{tExA`eIlX#9!X-?IWsxYZSTe7u79t3*-uh!Dx7SD7{JNZsX`4fj&f4qE>$#+ z_Bo%-C$=vMzCBjjmy&*n=CggcfYp;7(%$E%tu*^5M4VI%b6lsqQ~h+F%M@oD%63qB%V!ocx=&hhvicx~UirCY$c=+F@86_>tHzs|4= z#nQRoCd~2AoyD0-C332|lHlWhA4chwar5~e>{wrqjP>-$y&pi2*fjJAX}S;e$Z%Ot zz>6FB_C(iFPw!;~TSENe!6%qULx&LG&=$NVk*)3p&ImBh&^L@p7 z+$re=rH3kN3Q_V$)Fx#rBPQ=owDEuTeQA4&w~qijaQ6rO7Ef$YpW781IMipsXUke# zBntr^dePAV9_ILX_&KyX1rH(4yIUt-^y;jD$E)iNTVXw(4ceD}-M!l493248I>ndZ z89gRFV0DkrgSyu@1a-bCOD8tp1oQHQut|bHb8(G%ne-&SQ<7L)WQVq_&Pj2mZ~%8I zTRqX?j0EWSv=6u8eHpR20UdRvTy2cDUKOwHV}B6!2|mI0I(^9|44(nvta^0XxXJKK z*}c}5nX(<|f8c|UZ9llrB==(qq;ufYg72J>dh<6`J?TSX?yCw+!37pUBd~|1Z znC~x}NCi56IrL3I|5R9g(mAfR+>b6x(dLe#WVx2B;Y`blPIztijwtRb@ypD=nN}*`Pn7&6nwqXrulFv~h5P10D-wYY@Q1!75>2FYDeUt^b0^>9{CqJ|0}q9y9}_I$byl+% zsji}n{Au>}K0*Ie*+N-2SLz5kz2JCPF-pI8&h^d(nalk@o$cL!fcuQ@GqlP1`g&K9 z;hQM@YSJ$hV`wiEa@t^v>J!-Bv)4 z)hSJTr^O@6FP|t#6Ry<8sE~&j2iUFzFCMPo86Q`3NfQn$x_}cI2)-+_5?y)%ed2w~ zm@{(dm--~#!8c<=C(tPqmm_<=PG~^RNFPsnZ5c9o)XyKJi64KBzOVJ|$6&gPUjyF< zwqnDTL$qt84kyO>bd;^veS5lKI=!=Dh3m3*XvQzr`2sp`Z?U3tZ}CU|nct$H&IVCg zL;5Rzy688UPMPnLt~@iTUvpOY!dcoH1>!4!2V1J?unf{i!uDo z8h&N%U$Xb=EB(uZi(|rLdKV?W&$sQdP0Yqw*?Zf!O#%J_o%~Vko$xF=wh2C{l5IMj4N45NO(Ee1+msrX9`@6n zz-9@S5}O4t*>a_D1U9StO4BdASbVJF4E1_^n0>NY;Muns;k4|Y^t7k@bPtXS_Ph7{ zbrufin43qXi!nv%FzKNa`@dRNW{z6flYT7&XOy!(FV z`2p_%rby%q=&Beo^T>Ll5n1mltZ0{R!2bL1Bl`J)RgJ9%$LuQ#^eJPve!bVbK%ZKDKSkd@;LI1{kg>egr+%8%r}!@5 z4ZeEN;^q->^WulhdGNaT-T7{Oq}T(+-LCh|h6wTyNu=+SzbHLsQg=Y|J0=`_%?}gvxV4f?)45DR-&y(Nel+<&T{$wS^8KQT=0!rW*ZQV|f9G>`0$CI+ z@NT)2`Dp&IFY}PP&h|0ljqOV1ez4Zk%uW*>>l64U_2S&I;X3 zCJ^OYtPiC8G5n)O=A$0>$CKjK7&d?L(nSpojZ2&4V_Th=K*nNOeM{}QNoxF&u96M6 zV+-0}m`qnUGGCKu?~Z|Aq_^F*N6Xr32w-$OaZT!jVP-)8B!qVP%h=WYCOmPqm{ zKQ1*o|316k%HU#Sw@OB&NabO_su)u!B@+sU4pJsPD zH;o@-*jz&ioH`##@L3-sfDc>>SCYSRvC*8((#!WWI6vbL!265;gKW{3+Nh@u@!t79 z-@#9LWcSz!yFSJ_ZoYpdehkg1da(XHKL|^wG zqCIS=<@FH!UddX`z__CY@u=qf#IqMOb~;G8-5vXjyC2Xz@iq3GF~gq6Nq^5-Dk+n{ z9vZ0L^QpJo`FvlQv#(Fj7*Nj6y2gH2^C`7mQs#2M%=lqt@G0tmxnHu!xnV>}LTk!i z$=*Y7Qr82_nxEyq-0KhL<^kjRv3k+9e42E+pz+ip^Gr@{mAlLZqE`>|+{5z`uB!VW@}YX3;wl~bROlJ3xtM9lp8VR|NV|#gOD%b$!2JaIV-fsA ze8~j&qkpmg^8XE9ro3Si`aMz{`bjPhPI@`l6GN8AqzWN;Tk|E(4DM zNv0oIA|B z&=t3bW3;1lVMQy+uW3hCs5e6$lKn&Igd7B^ zsp}x=J0_arf+NLM&wMjAe=ql{cfr}%+%#iMx1A-FdhU?U3_CkcHqhie6>_}-kGyQ zeBp=>r9a`hx`V6X7wR9+`+?c1!ssh*FNh}M>(%5FjigilNqC^lL-;kSU-GE+GnKXZ z;g_KNc<^t}g=LJSwjB6Yc{1j;To}Hc2W{k^>}1VLbb!_cOJnYjK+hvw4?xG$(O3A( zq+SC?*?IG@?3ZACbF?`w*wi=dQr#i=LEi=Dypt?>iid2!>a&&D_p#V5(T(*X=6E$G z8nPunq@L2U=+#roN=FB_2ZwLa9y~Qdn>~|-&-$$NTF`C)^Q)AVeUpvQH&mTR}#J2H}hS+7RKbzLA+qlDW9Rw+m4xper4>W4}Oxfz2|u{eHT|fTmOao8s>z8 z=a}S$cSHL0fj(z-s!#l?{P+0zgXf4ZyW&;x=+MzU8v-aV9qD|4!fJvzTq-#hrO)rN@gG@(gWq zd>3sGW2F8}Nxk%au-*#leX6A1EBtzU&Y<2vr${FmUtdW6MGJN`Se*YgSMl-V@UQrI zjQF^{yJ+}5sjFeUc+{JtQ@)?@9vwZHCVmv3YK|jO!jr$$x2k*}J|VtjJ|e;zMvp5! zr!xVUSI@_vk1$RcFrmEs>W9I#eBp-GPB_~jfv)vKX|uP zd`B7T$sY_qV`*OMORu9{@n3xj+z*$)DtZW)cZ17?;1c}UZ+fdQk|V(=J*qzc73E~7 zB@4#oj4j$O_4!q16h40q*VfrdN z!6CF}{hIk$=#6cWKVA-B7gTqRUw7Q6ujFywj-l})JW~CB%7?&X8G2l}UI(s4cj=Y0 zfO(pa2j)C1&kXQ>dYthOW!8avmC?NYY|^E#h!3lqP8rQ(&gS0bdO26V&y^FMDtx%- zk`}b{E9@G+b$`HD*MGpAXZeV^dbKaSA2iSAJXlQjDgPc{B~RT}U#kuEBj)$xGT@Od zS3iD4{Xst_gCF7Mg_3@Bmh>a!_XBv!n+)p=KJJ1(DZRNQUHwzqqLQ?ruP^FbWY9?O z#fw2*0bKtKT%|hO&|f`E=N*hao0D(z6xSa5E1yO@CLQwqb7kw9bKyRawa2MTe5Y|L zeVqXBRxfN%hZ*mb58@IY7T>DwY225^oUH2Cy~gxC+$WG%`H4@(Ua4C3n}PF$s~zB^ z6n^oj<~&M$fZ%&^)(2otNxW9J#<&02espVp*9nu*@9-~5ekuGuY>#B)Zu+G@?%}Fu zt^Yj2z4a&IY5De(%-&=8;>EJ$kk75W9PrJWah5q@^yNO!r&sw>pT357%KLl29lh`N z>z7YIQr&{*1?nED-oT$%y~=ltx*W48f3OvwekFQ>IWC=JEnkAMh_%ympp)#eo~37{ zKV+wyNtZ5lVoiD3>Zsv7D$2@Es}AgR-Qc*1wn}|!&50ZakCLzd3=R3q=hLomE0|6P z53%PX!ZY>%13aR=?9aPsUw({y7AE2FJ%p3wDLDC6WMmj3X8^qZ6ekM*DhV`W*7{?D{%j8qW^$7ct#M@&4C&F10<#yW$?K?NJ%w+_OC^Yz&EH zN$shv3A8onzxZ=Cnrk!(@Id>|F&`E9D4J(H;QIlZdr-Lp*!E1dH*fa;h)?}{#nB12 zM}ST3Q1+O7a;KBC!2&yxOy}ycA;_a$19lucS24G-N-}vzFvoN89OmfpQKX~n+(zJQ z2|o2LEf~>Z$bXfUZQvArrHAAvi|-e-r>hUtdiuxVtik!{9rgpzhpRak%G3pVop!3F z3!})Lc>aq2c(q&0lOl44Gcm_s|J7fgzS ztdzf7*2|cd7-8lq$~Cu)yh+X`Vza``U&zl1^zk~{DV-BMMxP|BfztO z^)mMl&773g*@qcpOIIsTDAZdW3Z=r*xku=e`Xj&Qu&a5RM~kV@ow*R_0Xq0!Rxd-# zpshQ6*wpS>e!KEb)vo+r@rm@cZD&-kWVSyAUks(C3TFb>)szz*)&E(*ruJVaW+K4F z3$z`;#7B4r`+p{NpGlw9pBVjyr>ewT*b>g)Ll#ndi{RGcRQ*z7xoQ{H3bQ1oD!zTQX1ee+u4XbHaan~JYh>_Ein&YJpkZowR{Os=HN?};yxt_h9iTwlsKoDZ%u6PwyKw%VEh zD*cfy5I+X?*RH|R2d5KWB;Si~!#9ac4qM0=?Exzn8slp&#KiGoEJ&|2={=W^-sX7aF&rhIyKS>Du`AZU9ObXMCM!+qUvzbRqkPU_0w1C8UT&+@g#I*YiMUr<56Pe?{e{SRnK$F~Og$I8whPX8wdv=oiF!v%Iaf!u~x2_|eSqt2?K91H}9CcebKQB1x zXOl@+2ldGhu&|b-S$IpHgK^nSf=B%0!@|5;zvQ>9gf>CDQ~Y*s^V^iJ(A*9H_p42{ z5f!dU6U>(ba}@kgx5bZSp)5umBYwH?Y0R#o><0eg!^DkWTdf;O| zT;B?_`~)4!h_lyxPmF7*B3=0W^U$$3oqIBl596i_H7;vD$d&XevRMdCCq1sSO7|9H zG3*cTrMIplhGzqHuZ(>*Z+iC@KX;iqejU#T(Gw}k-A=vps53>KC)^iu$ZIaad+BM_ z{U725?nM{H7U~;jL0sf}E@h588cxg$JBj$^9D~CNk-?c>uM^|bT^>&K@{_E@S7VnF zp1vp}&bcD?Ionr(k3VouK^z*K=)&te1Y}r1Z zh5LVEj!!xY$F=S@Jt>U68%=Y|Z&3}+C9hD^S3G}+~xDj~Or+}{y zB)^e6$j=e%o!@{)yJ$CyE!oA~=lSdk-r2kET`kC+6!MFTmD>~p&&Evcu+&ZzN)PJB4f+k@P4un}a`84m2=@m!9A({h2nwnFXVcvew-_#9p=J| zE@jR|CVL#xnDdrzqxY8o$n$RX#o8BBw*k5ZefhFK7E>GIzvc905m)iX-_RHB^9lO$ z7gvW36&X{2+HHCLjTMDUu z$fS?v!kt!+;dm)ou`tck3(QatV90jhX{6Ny- zyNc4$-|6F95p~hTUD>aZf0Vg1i!I1qOa7?Ym4znO#)&3^jXC8BI+tB|6wXBdOnWah z9>T>)X9$GgY5eAkRR{RB{-f|GeJVX2Z-+}ium^*mc&Qm$Or;mlVKl{~V1J>4Dm5)x@k=1-l&jsv@e9w-o>14f0 z-=GO?&pr81irKo0-xutD;(hNE>|ZF}U(KGu`}k4Dj85m=%8d5nmhYZr$KHkR@cw8+ zOWNUEu2IRj#&%PHqbrO*(<;0vHck7w!27-(#VB%nou6)Fy!m!3W1N2FQF~*-1@1t8 zg7|IU4zk}XnahPT%+J!#ulR6{L6)T(46)%se(4VHxfi{Yf;M-ckNEC8WuQ<0G2$4G zg@B1~!{(70<<&Zi_DCyVEBT&(99_HbVT*%hw%nM!`UL#MsNGp`QrHc%$G%_4`;c=k zV{~sUD*li^Az1-7V7a=$7?5($$rjjhYUc{d)g~S;evA9dbZ;IO&2mnAI;{6INUPbm z$HIOI_o_$yQA55E->cEQ>9q08|2pa1J#H$S<{MREV%GHCL6%H2c5@m`^o{?wrymC_Uk|H{Q<^a)#hN%fdk0%p)+>V&N(yE%IK$R+-b> zlsPd89YD-_61&%~c?;mBkE;KFrVIblXV@Cj!=`%>7r)`1d>!##tzY*qNc(T|OyR#u zaP}r?Cn_i4%MqjK?4OV^N2?yY*qryd8o|Imsd97PlzRG`l%2Z2IMJUQ(pdC0o@2}H z8dgqpe4Xcr|Gpx2|5Rk_)Kn&jrpmTpK%(!=~@CzBck2LEfB;HP&MPH}eXP zlgfw6Q+fH=j6HM2Dcbfj*ykwE_}>#=H{BCz+wUr>UF8{zY#!rYaMzj#CqPrp`<17# z-@gv4o)~f8cX1wo;tsOlyqmn9EYE(^w8_k+_!sAz#)k?RRC%;o`M&HA`=1|!v zu5V9q%+_oKzfpFWl{re_rSU6W|I_L}*ejX&Qo>-9Fmqfaq7AzJnK zJ13LivmM=@c)-%}E@&WLLbN%H?k~#Eo#&5hv()F}&k7g9`|qlW^TD4x$}d^Lc!^(zUkth)gclwifHyjQ3`ma+Q&N1s}Z27MM@Zf0I6Iu0V1P zKNC-ztk%3XJdEzOv9=HIG~L;r(9ztu@mh29Vw03d{Qq0xk}|A^p$wt>Q2tE#XfAY` z{5`B8{5P@8A@Hg7y&mRJW&?-eIRPE?9OpR-4kO4$HZECeEp!o6!ral|x}Ne%UbU{5 zqKx*#Jw3zpYv1%D_$XZoU9pXGVteyTz_H+)V;+qTm{=INnXh}4Ih3QojxA#CyCQ1( zyTPe`Q>ur4->P*I*>^dK;CkByPGVkyd8{NpHt;9Rgo5UQq{FxP_|$xlY@+64dg*I0 zAA|JS`IvttE$F{uGk&cxr{8})pWr#@f9blW`v1NVw#UyK^nY5&^taKr=4j@iw^)M{J05)A2_Cb$*{JaidgmcNVolE%pA1+?~dsgO&et!=r`w)FqS}`#&|e&_oj0# zJ}$%qQ@M9PwcpO^3%1F?rZrN{^Uvn0`Nd4=1;#Cp5?^4l2mE`~b^ajt>WA`Z?O+Np z25Sum#{amAd4>tupADQ>N+-pWglTgkYum&x4Z^K81@-xL`h4K}XL5|;`Zeb%nEr?H zreLZee*o7V)!VbBuxajdIBWrp=T$J4hQ^|;zEx(I)C5xr<`C9B$`TQPf zrSe%pIl(WTBlydBKAn6D|3TiM57G}m3!DC%C|4?@lF48kdll9-Iwt z>fL8ZSIocoU2Ts;XNez`PrRYn7Rl1hNyc?W&w`{&(~_knvzIlGT=sEVsdpf!W9uQvI zuf<;gwy2LAm09Sw&wMp<>c#PYl>D0ei{eLz9B(a8ex26vyf{$i0l}MFmdPm|RKBYA z?&!VZ7h=em*7sDu>eZZ#c;ztl2DBRQ!&wTC-d#X?AalaE;Ev+wNv^;D=8!%N=oZlR z^VB^K{H4H$#xwzsKyzn&%#3w_Z@7JEh7Qg!oXb80bS||It6W^QD z7zKPp>020_S^YAc#z$%IBzi$#aBXo{O5YHD*BXxca2v3>w2PdS-#QFV>FWETxAfpj zaQ=_@D~WdEe-l~{JiD;aLDsEL+MS=wd;GMb%iNxPOX2w$;FQgkess2Z@pf0yj^dX2 z?w_5LJiL>6VD_eEB3_>t(&v-(6*8yiOoV+L)O#iG#TUX4V;)cMk)9-dI_bhc^Xt|Q zPKWm-yGMxa690Xt5?f3kOMTPR={muKU!8jmUSX`+Z}Ar+u7|kMD6rGEJp<*#)G2+T zwLQ(>DPAfB&uAW9csQi@z$CpcANfX~C*C~_4%vV}7E5h_blyU67T{-qdF6ojkANHD zLi+DR%0qkOX-{eGU7r4f{uW2JKR#{+qwt9>%$-O682JPJ=gld5{W&yBd^e>34viYp ze?fnx|7>5um+FIDV)tFC586v%9!|N899UYZ?A(s>QkxSUPC{m`x2djZak;pu48`G(v>p< zu=CfGC(xDOr*4g><=cxFULv3Nvx#@LkIne}E86djb!RixFOqjTalSjpJ1d{Arf-(^ zA#;vh3kv+sB=xM@x4*cvy*qm-@~Y*BU$HJMI!O)>MZV#UO`c@!mOj79yFe}jU8?l| zAzknZADZX=6u9{%@xp;TAgleFm#ATG!`o9aaAlW2rjs12T&dqESU86!_XB7ySm`&u zJ^KgY^CK?%U9oZZI!;zG%u`op?DyIQ?=wDp@&UjFHm}LXTB|?GC!J2*5b2u7SfTZ) zQ|zK>Sq{FxRsz3Zl{{bI!&+(^nGe9X@ob~`NU#Qcgw4!-_pDR-DA4zM{~@1`0)3BB zI-ctMX5sN+?Vn!XpHq;JyAzo{O zFC0l9A3`>j|1t8%NE=zt+kNDNe(s@B&kp*z!}YxC5A?k14bk6#zhwI*OIQ2wiiQDP zO23ixKwiZsf?xZaq_58FAL2Q!p=5z~g^f`^r*Ic}TZZ9JzR6C~#cL^KHW;%pmD;bd znS*R-opB9$0^Q2IM|scn=NAw7zQ%Om`D1mZ&Qlr-p9TF0bmj4%o?cge3?2}U#IFai zyXOz<%jtEc=SN9b&Y)j`uKYc*B&UP>kI|J!fO#YyKYIiocYIwb9^a|=;62clGkqTa zDKXxGj*yH6e(rF6nSwT&BMRDPPHRNDok+be535shi(P+5pZ1%S(cI$SQJ(Qye+~1g z5ze!fJ)L9r+Ou5UOU!ZnkABU~>U+rQ&p6f`=CMX#oO}B42@1XsQEuYI2gbB& zt)%Wro+tXx=nj&IiFMP&3VUZSYwkDL*ZarT{l*#8y{KXF5}mDLn5TAVGyEJ^;H{d) z+;QT4#l`d?oM0d4S#7dGb(zGAz+Hpg#UA?Uk;J1ltld@}i0NGwgDZa3pO!3}fS2^N#MFdE&EQony>L zaE&rm3D$K<3z1f45}xh(SK?G0)0o%1W+wAPJGWVBzGcVK)7rIObTu(oKXj(nrXBVL zQvG)4J)%4C%Z@ghJM&TKD>y_a8{+{DL!1dLT07?BjM2M8&Z6G1#>n6adR7syCSFVB zLRI8ro#a5`IolWcxf%0ZZYnZr_(hT_Z1bIYHrx?gh)sxh=TnA#LyNv%cvCiq^NwQR ziZ#o*$`>P_*4mi+!CYKpV`0mn&5K_r#s|HuxdP1@)NmENQNiRSHD5AUaX-Y~WQ9Zc zb#APaen^i2v&yQR{0r?Lm9HHIKIsy}z6;I$jisF!I$@OHi!I1Ud!WZU_6Bg(oblfQ zuV9)=o0-H9tq(9Q>A~R&j+A6szI!^?N4yW?ZwupuX9mu*vAq>-)}LYAd9l{kwWb`< z;0e|np9leqkN5N4NWOOb)7XeqQM3Wq7O%q5H_2=FUJ)}PTR#e3kdFQd@M+B)9?8Qa z$9{)zVGR2}SQ8MxIHo=?8H*|Qhy3EV@IJ3BXF!FBSubB9Y;#NS~%)Q^9*F<3+A z+}NBX{KQIZeNQ zM8AN~#?-4%b{&UUD)F#nf|v_bf3|RcJLho|FSDF_GUipw&x*fBz6)Vz*D3tWdgdTM z%NBv-T)2vSmY=@?Kfelm;%CLW?#gEp&*s)qxA;kM9*!IE^4AJK6EDYahnHIm%(21C zyYhcV-mCn)f?MlRtnJ!!<@Ky}zd4DaH9Y1K@>{+(fIO!Qzn_@J7IzmjG0t4zj1|ot zXpPLc-gzweMY)3)n|{@!SQE$cl)cu0lff94#w2CN)=&E{jqu*NI9>SO2|oqLL*vAyBY*i?0`lYMiA2jZAQ&iF#3A8%A!bx&~;XH1(|FLii4 zs5*k!pzCbR#@^yB$X$jpf$C#F7_6HNYtB{IPTtKSmL-5697Y`z3pWsJOuSF+M}FL-GuZnP5`>_L|IVK>s^cjgpal_P)b#dGj!9CP6I>~{Em`=opOj7w}0@3-gf z&W>~M?TZXP@3PNj!Sg@fksX^M|K#0SlOb*>qcV49$7R0I7YUxL_GF#d7y8PG9TME4 zIr9|2xm@d4dxA4JWN#G1Dwr&ZgRpIhcP_p?Zzdy8 zuFm8hFP+JptjDLdlkO`zz$QMEKd0w`X{^=O?!Xt=UZ}0Qow%F(iub#$>BeY-{YeuY zFD=S@zCu#0<$W3LjdnxyuSMe1@t%;~mXy<|ai_xhVQU^#t-V zPxV)w`kvVD{wcf*kMNFfDD1nf1q zZkQ~ayS&iERcD+mR*SZEX7X5Pmu3cZ5^9InvkU4LK=j zg+8}2J!;SQFDbY40{PjT!A@D_o9OeL)st>CtNu=*UCAMMEQ~kl8JyjEX<2;7OkkZ$ zNK&4(+%{-Pnw1F@ki`Z4v$$Zt3hMy(qNkq*Upu&pCsW|*H+apd-@3Z7Xm$!e(NKK@&o+kHC_W#5Vx18l_7zV=c;rePQQd32byUQV}Nh*kK(x_^h0=a@vQ`x(iPjq z5!OcWUcnw3XKcFg@BeoC*rEt!PZwJ>9T;Tmrunf&-?@l$KzRNsu~yp0F@<~WgHimG z`1O?wiOsx}IHF5eElwtf;)o883n%X8Cx1=&5biR-I^;*E3mZPp-ix)^I`e(+J0&T_ z9>;RhAKLHiVBf`~&srH_uQT!{|2j(gY{di;b5jdVU!UnD-sJZ?eigHv#6*5BZOV3w z9~cMq&-R}+zGuwPKiz-U7z{huKgEBR97K7p^`DUgd|HivR$5)R5ZrnDQom2XlG53A zU-tW`XLzhGodUMXhiJdI5UJd4{g!Xg2QMvU({ztbwy~vM{Px;_S+bHWBQr!Dm$YP2?l$D*r+F0v(T@pdT*dZt&^w?IPo* zfQK~3fzmYr4isl7JjCg{_H>S-t{8kC?C&_ibD4BhJX_G-9MQQ!N_aICtq%hFdDNOy70>;>Gbe%o`<~%_RIpsog9e0nmg#e>aDLZzXT6{8-3hgM!wO0zOrHY zwv!JV|82%6{SNO`UiE0s%dXS#K4j||+NToCTkM6$*PSaKP3HFC*Xs;aVA9zn_AJ|- zTvcyR)vLKflk7Z27WfCxul*G7-)&wkYJBub`lIrKa{=j3QAYlbWcYxcCt05RIC*q_ z>?Ya*A33v6deqJbKK#Z?_FkoSai$e#Un-{ZtHe~MP5y6Kdsm+8sb{S7Kwr6k=Ix); z#zFNnekVFT433wxZe<>R%6%=D>ZP9E*O@+lC{NBopE>vSMXPkq?s9kt+sApfYS*&?%L~hBGZmvf#z8?l1Fn<5 za-x%;RDEAxsD8Vjf4SDb_B4RcryP|}7T%{m48z0g*LZk1G7Jw3eYo6Vcwp|SPBb6F zLyN`3k(h^vBNh+KbKX2ufQOb6JhWImJT(jt&3=2L-=fP;#smCOo5Li`fJFUdo2D%qyjdJKy*9?19YlStqrU{cgx(=GmqVtIbzLexBpUQKT;sZ z-1Kbkb!69e?juIQ`GGwvbS3W<3v;Evr$uwtJ>!`RuDwhA%z48)N7kFq)?B;hvdjFr zY}K)f@;%$1L)Msw-mUrHo%U?aV0|1MSC_KWsmc%lW-<{ecj^g&b;%GhcE5bIz$>i zVeUV|#3L{#rFbI6lopZB2 z-Yexb{Mh_v@F!klD$??r_)F{R(p5d%DN{n1$h%Kb=32skUnlxiIHX=~?(uUT?ibc|07dj%O*K+3}pkoxA&FJ`>I~Z#A69 zz6Xze*ypjHd+0a)SP0Br2TtZMVtU}Ok0=Jo@>iz%C~}v|Bm12D?D3Z5^1VK9WkRpn zKHUjS>i-z}zl(eEN^mCgJMoJ87|7BXpHEch-P9re4C)Yn2K-japW>eYM_N5MrI>v^)33pvY# zu_OLF=MBgYgAX+Z6OJA7Yu&*pKiA*k$GyRIHnd8h!=z{P%)v^(HggU93f7_PWUqUA zDHn$}%olj)%sHdA8PqNNrn--uVck)15ZFq^-~{JM>m2FV8HWVE%1o7G9MM*jT-FL%KulYRy%3sXwe0f4dZ4qOwrEzt51*n1>pWb3GTP}xc?<}{3*C+9o*tx zI2Zmi?2i+SH=G9d`+@U1^hgjpvXJo}=M#qbHb_~ZgQQoUXO2~RWfs>+Cpw7V8@i&C z?0JTqPpN!krf4tFP+D-lw&YcN-b>FSyn%6-bdJvGI>Gtc!tv}iB{GV9J^@dxUEn0{ zU+5%)>obd-gkbwA-&_lDoZ0-cb=x>lb;)0F3XF_w6EH~ijH1+ORZk!$dyyN+64LH%PI)%ulc=i8@g z|3`lN?zWTVO!CDV0ycVg-r3!2{Z-b_?AT)@dvgeX<`Di&sbA9y4u|8bhci{JF2I-4 zzK>FT0q-EbzIYmVzfyuP!E9q5e0&41^?|hBi9Nyg4B?6x7K^LQcn?>Hz}2A=TrqAR z#MP%y)Al~UZ8Hp4rDxI)$5&2z2KiKMnquSL$q&TV_GgfZvcM)I6YyvV9vzg4pYaVM zof#7bSDYJ_55=@kHJ$rg_&cEaY{5a6e+ypYS2>B;V&?Vz>&r_d%bWo!9%=XF z3H(32OY(&7Iu}1F_y&gZD4tkz5weX;2pvCy?$mu4-QL4_eUiUY+6FdZI&}s%Ty~_E zvO34LHqCjH%%_Jq^D^YHcEq#BGKcUdg%{-s`R9q+F%IdHY36tAd7}EBmGc37uh8u| zVj-+QseDs18V|jSzE~k1xmfzn<2)} zl+}7cZHlpF+B*+3Ma<$f>auW_oJTs8ma_c{`Xso7qmlY1zri~;2*Azl>it{cR~E_+7LXwD=O9pOcbhd{3g52gGkn12ntnUKeur8o+B zbB52G@>f*;<9`3do2B#>%}aT;l%^x~A%ia}dPRKxd#~RI&qjJYsCfCH-EY(GaQ}?8 zfIV8r(iu<{tn+KX`=F0Ntm9~x@g`%3Ku<}hl}$FsHMX;U0dWR_PLeJ;S@bC)l2k}=C;=|~b;9}Z8teLH_@ISp zoUP6HuJ9hNtN9)ab9{x_T(vG#fzK1Fdb&`-nx-LLwpnYels%@lwWemzu1X<$$g_Cj zr*-l}{B?AEr0bTeU2pBOL2K^%{x55&^}rw>DmW`jdMV?+OdJ$(HN+ATmxKNEVnO83 zIN&G}+gTiS9`-frWNplq;*-u}j+Y;Ek-4`m%qjeNFWw6HCphPAuLk}JUSGD`zD%co z!J23EJVTu91I6A>&7*j+7JLI*`k`ENa;z~Or(Zfpw_o-aI2qDDIQU(fx#1Kta!0Y7 zwri4nhnO>5s)!XVBaIIYgNvcOGyS|%IG0QD-o%sCC3|Vt@+Wm?aU`+i z?ZukJ?a-ZX81tP)#S@BNPjkkz==E>j)qaCmv={(j(Ss9ovNo(D~+dV$XO;MrOHR{j2Bjyzvlw=-w9e1kJLx(C;zGt4h3<}6r`{_gqSdUVVcj`0ag z)}u9N#hfR2!>>W7a*b;IpfeN|dsfRH3GD+C4$H=Ut{BYEhiF^h8@I89p?Dh>(Hu;V1vQBR4?_xTQSXFl)LIztvBC){#fF&%AqB=57lv=HZdCTQk~+AX!~Kw zui6XB%wr8srdA2+;58YShiuU&u zp8?)?&-*$t3EPW{NWZrtkzXv`NFS42pX7ZT*C)8PbJaPNYq>tcbsg7-xNhKjKi6$s z_i??A>)l*aTootK%~f)or%^m>s-V2( zR>tlx{+qw{@*XQ=^ntw6Q^JRHuVX@CC*o9O2~`RA4*cq)^&c?~!^=p*ghJs6Oi@!a zbLQH$36n||#3$^aOEspMc`o6x@*B|MN zB(M{`;6cv~-PuU*BYkD0MTVtSkXAMs?@;c5^@ zt>eBclUo_vAC=F5tc1tHD~c&wL>loWVf^57#RL);6h$Y6#g~c=B)v}Y+KNHZ`S}k1 zgJcWYmu%ce8%#5JZACt9vXM^{v;650zi?LgR=b@p?Z!oBhefa3z@JmQJ#29p+tK&2-x71~)7Hko07EHVi9sndz4sKmMB94Nw!1IFv+g5F zXwkYe8}04xEA!LJO44F}TC60k#!ss$NfTWwz;{L5r!8B%gYYm&kmXG=LEcrCKJg7C%@#A{!etGeXV(mhvt=dHh#TQ|ffoB}PDIniB34GBp>708ORZ zJ`J3)DEld}i;{u(-F>xwdQC~1aqjJlk*@yO^PA#)hm!uw4+Oqr>i@6sq3t+hpVyD` z{C>#y3XL}TbaOg4Ms5F@bnBRWYK_)5!OxcMSu69mZ_mablOEE%xX#-IZtRNI&ap-I zn|w7Hjmc6L2T|wYzEPP}UoCS2x*r`&^=X|{_nbZ6_c~|p3ZEJqz5RREz$l9x^$*9P z+8cvz6JAU4sWHCv{#h2U_B<bt~LApddn7}!)*ud}OyN3H{6>ysE_AFN2 zkLF(GbdR6hcK|qpb(f&N5IR=y=sQxX4|*2*t?g+m{FF513-F+LXyIS>V9*x_ui7uQ z8(pDzxr_gK;P^$H|02IR@Q+vW&1L!Fm-5c^{_%eJYfVtGyOj zu?^V&?htiGDRWFPDSq(U`E9K$_=}LIjMxatr{0NotEflm2HyY7yG*~}j{&3II~LDk zzx7@9{l)TkVH4te^I`J+Ik=6hF6Iv9d#1q6_(NLj^wNN>@E4@T67t>oE(Jagw#?Qo z9K)2>IT+J z8ON;Nji>%iP<*$92_r-sjGXG#(G}$dZyl5y^ETfolYeiBsIv+uS4$7;x$M zCBcAOhSs!hn{Eg2K6Sfcb0v*z#gVC;*ol%jctW$ErZi70N=mad*^YyOlo~cE0RjY` zdC6^DC8aK;-Ly;5et+lQD~}bK(3gFlM<31S-h1x3=jDI?=l_1rk=*tW{Sti=%^8gB zxZ($W(LJ%AxGqc78Ll&szM=feqx~@ZD!!FX3|Gz3y~L`hU-OYZGvtMB+Y_bhyAt?O zv^+4+_=G%5Wp1wQOH&54u-4wpp7h)4Pl=!4`~>}#te!ES3%FX@-t9|zN6!Zj*n@aV z_&{8^9dF|9H3qv#({nz;i%mSAelPZd6ZF}uHE)8KX6jGVUSJR0joH~YWv*_mX~*dp zI1A6ZN@J$`*+b-gPx~6$_>dtUYq@+D+inAn2U7JXc(>Ear%A5a$`eQO=AE~t?Rpl) z;hDRXpZ={8e1Io{6ngBjM^5d*=bChLE!oi$*I|ctpL*7*)RNiC@w8KU%gPm%?v>p` zV?7S#N)}#Tc_PUAPcVk>Y$vC?Ta(?t)LeG`MDxl@cdL8VSd%*LN@9QNHrslCTH|m` zdL=UThtQRm*OD3kYrt@a^|vgm5c^Fzv=16d{br|RhylCzbFMbtCAv$!qK|6-$;7c? z+CJw|9_=5$@-OP(>{RonQmWwrHuv^%F2*bOx79XmvF&D; z-!|!qz@vR9$(KA6$Cv#n+HzAZ)yn(CB{h)iCTq!fnmjqrK+2!<3%^_M&6h>90^-g6}f(#1ZJ!ZHl=N9Z6j<9SBbnJ)`Z^1wP*( zlctXZJ!N40{t3p8wGN!kkvE@Xj6%3GesiWP%JYk1o|BzT!*Yax&JI=!op_PgnZ_~!E^!RagH33-J0 zrC_#^wMX2qU&cGpb?B;iX6D1R!=8cA$KIIe5~~F->Z)P~s`Ad4&QE^emi+aCS)NHL zU%q`Y`Qm%%1T;L%_eS!4`1~{ZAo|&A^bQ-sz%9UkgteslRx3t~PeT42($Vbqyp)xdN` z_gy+KGUPFg|G;+a4p-8i9{RcxJ_U@EA4wZf+sxgM99xO<0<*#_FdhV_sI;9*9Zn~5 zc`JYL4KnM#g}Nobo~!PQ)&4T$$TvEN$Efca@R7cE(a&MtOF#E=6M@c)P(CAFQn=cu zy3vt(N86^4xkH{IaNoGZH!*hiAbSWe@}wO?Ua{~2Ck3Nfc$arU(yo=TvbqOeQPwQy z&HNF2<|V1~Q(QC9l7~psSu_uG{XS*cy|F1j?|m`&G->~xU!RA}%fFRFLE{ffx4+fa;WOMGOAxT4b_(U!CtvK^3P zJ#wGUu6c&5??Ug0&C0lcN!eSiJcg{`XpJ6YGtT{}4}M5aM9+sdnwGh0v>|%r<=Btk z@fq8yT~qXle(cgVt!~pqkNhZ)ALY59JYibBtu*0Uo<7I8uk~0DgZrW_nfzCS2bcp^ zKBYa0=}-=d_cc&_8*NO+&nt)_tbTxR??;bJ-w~{+eF6DM_xq8V!#M)}ry0lOVET@< zCfl&)%qa9W#rmjRzP*ZPeVbwa>brRUiBFjHOf>%{nSarJ*W|+dqhRLW%uD7Uu}I86 z;%dN)=NS{}a-Xh!k$p4{2G29b^QC<2^?chGwebf(n7@#+<~rN4MQ}m~(VD6IDPxx_ zy#SvfXACHg{#sxmJdEde+&}td=k+dcV*;5a+gXleOk&E24`eR#J@R!{IHk5;gSZP*B%fG=7)kKDyMG>15QT6078qG^1d$I{7UEs2d0a7F7O zDf>przSJvUn2p77iCy%2T5qR+#pB4@YmWt2H|WbWeXSACJ&PP&{&FzZ<2Ulil0DuN z@UTO)?fSO#kn>74=W@Q)-1E>I-pKtjWW#P^6BxI-r+>xqp5gZbzx=PV&o;k}{Jzig z^Za&jpUO`K#IVd6t`~8waD64$4A%>|4sz{A=JMcOAPY8T#=j$t{%7G&bA26Yj9a#A z`ZL5Kv1euNGl6g>FJ0uSsm9w&wQ-ld0Yvxr@Qul94}dM!SCOP&nc2_KB{Nr|e;Rwn zuLnO^!O4%cw4Ne^9qzv&p9rqYCoTZgJrh>lAQRZR2t$v&0lYA$9+6LX;)+_$Dw@g{?S4rP$%aL7; zHP(u2u{cUT3mb5--RItJ^9cryskA8TGPOhX=NIbo+kF{i-N+_>+B}jGo^d@TUa=CL zD8^IiMphrvzADg}B(y|){W8|yJ+S3i@PI?xJoZ@iCb;@Rjptt+ly9ik{(1I=Kg_dY z;l6j#aci&8nYPZa_^rYJv@aOqx0m-%K#TWq{U2O+a}~^nTf{Gp3Wo2(hHbJN;WHL5 z=}Y3{`&vvTXv$q@(Ue~Jy5@Q;9| z<>`sw_wZ|_DhGnpo&$m8TD3*}YH*K`43RVOwJeSL0k6?{kF0;?dpO;5z zi70K5cAl50vyS?Jwe4r}GxRHrPj;5qdq+rT63t~&T7N0|h;pKOemSbgjq3sSs%M9A z0=k$WMnz{BF7rN%+@^AgnP=^-XjCuXgn4|MM>JC78p{aABpc#+qC*aC>KE>6^Ze-6x zjXknDHmXF%$5w(r^nBzRo;AO;H^r;o?X~*K6TxYXec2D5kFF_y!s=DB52dOT!PBH? zQWL=j`2*=^CUvAAJ6tbm{U=6g7i~#JFcAGqI5c)V9llKy@+U$?+_>*fku7mQmzOk=tZE;QGVw)+}nk&q{Q>lv1)7^h+*EPrnCBa4XHRP?>WbOW9 zzt8vc>~p;l`-;xK(|hEa1z#n61UsAT8~FI)`*EH$d7RR9@++^Q&bH_|eQmPm@pH>c zPX;ftz9R{aCl1`w;`;%EEahbCZRP=bz$EXW_o=%BCrO&4v|EC!$ft6gLz4~Dbtn8h z-yWcz`J&Uh$?e5)%|r{Pa5i=)c2br6aPD#B(RvyIi~{mAgAgCj53PcMEW-wZF-`Fs;6j_EpjZbJ?a$ zzhqa93-qQRIPjf0pE1z$`ICXqv*@lzS$e1Eg2sb+Twp9_qWc-{MXMaa82p(6SLAbe zkanrAAEz#j_u_FwKg>GyuRa@(oyHA*ZpY0vJ7o`Cqwi_M!g%F|#+uHmvGxxew|IPn z0~#Nv{{_!QFI%x`n%|l68x>l38LOhvv2BbF8y# z9~rAl6{SmUvvO?(JuTLyxSw2>|4ZuFf)C3K?1o0A-gGFCekGeo>P@3(=~vRZdrHig z>q6S}F2+1>KFj!!h7CY+pX>lO&-G!RQfD4)18OhzhBQbrG4|f?V}}%N&zNrn&%@&! zU-Kcd#akQijyAYrZM;w3itUkk66#SmBfs56ne0bp?n-k-kGeB001VNe2cQEfU?n}u zH&vwpR z>$GhkM?*4d?d!2;sXUd1YzeKx?pkIZ0iVt`D6i~;4`sg5JU^YcX9CTebn7kbr>#C| zth3Ohe?&ghw|e)^=pE_3YkSRwPHBR9d!6=%yP^)y>UO24vbXL3gC17Sw@S20XO^iv zNO-n}KKkMJLN9&U+88gsl}}pp`it-lr*tiQRooGrx6HI^-8(p5bAG_fL6@Le-y=Te zKP&bcnf^6=Q=&fEMUv=Z^JVFL*IRv+v9R^UW5F0$osR)x9*1zz9CAF`P|})s)<$ry zIDWVR=<1x{(Vxl_-)#owu}3DOK0AE#U2GMi-%9U`(!ahEICxdyu)R&peyAe=SLsXY z^DMma82&TS37>xc0dY~{+mb01)3Jgwt6ar1-w)iB=V|pb%KtI)$L$uqkK4VtonL2P zT)|oGe5|9Lb5Z&qE^22Nv`pi_SU;6)h?}_~dy?!N#+9!9)2)<8e0~vl)mhV*ub!&c zX}f$R-qV5aVh5rBS4Z{-Y#5nk_)g^OV4MeL$h+M;8eHk6ES!W}^Yl|XGI>wk^o%#&4s2a_lzyQD^Nrn8iFdIc zsF;FezIItAfAVtag!H$mt7JOe3r^B|PrJx^i|k`JG5(TEfXg^}M-`_d{rUtjIpHCD z*1v3VC9!5>E4gZ{kz8AC_>7FN_E1hI3(Al5xk7gTwNKmy~%XZ`U~YW-ctdjvs^l>pEh5 zVmx`0J~1~r7x~NBx`iWW?1b#Q-`*J6Y?kp}d!muY?zdLc9B@Os!q0O&-Hi2bNh8P^KPRZIVpqz9_L+>Z$ex95$3IU`~H?DanKaE+gnq)yTf<8OR}^~ay-liK!f+PEU$ z-SX-Gt~WA{>~*L5wP$szA={7Nc1Fh=uc6M$x4!x_5JuWLb*|rZkxz7EM(!SN_Xx}AEwGTV7 z==0aWH_>8^8?qmCI%?ym!Zw0XXWEEO89FhSU#0js!TSPe{#YYTy#@S_YP(Z7o+P%c zw}20pc|A9?D1C->#oGuE*QlR-L%Ro-<-ZX~c9sk(-?_?mdiD`lKHBTa2ZK*0;q-{7 zVsndiD5d4C%nE+a>6?6cUvJ;8YS4$j&B>jeKTeaJEtmX7Ya_ZpFvEWMlDl36=FZ=7|sUI5JYy2_dc+G%|tYb>hX7J%D%6@^p zB7k>usC2-__dZS9Gf`TSc$Y^04%!A^ql}^af#78Hj=jx>6UM(ZXZ8(0oK)X$2_DiF zU2bpnmSC29$=^fQ-W<3SHwX9e{Jo2qgV?3i=3dq^YkxFswe2b1<-Glnp8e@{*aC@{ z=d4LT&|X!0sPlE~Z7{#9i}_Zu8J3Q@U*oECu(w(pvB4)KIE37 z*3geZIoj9F!i=%)v=M`E#DnWyC_BC->O*Y*dNXmtQ_#SvpI009@lzXY-hmIRUz0Zn zdw8EQXZPh#!JBW`7-PjH9SmaJ=?2b>Eq$obPU20#mz2LR$nXp8TIf9BXwGBLS$;1d z=W84_eyNSO1gG@Oc&?%DLB>(`!Ok%?*M~ZjN#7EH^KB2k$wP)#ysTpbU*g%&9OKroViAf6^Wi%;Bv*>ZE_;|uq|lW$h`leUQTIsYzY%q?(*$3 zd?3p6hvW&<>NYL)zMC5}*nEW_GuV7nAGoDq_F;>2zk$uK+P(?hUSoWA8(2?tjyBx! zBedZoi`r0#>Mu~gnb^;GR9o|&v9kHY=rGbtI_>v9GMr-G*J0z6Pj@}nJ=m``7k(9A zzv2&#EBdpwT~v(!^1Sx(vM~qC$rG+oxJNi}ssh~-9eW@h+Mnf{GA`D3(q)I%nZ`QH z*d!b?8rcSSLOf-+Rt%TyfbvhUA>X%UuSPzsd7d%%k)}AwhZ$q}z-ulvg>in@@6SIc zTkziK`8u9!J>h)Px+d97wRUL}KgG=}mfzzy$nQp*Z#38&UFEOvDf73Nqt5|{r#}u| ztj}t_S%P&%De=qui}J@v*FeAFT0n2nex7ze9-hUoi>ufZow5vh-*)kDw@m$D@D#RQ z%`3`UNm+d^@4rW^rB6AJs-Ezjt!D$@`P3D!b9zzZ#k2a0!X4+e<*X+CX^ju>p1>Z` zS%=yy|CRQnV!k)uE!%BJ8}xpc!G2&4o*E&~i|!Yj33Nc&cI3-fnFp0)9* z$m{T}K?XUGwQB0;Zob*gH%aR87kwlCrnpMQly2!aHnu^!#tn?=W_~4pb#Nwi*zt<% z-g{l=daWJ(@Idlz;J1t4lnw2n+MmwB#n`w(KXBk)Cy z7d(-Db%8njSaWTpwm-~An%bwdjgvy@XTxV7s9kX zK`giE{RX~&HFID5tT2tNnw1}DAAS+_MShXcC-X+~$p^Or9{;HI1?>wOn(tAYp28o* z4}Z`;OHbqv`U2n7sjo;qpXXk5O#Yw~+&{>@&%5K?Yj0UL$;BooIQb!*kZsSSUE8TM z^by6pbf5JRokxD*o#YJRT^_uX9-SB5g@=rt?5@bb*#dP5*MxJzy-u8yyv1Cw_$=8( zKBdp$_fXmSsO-e@KAjPrO+X)2wik_mnzR^qfom`DwB>jj2fi2V)wbyo87Y}kqn{v z!K8oC<7%|B`=zmrxkbP8RFW#fE*Lce&dLCY@@eiJnhs{r3t}8f&DNT$nL8I&)z5sh z2;5iHkY~%-B60_yp$A(d>;tGZCR&5!l+nMi#V{}N8(b$I@(uaklFT*P;aQJ5CmxY< z{D$nR31~HQa$vRi#vuDQ7sB)ROb(nrZ@cz^9mw1Ktl>kC)qIzoe6V;2IO?l^ZSh;- zj?NxA1s!%tt0w)1XpGhwJJFhH^+PeutBqpL3eByQbwBx2qiV|xd(Ht1%5}=7p}BD_ z?+<@WZN1CR4`=!L7XMZMLfsMGDv$8Y$)1m{^wKuQxTbuEb*wJe4Pg=i)puER`pQ<>EXs9F-@A|C@B=Pq!4G>>?C-f`e*V*| zBbvc_c}p{5TTMKFWBMVVika`WdW>Rh9xnmcjYoo$*OeQjblGG~?5FPVq@oQq`ok%!5r_zv|u=9TD#Eyu0(=G_mr z;Q7{$Ek8@mI~Kg-bI85y7a;oN?5(!cU-X2eQ^Y1+9B+(YR&C_!bv|s0M$ZjZ_ zxG|FJ^iKT*w#_$SGXtk={0RHG1i2Ta!=blvKS-Iz4dc3BBOkT*$f*oz7p^pOqWOZK z7x~|8Y^ZGSd@Fr*Bl%puRXrd3-TCKqzE->kzSW_M;r{n2^sGO^Mk2V%kE(qMzlAUH zJNUo83vIXcP)BqA%8R8t2`8ThC!elRo>yy^y@{X*9oBv(!cpda6YRxDL2NtatapW@ zp?yhhk)97MY=3{O<9&i}^ghRX=^=5MDo-(c_`9>x3BJ{3UaM!VOT*qfFcig@Zzj%3 z^FU`6_Iaa$>w&Yht;BB!zpcpTY0A!+&(cOSr?S|P{I&bxb?W<(zn{Nw4`r=~mz;?| zN?YD4T(v$cxMbZ=-QDoi5I;FARkUm|?^RUM5 z4ViG|5^_|z!FytdZ7X7G6X60Y;m0en-GO-z~W;IHINA?_6q@0*D>bim@Q&UOvs z%<}DFU>vsVfNj^zzouQUj@tF=uw5!+sdmlK7QIuubng#x&sjr`T?2((D{3FO)ch&h zs6Ct%ORo3^_Jh14hQ$bDygQojzzA|H`3YOhdmlOVde*~=X4rK?pEq`WP)rYHhw$K^ z#;-NM{=eogbWNendfE$zHlY{Hpx^OKLD^J^bp*@$?fSDJb0<1(HMjyDD!B#$((sF9ZByK(fiZ-zT>@O(d_rRLi;_$*C)8X|DWeCto;&rw7j4( z&uUF(f;D~rw4#>$#pP!CKm35$SKhsocUo5?e3QTN0`LX-41b;U!Oww5vKj4T4nae> zzVj8*k*nAv?j$X=t6(>@y5G9r#UAq~{C-1wV9+n%^J>c1TJQA^{iBSxpx1`)>XgfQ zZj6W4g$V}-`9?ae&ODK>xSd$lFs*LWE+Xw`NYnS6T|=MEK)lvebg76RL3Bv><%s99 z4jcRUMC)#Mv~e#q)a2jS8tu`(6@Ekbpt2;xyj)qbalfAWcCiOcm-s64V;3>#>X%{$ zwwKO^$@vjXc9r&_!x!2^pJFV2>lWgE@90PN?#0+iyF}-1#$Ji7{rqFWE7>nVXP_l& z;yE^+{jP8RnQ+&)XP7ypZ>Rn%^G++zo
fd<`{$=`e=lh=4`X@5@TM*Dnf?(3XQ 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 DB6YNi diff --git a/source_modules/sddc_source/src/libsddc/CMakeLists.txt b/source_modules/sddc_source/src/libsddc/CMakeLists.txt deleted file mode 100644 index 41ca755..0000000 --- a/source_modules/sddc_source/src/libsddc/CMakeLists.txt +++ /dev/null @@ -1,78 +0,0 @@ -cmake_minimum_required(VERSION 3.13) -project(SDDC VERSION 1.0.1) - -include(CTest) - -### build options -# default build type: Release -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release") -endif(NOT CMAKE_BUILD_TYPE) -message(STATUS "Build type: " ${CMAKE_BUILD_TYPE} " - Version: " ${VERSION} " / " ${LIBVER}) - -# allow disabling optimizations - for debug reasons -option(USE_SIMD_OPTIMIZATIONS "enable SIMD optimizations" ON) - -# allow enabling address sanitizer - for debug reasons -if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - option(USE_DEBUG_ASAN "use GCC's address sanitizer?" OFF) -endif() - -if (USE_DEBUG_ASAN) - set(ASANLIB "asan") -else() - set(ASANLIB "") -endif() - -if (MSVC) - set(CMAKE_CXX_FLAGS "-O2 /std:c++17 /EHsc /W3") - - get_filename_component(SDKPATH ${CMAKE_LINKER} DIRECTORY) - find_program(LIBEXE lib HINTS ${SDKPATH} REQUIRED) - - # External Project FFTW on Windows - if(${CMAKE_EXE_LINKER_FLAGS} MATCHES "X86") - SET(FFTW_URL "ftp://ftp.fftw.org/pub/fftw/fftw-3.3.5-dll32.zip") - SET(ARCH x86) - SET(HASH 29882a43033c9393479a4df52a2e9120589c06a2b724155b1a682747fa3e57d4) - else() - SET(FFTW_URL "ftp://ftp.fftw.org/pub/fftw/fftw-3.3.5-dll64.zip") - SET(ARCH x64) - SET(HASH cfd88dc0e8d7001115ea79e069a2c695d52c8947f5b4f3b7ac54a192756f439f) - endif() - - include(ExternalProject) - ExternalProject_Add( - LIBFFTW - URL ${FFTW_URL} - URL_HASH SHA256=${HASH} - BUILD_IN_SOURCE TRUE - CONFIGURE_COMMAND "" - BUILD_COMMAND ${LIBEXE} /def:./libfftw3f-3.def /MACHINE:${ARCH} /OUT:./fftw3f-3.lib - INSTALL_COMMAND "" - ) - ExternalProject_Get_Property(LIBFFTW SOURCE_DIR) - SET(LIBFFTW_INCLUDE_DIRS ${SOURCE_DIR}) - SET(LIBFFTW_LIBRARY_DIRS ${SOURCE_DIR}) - SET(LIBFFTW_LIBRARIES fftw3f-3) - - add_subdirectory(ExtIO_sddc) -else() - - if (USE_DEBUG_ASAN) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address") - set(CMAKE_CXX_FLAGS "-O0 -std=c++17 -Wall -Werror") - else() - set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -Wall -Werror") - endif(USE_DEBUG_ASAN) - #add_compile_options(-Wall -Wextra -pedantic) - include(FindPkgConfig) - pkg_check_modules(LIBUSB REQUIRED libusb-1.0) - pkg_check_modules(LIBFFTW REQUIRED fftw3f) -endif (MSVC) - -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG") - -add_subdirectory(Core) -add_subdirectory(libsddc) -add_subdirectory(unittest) diff --git a/source_modules/sddc_source/src/libsddc/Core/CMakeLists.txt b/source_modules/sddc_source/src/libsddc/Core/CMakeLists.txt deleted file mode 100644 index 7585a6d..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/CMakeLists.txt +++ /dev/null @@ -1,35 +0,0 @@ -cmake_minimum_required(VERSION 3.13) - -if (MSVC) - file(GLOB ARCH_SRC "arch/win32/*.cpp" "arch/win32/CyAPI/*.cpp") -else() - file(GLOB ARCH_SRC "arch/linux/*.c" "arch/linux/*.cpp") -endif (MSVC) - -file(GLOB SRC "*.cpp" "radio/*.cpp" "pffft/*.cpp" ${ARCH_SRC}) - -include_directories("." "CyAPI/" "pffft/") - -if (MSVC) - set_source_files_properties(fft_mt_r2iq_avx.cpp PROPERTIES COMPILE_FLAGS /arch:AVX) - set_source_files_properties(fft_mt_r2iq_avx2.cpp PROPERTIES COMPILE_FLAGS /arch:AVX2) - set_source_files_properties(fft_mt_r2iq_avx512.cpp PROPERTIES COMPILE_FLAGS /arch:AVX512) -else() - set_source_files_properties(fft_mt_r2iq_avx.cpp PROPERTIES COMPILE_FLAGS -mavx) - set_source_files_properties(fft_mt_r2iq_avx2.cpp PROPERTIES COMPILE_FLAGS -mavx2) - set_source_files_properties(fft_mt_r2iq_avx512.cpp PROPERTIES COMPILE_FLAGS -mavx512f) - - include_directories(${LIBUSB_INCLUDE_DIRS}) -endif (MSVC) - -include_directories(${LIBFFTW_INCLUDE_DIRS}) - -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG") - -add_library(SDDC_CORE STATIC ${SRC}) -set_target_properties(SDDC_CORE PROPERTIES POSITION_INDEPENDENT_CODE True) -target_compile_definitions(SDDC_CORE PUBLIC _CRT_SECURE_NO_WARNINGS) - -if (NOT USE_SIMD_OPTIMIZATIONS) - target_compile_definitions(SDDC_CORE PRIVATE NO_SIMD_OPTIM) -endif() diff --git a/source_modules/sddc_source/src/libsddc/Core/FX3Class.h b/source_modules/sddc_source/src/libsddc/Core/FX3Class.h deleted file mode 100644 index 9cb9622..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/FX3Class.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef FX3CLASS_H -#define FX3CLASS_H - -// -// FX3handler.cpp -// 2020 10 12 Oscar Steila ik1xpv -// loading arm code.img from resource by Howard Su and Hayati Ayguen -// This module was previous named:openFX3.cpp -// MIT License Copyright (c) 2016 Booya Corp. -// booyasdr@gmail.com, http://booyasdr.sf.net -// modified 2017 11 30 ik1xpv@gmail.com, http://www.steila.com/blog -// - -#include -#include -#include "../Interface.h" -#include "dsp/ringbuffer.h" - -class fx3class -{ -public: - virtual ~fx3class(void) {} - virtual bool Open(uint8_t* fw_data, uint32_t fw_size) = 0; - virtual bool Control(FX3Command command, uint8_t data = 0) = 0; - virtual bool Control(FX3Command command, uint32_t data) = 0; - virtual bool Control(FX3Command command, uint64_t data) = 0; - virtual bool SetArgument(uint16_t index, uint16_t value) = 0; - virtual bool GetHardwareInfo(uint32_t* data) = 0; - virtual bool ReadDebugTrace(uint8_t* pdata, uint8_t len) = 0; - virtual void StartStream(ringbuffer& input, int numofblock) = 0; - virtual void StopStream() = 0; - -}; - -extern "C" fx3class* CreateUsbHandler(); - -#endif // FX3CLASS_H diff --git a/source_modules/sddc_source/src/libsddc/Core/PScope_uti.cpp b/source_modules/sddc_source/src/libsddc/Core/PScope_uti.cpp deleted file mode 100644 index bb323e3..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/PScope_uti.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "PScope_uti.h" -#include "license.txt" - -int PScopeShot(const char * filename, const char * title2, const char * title1, short * data, float samplerate, unsigned int numsamples ) -{ - FILE *fp; - fp = fopen(filename, "w+"); - fputs("Version,115\n", fp); - fprintf(fp, "Retainers,0,1,%d,1024,0,%f,1,1\n",numsamples,samplerate ); - fputs("Placement,44,0,1,-1,-1,-1,-1,88,40,1116,879", fp); - fputs("WindMgr,7,2,0\n", fp); - fputs("Page,0,2\n", fp); - fputs("Col,3,1\n", fp); - fputs("Row,2,1\n", fp); - fputs("Row,3,146\n", fp); - fputs("Row,1,319\n", fp); - fputs("Col,2,1063\n", fp); - fputs("Row,4,1\n", fp); - fputs("Row,0,319\n", fp); - fputs("Page,1,2\n", fp); - fputs("Col,1,1\n", fp); - fputs("Row,1,1\n", fp); - fputs("Col,2,425\n", fp); - fputs("Row,4,1\n", fp); - fputs("Row,0,319\n", fp); - fprintf(fp,"DemoID,%s,%s,0\n", title1, title2 ); - fprintf(fp,"RawData,1,%d,16,-32768,32767,%f,-3.276800e+04,3.276800e+04\n", numsamples,samplerate); - for (unsigned int n = 0; n < numsamples; n++ ) - { - fprintf(fp, "%d\n", data[n]); - } - fputs("end\n", fp); - return fclose(fp); -} - diff --git a/source_modules/sddc_source/src/libsddc/Core/PScope_uti.h b/source_modules/sddc_source/src/libsddc/Core/PScope_uti.h deleted file mode 100644 index ffe2944..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/PScope_uti.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _PSCOPE_ -#define _PSCOPE_ -#include "license.txt" -#include -#include - -int PScopeShot(const char * filename, const char * title1, const char * title2, short * data, float samplerate, unsigned int numsamples ); - -#endif // _PSCOPE_ diff --git a/source_modules/sddc_source/src/libsddc/Core/RadioHandler.cpp b/source_modules/sddc_source/src/libsddc/Core/RadioHandler.cpp deleted file mode 100644 index 0312830..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/RadioHandler.cpp +++ /dev/null @@ -1,440 +0,0 @@ -#include "license.txt" - -#include -#include -#include -#include "pf_mixer.h" -#include "RadioHandler.h" -#include "sddc_config.h" -#include "fft_mt_r2iq.h" -#include "sddc_config.h" -#include "PScope_uti.h" -#include "../Interface.h" - -#include - -using namespace std::chrono; - -// transfer variables - -unsigned long Failures = 0; - -void RadioHandlerClass::OnDataPacket() -{ - auto len = outputbuffer.getBlockSize() / 2 / sizeof(float); - - while(run) - { - auto buf = outputbuffer.getReadPtr(); - - if (!run) - break; - - if (fc != 0.0f) - { - std::unique_lock lk(fc_mutex); - shift_limited_unroll_C_sse_inp_c((complexf*)buf, len, stateFineTune); - } - -#ifdef _DEBUG //PScope buffer screenshot - if (saveADCsamplesflag == true) - { - saveADCsamplesflag = false; // do it once - unsigned int numsamples = transferSize / sizeof(int16_t); - float samplerate = (float) getSampleRate(); - PScopeShot("ADCrealsamples.adc", "ExtIO_sddc.dll", - "ADCrealsamples.adc input real ADC 16 bit samples", - (short*)buf, samplerate, numsamples); - } -#endif - - Callback(buf, len); - - outputbuffer.ReadDone(); - - SamplesXIF += len; - } -} - -RadioHandlerClass::RadioHandlerClass() : - DbgPrintFX3(nullptr), - GetConsoleIn(nullptr), - run(false), - pga(false), - dither(false), - randout(false), - biasT_HF(false), - biasT_VHF(false), - firmware(0), - modeRF(NOMODE), - adcrate(DEFAULT_ADC_FREQ), - fc(0.0f), - hardware(new DummyRadio(nullptr)) -{ - inputbuffer.setBlockSize(transferSamples); - - stateFineTune = new shift_limited_unroll_C_sse_data_t(); -} - -RadioHandlerClass::~RadioHandlerClass() -{ - delete stateFineTune; -} - -const char *RadioHandlerClass::getName() -{ - return hardware->getName(); -} - -bool RadioHandlerClass::Init(fx3class* Fx3, void (*callback)(const float*, uint32_t), r2iqControlClass *r2iqCntrl) -{ - uint8_t rdata[4]; - this->fx3 = Fx3; - this->Callback = callback; - - if (r2iqCntrl == nullptr) - r2iqCntrl = new fft_mt_r2iq(); - - Fx3->GetHardwareInfo((uint32_t*)rdata); - - radio = (RadioModel)rdata[0]; - firmware = (rdata[1] << 8) + rdata[2]; - - delete hardware; // delete dummy instance - switch (radio) - { - case HF103: - hardware = new HF103Radio(Fx3); - break; - - case BBRF103: - hardware = new BBRF103Radio(Fx3); - break; - - case RX888: - hardware = new RX888Radio(Fx3); - break; - - case RX888r2: - hardware = new RX888R2Radio(Fx3); - break; - - case RX888r3: - hardware = new RX888R3Radio(Fx3); - break; - - case RX999: - hardware = new RX999Radio(Fx3); - break; - - case RXLUCY: - hardware = new RXLucyRadio(Fx3); - break; - - default: - hardware = new DummyRadio(Fx3); - DbgPrintf("WARNING no SDR connected\n"); - break; - } - adcrate = adcnominalfreq; - hardware->Initialize(adcnominalfreq); - DbgPrintf("%s | firmware %x\n", hardware->getName(), firmware); - this->r2iqCntrl = r2iqCntrl; - r2iqCntrl->Init(hardware->getGain(), &inputbuffer, &outputbuffer); - - return true; -} - -bool RadioHandlerClass::Start(int srate_idx) -{ - Stop(); - DbgPrintf("RadioHandlerClass::Start\n"); - - int decimate = 4 - srate_idx; // 5 IF bands - if (adcnominalfreq > N2_BANDSWITCH) - decimate = 5 - srate_idx; // 6 IF bands - if (decimate < 0) - { - decimate = 0; - DbgPrintf("WARNING decimate mismatch at srate_idx = %d\n", srate_idx); - } - run = true; - count = 0; - - hardware->FX3producerOn(); // FX3 start the producer - - outputbuffer.setBlockSize(EXT_BLOCKLEN * 2 * sizeof(float)); - - // 0,1,2,3,4 => 32,16,8,4,2 MHz - r2iqCntrl->setDecimate(decimate); - r2iqCntrl->TurnOn(); - fx3->StartStream(inputbuffer, QUEUE_SIZE); - - submit_thread = std::thread( - [this]() { - this->OnDataPacket(); - }); - - show_stats_thread = std::thread([this](void*) { - this->CaculateStats(); - }, nullptr); - - return true; -} - -bool RadioHandlerClass::Stop() -{ - std::unique_lock lk(stop_mutex); - DbgPrintf("RadioHandlerClass::Stop %d\n", run); - if (run) - { - run = false; // now waits for threads - - r2iqCntrl->TurnOff(); - - fx3->StopStream(); - - run = false; // now waits for threads - - show_stats_thread.join(); //first to be joined - DbgPrintf("show_stats_thread join2\n"); - - submit_thread.join(); - DbgPrintf("submit_thread join1\n"); - - hardware->FX3producerOff(); //FX3 stop the producer - } - return true; -} - - -bool RadioHandlerClass::Close() -{ - delete hardware; - hardware = nullptr; - - return true; -} - -bool RadioHandlerClass::UpdateSampleRate(uint32_t samplefreq) -{ - hardware->Initialize(samplefreq); - - this->adcrate = samplefreq; - - return 0; -} - -// attenuator RF used in HF -int RadioHandlerClass::UpdateattRF(int att) -{ - if (hardware->UpdateattRF(att)) - { - return att; - } - return 0; -} - -// attenuator RF used in HF -int RadioHandlerClass::UpdateIFGain(int idx) -{ - if (hardware->UpdateGainIF(idx)) - { - return idx; - } - - return 0; -} - -int RadioHandlerClass::GetRFAttSteps(const float **steps) -{ - return hardware->getRFSteps(steps); -} - -int RadioHandlerClass::GetIFGainSteps(const float **steps) -{ - return hardware->getIFSteps(steps); -} - -bool RadioHandlerClass::UpdatemodeRF(rf_mode mode) -{ - if (modeRF != mode){ - modeRF = mode; - DbgPrintf("Switch to mode: %d\n", modeRF); - - hardware->UpdatemodeRF(mode); - - if (mode == VHFMODE) - r2iqCntrl->setSideband(true); - else - r2iqCntrl->setSideband(false); - } - return true; -} - -rf_mode RadioHandlerClass::PrepareLo(uint64_t lo) -{ - return hardware->PrepareLo(lo); -} - -uint64_t RadioHandlerClass::TuneLO(uint64_t wishedFreq) -{ - uint64_t actLo; - - actLo = hardware->TuneLo(wishedFreq); - - // we need shift the samples - int64_t offset = wishedFreq - actLo; - DbgPrintf("Offset freq %" PRIi64 "\n", offset); - float fc = r2iqCntrl->setFreqOffset(offset / (getSampleRate() / 2.0f)); - if (GetmodeRF() == VHFMODE) - fc = -fc; // sign change with sideband used - if (this->fc != fc) - { - std::unique_lock lk(fc_mutex); - *stateFineTune = shift_limited_unroll_C_sse_init(fc, 0.0F); - this->fc = fc; - } - - return wishedFreq; -} - -bool RadioHandlerClass::UptDither(bool b) -{ - dither = b; - if (dither) - hardware->FX3SetGPIO(DITH); - else - hardware->FX3UnsetGPIO(DITH); - return dither; -} - -bool RadioHandlerClass::UptPga(bool b) -{ - pga = b; - if (pga) - hardware->FX3SetGPIO(PGA_EN); - else - hardware->FX3UnsetGPIO(PGA_EN); - return pga; -} - -bool RadioHandlerClass::UptRand(bool b) -{ - randout = b; - if (randout) - hardware->FX3SetGPIO(RANDO); - else - hardware->FX3UnsetGPIO(RANDO); - r2iqCntrl->updateRand(randout); - return randout; -} - -void RadioHandlerClass::CaculateStats() -{ - high_resolution_clock::time_point EndingTime; - float kbRead = 0; - float kSReadIF = 0; - - kbRead = 0; // zeros the kilobytes counter - kSReadIF = 0; - - BytesXferred = 0; - SamplesXIF = 0; - - uint8_t debdata[MAXLEN_D_USB]; - memset(debdata, 0, MAXLEN_D_USB); - - auto StartingTime = high_resolution_clock::now(); - - while (run) { - kbRead = float(BytesXferred) / 1000.0f; - kSReadIF = float(SamplesXIF) / 1000.0f; - - EndingTime = high_resolution_clock::now(); - - duration> timeElapsed(EndingTime-StartingTime); - - mBps = (float)kbRead / timeElapsed.count() / 1000 / sizeof(int16_t); - mSpsIF = (float)kSReadIF / timeElapsed.count() / 1000; - - BytesXferred = 0; - SamplesXIF = 0; - - StartingTime = high_resolution_clock::now(); - -#ifdef _DEBUG - int nt = 10; - while (nt-- > 0) - { - std::this_thread::sleep_for(0.05s); - debdata[0] = 0; //clean buffer - if (GetConsoleIn != nullptr) - { - GetConsoleIn((char *)debdata, MAXLEN_D_USB); - if (debdata[0] !=0) - DbgPrintf("%s", (char*)debdata); - } - - if (hardware->ReadDebugTrace(debdata, MAXLEN_D_USB) == true) // there are message from FX3 ? - { - int len = strlen((char*)debdata); - if (len > MAXLEN_D_USB - 1) len = MAXLEN_D_USB - 1; - debdata[len] = 0; - if ((len > 0)&&(DbgPrintFX3 != nullptr)) - { - DbgPrintFX3("%s", (char*)debdata); - memset(debdata, 0, sizeof(debdata)); - } - } - - } -#else - std::this_thread::sleep_for(0.5s); -#endif - } - return; -} - -void RadioHandlerClass::UpdBiasT_HF(bool flag) -{ - biasT_HF = flag; - - if (biasT_HF) - hardware->FX3SetGPIO(BIAS_HF); - else - hardware->FX3UnsetGPIO(BIAS_HF); -} - -void RadioHandlerClass::UpdBiasT_VHF(bool flag) -{ - biasT_VHF = flag; - if (biasT_VHF) - hardware->FX3SetGPIO(BIAS_VHF); - else - hardware->FX3UnsetGPIO(BIAS_VHF); -} - -void RadioHandlerClass::uptLed(int led, bool on) -{ - int pin; - switch(led) - { - case 0: - pin = LED_YELLOW; - break; - case 1: - pin = LED_RED; - break; - case 2: - pin = LED_BLUE; - break; - default: - return; - } - - if (on) - hardware->FX3SetGPIO(pin); - else - hardware->FX3UnsetGPIO(pin); -} diff --git a/source_modules/sddc_source/src/libsddc/Core/RadioHandler.h b/source_modules/sddc_source/src/libsddc/Core/RadioHandler.h deleted file mode 100644 index 4ae6d4e..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/RadioHandler.h +++ /dev/null @@ -1,341 +0,0 @@ -#ifndef RADIOHANDLER_H -#define RADIOHANDLER_H - -#include "license.txt" - -#include "sddc_config.h" -#include -#include -#include -#include -#include "FX3Class.h" - -#include "dsp/ringbuffer.h" - -class RadioHardware; -class r2iqControlClass; - -enum { - RESULT_OK, - RESULT_BIG_STEP, - RESULT_TOO_HIGH, - RESULT_TOO_LOW, - RESULT_NOT_POSSIBLE -}; - -struct shift_limited_unroll_C_sse_data_s; -typedef struct shift_limited_unroll_C_sse_data_s shift_limited_unroll_C_sse_data_t; - -class RadioHandlerClass { -public: - RadioHandlerClass(); - virtual ~RadioHandlerClass(); - bool Init(fx3class* Fx3, void (*callback)(const float*, uint32_t), r2iqControlClass *r2iqCntrl = nullptr); - bool Start(int srate_idx); - bool Stop(); - bool Close(); - bool IsReady(){return true;} - - int GetRFAttSteps(const float **steps); - int UpdateattRF(int attIdx); - - int GetIFGainSteps(const float **steps); - int UpdateIFGain(int attIdx); - - bool UpdatemodeRF(rf_mode mode); - rf_mode GetmodeRF(){return (rf_mode)modeRF;} - bool UptDither (bool b); - bool GetDither () {return dither;} - bool UptPga(bool b); - bool GetPga() { return pga;} - bool UptRand (bool b); - bool GetRand () {return randout;} - uint16_t GetFirmware() { return firmware; } - - uint32_t getSampleRate() { return adcrate; } - bool UpdateSampleRate(uint32_t samplerate); - - float getBps() const { return mBps; } - float getSpsIF() const {return mSpsIF; } - - const char* getName(); - RadioModel getModel() { return radio; } - - bool GetBiasT_HF() { return biasT_HF; } - void UpdBiasT_HF(bool flag); - bool GetBiasT_VHF() { return biasT_VHF; } - void UpdBiasT_VHF(bool flag); - - uint64_t TuneLO(uint64_t lo); - rf_mode PrepareLo(uint64_t lo); - - void uptLed(int led, bool on); - - void EnableDebug(void (*dbgprintFX3)(const char* fmt, ...), bool (*getconsolein)(char* buf, int maxlen)) - { - this->DbgPrintFX3 = dbgprintFX3; - this->GetConsoleIn = getconsolein; - }; - - bool ReadDebugTrace(uint8_t* pdata, uint8_t len) { return fx3->ReadDebugTrace(pdata, len); } - -private: - void AdcSamplesProcess(); - void AbortXferLoop(int qidx); - void CaculateStats(); - void OnDataPacket(); - r2iqControlClass* r2iqCntrl; - - void (*Callback)(const float *data, uint32_t length); - void (*DbgPrintFX3)(const char* fmt, ...); - bool (*GetConsoleIn)(char* buf, int maxlen); - - bool run; - unsigned long count; // absolute index - - bool pga; - bool dither; - bool randout; - bool biasT_HF; - bool biasT_VHF; - uint16_t firmware; - rf_mode modeRF; - RadioModel radio; - - // transfer variables - ringbuffer inputbuffer; - ringbuffer outputbuffer; - - // threads - std::thread show_stats_thread; - std::thread submit_thread; - - // stats - unsigned long BytesXferred; - unsigned long SamplesXIF; - float mBps; - float mSpsIF; - - fx3class *fx3; - uint32_t adcrate; - - std::mutex fc_mutex; - std::mutex stop_mutex; - float fc; - RadioHardware* hardware; - shift_limited_unroll_C_sse_data_t* stateFineTune; -}; - -extern unsigned long Failures; - -class RadioHardware { -public: - RadioHardware(fx3class* fx3) : Fx3(fx3), gpios(0) {} - - virtual ~RadioHardware(); - virtual const char* getName() = 0; - virtual rf_mode PrepareLo(uint64_t freq) = 0; - virtual float getGain() { return BBRF103_GAINFACTOR; } - virtual void Initialize(uint32_t samplefreq) = 0; - virtual bool UpdatemodeRF(rf_mode mode) = 0; - virtual bool UpdateattRF(int attIndex) = 0; - virtual uint64_t TuneLo(uint64_t freq) = 0; - - virtual int getRFSteps(const float** steps ) { return 0; } - virtual int getIFSteps(const float** steps ) { return 0; } - virtual bool UpdateGainIF(int attIndex) { return false; } - - bool FX3producerOn() { return Fx3->Control(STARTFX3); } - bool FX3producerOff() { return Fx3->Control(STOPFX3); } - - bool ReadDebugTrace(uint8_t* pdata, uint8_t len) { return Fx3->ReadDebugTrace(pdata, len); } - - bool FX3SetGPIO(uint32_t mask); - bool FX3UnsetGPIO(uint32_t mask); - -protected: - fx3class* Fx3; - uint32_t gpios; -}; - -class BBRF103Radio : public RadioHardware { -public: - BBRF103Radio(fx3class* fx3); - const char* getName() override { return "BBRF103"; } - float getGain() override { return BBRF103_GAINFACTOR; } - rf_mode PrepareLo(uint64_t freq) override; - void Initialize(uint32_t samplefreq) override; - bool UpdatemodeRF(rf_mode mode) override; - uint64_t TuneLo(uint64_t freq) override; - bool UpdateattRF(int attIndex) override; - bool UpdateGainIF(int attIndex) override; - - int getRFSteps(const float** steps ) override; - int getIFSteps(const float** steps ) override; - -private: - static const int step_size = 29; - static const float steps[step_size]; - static const float hfsteps[3]; - - static const int if_step_size = 16; - static const float if_steps[if_step_size]; - - uint32_t SampleRate; -}; - -class RX888Radio : public BBRF103Radio { -public: - RX888Radio(fx3class* fx3) : BBRF103Radio(fx3) {} - const char* getName() override { return "RX888"; } - float getGain() override { return RX888_GAINFACTOR; } -}; - -class RX888R2Radio : public RadioHardware { -public: - RX888R2Radio(fx3class* fx3); - const char* getName() override { return "RX888 mkII"; } - float getGain() override { return RX888mk2_GAINFACTOR; } - rf_mode PrepareLo(uint64_t freq) override; - void Initialize(uint32_t samplefreq) override; - bool UpdatemodeRF(rf_mode mode) override; - uint64_t TuneLo(uint64_t freq) override; - bool UpdateattRF(int attIndex) override; - bool UpdateGainIF(int attIndex) override; - - int getRFSteps(const float** steps ) override; - int getIFSteps(const float** steps ) override; - -private: - static const int hf_rf_step_size = 64; - static const int hf_if_step_size = 127; - static const int vhf_if_step_size = 16; - static const int vhf_rf_step_size = 29; - - float hf_rf_steps[hf_rf_step_size]; - float hf_if_steps[hf_if_step_size]; - static const float vhf_rf_steps[vhf_rf_step_size]; - static const float vhf_if_steps[vhf_if_step_size]; - - uint32_t SampleRate; -}; - -class RX888R3Radio : public RadioHardware { -public: - RX888R3Radio(fx3class* fx3); - const char* getName() override { return "RX888 mkIII"; } - float getGain() override { return RX888mk2_GAINFACTOR; } - rf_mode PrepareLo(uint64_t freq) override; - void Initialize(uint32_t samplefreq) override; - bool UpdatemodeRF(rf_mode mode) override; - uint64_t TuneLo(uint64_t freq) override; - bool UpdateattRF(int attIndex) override; - bool UpdateGainIF(int attIndex) override; - - int getRFSteps(const float** steps ) override; - int getIFSteps(const float** steps ) override; - -private: - static const int hf_rf_step_size = 64; - static const int hf_if_step_size = 127; - static const int vhf_if_step_size = 16; - static const int vhf_rf_step_size = 29; - - float hf_rf_steps[hf_rf_step_size]; - float hf_if_steps[hf_if_step_size]; - static const float vhf_rf_steps[vhf_rf_step_size]; - static const float vhf_if_steps[vhf_if_step_size]; - - uint32_t SampleRate; -}; - -class RX999Radio : public RadioHardware { -public: - RX999Radio(fx3class* fx3); - const char* getName() override { return "RX999"; } - float getGain() override { return RX888_GAINFACTOR; } - - rf_mode PrepareLo(uint64_t freq) override; - void Initialize(uint32_t samplefreq) override; - bool UpdatemodeRF(rf_mode mode) override; - uint64_t TuneLo(uint64_t freq) override; - bool UpdateattRF(int attIndex) override; - bool UpdateGainIF(int attIndex) override; - - int getRFSteps(const float** steps ) override; - int getIFSteps(const float** steps ) override; - -private: - static const int if_step_size = 127; - - float if_steps[if_step_size]; - uint32_t SampleRate; -}; - -class HF103Radio : public RadioHardware { -public: - HF103Radio(fx3class* fx3); - const char* getName() override { return "HF103"; } - float getGain() override { return HF103_GAINFACTOR; } - - rf_mode PrepareLo(uint64_t freq) override; - - void Initialize(uint32_t samplefreq) override {}; - - bool UpdatemodeRF(rf_mode mode) override; - - uint64_t TuneLo(uint64_t freq) override { return 0; } - - bool UpdateattRF(int attIndex) override; - - int getRFSteps(const float** steps ) override; - -private: - static const int step_size = 64; - float steps[step_size]; -}; - -class RXLucyRadio : public RadioHardware { -public: - RXLucyRadio(fx3class* fx3); - const char* getName() override { return "Lucy"; } - float getGain() override { return HF103_GAINFACTOR; } - - rf_mode PrepareLo(uint64_t freq) override; - void Initialize(uint32_t samplefreq) override; - bool UpdatemodeRF(rf_mode mode) override; - uint64_t TuneLo(uint64_t freq) override ; - bool UpdateattRF(int attIndex) override; - bool UpdateGainIF(int attIndex) override; - - int getRFSteps(const float** steps) override; - int getIFSteps(const float** steps) override; - -private: - static const int step_size = 16; - float steps[step_size]; - - static const int if_step_size = 64; - float if_steps[if_step_size]; - uint32_t SampleRate; -}; - -class DummyRadio : public RadioHardware { -public: - DummyRadio(fx3class* fx3) : RadioHardware(fx3) {} - const char* getName() override { return "Dummy"; } - - rf_mode PrepareLo(uint64_t freq) override - { return HFMODE;} - void Initialize(uint32_t samplefreq) override {} - bool UpdatemodeRF(rf_mode mode) override { return true; } - bool UpdateattRF(int attIndex) override { return true; } - uint64_t TuneLo(uint64_t freq) override { - if (freq < 64000000 /2) - return 0; - else - return freq; - } -}; - -#endif diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/linux/FX3handler.cpp b/source_modules/sddc_source/src/libsddc/Core/arch/linux/FX3handler.cpp deleted file mode 100644 index 8d4a94b..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/linux/FX3handler.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include - -#include "FX3handler.h" -#include "usb_device.h" - -fx3class* CreateUsbHandler() -{ - return new fx3handler(); -} - -fx3handler::fx3handler() -{ -} - -fx3handler::~fx3handler() -{ -} - -bool fx3handler::Open(uint8_t* fw_data, uint32_t fw_size) -{ - dev = usb_device_open(0, (const char*)fw_data, fw_size); - - return dev != nullptr; -} - -bool fx3handler::Control(FX3Command command, uint8_t data) -{ - return usb_device_control(this->dev, command, 0, 0, (uint8_t *) &data, sizeof(data), 0) == 0; -} - -bool fx3handler::Control(FX3Command command, uint32_t data) -{ - return usb_device_control(this->dev, command, 0, 0, (uint8_t *) &data, sizeof(data), 0) == 0; -} - -bool fx3handler::Control(FX3Command command, uint64_t data) -{ - return usb_device_control(this->dev, command, 0, 0, (uint8_t *) &data, sizeof(data), 0) == 0; -} - -bool fx3handler::SetArgument(uint16_t index, uint16_t value) -{ - uint8_t data = 0; - return usb_device_control(this->dev, SETARGFX3, value, index, (uint8_t *) &data, sizeof(data), 0) == 0; -} - -bool fx3handler::GetHardwareInfo(uint32_t* data) -{ - return usb_device_control(this->dev, TESTFX3, 0, 0, (uint8_t *) data, sizeof(*data), 1) == 0; -} - -void fx3handler::StartStream(ringbuffer& input, int numofblock) -{ - inputbuffer = &input; - auto readsize = input.getWriteCount() * sizeof(uint16_t); - stream = streaming_open_async(this->dev, readsize, numofblock, PacketRead, this); - - // Start background thread to poll the events - run = true; - poll_thread = std::thread( - [this]() { - while(run) - { - usb_device_handle_events(this->dev); - } - }); - - if (stream) - { - streaming_start(stream); - } -} - -void fx3handler::StopStream() -{ - run = false; - poll_thread.join(); - - streaming_stop(stream); - streaming_close(stream); -} - -void fx3handler::PacketRead(uint32_t data_size, uint8_t *data, void *context) -{ - fx3handler *handler = (fx3handler*)context; - - auto *ptr = handler->inputbuffer->getWritePtr(); - memcpy(ptr, data, data_size); - handler->inputbuffer->WriteDone(); -} - -bool fx3handler::ReadDebugTrace(uint8_t* pdata, uint8_t len) -{ - return true; -} diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/linux/FX3handler.h b/source_modules/sddc_source/src/libsddc/Core/arch/linux/FX3handler.h deleted file mode 100644 index c43cbf9..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/linux/FX3handler.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef FX3HANDLER_H -#define FX3HANDLER_H - -#include "sddc_config.h" - -#define VENDOR_ID (0x04B4) -#define STREAMER_ID (0x00F1) -#define BOOTLOADER_ID (0x00F3) - -#include "FX3Class.h" -#include "usb_device.h" -#include "streaming.h" -#include "dsp/ringbuffer.h" - -class fx3handler : public fx3class -{ -public: - fx3handler(); - virtual ~fx3handler(void); - bool Open(uint8_t* fw_data, uint32_t fw_size) override; - bool Control(FX3Command command, uint8_t data) override; - bool Control(FX3Command command, uint32_t data) override; - bool Control(FX3Command command, uint64_t data) override; - bool SetArgument(uint16_t index, uint16_t value) override; - bool GetHardwareInfo(uint32_t* data) override; - bool ReadDebugTrace(uint8_t* pdata, uint8_t len); - void StartStream(ringbuffer& input, int numofblock); - void StopStream(); - -private: - bool ReadUsb(uint8_t command, uint16_t value, uint16_t index, uint8_t *data, size_t size); - bool WriteUsb(uint8_t command, uint16_t value, uint16_t index, uint8_t *data, size_t size); - - static void PacketRead(uint32_t data_size, uint8_t *data, void *context); - - usb_device_t *dev; - streaming_t *stream; - ringbuffer *inputbuffer; - bool run; - std::thread poll_thread; -}; - - -#endif // FX3HANDLER_H diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/linux/ezusb.c b/source_modules/sddc_source/src/libsddc/Core/arch/linux/ezusb.c deleted file mode 100644 index bcb7dc0..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/linux/ezusb.c +++ /dev/null @@ -1,815 +0,0 @@ -/* - * Copyright © 2001 Stephen Williams (steve@icarus.com) - * Copyright © 2001-2002 David Brownell (dbrownell@users.sourceforge.net) - * Copyright © 2008 Roger Williams (rawqux@users.sourceforge.net) - * Copyright © 2012 Pete Batard (pete@akeo.ie) - * Copyright © 2013 Federico Manzan (f.manzan@gmail.com) - * - * This source code is free software; you can redistribute it - * and/or modify it in source code form under the terms of the GNU - * General Public License as published by the Free Software - * Foundation; either version 2 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#include -#include -#include -#include -#include -#include - -#include "libusb.h" -#include "ezusb.h" - -//extern void logerror(const char *format, ...) -// __attribute__ ((format(printf, 1, 2))); -// - -void logerror(const char *format, ...) - __attribute__ ((format (__printf__, 1, 2))); - -void logerror(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); -} - - -/* - * This file contains functions for uploading firmware into Cypress - * EZ-USB microcontrollers. These chips use control endpoint 0 and vendor - * specific commands to support writing into the on-chip SRAM. They also - * support writing into the CPUCS register, which is how we reset the - * processor after loading firmware (including the reset vector). - * - * These Cypress devices are 8-bit 8051 based microcontrollers with - * special support for USB I/O. They come in several packages, and - * some can be set up with external memory when device costs allow. - * Note that the design was originally by AnchorChips, so you may find - * references to that vendor (which was later merged into Cypress). - * The Cypress FX parts are largely compatible with the Anchorhip ones. - */ - -int verbose = 1; - -/* - * return true if [addr,addr+len] includes external RAM - * for Anchorchips EZ-USB or Cypress EZ-USB FX - */ -static bool fx_is_external(uint32_t addr, size_t len) -{ - /* with 8KB RAM, 0x0000-0x1b3f can be written - * we can't tell if it's a 4KB device here - */ - if (addr <= 0x1b3f) - return ((addr + len) > 0x1b40); - - /* there may be more RAM; unclear if we can write it. - * some bulk buffers may be unused, 0x1b3f-0x1f3f - * firmware can set ISODISAB for 2KB at 0x2000-0x27ff - */ - return true; -} - -/* - * return true if [addr,addr+len] includes external RAM - * for Cypress EZ-USB FX2 - */ -static bool fx2_is_external(uint32_t addr, size_t len) -{ - /* 1st 8KB for data/code, 0x0000-0x1fff */ - if (addr <= 0x1fff) - return ((addr + len) > 0x2000); - - /* and 512 for data, 0xe000-0xe1ff */ - else if (addr >= 0xe000 && addr <= 0xe1ff) - return ((addr + len) > 0xe200); - - /* otherwise, it's certainly external */ - else - return true; -} - -/* - * return true if [addr,addr+len] includes external RAM - * for Cypress EZ-USB FX2LP - */ -static bool fx2lp_is_external(uint32_t addr, size_t len) -{ - /* 1st 16KB for data/code, 0x0000-0x3fff */ - if (addr <= 0x3fff) - return ((addr + len) > 0x4000); - - /* and 512 for data, 0xe000-0xe1ff */ - else if (addr >= 0xe000 && addr <= 0xe1ff) - return ((addr + len) > 0xe200); - - /* otherwise, it's certainly external */ - else - return true; -} - - -/*****************************************************************************/ - -/* - * These are the requests (bRequest) that the bootstrap loader is expected - * to recognize. The codes are reserved by Cypress, and these values match - * what EZ-USB hardware, or "Vend_Ax" firmware (2nd stage loader) uses. - * Cypress' "a3load" is nice because it supports both FX and FX2, although - * it doesn't have the EEPROM support (subset of "Vend_Ax"). - */ -#define RW_INTERNAL 0xA0 /* hardware implements this one */ -#define RW_MEMORY 0xA3 - -/* - * Issues the specified vendor-specific write request. - */ -static int ezusb_write(libusb_device_handle *device, const char *label, - uint8_t opcode, uint32_t addr, const unsigned char *data, size_t len) -{ - int status; - - if (verbose > 1) - logerror("%s, addr 0x%08x len %4u (0x%04x)\n", label, addr, (unsigned)len, (unsigned)len); - status = libusb_control_transfer(device, - LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, - opcode, addr & 0xFFFF, addr >> 16, - (unsigned char*)data, (uint16_t)len, 1000); - if (status != (signed)len) { - if (status < 0) - logerror("%s: %s\n", label, libusb_error_name(status)); - else - logerror("%s ==> %d\n", label, status); - } - return (status < 0) ? -EIO : 0; -} - -/* - * Issues the specified vendor-specific read request. - */ -static int ezusb_read(libusb_device_handle *device, const char *label, - uint8_t opcode, uint32_t addr, const unsigned char *data, size_t len) -{ - int status; - - if (verbose > 1) - logerror("%s, addr 0x%08x len %4u (0x%04x)\n", label, addr, (unsigned)len, (unsigned)len); - status = libusb_control_transfer(device, - LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, - opcode, addr & 0xFFFF, addr >> 16, - (unsigned char*)data, (uint16_t)len, 1000); - if (status != (signed)len) { - if (status < 0) - logerror("%s: %s\n", label, libusb_error_name(status)); - else - logerror("%s ==> %d\n", label, status); - } - return (status < 0) ? -EIO : 0; -} - -/* - * Modifies the CPUCS register to stop or reset the CPU. - * Returns false on error. - */ -static bool ezusb_cpucs(libusb_device_handle *device, uint32_t addr, bool doRun) -{ - int status; - uint8_t data = doRun ? 0x00 : 0x01; - - if (verbose) - logerror("%s\n", data ? "stop CPU" : "reset CPU"); - status = libusb_control_transfer(device, - LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, - RW_INTERNAL, addr & 0xFFFF, addr >> 16, - &data, 1, 1000); - if ((status != 1) && - /* We may get an I/O error from libusb as the device disappears */ - ((!doRun) || (status != LIBUSB_ERROR_IO))) - { - const char *mesg = "can't modify CPUCS"; - if (status < 0) - logerror("%s: %s\n", mesg, libusb_error_name(status)); - else - logerror("%s\n", mesg); - return false; - } else - return true; -} - -/* - * Send an FX3 jumpt to address command - * Returns false on error. - */ -static bool ezusb_fx3_jump(libusb_device_handle *device, uint32_t addr) -{ - int status; - - if (verbose) - logerror("transfer execution to Program Entry at 0x%08x\n", addr); - status = libusb_control_transfer(device, - LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, - RW_INTERNAL, addr & 0xFFFF, addr >> 16, - NULL, 0, 1000); - /* We may get an I/O error from libusb as the device disappears */ - if ((status != 0) && (status != LIBUSB_ERROR_IO)) - { - const char *mesg = "failed to send jump command"; - if (status < 0) - logerror("%s: %s\n", mesg, libusb_error_name(status)); - else - logerror("%s\n", mesg); - return false; - } else - return true; -} - -/*****************************************************************************/ - -/* - * Parse an Intel HEX image file and invoke the poke() function on the - * various segments to implement policies such as writing to RAM (with - * a one or two stage loader setup, depending on the firmware) or to - * EEPROM (two stages required). - * - * image - the hex image file - * context - for use by poke() - * is_external - if non-null, used to check which segments go into - * external memory (writable only by software loader) - * poke - called with each memory segment; errors indicated - * by returning negative values. - * - * Caller is responsible for halting CPU as needed, such as when - * overwriting a second stage loader. - */ -static int parse_ihex(FILE *image, void *context, - bool (*is_external)(uint32_t addr, size_t len), - int (*poke) (void *context, uint32_t addr, bool external, - const unsigned char *data, size_t len)) -{ - unsigned char data[1023]; - uint32_t data_addr = 0; - size_t data_len = 0; - int rc; - int first_line = 1; - bool external = false; - - /* Read the input file as an IHEX file, and report the memory segments - * as we go. Each line holds a max of 16 bytes, but uploading is - * faster (and EEPROM space smaller) if we merge those lines into larger - * chunks. Most hex files keep memory segments together, which makes - * such merging all but free. (But it may still be worth sorting the - * hex files to make up for undesirable behavior from tools.) - * - * Note that EEPROM segments max out at 1023 bytes; the upload protocol - * allows segments of up to 64 KBytes (more than a loader could handle). - */ - for (;;) { - char buf[512], *cp; - char tmp, type; - size_t len; - unsigned idx, off; - - cp = fgets(buf, sizeof(buf), image); - if (cp == NULL) { - logerror("EOF without EOF record!\n"); - break; - } - - /* EXTENSION: "# comment-till-end-of-line", for copyrights etc */ - if (buf[0] == '#') - continue; - - if (buf[0] != ':') { - logerror("not an ihex record: %s", buf); - return -2; - } - - /* ignore any newline */ - cp = strchr(buf, '\n'); - if (cp) - *cp = 0; - - if (verbose >= 3) - logerror("** LINE: %s\n", buf); - - /* Read the length field (up to 16 bytes) */ - tmp = buf[3]; - buf[3] = 0; - len = strtoul(buf+1, NULL, 16); - buf[3] = tmp; - - /* Read the target offset (address up to 64KB) */ - tmp = buf[7]; - buf[7] = 0; - off = (unsigned int)strtoul(buf+3, NULL, 16); - buf[7] = tmp; - - /* Initialize data_addr */ - if (first_line) { - data_addr = off; - first_line = 0; - } - - /* Read the record type */ - tmp = buf[9]; - buf[9] = 0; - type = (char)strtoul(buf+7, NULL, 16); - buf[9] = tmp; - - /* If this is an EOF record, then make it so. */ - if (type == 1) { - if (verbose >= 2) - logerror("EOF on hexfile\n"); - break; - } - - if (type != 0) { - logerror("unsupported record type: %u\n", type); - return -3; - } - - if ((len * 2) + 11 > strlen(buf)) { - logerror("record too short?\n"); - return -4; - } - - /* FIXME check for _physically_ contiguous not just virtually - * e.g. on FX2 0x1f00-0x2100 includes both on-chip and external - * memory so it's not really contiguous */ - - /* flush the saved data if it's not contiguous, - * or when we've buffered as much as we can. - */ - if (data_len != 0 - && (off != (data_addr + data_len) - /* || !merge */ - || (data_len + len) > sizeof(data))) { - if (is_external) - external = is_external(data_addr, data_len); - rc = poke(context, data_addr, external, data, data_len); - if (rc < 0) - return -1; - data_addr = off; - data_len = 0; - } - - /* append to saved data, flush later */ - for (idx = 0, cp = buf+9 ; idx < len ; idx += 1, cp += 2) { - tmp = cp[2]; - cp[2] = 0; - data[data_len + idx] = (uint8_t)strtoul(cp, NULL, 16); - cp[2] = tmp; - } - data_len += len; - } - - - /* flush any data remaining */ - if (data_len != 0) { - if (is_external) - external = is_external(data_addr, data_len); - rc = poke(context, data_addr, external, data, data_len); - if (rc < 0) - return -1; - } - return 0; -} - -/* - * Parse a binary image file and write it as is to the target. - * Applies to Cypress BIX images for RAM or Cypress IIC images - * for EEPROM. - * - * image - the BIX image file - * context - for use by poke() - * is_external - if non-null, used to check which segments go into - * external memory (writable only by software loader) - * poke - called with each memory segment; errors indicated - * by returning negative values. - * - * Caller is responsible for halting CPU as needed, such as when - * overwriting a second stage loader. - */ -static int parse_bin(FILE *image, void *context, - bool (*is_external)(uint32_t addr, size_t len), int (*poke)(void *context, - uint32_t addr, bool external, const unsigned char *data, size_t len)) -{ - unsigned char data[4096]; - uint32_t data_addr = 0; - size_t data_len = 0; - int rc; - bool external = false; - - for (;;) { - data_len = fread(data, 1, 4096, image); - if (data_len == 0) - break; - if (is_external) - external = is_external(data_addr, data_len); - rc = poke(context, data_addr, external, data, data_len); - if (rc < 0) - return -1; - data_addr += (uint32_t)data_len; - } - return feof(image)?0:-1; -} - -/* - * Parse a Cypress IIC image file and invoke the poke() function on the - * various segments for writing to RAM - * - * image - the IIC image file - * context - for use by poke() - * is_external - if non-null, used to check which segments go into - * external memory (writable only by software loader) - * poke - called with each memory segment; errors indicated - * by returning negative values. - * - * Caller is responsible for halting CPU as needed, such as when - * overwriting a second stage loader. - */ -static int parse_iic(FILE *image, void *context, - bool (*is_external)(uint32_t addr, size_t len), - int (*poke)(void *context, uint32_t addr, bool external, const unsigned char *data, size_t len)) -{ - unsigned char data[4096]; - uint32_t data_addr = 0; - size_t data_len = 0, read_len; - uint8_t block_header[4]; - int rc; - bool external = false; - long file_size, initial_pos; - - initial_pos = ftell(image); - if (initial_pos < 0) - return -1; - - if (fseek(image, 0L, SEEK_END) != 0) - return -1; - file_size = ftell(image); - if (fseek(image, initial_pos, SEEK_SET) != 0) - return -1; - for (;;) { - /* Ignore the trailing reset IIC data (5 bytes) */ - if (ftell(image) >= (file_size - 5)) - break; - if (fread(&block_header, 1, sizeof(block_header), image) != 4) { - logerror("unable to read IIC block header\n"); - return -1; - } - data_len = (block_header[0] << 8) + block_header[1]; - data_addr = (block_header[2] << 8) + block_header[3]; - if (data_len > sizeof(data)) { - /* If this is ever reported as an error, switch to using malloc/realloc */ - logerror("IIC data block too small - please report this error to libusb.info\n"); - return -1; - } - read_len = fread(data, 1, data_len, image); - if (read_len != data_len) { - logerror("read error\n"); - return -1; - } - if (is_external) - external = is_external(data_addr, data_len); - rc = poke(context, data_addr, external, data, data_len); - if (rc < 0) - return -1; - } - return 0; -} - -/* the parse call will be selected according to the image type */ -static int (*parse[IMG_TYPE_MAX])(FILE *image, void *context, bool (*is_external)(uint32_t addr, size_t len), - int (*poke)(void *context, uint32_t addr, bool external, const unsigned char *data, size_t len)) - = { parse_ihex, parse_iic, parse_bin }; - -/*****************************************************************************/ - -/* - * For writing to RAM using a first (hardware) or second (software) - * stage loader and 0xA0 or 0xA3 vendor requests - */ -typedef enum { - _undef = 0, - internal_only, /* hardware first-stage loader */ - skip_internal, /* first phase, second-stage loader */ - skip_external /* second phase, second-stage loader */ -} ram_mode; - -struct ram_poke_context { - libusb_device_handle *device; - ram_mode mode; - size_t total, count; -}; - -#define RETRY_LIMIT 5 - -static int ram_poke(void *context, uint32_t addr, bool external, - const unsigned char *data, size_t len) -{ - struct ram_poke_context *ctx = (struct ram_poke_context*)context; - int rc; - unsigned retry = 0; - - switch (ctx->mode) { - case internal_only: /* CPU should be stopped */ - if (external) { - logerror("can't write %u bytes external memory at 0x%08x\n", - (unsigned)len, addr); - return -EINVAL; - } - break; - case skip_internal: /* CPU must be running */ - if (!external) { - if (verbose >= 2) { - logerror("SKIP on-chip RAM, %u bytes at 0x%08x\n", - (unsigned)len, addr); - } - return 0; - } - break; - case skip_external: /* CPU should be stopped */ - if (external) { - if (verbose >= 2) { - logerror("SKIP external RAM, %u bytes at 0x%08x\n", - (unsigned)len, addr); - } - return 0; - } - break; - case _undef: - default: - logerror("bug\n"); - return -EDOM; - } - - ctx->total += len; - ctx->count++; - - /* Retry this till we get a real error. Control messages are not - * NAKed (just dropped) so time out means is a real problem. - */ - while ((rc = ezusb_write(ctx->device, - external ? "write external" : "write on-chip", - external ? RW_MEMORY : RW_INTERNAL, - addr, data, len)) < 0 - && retry < RETRY_LIMIT) { - if (rc != LIBUSB_ERROR_TIMEOUT) - break; - retry += 1; - } - return rc; -} - -/* - * Load a Cypress Image file into target RAM. - * See http://www.cypress.com/?docID=41351 (AN76405 PDF) for more info. - */ -int fx3_load_ram(libusb_device_handle *device, const char *image) -{ - uint32_t dCheckSum, dExpectedCheckSum, dAddress, i, dLen, dLength; - uint32_t* dImageBuf; - const unsigned char *bBuf, *hBuf; - unsigned char blBuf[4], rBuf[4096]; - int ret = 0; - int offset = 0; - - hBuf = image; - offset += 4; - // check "CY" signature byte and format - if ((hBuf[0] != 'C') || (hBuf[1] != 'Y')) { - logerror("image doesn't have a CYpress signature\n"); - ret = -3; - goto exit; - } - - // Check bImageType - switch(hBuf[3]) { - case 0xB0: - if (verbose) - logerror("normal FW binary %s image with checksum\n", (hBuf[2]&0x01)?"data":"executable"); - break; - case 0xB1: - logerror("security binary image is not currently supported\n"); - ret = -3; - goto exit; - case 0xB2: - logerror("VID:PID image is not currently supported\n"); - ret = -3; - goto exit; - default: - logerror("invalid image type 0x%02X\n", hBuf[3]); - ret = -3; - goto exit; - } - - // Read the bootloader version - if (verbose) { - if ((ezusb_read(device, "read bootloader version", RW_INTERNAL, 0xFFFF0020, blBuf, 4) < 0)) { - logerror("Could not read bootloader version\n"); - ret = -8; - goto exit; - } - logerror("FX3 bootloader version: 0x%02X%02X%02X%02X\n", blBuf[3], blBuf[2], blBuf[1], blBuf[0]); - } - - dCheckSum = 0; - if (verbose) - logerror("writing image...\n"); - while (1) { - dLength = *(uint32_t*)(image+offset); offset += sizeof(uint32_t); - dAddress = *(uint32_t*)(image+offset); offset += sizeof(uint32_t); - - if (dLength == 0) - break; // done - - // read sections - dImageBuf = (uint32_t*)(image+offset); offset += sizeof(uint32_t) * dLength; - - for (i = 0; i < dLength; i++) - dCheckSum += dImageBuf[i]; - dLength <<= 2; // convert to Byte length - bBuf = (unsigned char*) dImageBuf; - - while (dLength > 0) { - dLen = 4096; // 4K max - if (dLen > dLength) - dLen = dLength; - if ((ezusb_write(device, "write firmware", RW_INTERNAL, dAddress, bBuf, dLen) < 0) || - (ezusb_read(device, "read firmware", RW_INTERNAL, dAddress, rBuf, dLen) < 0)) { - logerror("R/W error\n"); - ret = -5; - goto exit; - } - // Verify data: rBuf with bBuf - for (i = 0; i < dLen; i++) { - if (rBuf[i] != bBuf[i]) { - logerror("verify error"); - ret = -6; - goto exit; - } - } - - dLength -= dLen; - bBuf += dLen; - dAddress += dLen; - } - } - - // read pre-computed checksum data - dExpectedCheckSum = *(uint32_t*)(image + offset); offset += sizeof(uint32_t); - if (dCheckSum != dExpectedCheckSum) { - logerror("checksum error\n"); - ret = -7; - goto exit; - } - - // transfer execution to Program Entry - if (!ezusb_fx3_jump(device, dAddress)) { - ret = -6; - } - -exit: - return ret; -} - -/* - * Load a firmware file into target RAM. device is the open libusb - * device, and the path is the name of the source file. Open the file, - * parse the bytes, and write them in one or two phases. - * - * If stage == 0, this uses the first stage loader, built into EZ-USB - * hardware but limited to writing on-chip memory or CPUCS. Everything - * is written during one stage, unless there's an error such as the image - * holding data that needs to be written to external memory. - * - * Otherwise, things are written in two stages. First the external - * memory is written, expecting a second stage loader to have already - * been loaded. Then file is re-parsed and on-chip memory is written. - */ -int ezusb_load_ram(libusb_device_handle *device, const char *path, int fx_type, int img_type, int stage) -{ - FILE *image; - uint32_t cpucs_addr; - bool (*is_external)(uint32_t off, size_t len); - struct ram_poke_context ctx; - int status; - uint8_t iic_header[8] = { 0 }; - int ret = 0; - - if (fx_type == FX_TYPE_FX3) - return fx3_load_ram(device, path); - - image = fopen(path, "rb"); - if (image == NULL) { - logerror("%s: unable to open for input.\n", path); - return -2; - } else if (verbose > 1) - logerror("open firmware image %s for RAM upload\n", path); - - if (img_type == IMG_TYPE_IIC) { - if ( (fread(iic_header, 1, sizeof(iic_header), image) != sizeof(iic_header)) - || (((fx_type == FX_TYPE_FX2LP) || (fx_type == FX_TYPE_FX2)) && (iic_header[0] != 0xC2)) - || ((fx_type == FX_TYPE_AN21) && (iic_header[0] != 0xB2)) - || ((fx_type == FX_TYPE_FX1) && (iic_header[0] != 0xB6)) ) { - logerror("IIC image does not contain executable code - cannot load to RAM.\n"); - ret = -1; - goto exit; - } - } - - /* EZ-USB original/FX and FX2 devices differ, apart from the 8051 core */ - switch(fx_type) { - case FX_TYPE_FX2LP: - cpucs_addr = 0xe600; - is_external = fx2lp_is_external; - break; - case FX_TYPE_FX2: - cpucs_addr = 0xe600; - is_external = fx2_is_external; - break; - default: - cpucs_addr = 0x7f92; - is_external = fx_is_external; - break; - } - - /* use only first stage loader? */ - if (stage == 0) { - ctx.mode = internal_only; - - /* if required, halt the CPU while we overwrite its code/data */ - if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, false)) - { - ret = -1; - goto exit; - } - - /* 2nd stage, first part? loader was already uploaded */ - } else { - ctx.mode = skip_internal; - - /* let CPU run; overwrite the 2nd stage loader later */ - if (verbose) - logerror("2nd stage: write external memory\n"); - } - - /* scan the image, first (maybe only) time */ - ctx.device = device; - ctx.total = ctx.count = 0; - status = parse[img_type](image, &ctx, is_external, ram_poke); - if (status < 0) { - logerror("unable to upload %s\n", path); - ret = status; - goto exit; - } - - /* second part of 2nd stage: rescan */ - // TODO: what should we do for non HEX images there? - if (stage) { - ctx.mode = skip_external; - - /* if needed, halt the CPU while we overwrite the 1st stage loader */ - if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, false)) - { - ret = -1; - goto exit; - } - - /* at least write the interrupt vectors (at 0x0000) for reset! */ - rewind(image); - if (verbose) - logerror("2nd stage: write on-chip memory\n"); - status = parse_ihex(image, &ctx, is_external, ram_poke); - if (status < 0) { - logerror("unable to completely upload %s\n", path); - ret = status; - goto exit; - } - } - - if (verbose && (ctx.count != 0)) { - logerror("... WROTE: %d bytes, %d segments, avg %d\n", - (int)ctx.total, (int)ctx.count, (int)(ctx.total/ctx.count)); - } - - /* if required, reset the CPU so it runs what we just uploaded */ - if (cpucs_addr && !ezusb_cpucs(device, cpucs_addr, true)) - ret = -1; - -exit: - fclose(image); - return ret; -} diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/linux/ezusb.h b/source_modules/sddc_source/src/libsddc/Core/arch/linux/ezusb.h deleted file mode 100644 index e18ed33..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/linux/ezusb.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef ezusb_H -#define ezusb_H -/* - * Copyright © 2001 Stephen Williams (steve@icarus.com) - * Copyright © 2002 David Brownell (dbrownell@users.sourceforge.net) - * Copyright © 2013 Federico Manzan (f.manzan@gmail.com) - * - * This source code is free software; you can redistribute it - * and/or modify it in source code form under the terms of the GNU - * General Public License as published by the Free Software - * Foundation; either version 2 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#if defined(_MSC_VER) -#define __attribute__(x) -#if defined(_PREFAST_) -#pragma warning(disable:28193) -#endif -#endif - -#include - -#define FX_TYPE_UNDEFINED -1 -#define FX_TYPE_AN21 0 /* Original AnchorChips parts */ -#define FX_TYPE_FX1 1 /* Updated Cypress versions */ -#define FX_TYPE_FX2 2 /* USB 2.0 versions */ -#define FX_TYPE_FX2LP 3 /* Updated FX2 */ -#define FX_TYPE_FX3 4 /* USB 3.0 versions */ -#define FX_TYPE_MAX 5 -#define FX_TYPE_NAMES { "an21", "fx", "fx2", "fx2lp", "fx3" } - -#define IMG_TYPE_UNDEFINED -1 -#define IMG_TYPE_HEX 0 /* Intel HEX */ -#define IMG_TYPE_IIC 1 /* Cypress 8051 IIC */ -#define IMG_TYPE_BIX 2 /* Cypress 8051 BIX */ -#define IMG_TYPE_IMG 3 /* Cypress IMG format */ -#define IMG_TYPE_MAX 4 -#define IMG_TYPE_NAMES { "Intel HEX", "Cypress 8051 IIC", "Cypress 8051 BIX", "Cypress IMG format" } - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Automatically identified devices (VID, PID, type, designation). - * TODO: Could use some validation. Also where's the FX2? - */ -typedef struct { - uint16_t vid; - uint16_t pid; - int type; - const char* designation; -} fx_known_device; - -#define FX_KNOWN_DEVICES { \ - { 0x0547, 0x2122, FX_TYPE_AN21, "Cypress EZ-USB (2122S)" },\ - { 0x0547, 0x2125, FX_TYPE_AN21, "Cypress EZ-USB (2121S/2125S)" },\ - { 0x0547, 0x2126, FX_TYPE_AN21, "Cypress EZ-USB (2126S)" },\ - { 0x0547, 0x2131, FX_TYPE_AN21, "Cypress EZ-USB (2131Q/2131S/2135S)" },\ - { 0x0547, 0x2136, FX_TYPE_AN21, "Cypress EZ-USB (2136S)" },\ - { 0x0547, 0x2225, FX_TYPE_AN21, "Cypress EZ-USB (2225)" },\ - { 0x0547, 0x2226, FX_TYPE_AN21, "Cypress EZ-USB (2226)" },\ - { 0x0547, 0x2235, FX_TYPE_AN21, "Cypress EZ-USB (2235)" },\ - { 0x0547, 0x2236, FX_TYPE_AN21, "Cypress EZ-USB (2236)" },\ - { 0x04b4, 0x6473, FX_TYPE_FX1, "Cypress EZ-USB FX1" },\ - { 0x04b4, 0x8613, FX_TYPE_FX2LP, "Cypress EZ-USB FX2LP (68013A/68014A/68015A/68016A)" }, \ - { 0x04b4, 0x00f3, FX_TYPE_FX3, "Cypress FX3" },\ -} - -/* - * This function uploads the firmware from the given file into RAM. - * Stage == 0 means this is a single stage load (or the first of - * two stages). Otherwise it's the second of two stages; the - * caller having preloaded the second stage loader. - * - * The target processor is reset at the end of this upload. - */ -extern int ezusb_load_ram(libusb_device_handle *device, - const char *path, int fx_type, int img_type, int stage); - -extern int fx3_load_ram(libusb_device_handle *device, const char *image); - -/* - * This function uploads the firmware from the given file into EEPROM. - * This uses the right CPUCS address to terminate the EEPROM load with - * a reset command where FX parts behave differently than FX2 ones. - * The configuration byte is as provided here (zero for an21xx parts) - * and the EEPROM type is set so that the microcontroller will boot - * from it. - * - * The caller must have preloaded a second stage loader that knows - * how to respond to the EEPROM write request. - */ -extern int ezusb_load_eeprom(libusb_device_handle *device, - const char *path, int fx_type, int img_type, int config); - -/* Verbosity level (default 1). Can be increased or decreased with options v/q */ -extern int verbose; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/linux/logging.c b/source_modules/sddc_source/src/libsddc/Core/arch/linux/logging.c deleted file mode 100644 index 2024044..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/linux/logging.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * logging.c - logging functions - * - * Copyright (C) 2020 by Franco Venturi - * - * 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 . - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#include -#include - -#include "logging.h" - - -void log_error(const char *error_message, const char *function, - const char *file, int line) { - fprintf(stderr, "ERROR - %s in %s at %s:%d\n", error_message, function, - file, line); - return; -} - -void log_usb_error(int usb_error_code, const char *function, const char *file, - int line) { - fprintf(stderr, "ERROR - USB error %s in %s at %s:%d\n", - libusb_error_name(usb_error_code), function, file, line); - return; -} - -void log_usb_warning(int usb_error_code, const char *function, const char *file, - int line) { - fprintf(stderr, "WARNING - USB warning %s in %s at %s:%d\n", - libusb_error_name(usb_error_code), function, file, line); - return; -} diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/linux/logging.h b/source_modules/sddc_source/src/libsddc/Core/arch/linux/logging.h deleted file mode 100644 index 6c1bfbd..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/linux/logging.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * logging.h - logging functions - * - * Copyright (C) 2020 by Franco Venturi - * - * 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 . - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#ifndef __LOGGING_H -#define __LOGGING_H - -#include - - -#ifdef __cplusplus -extern "C" { -#endif - -void log_error(const char *error_message, const char *function, - const char *file, int line); -void log_usb_error(int usb_error_code, const char *function, const char *file, - int line); -void log_usb_warning(int usb_error_code, const char *function, const char *file, - int line); - -#ifdef __cplusplus -} -#endif - -#endif /* __LOGGING_H */ diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/linux/streaming.c b/source_modules/sddc_source/src/libsddc/Core/arch/linux/streaming.c deleted file mode 100644 index 8839b42..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/linux/streaming.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * streaming.c - streaming functions - * - * Copyright (C) 2020 by Franco Venturi - * - * 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 . - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -/* References: - * - librtlsdr.c: https://github.com/librtlsdr/librtlsdr/blob/development/src/librtlsdr.c - * - Ettus Research UHD libusb1_zero_copy.cpp: https://github.com/EttusResearch/uhd/blob/master/host/lib/transport/libusb1_zero_copy.cpp - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "streaming.h" -#include "usb_device.h" -#include "usb_device_internals.h" -#include "logging.h" - - -typedef struct streaming streaming_t; - -/* internal functions */ -static void streaming_read_async_callback(struct libusb_transfer *transfer); - - -enum StreamingStatus { - STREAMING_STATUS_OFF, - STREAMING_STATUS_READY, - STREAMING_STATUS_STREAMING, - STREAMING_STATUS_CANCELLED, - STREAMING_STATUS_FAILED = 0xff -}; - -typedef struct streaming { - enum StreamingStatus status; - int random; - usb_device_t *usb_device; - uint32_t sample_rate; - uint32_t frame_size; - uint32_t num_frames; - sddc_read_async_cb_t callback; - void *callback_context; - uint8_t **frames; - struct libusb_transfer **transfers; - atomic_int active_transfers; -} streaming_t; - - -static const uint32_t DEFAULT_SAMPLE_RATE = 64000000; /* 64Msps */ -static const uint32_t DEFAULT_FRAME_SIZE = (2 * 64000000 / 1000); /* ~ 1 ms */ -static const uint32_t DEFAULT_NUM_FRAMES = 96; /* we should not exceed 120 ms in total! */ -const unsigned int BULK_XFER_TIMEOUT = 5000; // timeout (in ms) for each bulk transfer - - -streaming_t *streaming_open_sync(usb_device_t *usb_device) -{ - streaming_t *ret_val = 0; - - /* we must have a bulk in device to transfer data from */ - if (usb_device->bulk_in_endpoint_address == 0) { - log_error("no USB bulk in endpoint found", __func__, __FILE__, __LINE__); - return ret_val; - } - - /* we are good here - create and initialize the streaming */ - streaming_t *this = (streaming_t *) malloc(sizeof(streaming_t)); - this->status = STREAMING_STATUS_READY; - this->random = 0; - this->usb_device = usb_device; - this->sample_rate = DEFAULT_SAMPLE_RATE; - this->frame_size = 0; - this->num_frames = 0; - this->callback = 0; - this->callback_context = 0; - this->frames = 0; - this->transfers = 0; - atomic_init(&this->active_transfers, 0); - - ret_val = this; - return ret_val; -} - - -streaming_t *streaming_open_async(usb_device_t *usb_device, uint32_t frame_size, - uint32_t num_frames, sddc_read_async_cb_t callback, - void *callback_context) -{ - streaming_t *ret_val = 0; - - /* we must have a bulk in device to transfer data from */ - if (usb_device->bulk_in_endpoint_address == 0) { - log_error("no USB bulk in endpoint found", __func__, __FILE__, __LINE__); - return ret_val; - } - - /* frame size must be a multiple of max_packet_size * max_burst */ - uint32_t max_xfer_size = usb_device->bulk_in_max_packet_size * - usb_device->bulk_in_max_burst; - if ( !max_xfer_size ) { - fprintf(stderr, "ERROR: maximum transfer size is 0. probably not connected at USB 3 port?!\n"); - return ret_val; - } - - num_frames = num_frames > 0 ? num_frames : DEFAULT_NUM_FRAMES; - frame_size = frame_size > 0 ? frame_size : DEFAULT_FRAME_SIZE; - frame_size = max_xfer_size * ((frame_size +max_xfer_size -1) / max_xfer_size); // round up - int iso_packets_per_frame = frame_size / usb_device->bulk_in_max_packet_size; - fprintf(stderr, "frame_size = %u, iso_packets_per_frame = %d\n", (unsigned)frame_size, iso_packets_per_frame); - - if (frame_size % max_xfer_size != 0) { - fprintf(stderr, "frame size must be a multiple of %d\n", max_xfer_size); - return ret_val; - } - - /* allocate frames for zerocopy USB bulk transfers */ - uint8_t **frames = (uint8_t **) malloc(num_frames * sizeof(uint8_t *)); - for (uint32_t i = 0; i < num_frames; ++i) { - frames[i] = libusb_dev_mem_alloc(usb_device->dev_handle, frame_size); - if (frames[i] == 0) { - log_error("libusb_dev_mem_alloc() failed", __func__, __FILE__, __LINE__); - for (uint32_t j = 0; j < i; j++) { - libusb_dev_mem_free(usb_device->dev_handle, frames[j], frame_size); - } - return ret_val; - } - } - - /* we are good here - create and initialize the streaming */ - streaming_t *this = (streaming_t *) malloc(sizeof(streaming_t)); - this->status = STREAMING_STATUS_READY; - this->random = 0; - this->usb_device = usb_device; - this->sample_rate = DEFAULT_SAMPLE_RATE; - this->frame_size = frame_size > 0 ? frame_size : DEFAULT_FRAME_SIZE; - this->num_frames = num_frames > 0 ? num_frames : DEFAULT_NUM_FRAMES; - this->callback = callback; - this->callback_context = callback_context; - this->frames = frames; - - /* populate the required libusb_transfer fields */ - struct libusb_transfer **transfers = (struct libusb_transfer **) malloc(num_frames * sizeof(struct libusb_transfer *)); - for (uint32_t i = 0; i < num_frames; ++i) { - transfers[i] = libusb_alloc_transfer(0); // iso_packets_per_frame ? - libusb_fill_bulk_transfer(transfers[i], usb_device->dev_handle, - usb_device->bulk_in_endpoint_address, - frames[i], frame_size, streaming_read_async_callback, - this, BULK_XFER_TIMEOUT); - } - this->transfers = transfers; - atomic_init(&this->active_transfers, 0); - - ret_val = this; - return ret_val; -} - - -void streaming_close(streaming_t *this) -{ - if (this->transfers) { - for (uint32_t i = 0; i < this->num_frames; ++i) { - libusb_free_transfer(this->transfers[i]); - } - free(this->transfers); - } - if (this->frames != 0) { - for (uint32_t i = 0; i < this->num_frames; ++i) { - libusb_dev_mem_free(this->usb_device->dev_handle, this->frames[i], - this->frame_size); - } - free(this->frames); - } - free(this); - return; -} - - -int streaming_set_sample_rate(streaming_t *this, uint32_t sample_rate) -{ - /* no checks yet */ - this->sample_rate = sample_rate; - return 0; -} - - -int streaming_set_random(streaming_t *this, int random) -{ - this->random = random; - return 0; -} - - -int streaming_start(streaming_t *this) -{ - if (this->status != STREAMING_STATUS_READY) { - fprintf(stderr, "ERROR - streaming_start() called with streaming status not READY: %d\n", this->status); - return -1; - } - - /* if there is no callback, then streaming is synchronous - nothing to do */ - if (this->callback == 0) { - this->status = STREAMING_STATUS_STREAMING; - return 0; - } - - /* submit all the transfers */ - atomic_init(&this->active_transfers, 0); - for (uint32_t i = 0; i < this->num_frames; ++i) { - int ret = libusb_submit_transfer(this->transfers[i]); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - this->status = STREAMING_STATUS_FAILED; - return -1; - } - atomic_fetch_add(&this->active_transfers, 1); - } - - this->status = STREAMING_STATUS_STREAMING; - - return 0; -} - - -int streaming_stop(streaming_t *this) -{ - /* if there is no callback, then streaming is synchronous - nothing to do */ - if (this->callback == 0) { - if (this->status == STREAMING_STATUS_STREAMING) { - this->status = STREAMING_STATUS_READY; - } - return 0; - } - - this->status = STREAMING_STATUS_CANCELLED; - /* cancel all the active transfers */ - for (uint32_t i = 0; i < this->num_frames; ++i) { - int ret = libusb_cancel_transfer(this->transfers[i]); - if (ret < 0) { - if (ret == LIBUSB_ERROR_NOT_FOUND) { - continue; - } - log_usb_error(ret, __func__, __FILE__, __LINE__); - this->status = STREAMING_STATUS_FAILED; - } - } - - /* flush all the events */ - struct timeval noblock = { 0, 0 }; - int ret = libusb_handle_events_timeout_completed(this->usb_device->context, &noblock, 0); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - this->status = STREAMING_STATUS_FAILED; - } - - return 0; -} - - -int streaming_reset_status(streaming_t *this) -{ - switch (this->status) { - case STREAMING_STATUS_READY: - /* nothing to do here */ - return 0; - case STREAMING_STATUS_CANCELLED: - case STREAMING_STATUS_FAILED: - if (this->active_transfers > 0) { - fprintf(stderr, "ERROR - streaming_reset_status() called with %d transfers still active\n", - this->active_transfers); - return -1; - } - break; - default: - fprintf(stderr, "ERROR - streaming_reset_status() called with invalid status: %d\n", - this->status); - return -1; - } - - /* we are good here; reset the status */ - this->status = STREAMING_STATUS_READY; - return 0; -} - - -int streaming_read_sync(streaming_t *this, uint8_t *data, int length, int *transferred) -{ - int ret = libusb_bulk_transfer(this->usb_device->dev_handle, - this->usb_device->bulk_in_endpoint_address, - data, length, transferred, BULK_XFER_TIMEOUT); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - return -1; - } - - /* remove ADC randomization */ - if (this->random) { - uint16_t *samples = (uint16_t *) data; - int n = *transferred / 2; - for (int i = 0; i < n; ++i) { - if (samples[i] & 1) { - samples[i] ^= 0xfffe; - } - } - } - - return 0; -} - - -/* internal functions */ -static void LIBUSB_CALL streaming_read_async_callback(struct libusb_transfer *transfer) -{ - streaming_t *this = (streaming_t *) transfer->user_data; - int ret; - switch (transfer->status) { - case LIBUSB_TRANSFER_COMPLETED: - /* success!!! */ - if (this->status == STREAMING_STATUS_STREAMING) { - /* remove ADC randomization */ - if (this->random) { - uint16_t *samples = (uint16_t *) transfer->buffer; - int n = transfer->actual_length / 2; - for (int i = 0; i < n; ++i) { - if (samples[i] & 1) { - samples[i] ^= 0xfffe; - } - } - } - this->callback(transfer->actual_length, transfer->buffer, - this->callback_context); - ret = libusb_submit_transfer(transfer); - if (ret == 0) { - return; - } - log_usb_error(ret, __func__, __FILE__, __LINE__); - } - break; - case LIBUSB_TRANSFER_CANCELLED: - /* librtlsdr does also ignore LIBUSB_TRANSFER_CANCELLED */ - return; - case LIBUSB_TRANSFER_ERROR: - case LIBUSB_TRANSFER_TIMED_OUT: - case LIBUSB_TRANSFER_STALL: - case LIBUSB_TRANSFER_NO_DEVICE: - case LIBUSB_TRANSFER_OVERFLOW: - log_usb_error(transfer->status, __func__, __FILE__, __LINE__); - break; - } - - this->status = STREAMING_STATUS_FAILED; - atomic_fetch_sub(&this->active_transfers, 1); - fprintf(stderr, "Cancelling\n"); - /* cancel all the active transfers */ - for (uint32_t i = 0; i < this->num_frames; ++i) { - int ret = libusb_cancel_transfer(transfer); - if (ret < 0) { - if (ret == LIBUSB_ERROR_NOT_FOUND) { - continue; - } - log_usb_error(ret, __func__, __FILE__, __LINE__); - } - } - return; -} diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/linux/streaming.h b/source_modules/sddc_source/src/libsddc/Core/arch/linux/streaming.h deleted file mode 100644 index 6283c91..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/linux/streaming.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * streaming.h - streaming functions - * - * Copyright (C) 2020 by Franco Venturi - * - * 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 . - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#ifndef __STREAMING_H -#define __STREAMING_H - -#include "usb_device.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct streaming streaming_t; - -typedef void (*sddc_read_async_cb_t)(uint32_t data_size, uint8_t *data, - void *context); - -streaming_t *streaming_open_sync(usb_device_t *usb_device); - -streaming_t *streaming_open_async(usb_device_t *usb_device, uint32_t frame_size, - uint32_t num_frames, - sddc_read_async_cb_t callback, - void *callback_context); - -void streaming_close(streaming_t *that); - -int streaming_set_sample_rate(streaming_t *that, uint32_t sample_rate); - -int streaming_set_random(streaming_t *that, int random); - -int streaming_start(streaming_t *that); - -int streaming_stop(streaming_t *that); - -int streaming_reset_status(streaming_t *that); - -int streaming_read_sync(streaming_t *that, uint8_t *data, int length, - int *transferred); - -#ifdef __cplusplus -} -#endif - -#endif /* __STREAMING_H */ diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/linux/usb_device.c b/source_modules/sddc_source/src/libsddc/Core/arch/linux/usb_device.c deleted file mode 100644 index 36b454d..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/linux/usb_device.c +++ /dev/null @@ -1,574 +0,0 @@ -/* - * usb_device.c - Basic USB and USB control functions - * - * Copyright (C) 2020 by Franco Venturi - * - * 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 . - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -/* References: - * - FX3 SDK for Linux Platforms (https://www.cypress.com/documentation/software-and-drivers/ez-usb-fx3-software-development-kit) - * example: cyusb_linux_1.0.5/src/download_fx3.cpp - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "usb_device.h" -#include "usb_device_internals.h" -#include "ezusb.h" -#include "logging.h" - - -typedef struct usb_device usb_device_t; - -/* internal functions */ -static libusb_device_handle *find_usb_device(int index, libusb_context *ctx, - libusb_device **device, int *needs_firmware); -static int load_image(libusb_device_handle *dev_handle, - const char *image, uint32_t size); -static int validate_image(const uint8_t *image, const size_t size); -static int transfer_image(const uint8_t *image, - libusb_device_handle *dev_handle); -static int list_endpoints(struct libusb_endpoint_descriptor endpoints[], - struct libusb_ss_endpoint_companion_descriptor ss_endpoints[], - libusb_device *device); - - -struct usb_device_id { - uint16_t vid; - uint16_t pid; - int needs_firmware; -}; - - -static struct usb_device_id usb_device_ids[] = { - { 0x04b4, 0x00f3, 1 }, /* Cypress / FX3 Boot-loader */ - { 0x04b4, 0x00f1, 0 } /* Cypress / FX3 Streamer Example */ -}; -static int n_usb_device_ids = sizeof(usb_device_ids) / sizeof(usb_device_ids[0]); - - -int usb_device_count_devices() -{ - int ret_val = -1; - - int ret = libusb_init(0); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - goto FAIL0; - } - libusb_device **list = 0; - ssize_t nusbdevices = libusb_get_device_list(0, &list); - if (nusbdevices < 0) { - log_usb_error(nusbdevices, __func__, __FILE__, __LINE__); - goto FAIL1; - } - int count = 0; - for (ssize_t i = 0; i < nusbdevices; ++i) { - libusb_device *dev = list[i]; - struct libusb_device_descriptor desc; - ret = libusb_get_device_descriptor(dev, &desc); - for (int i = 0; i < n_usb_device_ids; ++i) { - if (desc.idVendor == usb_device_ids[i].vid && - desc.idProduct == usb_device_ids[i].pid) { - count++; - } - } - } - libusb_free_device_list(list, 1); - - ret_val = count; - -FAIL1: - libusb_exit(0); -FAIL0: - return ret_val; -} - - -int usb_device_get_device_list(struct usb_device_info **usb_device_infos) -{ - const int MAX_STRING_BYTES = 256; - - int ret_val = -1; - - if (usb_device_infos == 0) { - log_error("argument usb_device_infos is a null pointer", __func__, __FILE__, __LINE__); - goto FAIL0; - } - - int ret = libusb_init(0); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - goto FAIL0; - } - libusb_device **list = 0; - ssize_t nusbdevices = libusb_get_device_list(0, &list); - if (nusbdevices < 0) { - log_usb_error(nusbdevices, __func__, __FILE__, __LINE__); - goto FAIL1; - } - - struct usb_device_info *device_infos = (struct usb_device_info *) malloc((nusbdevices + 1) * sizeof(struct usb_device_info)); - int count = 0; - for (ssize_t j = 0; j < nusbdevices; ++j) { - libusb_device *device = list[j]; - struct libusb_device_descriptor desc; - ret = libusb_get_device_descriptor(device, &desc); - for (int i = 0; i < n_usb_device_ids; ++i) { - if (!(desc.idVendor == usb_device_ids[i].vid && - desc.idProduct == usb_device_ids[i].pid)) { - continue; - } - - libusb_device_handle *dev_handle = 0; - ret = libusb_open(device, &dev_handle); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - goto FAIL2; - } - - device_infos[count].manufacturer = (unsigned char *) malloc(MAX_STRING_BYTES); - device_infos[count].manufacturer[0] = '\0'; - if (desc.iManufacturer) { - ret = libusb_get_string_descriptor_ascii(dev_handle, desc.iManufacturer, - device_infos[count].manufacturer, MAX_STRING_BYTES); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - goto FAIL3; - } - device_infos[count].manufacturer = (unsigned char *) realloc(device_infos[count].manufacturer, ret); - } - - device_infos[count].product = (unsigned char *) malloc(MAX_STRING_BYTES); - device_infos[count].product[0] = '\0'; - if (desc.iProduct) { - ret = libusb_get_string_descriptor_ascii(dev_handle, desc.iProduct, - device_infos[count].product, MAX_STRING_BYTES); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - goto FAIL3; - } - device_infos[count].product = (unsigned char *) realloc(device_infos[count].product, ret); - } - - device_infos[count].serial_number = (unsigned char *) malloc(MAX_STRING_BYTES); - device_infos[count].serial_number[0] = '\0'; - if (desc.iSerialNumber) { - ret = libusb_get_string_descriptor_ascii(dev_handle, desc.iSerialNumber, - device_infos[count].serial_number, MAX_STRING_BYTES); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - goto FAIL3; - } - device_infos[count].serial_number = (unsigned char *) realloc(device_infos[count].serial_number, ret); - } - - ret = 0; -FAIL3: - libusb_close(dev_handle); - if (ret < 0) { - goto FAIL2; - } - count++; - } - } - - device_infos[count].manufacturer = 0; - device_infos[count].product = 0; - device_infos[count].serial_number = 0; - - *usb_device_infos = device_infos; - ret_val = count; - -FAIL2: - libusb_free_device_list(list, 1); -FAIL1: - libusb_exit(0); -FAIL0: - return ret_val; -} - - -int usb_device_free_device_list(struct usb_device_info *usb_device_infos) -{ - for (struct usb_device_info *udi = usb_device_infos; - udi->manufacturer || udi->product || udi->serial_number; - ++udi) { - if (udi->manufacturer) { - free(udi->manufacturer); - } - if (udi->product) { - free(udi->product); - } - if (udi->serial_number) { - free(udi->serial_number); - } - } - free(usb_device_infos); - return 0; -} - - -usb_device_t *usb_device_open(int index, const char* image, - uint32_t size) -{ - usb_device_t *ret_val = 0; - libusb_context *ctx = 0; - - int ret = libusb_init(&ctx); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - goto FAIL0; - } - - libusb_device *device; - int needs_firmware = 0; - libusb_device_handle *dev_handle = find_usb_device(index, ctx, &device, &needs_firmware); - if (dev_handle == 0) { - goto FAIL1; - } - - if (needs_firmware) { - ret = load_image(dev_handle, image, size); - if (ret != 0) { - log_error("load_image() failed", __func__, __FILE__, __LINE__); - goto FAIL2; - } - - /* rescan USB to get a new device handle */ - libusb_close(dev_handle); - - /* wait unitl firmware is ready */ - usleep(500 * 1000L); - - needs_firmware = 0; - dev_handle = find_usb_device(index, ctx, &device, &needs_firmware); - if (dev_handle == 0) { - goto FAIL1; - } - if (needs_firmware) { - log_error("device is still in boot loader mode", __func__, __FILE__, __LINE__); - goto FAIL2; - } - } - - int speed = libusb_get_device_speed(device); - if ( speed == LIBUSB_SPEED_LOW || speed == LIBUSB_SPEED_FULL || speed == LIBUSB_SPEED_HIGH ) { - log_error("USB 3.x SuperSpeed connection failed", __func__, __FILE__, __LINE__); - goto FAIL2; - } - - /* list endpoints */ - struct libusb_endpoint_descriptor endpoints[MAX_ENDPOINTS]; - struct libusb_ss_endpoint_companion_descriptor ss_endpoints[MAX_ENDPOINTS]; - ret = list_endpoints(endpoints, ss_endpoints, device); - if (ret < 0) { - log_error("list_endpoints() failed", __func__, __FILE__, __LINE__); - goto FAIL2; - } - int nendpoints = ret; - uint8_t bulk_in_endpoint_address = 0; - uint16_t bulk_in_max_packet_size = 0; - uint8_t bulk_in_max_burst = 0; - for (int i = 0; i < nendpoints; ++i) { - if ((endpoints[i].bmAttributes & 0x03) == LIBUSB_TRANSFER_TYPE_BULK && - (endpoints[i].bEndpointAddress & 0x80) == LIBUSB_ENDPOINT_IN) { - bulk_in_endpoint_address = endpoints[i].bEndpointAddress; - bulk_in_max_packet_size = endpoints[i].wMaxPacketSize; - bulk_in_max_burst = ss_endpoints[i].bLength == 0 ? 0 : - ss_endpoints[i].bMaxBurst; - break; - } - } - if (bulk_in_endpoint_address == 0) { - fprintf(stderr, "ERROR - bulk in endpoint not found\n"); - goto FAIL2; - } - - /* we are good here - create and initialize the usb_device */ - usb_device_t *this = (usb_device_t *) malloc(sizeof(usb_device_t)); - this->dev = device; - this->dev_handle = dev_handle; - this->context = ctx; - this->completed = 0; - this->nendpoints = nendpoints; - memset(this->endpoints, 0, sizeof(this->endpoints)); - for (int i = 0; i < nendpoints; ++i) { - this->endpoints[i] = endpoints[i]; - this->ss_endpoints[i] = ss_endpoints[i]; - } - this->bulk_in_endpoint_address = bulk_in_endpoint_address; - this->bulk_in_max_packet_size = bulk_in_max_packet_size; - this->bulk_in_max_burst = bulk_in_max_burst; - - ret_val = this; - return ret_val; - -FAIL2: - libusb_close(dev_handle); -FAIL1: - libusb_exit(0); -FAIL0: - return ret_val; -} - - -void usb_device_close(usb_device_t *this) -{ - libusb_close(this->dev_handle); - free(this); - libusb_exit(0); - return; -} - - -int usb_device_handle_events(usb_device_t *this) -{ - return libusb_handle_events_completed(this->context, &this->completed); -} - -int usb_device_control(usb_device_t *this, uint8_t request, uint16_t value, - uint16_t index, uint8_t *data, uint16_t length, int read) { - - const uint8_t bmWriteRequestType = LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE; - const uint8_t bmReadRequestType = LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE; - const unsigned int timeout = 5000; // timeout (in ms) for each command - int ret; - - if (!read) { - ret = libusb_control_transfer(this->dev_handle, bmWriteRequestType, - request, value, index, data, length, - timeout); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - return -1; - } - } - else - { - ret = libusb_control_transfer(this->dev_handle, bmReadRequestType, - request, value, index, data, length, - timeout); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - return -1; - } - } - - return 0; -} - - - -/* internal functions */ -static libusb_device_handle *find_usb_device(int index, libusb_context *ctx, - libusb_device **device, int *needs_firmware) -{ - libusb_device_handle *ret_val = 0; - - *device = 0; - *needs_firmware = 0; - - libusb_device **list = 0; - ssize_t nusbdevices = libusb_get_device_list(ctx, &list); - if (nusbdevices < 0) { - log_usb_error(nusbdevices, __func__, __FILE__, __LINE__); - goto FAIL0; - } - - int count = 0; - for (ssize_t j = 0; j < nusbdevices; ++j) { - libusb_device *dev = list[j]; - struct libusb_device_descriptor desc; - libusb_get_device_descriptor(dev, &desc); - for (int i = 0; i < n_usb_device_ids; ++i) { - if (desc.idVendor == usb_device_ids[i].vid && - desc.idProduct == usb_device_ids[i].pid) { - if (count == index) { - *device = dev; - *needs_firmware = usb_device_ids[i].needs_firmware; - } - count++; - } - } - } - - if (*device == 0) { - fprintf(stderr, "ERROR - usb_device@%d not found\n", index); - goto FAIL1; - } - - libusb_device_handle *dev_handle = 0; - int ret = libusb_open(*device, &dev_handle); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - goto FAIL1; - } - libusb_free_device_list(list, 1); - - ret = libusb_kernel_driver_active(dev_handle, 0); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - goto FAILA; - } - if (ret == 1) { - fprintf(stderr, "ERROR - device busy\n"); - goto FAILA; - } - - ret = libusb_claim_interface(dev_handle, 0); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - goto FAILA; - } - - ret_val = dev_handle; - return ret_val; - -FAILA: - libusb_close(dev_handle); - return ret_val; - -FAIL1: - libusb_free_device_list(list, 1); -FAIL0: - return ret_val; -} - - -int load_image(libusb_device_handle *dev_handle, const char *image, uint32_t image_size) -{ - int ret_val = -1; - - const int fx_type = FX_TYPE_FX3; - const int img_type = IMG_TYPE_IMG; - const int stage = 0; - verbose = 1; - - ret_val = fx3_load_ram(dev_handle, image); - return ret_val; -} - - -static int transfer_image(const uint8_t *image, - libusb_device_handle *dev_handle) -{ - const uint8_t bmRequestType = LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE; - const uint8_t bRequest = 0xa0; // vendor command - const unsigned int timeout = 5000; // timeout (in ms) for each command - const size_t max_write_size = 2 * 1024; // max write size in bytes - - // skip first word with 'CY' magic - uint32_t *current = (uint32_t *) image + 1; - - while (1) { - uint32_t loadSz = *current++; - if (loadSz == 0) { - break; - } - uint32_t address = *current++; - - unsigned char *data = (unsigned char *) current; - for (size_t nleft = loadSz * 4; nleft > 0; ) { - uint16_t wLength = nleft > max_write_size ? max_write_size : nleft; - int ret = libusb_control_transfer(dev_handle, bmRequestType, bRequest, - address & 0xffff, address >> 16, - data, wLength, timeout); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - return -1; - } - if (!(ret == wLength)) { - fprintf(stderr, "ERROR - libusb_control_transfer() returned less bytes than expected - actual=%hu expected=%hu\n", ret, wLength); - return -1; - } - data += wLength; - nleft -= wLength; - } - current += loadSz; - } - - uint32_t entryAddr = *current++; - uint32_t checksum __attribute__((unused)) = *current++; - - sleep(1); - - int ret = libusb_control_transfer(dev_handle, bmRequestType, bRequest, - entryAddr & 0xffff, entryAddr >> 16, - 0, 0, timeout); - if (ret < 0) { - log_usb_warning(ret, __func__, __FILE__, __LINE__); - } - - return 0; -} - - -static int list_endpoints(struct libusb_endpoint_descriptor endpoints[], - struct libusb_ss_endpoint_companion_descriptor ss_endpoints[], - libusb_device *device) -{ - struct libusb_config_descriptor *config; - int ret = libusb_get_active_config_descriptor(device, &config); - if (ret < 0) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - return -1; - } - - int count = 0; - - /* loop through the interfaces */ - for (int intf = 0; intf < config->bNumInterfaces; ++intf) { - const struct libusb_interface *interface = &config->interface[intf]; - for (int setng = 0; setng < interface->num_altsetting; ++setng) { - const struct libusb_interface_descriptor *setting = &interface->altsetting[setng]; - for (int endp = 0; endp < setting->bNumEndpoints; ++endp) { - const struct libusb_endpoint_descriptor *endpoint = &setting->endpoint[endp]; - if (count == MAX_ENDPOINTS) { - fprintf(stderr, "WARNING - found too many USB endpoints; returning only the first %d\n", MAX_ENDPOINTS); - return count; - } - endpoints[count] = *endpoint; - struct libusb_ss_endpoint_companion_descriptor *endpoint_ss_companion; - ret = libusb_get_ss_endpoint_companion_descriptor(0, endpoint, - &endpoint_ss_companion); - if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND) { - log_usb_error(ret, __func__, __FILE__, __LINE__); - return -1; - } - if (ret == 0) { - ss_endpoints[count] = *endpoint_ss_companion; - } else { - ss_endpoints[count].bLength = 0; - } - libusb_free_ss_endpoint_companion_descriptor(endpoint_ss_companion); - count++; - } - } - } - - return count; -} diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/linux/usb_device.h b/source_modules/sddc_source/src/libsddc/Core/arch/linux/usb_device.h deleted file mode 100644 index f9e4533..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/linux/usb_device.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * usb_device.h - Basic USB and USB control functions - * - * Copyright (C) 2020 by Franco Venturi - * - * 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 . - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#ifndef __USB_DEVICE_H -#define __USB_DEVICE_H - -#include - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct usb_device usb_device_t; - -struct usb_device_info { - unsigned char *manufacturer; - unsigned char *product; - unsigned char *serial_number; -}; - -int usb_device_count_devices(); - -int usb_device_get_device_list(struct usb_device_info **usb_device_infos); - -int usb_device_free_device_list(struct usb_device_info *usb_device_infos); - -usb_device_t *usb_device_open(int index, const char* image, - uint32_t size); - -int usb_device_handle_events(usb_device_t *t); - -void usb_device_close(usb_device_t *t); - -int usb_device_control(usb_device_t *t, uint8_t request, uint16_t value, - uint16_t index, uint8_t *data, uint16_t length, int read); - -#ifdef __cplusplus -} -#endif - -#endif /* __USB_DEVICE_H */ diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/linux/usb_device_internals.h b/source_modules/sddc_source/src/libsddc/Core/arch/linux/usb_device_internals.h deleted file mode 100644 index b5edd50..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/linux/usb_device_internals.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * usb_device_internals.h - internal USB structures to be shared between - * usb_device and usb_streaming - * - * Copyright (C) 2020 by Franco Venturi - * - * 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 . - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#ifndef __USB_DEVICE_INTERNALS_H -#define __USB_DEVICE_INTERNALS_H - -#include "usb_device.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct usb_device { - libusb_device *dev; - libusb_device_handle *dev_handle; - libusb_context *context; - int completed; - int nendpoints; -#define MAX_ENDPOINTS (16) - struct libusb_endpoint_descriptor endpoints[MAX_ENDPOINTS]; - struct libusb_ss_endpoint_companion_descriptor ss_endpoints[MAX_ENDPOINTS]; - uint8_t bulk_in_endpoint_address; - uint16_t bulk_in_max_packet_size; - uint8_t bulk_in_max_burst; -} usb_device_t; -typedef struct usb_device usb_device_t; - -#ifdef __cplusplus -} -#endif - -#endif /* __USB_DEVICE_INTERNALS_H */ diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/CyAPI.cpp b/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/CyAPI.cpp deleted file mode 100644 index 00d515e..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/CyAPI.cpp +++ /dev/null @@ -1,3359 +0,0 @@ -/* - ## Cypress CyAPI C++ library source file (CyAPI.cpp) - ## ======================================================= - ## - ## Copyright Cypress Semiconductor Corporation, 2009-2012, - ## All Rights Reserved - ## UNPUBLISHED, LICENSED SOFTWARE. - ## - ## CONFIDENTIAL AND PROPRIETARY INFORMATION - ## WHICH IS THE PROPERTY OF CYPRESS. - ## - ## Use of this file is governed - ## by the license agreement included in the file - ## - ## /license/license.rtf - ## - ## where is the Cypress software - ## install root directory path. - ## - ## ======================================================= -*/ -#ifndef WINVER -#define WINVER 0x0500 -#endif - -#include -#include -#include -#include "cyioctl.h" -#include "CyAPI.h" -#include "UsbdStatus.h" -#include "dbt.h" - -const char API_VERSION[8] = "1.3.2.0"; - -UINT SPI_FLASH_PAGE_SIZE_IN_BYTE = 256; -UINT SPI_FLASH_SECTOR_SIZE_IN_BYTE = (64 * 1024); -UINT CYWB_BL_MAX_BUFFER_SIZE_WHEN_USING_EP0_TRANSPORT = BUFSIZE_UPORT; //(8 * 512); // 4KB - -//////////////////////////////////////////////////////////////////////////////// -// -// The USB Device Class -// -//////////////////////////////////////////////////////////////////////////////// - -// Constructor -CCyUSBDevice::CCyUSBDevice(HANDLE hnd, GUID guid, BOOL bOpen) -{ - hDevice = INVALID_HANDLE_VALUE; - hDevNotification = 0; - hHndNotification = 0; - - DevNum = 0; - CfgNum = 0; - IntfcNum = 0; // The current selected interface's bInterfaceNumber - IntfcIndex = 0; // The entry in the Config's interfaces table matching to IntfcNum and AltSetting - - Devices = 0; - Interfaces = 0; - AltInterfaces = 0; - Configs = 0; - - DrvGuid = guid; - hWnd = hnd; - LastError = 0; - - EndPoints = NULL; - ControlEndPt = NULL; - IsocInEndPt = NULL; - IsocOutEndPt = NULL; - BulkInEndPt = NULL; - BulkOutEndPt = NULL; - InterruptInEndPt = NULL; - InterruptOutEndPt = NULL; - - USBCfgs[0] = NULL; - USBCfgs[1] = NULL; - USBConfigDescriptors[0] = NULL; - USBConfigDescriptors[1] = NULL; - pUsbBosDescriptor = NULL; - UsbBos = NULL; - - ZeroMemory(Manufacturer, USB_STRING_MAXLEN); - ZeroMemory(Product, USB_STRING_MAXLEN); - ZeroMemory(SerialNumber, USB_STRING_MAXLEN); - ZeroMemory(DeviceName, USB_STRING_MAXLEN); - ZeroMemory(FriendlyName, USB_STRING_MAXLEN); - - - if (hnd) RegisterForPnpEvents(hnd); - - if (bOpen) Open(DevNum); -} - -//______________________________________________________________________________ - -CCyUSBDevice::~CCyUSBDevice(void) -{ - - Close(); - - if (hDevNotification) { - if (! UnregisterDeviceNotification(hDevNotification)) - throw "Failed to close the device notification handle."; - hDevNotification = 0; - } - -} - - -//______________________________________________________________________________ -// -// It is expected that the device will only expose a single Config via the -// Windows USB HCD stack. The driver doesn't even expose an IOCTL for setting -// the configuration. -// -// This method just initializes a bunch of important variables, most important -// of which is the call to SetAltIntfcParams( ). - -void CCyUSBDevice::SetConfig(UCHAR cfg){ - - if (!USBCfgs[0]) return; - - CfgNum = 0; - if ((USBCfgs[0]) && (USBCfgs[0]->iConfiguration == cfg)) CfgNum = cfg; - if ((USBCfgs[1]) && (USBCfgs[1]->iConfiguration == cfg)) CfgNum = cfg; - - ConfigValue = USBCfgs[CfgNum]->bConfigurationValue; - ConfigAttrib = USBCfgs[CfgNum]->bmAttributes; - MaxPower = USBCfgs[CfgNum]->MaxPower; - Interfaces = USBCfgs[CfgNum]->bNumInterfaces; - AltInterfaces = USBCfgs[CfgNum]->AltInterfaces; - IntfcNum = USBCfgs[CfgNum]->Interfaces[0]->bInterfaceNumber; - - UCHAR a = AltIntfc(); // Get the current alt setting from the device - SetAltIntfcParams(a); // Initializes endpts, IntfcIndex, etc. without actually setting the AltInterface - - if (USBCfgs[CfgNum]->Interfaces[IntfcIndex]) { - IntfcClass = USBCfgs[CfgNum]->Interfaces[IntfcIndex]->bInterfaceClass; - IntfcSubClass = USBCfgs[CfgNum]->Interfaces[IntfcIndex]->bInterfaceSubClass; - IntfcProtocol = USBCfgs[CfgNum]->Interfaces[IntfcIndex]->bInterfaceProtocol; - } - - -} - -//______________________________________________________________________________ - - -UCHAR CCyUSBDevice::ConfigCount(void){ - - if (hDevice == INVALID_HANDLE_VALUE) return (UCHAR) NULL; - - return Configs; - -} - -//______________________________________________________________________________ - -UCHAR CCyUSBDevice::IntfcCount(void){ - - if (hDevice == INVALID_HANDLE_VALUE) return (UCHAR) NULL; - - return Interfaces; - -} - -//______________________________________________________________________________ -// This method is not currently exposed because the driver does not support -// selection of the interface. This is because the Windows USB hub driver -// creates a new device node for each interface. -/* -void CCyUSBDevice::SetInterface(UCHAR i){ -if (i < NumInterfaces) IntfcNum = i; - -if (Configs[CfgNum]) { -for (int j=0; j < Configs[CfgNum]->bAltInterfaces; j++) -if ( (Configs[CfgNum]->Interfaces[j]->bInterfaceNumber == IntfcNum) && -(Configs[CfgNum]->Interfaces[j]->bAlternateSetting == AltSetting) ) { - - -// TODO: Select the specified interface via the driver - - - -IntfcIndex = j; -return; -} -} - -} - -*/ -//______________________________________________________________________________ - -UCHAR CCyUSBDevice::AltIntfc(void){ - - UCHAR alt; - if (IoControl(IOCTL_ADAPT_GET_ALT_INTERFACE_SETTING, &alt, 1)) - return alt; - else - return 0xFF; -} - - -//______________________________________________________________________________ - -void CCyUSBDevice::SetAltIntfcParams(UCHAR alt){ - - // Find match of IntfcNum and alt in table of interfaces - if (USBCfgs[CfgNum]) { - for (int j=0; j < USBCfgs[CfgNum]->AltInterfaces; j++) - if ( //(USBCfgs[CfgNum]->Interfaces[j]->bInterfaceNumber == IntfcNum) && - (USBCfgs[CfgNum]->Interfaces[j]->bAlternateSetting == alt) ) { - - IntfcIndex = j; - IntfcClass = USBCfgs[CfgNum]->Interfaces[j]->bInterfaceClass; - IntfcSubClass = USBCfgs[CfgNum]->Interfaces[j]->bInterfaceSubClass;; - IntfcProtocol = USBCfgs[CfgNum]->Interfaces[j]->bInterfaceProtocol;; - - SetEndPointPtrs(); - return; - } - } - -} - -//______________________________________________________________________________ - -bool CCyUSBDevice::SetAltIntfc(UCHAR alt){ - - bool bSuccess = false; - - if (alt == AltIntfc()) return true; - - // Find match of IntfcNum and alt in table of interfaces - if (USBCfgs[CfgNum]) { - for (int j=0; j < USBCfgs[CfgNum]->AltInterfaces; j++) - if ( //(USBCfgs[CfgNum]->Interfaces[j]->bInterfaceNumber == IntfcNum) && - (USBCfgs[CfgNum]->Interfaces[j]->bAlternateSetting == alt) ) { - - IntfcIndex = j; - - // Actually change to the alt interface, calling the driver - bSuccess = IoControl(IOCTL_ADAPT_SELECT_INTERFACE, &alt, 1L); - - IntfcClass = USBCfgs[CfgNum]->Interfaces[j]->bInterfaceClass; - IntfcSubClass = USBCfgs[CfgNum]->Interfaces[j]->bInterfaceSubClass;; - IntfcProtocol = USBCfgs[CfgNum]->Interfaces[j]->bInterfaceProtocol;; - - SetEndPointPtrs(); - return bSuccess; - } - } - - return bSuccess; - -} - -//______________________________________________________________________________ -// Returns the total number of alternate interfaces for the current interface - -UCHAR CCyUSBDevice::AltIntfcCount(void) { - - if (USBCfgs[CfgNum]) - return USBCfgs[CfgNum]->Interfaces[IntfcIndex]->bAltSettings - 1; - - return 0; // The primary interface is not considered an Alt interface - // even though it does have an AltSetting value (0) - -} - - -//______________________________________________________________________________ - -UCHAR CCyUSBDevice::EndPointCount(void) { - - if (hDevice == INVALID_HANDLE_VALUE) return (UCHAR) NULL; - - if (USBCfgs[CfgNum]) - return USBCfgs[CfgNum]->Interfaces[IntfcIndex]->bNumEndpoints+1; // Include EndPt0 - - return (UCHAR) NULL; -} - - -//______________________________________________________________________________ - -void CCyUSBDevice::GetDeviceName(void) { - - ZeroMemory(DeviceName, USB_STRING_MAXLEN); - - if (hDevice == INVALID_HANDLE_VALUE) return; - - IoControl(IOCTL_ADAPT_GET_DEVICE_NAME, (PUCHAR)DeviceName, USB_STRING_MAXLEN); -} - -//______________________________________________________________________________ - -void CCyUSBDevice::GetFriendlyName(void) { - - ZeroMemory(FriendlyName, USB_STRING_MAXLEN); - - if (hDevice == INVALID_HANDLE_VALUE) return; - - IoControl(IOCTL_ADAPT_GET_FRIENDLY_NAME, (PUCHAR)FriendlyName, USB_STRING_MAXLEN); -} - -//______________________________________________________________________________ - -void CCyUSBDevice::GetUSBAddress(void) { - - if (hDevice == INVALID_HANDLE_VALUE) { - USBAddress = 0; - return; - } - - bool bRetVal = IoControl(IOCTL_ADAPT_GET_ADDRESS, &USBAddress, 1L); - if (!bRetVal || BytesXfered == 0) USBAddress = 0; -} - -//______________________________________________________________________________ - -void CCyUSBDevice::GetDriverVer(void) { - - if (hDevice == INVALID_HANDLE_VALUE) { - DriverVersion = (ULONG) NULL; - return; - } - - bool bRetVal = IoControl(IOCTL_ADAPT_GET_DRIVER_VERSION, (PUCHAR) &DriverVersion, sizeof(ULONG)); - if (!bRetVal || BytesXfered == 0) DriverVersion = 0; -} - -//______________________________________________________________________________ - -void CCyUSBDevice::GetUSBDIVer(void) { - - if (hDevice == INVALID_HANDLE_VALUE) { - USBDIVersion = (ULONG) NULL; - return; - } - - bool bRetVal = IoControl(IOCTL_ADAPT_GET_USBDI_VERSION, (PUCHAR) &USBDIVersion, sizeof(ULONG)); - if (!bRetVal || BytesXfered == 0) USBDIVersion = 0; -} - -//______________________________________________________________________________ - -UCHAR CCyUSBDevice::DeviceCount(void){ - - //SP_DEVINFO_DATA devInfoData; - SP_DEVICE_INTERFACE_DATA devInterfaceData; - - //Open a handle to the plug and play dev node. - //SetupDiGetClassDevs() returns a device information set that contains info on all - // installed devices of a specified class which are present. - HDEVINFO hwDeviceInfo = SetupDiGetClassDevs ( (LPGUID) &DrvGuid, - NULL, - NULL, - DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); - - Devices = 0; - - if (hwDeviceInfo != INVALID_HANDLE_VALUE) { - - //SetupDiEnumDeviceInterfaces() returns information about device interfaces - // exposed by one or more devices. Each call returns information about one interface. - //The routine can be called repeatedly to get information about several interfaces - // exposed by one or more devices. - - devInterfaceData.cbSize = sizeof(devInterfaceData); - - // Count the number of devices - int i=0; - Devices = 0; - bool bDone = false; - - while (!bDone) { - BOOL bRetVal = SetupDiEnumDeviceInterfaces (hwDeviceInfo, 0, (LPGUID) &DrvGuid, - i, &devInterfaceData); - - if (bRetVal) - Devices++; - else { - DWORD dwLastError = GetLastError(); - if (dwLastError == ERROR_NO_MORE_ITEMS) bDone = TRUE; - } - - i++; - } - - SetupDiDestroyDeviceInfoList(hwDeviceInfo); - } - - return Devices; -} - -//______________________________________________________________________________ - -bool CCyUSBDevice::CreateHandle(UCHAR dev){ - - Devices = DeviceCount(); - - if (!Devices) return false; - - if (dev > (Devices - 1)) return false; //dev = Devices-1; - - SP_DEVINFO_DATA devInfoData; - SP_DEVICE_INTERFACE_DATA devInterfaceData; - PSP_INTERFACE_DEVICE_DETAIL_DATA functionClassDeviceData; - SP_INTERFACE_DEVICE_DETAIL_DATA tmpInterfaceDeviceDetailData; - - ULONG requiredLength = 0; - int deviceNumber = dev; - - HANDLE hFile; - - //Open a handle to the plug and play dev node. - //SetupDiGetClassDevs() returns a device information set that contains info on all - // installed devices of a specified class which are present. - HDEVINFO hwDeviceInfo = SetupDiGetClassDevs ( (LPGUID) &DrvGuid, - NULL, - NULL, - DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); - - if (hwDeviceInfo != INVALID_HANDLE_VALUE) { - - //SetupDiEnumDeviceInterfaces() returns information about device interfaces - // exposed by one or more devices. Each call returns information about one interface. - //The routine can be called repeatedly to get information about several interfaces - // exposed by one or more devices. - - devInterfaceData.cbSize = sizeof(devInterfaceData); - - if (SetupDiEnumDeviceInterfaces ( hwDeviceInfo, 0, (LPGUID) &DrvGuid, - deviceNumber, &devInterfaceData)) { - //Allocate a function class device data structure to receive the goods about this - // particular device. - SetupDiGetInterfaceDeviceDetail ( hwDeviceInfo, &devInterfaceData, NULL, 0, - &requiredLength, NULL); - - ULONG predictedLength = requiredLength; - - functionClassDeviceData = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc (predictedLength); - functionClassDeviceData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA); - devInfoData.cbSize = sizeof(devInfoData); - //Retrieve the information from Plug and Play */ - if (SetupDiGetInterfaceDeviceDetail (hwDeviceInfo, - &devInterfaceData, - functionClassDeviceData, - predictedLength, - &requiredLength, - &devInfoData)) { - - /* NOTE : x64 packing issue ,requiredLength return 5byte size of the (SP_INTERFACE_DEVICE_DETAIL_DATA) and functionClassDeviceData needed sizeof functionClassDeviceData 8byte */ - int pathLen = requiredLength - (sizeof (tmpInterfaceDeviceDetailData.cbSize)+sizeof (tmpInterfaceDeviceDetailData.DevicePath)); - //int pathLen = requiredLength - functionClassDeviceData->cbSize; - - memcpy (DevPath, functionClassDeviceData->DevicePath, pathLen); - DevPath[pathLen] = 0; - - hFile = CreateFile (DevPath, - GENERIC_WRITE | GENERIC_READ, - FILE_SHARE_WRITE | FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - - DWORD errCode = GetLastError(); - free(functionClassDeviceData); - SetupDiDestroyDeviceInfoList(hwDeviceInfo); - - if (hFile == INVALID_HANDLE_VALUE) - { - LastError = GetLastError(); - return false; - } - // hDevice, DevNum, USBDeviceDescriptor, and Configs are data members - hDevice = hFile; - - return true; - } - - } - - SetupDiDestroyDeviceInfoList(hwDeviceInfo); - - } - - // Got here by failing at some point - - hDevice = INVALID_HANDLE_VALUE; - DevNum = 0; - return false; - -} - - -//______________________________________________________________________________ - -bool CCyUSBDevice::Open(UCHAR dev){ - - // If this CCyUSBDevice object already has the driver open, close it. - if (hDevice != INVALID_HANDLE_VALUE) - Close(); - - - - if (CreateHandle(dev)) { - DevNum = dev; - - // Important call: Gets the device descriptor data from the device - GetDevDescriptor(); - - // Gets the language IDs and selects English, if avail - SetStringDescrLanguage(); - - GetString(Manufacturer,USBDeviceDescriptor.iManufacturer); - GetString(Product,USBDeviceDescriptor.iProduct); - GetString(SerialNumber,USBDeviceDescriptor.iSerialNumber); - - // Get BOS descriptor - if ((BcdUSB & BCDUSBJJMASK) == USB30MAJORVER) - { - if(GetInternalBosDescriptor()) // USB3.0 specific descriptor - { - try - { - UsbBos = new CCyUSBBOS(hDevice,pUsbBosDescriptor); - } - catch(char *Str) - { - char *Str1 = Str;// just to ignore warning - MessageBox(NULL,"Please correct firmware BOS descriptor table","Wrong BOS Descriptor",(UINT) NULL); - Close(); // Close the device handle. - return false; - } - } - } - GetUSBAddress(); - GetDeviceName(); - GetFriendlyName(); - GetDriverVer(); - GetUSBDIVer(); - GetSpeed(); - - // Gets the config (including interface and endpoint) descriptors from the device - for (int i=0; iDscLen = 7; - ControlEndPt->DscType = 5; - ControlEndPt->Address = 0; - ControlEndPt->Attributes = 0; - ControlEndPt->MaxPktSize = MaxPacketSize; - ControlEndPt->Interval = 0; - - // We succeeded in openning a handle to the device. But, the device - // is not returning descriptors properly. We don't call Close( ) because - // we want to leave the hDevice intact, giving the user the opportunity - // to call the Reset( ) method - if (!USBCfgs[0] || !USBCfgs[0]->Interfaces[0]) - return false; - - // This call sets values for ConfigVal, ConfigAttrib, MaxPower, etc. - SetConfig(0); - - // If we registered for device notification, also register the handle - // This is necessary in order to receive notification of removal (allowing us to close) - // before the device re-connects (for such things as our ReConnect method). - if (hDevNotification) { - DEV_BROADCAST_HANDLE hFilter; - hFilter.dbch_size = sizeof(DEV_BROADCAST_HANDLE); - hFilter.dbch_devicetype = DBT_DEVTYP_HANDLE; - hFilter.dbch_handle = hDevice; - - hHndNotification = RegisterDeviceNotification(hWnd, (PVOID) &hFilter, DEVICE_NOTIFY_WINDOW_HANDLE); - } - - return true; - } - - - // Got here by failing at some point - - hDevice = INVALID_HANDLE_VALUE; - DevNum = 0; - return false; -} - - -//______________________________________________________________________________ - -void CCyUSBDevice::DestroyHandle(void){ - - if ( hDevice != INVALID_HANDLE_VALUE ) { - - if (hHndNotification) - if (! UnregisterDeviceNotification(hHndNotification)) - { - LastError = GetLastError(); - throw "Failed to close the handle notification handle."; - } - - if (! CloseHandle(hDevice)) - { - LastError = GetLastError(); - throw "Failed to close handle to driver."; - } - - hDevice = INVALID_HANDLE_VALUE; - hHndNotification = 0; - } - -} -//______________________________________________________________________________ - -void CCyUSBDevice::Close(void){ - - DestroyHandle(); - ZeroMemory(&USBDeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); - - if(pUsbBosDescriptor) - { - free(pUsbBosDescriptor); - pUsbBosDescriptor =NULL; - } - if(UsbBos) - { - delete UsbBos ; - UsbBos = NULL; - } - // Clean-up dynamically allocated objects - for (int i=0; iSetupPacket.bmReqType.Direction = DIR_DEVICE_TO_HOST; - pSingleTransfer->SetupPacket.bmReqType.Type = 0; - pSingleTransfer->SetupPacket.bmReqType.Recipient = 0; - pSingleTransfer->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; - pSingleTransfer->SetupPacket.wVal.hiByte = USB_BOS_DESCRIPTOR_TYPE; - pSingleTransfer->SetupPacket.wVal.lowByte = 0; - pSingleTransfer->SetupPacket.wLength = sizeof(USB_BOS_DESCRIPTOR); - pSingleTransfer->SetupPacket.ulTimeOut = 5; - pSingleTransfer->BufferLength = pSingleTransfer->SetupPacket.wLength; - pSingleTransfer->BufferOffset = sizeof(SINGLE_TRANSFER); - - bool bRetVal = IoControl(IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER, buf, length); - UsbdStatus = pSingleTransfer->UsbdStatus; - NtStatus = pSingleTransfer->NtStatus; - - if (bRetVal) { - PUSB_BOS_DESCRIPTOR BosDesc = (PUSB_BOS_DESCRIPTOR)((PCHAR)pSingleTransfer + pSingleTransfer->BufferOffset); - USHORT BosDescLength= BosDesc->wTotalLength; - - length = sizeof(SINGLE_TRANSFER) + BosDescLength; - PUCHAR buf2 = new UCHAR[length]; - ZeroMemory (buf2, length); - - pSingleTransfer = (PSINGLE_TRANSFER) buf2; - pSingleTransfer->SetupPacket.bmReqType.Direction = DIR_DEVICE_TO_HOST; - pSingleTransfer->SetupPacket.bmReqType.Type = 0; - pSingleTransfer->SetupPacket.bmReqType.Recipient = 0; - pSingleTransfer->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; - pSingleTransfer->SetupPacket.wVal.hiByte = USB_BOS_DESCRIPTOR_TYPE; - pSingleTransfer->SetupPacket.wVal.lowByte = 0; - pSingleTransfer->SetupPacket.wLength = BosDescLength; - pSingleTransfer->SetupPacket.ulTimeOut = 5; - pSingleTransfer->BufferLength = pSingleTransfer->SetupPacket.wLength; - pSingleTransfer->BufferOffset = sizeof(SINGLE_TRANSFER); - - bRetVal = IoControl(IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER, buf2, length); - UsbdStatus = pSingleTransfer->UsbdStatus; - NtStatus = pSingleTransfer->NtStatus; - - if (bRetVal) - { - pUsbBosDescriptor = (PUSB_BOS_DESCRIPTOR)malloc(BosDescLength); - memcpy(pUsbBosDescriptor, (PVOID)((PCHAR)pSingleTransfer + pSingleTransfer->BufferOffset), BosDescLength); - } - - delete[] buf2; - - } - - delete[] buf; - return bRetVal; -} -void CCyUSBDevice::GetDevDescriptor(void) -{ - - ULONG length = sizeof(SINGLE_TRANSFER) + sizeof(USB_DEVICE_DESCRIPTOR); - PUCHAR buf = new UCHAR[length]; - ZeroMemory (buf, length); - - //USB_DEVICE_DESCRIPTOR devDescriptor; - ZeroMemory (&USBDeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); - - PSINGLE_TRANSFER pSingleTransfer = (PSINGLE_TRANSFER) buf; - pSingleTransfer->SetupPacket.bmReqType.Direction = DIR_DEVICE_TO_HOST; - pSingleTransfer->SetupPacket.bmReqType.Type = 0; - pSingleTransfer->SetupPacket.bmReqType.Recipient = 0; - pSingleTransfer->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; - pSingleTransfer->SetupPacket.wVal.hiByte = USB_DEVICE_DESCRIPTOR_TYPE; - pSingleTransfer->SetupPacket.wLength = sizeof(USB_DEVICE_DESCRIPTOR); - pSingleTransfer->SetupPacket.ulTimeOut = 5; - pSingleTransfer->BufferLength = pSingleTransfer->SetupPacket.wLength; - pSingleTransfer->BufferOffset = sizeof(SINGLE_TRANSFER); - - bool bRetVal = IoControl(IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER, buf, length); - UsbdStatus = pSingleTransfer->UsbdStatus; - NtStatus = pSingleTransfer->NtStatus; - - if (bRetVal) { - memcpy(&USBDeviceDescriptor, (PVOID)((PCHAR)pSingleTransfer + pSingleTransfer->BufferOffset), sizeof(USB_DEVICE_DESCRIPTOR)); - - BcdUSB = USBDeviceDescriptor.bcdUSB; - VendorID = USBDeviceDescriptor.idVendor; - ProductID = USBDeviceDescriptor.idProduct; - DevClass = USBDeviceDescriptor.bDeviceClass; - DevSubClass = USBDeviceDescriptor.bDeviceSubClass; - DevProtocol = USBDeviceDescriptor.bDeviceProtocol; - if((BcdUSB & BCDUSBJJMASK) == USB20MAJORVER) - MaxPacketSize = USBDeviceDescriptor.bMaxPacketSize0; - else - MaxPacketSize = (1<SetupPacket.bmReqType.Direction = DIR_DEVICE_TO_HOST; - pSingleTransfer->SetupPacket.bmReqType.Type = 0; - pSingleTransfer->SetupPacket.bmReqType.Recipient = 0; - pSingleTransfer->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; - pSingleTransfer->SetupPacket.wVal.hiByte = USB_STRING_DESCRIPTOR_TYPE; - pSingleTransfer->SetupPacket.wVal.lowByte = 0; - pSingleTransfer->SetupPacket.wLength = sizeof(USB_COMMON_DESCRIPTOR); - pSingleTransfer->SetupPacket.ulTimeOut = 5; - pSingleTransfer->BufferLength = pSingleTransfer->SetupPacket.wLength; - pSingleTransfer->BufferOffset = sizeof(SINGLE_TRANSFER); - - bool bRetVal = IoControl(IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER, buf, length); - UsbdStatus = pSingleTransfer->UsbdStatus; - - if (bRetVal) { - memcpy(&cmnDescriptor, (PVOID)((PCHAR)pSingleTransfer + pSingleTransfer->BufferOffset), sizeof(USB_COMMON_DESCRIPTOR)); - - int LangIDs = (cmnDescriptor.bLength - 2 ) / 2; - - // Get the entire descriptor, all LangIDs - length = sizeof(SINGLE_TRANSFER) + cmnDescriptor.bLength; - PUCHAR buf2 = new UCHAR[length]; - ZeroMemory (buf2, length); - - pSingleTransfer = (PSINGLE_TRANSFER) buf2; - pSingleTransfer->SetupPacket.bmReqType.Direction = DIR_DEVICE_TO_HOST; - pSingleTransfer->SetupPacket.bmReqType.Type = 0; - pSingleTransfer->SetupPacket.bmReqType.Recipient = 0; - pSingleTransfer->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; - pSingleTransfer->SetupPacket.wVal.hiByte = USB_STRING_DESCRIPTOR_TYPE; - pSingleTransfer->SetupPacket.wVal.lowByte = 0; - pSingleTransfer->SetupPacket.wLength = cmnDescriptor.bLength; - pSingleTransfer->SetupPacket.ulTimeOut = 5; - pSingleTransfer->BufferLength = pSingleTransfer->SetupPacket.wLength; - pSingleTransfer->BufferOffset = sizeof(SINGLE_TRANSFER); - - bRetVal = IoControl(IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER, buf2, length); - - UsbdStatus = pSingleTransfer->UsbdStatus; - - if (bRetVal) { - PUSB_STRING_DESCRIPTOR IDs = (PUSB_STRING_DESCRIPTOR) (buf2 + sizeof(SINGLE_TRANSFER)); - - StrLangID =(LangIDs) ? IDs[0].bString[0] : 0; - - for (int i=0; iSetupPacket.bmReqType.Direction = DIR_DEVICE_TO_HOST; - pSingleTransfer->SetupPacket.bmReqType.Type = 0; - pSingleTransfer->SetupPacket.bmReqType.Recipient = 0; - pSingleTransfer->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; - pSingleTransfer->SetupPacket.wVal.hiByte = USB_STRING_DESCRIPTOR_TYPE; - pSingleTransfer->SetupPacket.wVal.lowByte = sIndex; - pSingleTransfer->SetupPacket.wIndex = StrLangID; - pSingleTransfer->SetupPacket.wLength = sizeof(USB_COMMON_DESCRIPTOR); - pSingleTransfer->SetupPacket.ulTimeOut = 5; - pSingleTransfer->BufferLength = pSingleTransfer->SetupPacket.wLength; - pSingleTransfer->BufferOffset = sizeof(SINGLE_TRANSFER); - - bool bRetVal = IoControl(IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER, buf, length); - UsbdStatus = pSingleTransfer->UsbdStatus; - NtStatus = pSingleTransfer->NtStatus; - - if (bRetVal) { - memcpy(&cmnDescriptor, (PVOID)((PCHAR)pSingleTransfer + pSingleTransfer->BufferOffset), sizeof(USB_COMMON_DESCRIPTOR)); - - // Get the entire descriptor - length = sizeof(SINGLE_TRANSFER) + cmnDescriptor.bLength; - PUCHAR buf2 = new UCHAR[length]; - ZeroMemory (buf2, length); - - pSingleTransfer = (PSINGLE_TRANSFER) buf2; - pSingleTransfer->SetupPacket.bmReqType.Direction = DIR_DEVICE_TO_HOST; - pSingleTransfer->SetupPacket.bmReqType.Type = 0; - pSingleTransfer->SetupPacket.bmReqType.Recipient = 0; - pSingleTransfer->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; - pSingleTransfer->SetupPacket.wVal.hiByte = USB_STRING_DESCRIPTOR_TYPE; - pSingleTransfer->SetupPacket.wVal.lowByte = sIndex; - pSingleTransfer->SetupPacket.wIndex = StrLangID; - pSingleTransfer->SetupPacket.wLength = cmnDescriptor.bLength; - pSingleTransfer->SetupPacket.ulTimeOut = 5; - pSingleTransfer->BufferLength = pSingleTransfer->SetupPacket.wLength; - pSingleTransfer->BufferOffset = sizeof(SINGLE_TRANSFER); - - bRetVal = IoControl(IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER, buf2, length); - UsbdStatus = pSingleTransfer->UsbdStatus; - NtStatus = pSingleTransfer->NtStatus; - - UCHAR bytes = (buf2[sizeof(SINGLE_TRANSFER)]); - UCHAR signature = (buf2[sizeof(SINGLE_TRANSFER)+1]); - - if (bRetVal && (bytes>2) && (signature == 0x03)) { - ZeroMemory (str, USB_STRING_MAXLEN); - memcpy(str, (PVOID)((PCHAR)pSingleTransfer + pSingleTransfer->BufferOffset+2), bytes-2); - } - - delete[] buf2; - - } - - delete[] buf; -} - -//______________________________________________________________________________ - -void CCyUSBDevice::GetCfgDescriptor(int descIndex) -{ - - ULONG length = sizeof(SINGLE_TRANSFER) + sizeof(USB_CONFIGURATION_DESCRIPTOR); - PUCHAR buf = new UCHAR[length]; - ZeroMemory (buf, length); - - PSINGLE_TRANSFER pSingleTransfer = (PSINGLE_TRANSFER) buf; - pSingleTransfer->SetupPacket.bmReqType.Direction = DIR_DEVICE_TO_HOST; - pSingleTransfer->SetupPacket.bmReqType.Type = 0; - pSingleTransfer->SetupPacket.bmReqType.Recipient = 0; - pSingleTransfer->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; - pSingleTransfer->SetupPacket.wVal.hiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; - pSingleTransfer->SetupPacket.wVal.lowByte = descIndex; - pSingleTransfer->SetupPacket.wLength = sizeof(USB_CONFIGURATION_DESCRIPTOR); - pSingleTransfer->SetupPacket.ulTimeOut = 5; - pSingleTransfer->BufferLength = pSingleTransfer->SetupPacket.wLength; - pSingleTransfer->BufferOffset = sizeof(SINGLE_TRANSFER); - - bool bRetVal = IoControl(IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER, buf, length); - UsbdStatus = pSingleTransfer->UsbdStatus; - NtStatus = pSingleTransfer->NtStatus; - - if (bRetVal) { - PUSB_CONFIGURATION_DESCRIPTOR configDesc = (PUSB_CONFIGURATION_DESCRIPTOR)((PCHAR)pSingleTransfer + pSingleTransfer->BufferOffset); - USHORT configDescLength= configDesc->wTotalLength; - - length = sizeof(SINGLE_TRANSFER) + configDescLength; - PUCHAR buf2 = new UCHAR[length]; - ZeroMemory (buf2, length); - - pSingleTransfer = (PSINGLE_TRANSFER) buf2; - pSingleTransfer->SetupPacket.bmReqType.Direction = DIR_DEVICE_TO_HOST; - pSingleTransfer->SetupPacket.bmReqType.Type = 0; - pSingleTransfer->SetupPacket.bmReqType.Recipient = 0; - pSingleTransfer->SetupPacket.bRequest = USB_REQUEST_GET_DESCRIPTOR; - pSingleTransfer->SetupPacket.wVal.hiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; - pSingleTransfer->SetupPacket.wVal.lowByte = descIndex; - pSingleTransfer->SetupPacket.wLength = configDescLength; - pSingleTransfer->SetupPacket.ulTimeOut = 5; - pSingleTransfer->BufferLength = pSingleTransfer->SetupPacket.wLength; - pSingleTransfer->BufferOffset = sizeof(SINGLE_TRANSFER); - - bRetVal = IoControl(IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER, buf2, length); - UsbdStatus = pSingleTransfer->UsbdStatus; - NtStatus = pSingleTransfer->NtStatus; - - if (bRetVal){ - USBConfigDescriptors[descIndex] = (PUSB_CONFIGURATION_DESCRIPTOR)malloc(configDescLength); - memcpy(USBConfigDescriptors[descIndex], (PVOID)((PCHAR)pSingleTransfer + pSingleTransfer->BufferOffset), configDescLength); - } - - delete[] buf2; - - } - - delete[] buf; -} - -//______________________________________________________________________________ - -bool CCyUSBDevice::Reset() -{ - return IoControl(IOCTL_ADAPT_RESET_PARENT_PORT, NULL, 0); -} - -//______________________________________________________________________________ - -bool CCyUSBDevice::ReConnect() -{ - return IoControl(IOCTL_ADAPT_CYCLE_PORT, NULL, 0); -} - - -//______________________________________________________________________________ - -bool CCyUSBDevice::Suspend() -{ - if (PowerState() == 4) return true; - - ULONG state = 4; - bool ret = IoControl(IOCTL_ADAPT_SET_DEVICE_POWER_STATE, (PUCHAR) &state, sizeof(state)); - - if ( 0 == state) return ret; - - return true; - -} - - -//______________________________________________________________________________ - -bool CCyUSBDevice::Resume() -{ - if (PowerState() == 1) return true; - - ULONG state = 1; - bool ret = IoControl(IOCTL_ADAPT_SET_DEVICE_POWER_STATE, (PUCHAR) &state, sizeof(state)); - - if ( 0 == state) return ret; - - return true; -} - - -//______________________________________________________________________________ - -void CCyUSBDevice::GetSpeed() -{ - ULONG speed = 0; - bHighSpeed = false; - bSuperSpeed = false; - - IoControl(IOCTL_ADAPT_GET_DEVICE_SPEED, (PUCHAR) &speed, sizeof(speed)); - - bHighSpeed = (speed == DEVICE_SPEED_HIGH); - bSuperSpeed = (speed == DEVICE_SPEED_SUPER); -} - - -//______________________________________________________________________________ - -UCHAR CCyUSBDevice::PowerState() -{ - ULONG state; - bool rval = IoControl(IOCTL_ADAPT_GET_DEVICE_POWER_STATE, (PUCHAR) &state, sizeof(state)); - - UCHAR s = (UCHAR) NULL; - - if (rval) s = (UCHAR) state; - - return s; - -} - - -//______________________________________________________________________________ - -CCyUSBEndPoint * CCyUSBDevice::EndPointOf(UCHAR addr) //throw(...) -{ - - if (addr == 0) return ControlEndPt; - - CCyUSBEndPoint *ept; - - int n = EndPointCount(); - - for (int i=0; iInterfaces[IntfcIndex]->EndPoints[i]; - - if (ept) - { - if (addr == ept->Address) return ept; } - else - throw "Failed to find endpoint."; - } - - return NULL; // Error - -} -//______________________________________________________________________________ - -bool CCyUSBDevice::GetBosDescriptor(PUSB_BOS_DESCRIPTOR descr) -{ - if ((BcdUSB & BCDUSBJJMASK) == USB30MAJORVER) - { - if(UsbBos!=NULL) - { - descr->bLength = UsbBos->bLength; - descr->bDescriptorType = UsbBos->bDescriptorType; - descr->bNumDeviceCaps = UsbBos->bNumDeviceCaps; - descr->wTotalLength = UsbBos->wTotalLength; - return true; - } - return false; - } - else - return false; -} -bool CCyUSBDevice::GetBosUSB20DeviceExtensionDescriptor(PUSB_BOS_USB20_DEVICE_EXTENSION descr) -{ - if ((BcdUSB & BCDUSBJJMASK) == USB30MAJORVER) - { - if(UsbBos->pUSB20_DeviceExt != NULL) - { - descr->bLength = UsbBos->pUSB20_DeviceExt->bLength; - descr->bDescriptorType = UsbBos->pUSB20_DeviceExt->bDescriptorType; - descr->bDevCapabilityType = UsbBos->pUSB20_DeviceExt->bDevCapabilityType; - descr->bmAttribute = UsbBos->pUSB20_DeviceExt->bmAttribute; - return true; - } - return false; - } - else - return false; -} -bool CCyUSBDevice::GetBosContainedIDDescriptor(PUSB_BOS_CONTAINER_ID descr) -{ - if ((BcdUSB & BCDUSBJJMASK) == USB30MAJORVER) - { - if(UsbBos->pContainer_ID != NULL) - { - descr->bLength = UsbBos->pContainer_ID->bLength; - descr->bDescriptorType = UsbBos->pContainer_ID->bDescriptorType; - descr->bDevCapabilityType = UsbBos->pContainer_ID->bDevCapabilityType; - descr->bReserved = UsbBos->pContainer_ID->bReserved; - for (int i=0;iContainerID[i] = UsbBos->pContainer_ID->ContainerID[i]; - - return true; - } - return false; - } - else - return false; -} -bool CCyUSBDevice::GetBosSSCapabilityDescriptor(PUSB_BOS_SS_DEVICE_CAPABILITY descr) -{ - if ((BcdUSB & BCDUSBJJMASK) == USB30MAJORVER) - { - if(UsbBos->pSS_DeviceCap != NULL) - { - descr->bLength = UsbBos->pSS_DeviceCap->bLength; - descr->bDescriptorType = UsbBos->pSS_DeviceCap->bDescriptorType; - descr->bDevCapabilityType = UsbBos->pSS_DeviceCap->bDevCapabilityType; - descr->bFunctionalitySupporte = UsbBos->pSS_DeviceCap->bFunctionalitySupporte; - descr->bmAttribute = UsbBos->pSS_DeviceCap->bmAttribute; - descr->bU1DevExitLat = UsbBos->pSS_DeviceCap->bU1DevExitLat; - descr->wSpeedsSuported = UsbBos->pSS_DeviceCap->SpeedsSuported; - descr->bU2DevExitLat = UsbBos->pSS_DeviceCap->bU2DevExitLat; - return true; - } - return false; - } - else - return false; -} -//______________________________________________________________________________ - -void CCyUSBDevice::GetDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR descr) -{ - // Copy the internal private data to the passed parameter - *descr = USBDeviceDescriptor; -} - -//______________________________________________________________________________ - -void CCyUSBDevice::GetConfigDescriptor(PUSB_CONFIGURATION_DESCRIPTOR descr) -{ - // Copy the internal private data to the passed parameter - *descr = *USBConfigDescriptors[CfgNum]; -} - -//______________________________________________________________________________ - -void CCyUSBDevice::GetIntfcDescriptor(PUSB_INTERFACE_DESCRIPTOR descr) -{ - CCyUSBInterface *i = USBCfgs[CfgNum]->Interfaces[IntfcIndex]; - - // Copy the internal private data to the passed parameter - descr->bLength = i->bLength; - descr->bDescriptorType = i->bDescriptorType; - descr->bInterfaceNumber = i->bInterfaceNumber; - descr->bAlternateSetting = i->bAlternateSetting; - descr->bNumEndpoints = i->bNumEndpoints; - descr->bInterfaceClass = i->bInterfaceClass; - descr->bInterfaceSubClass = i->bInterfaceSubClass; - descr->bInterfaceProtocol = i->bInterfaceProtocol; - descr->iInterface = i->iInterface; -} - -//______________________________________________________________________________ - -CCyUSBConfig CCyUSBDevice::GetUSBConfig(int index) -{ - // Rarely (i.e. never) have more than 1 Configuration - int i = (index > (Configs-1)) ? 0 : index; - - return *USBCfgs[i]; // Invoke the copy constructor -} - -//______________________________________________________________________________ - -void CCyUSBDevice::UsbdStatusString(ULONG stat, PCHAR str) -{ - //CString tmp; // MFC Version - //String tmp; - - char StateStr[24]; - char StatusStr[64]; - ZeroMemory(StateStr,24); - ZeroMemory(StatusStr,64); - - if (! USBD_STATUS(stat)) { - sprintf(StateStr,"[state=SUCCESS "); - sprintf(StatusStr,"status=USBD_STATUS_SUCCESS]"); - } else { - - switch(USBD_STATE(stat)) { - case USBD_STATUS_SUCCESS: sprintf(StateStr," [state=SUCCESS "); break; - case USBD_STATUS_PENDING: sprintf(StateStr," [state=PENDING "); break; - case USBD_STATUS_HALTED: sprintf(StateStr," [state=STALLED "); break; - case USBD_STATUS_ERROR: sprintf(StateStr," [state=ERROR "); break; - default: break; - } - - switch(stat|0xC0000000L) { // Note: error typedefs have both error and stall bit set - case USBD_STATUS_CRC: sprintf(StatusStr,"status=USBD_STATUS_CRC]"); break; - case USBD_STATUS_BTSTUFF: sprintf(StatusStr,"status=USBD_STATUS_BTSTUFF]"); break; - case USBD_STATUS_DATA_TOGGLE_MISMATCH: sprintf(StatusStr,"status=USBD_STATUS_DATA_TOGGLE_MISMATCH]"); break; - case USBD_STATUS_STALL_PID: sprintf(StatusStr,"status=USBD_STATUS_STALL_PID]"); break; - case USBD_STATUS_DEV_NOT_RESPONDING: sprintf(StatusStr,"status=USBD_STATUS_DEV_NOT_RESPONDING]"); break; - case USBD_STATUS_PID_CHECK_FAILURE: sprintf(StatusStr,"status=USBD_STATUS_PID_CHECK_FAILURE]"); break; - case USBD_STATUS_UNEXPECTED_PID: sprintf(StatusStr,"status=USBD_STATUS_UNEXPECTED_PID]"); break; - case USBD_STATUS_DATA_OVERRUN: sprintf(StatusStr,"status=USBD_STATUS_DATA_OVERRUN]"); break; - case USBD_STATUS_DATA_UNDERRUN: sprintf(StatusStr,"status=USBD_STATUS_DATA_UNDERRUN]"); break; - case USBD_STATUS_RESERVED1: sprintf(StatusStr,"status=USBD_STATUS_RESERVED1]"); break; - case USBD_STATUS_RESERVED2: sprintf(StatusStr,"status=USBD_STATUS_RESERVED2]"); break; - case USBD_STATUS_BUFFER_OVERRUN: sprintf(StatusStr,"status=USBD_STATUS_BUFFER_OVERRUN]"); break; - case USBD_STATUS_BUFFER_UNDERRUN: sprintf(StatusStr,"status=USBD_STATUS_BUFFER_UNDERRUN]"); break; - case USBD_STATUS_NOT_ACCESSED: sprintf(StatusStr,"status=USBD_STATUS_NOT_ACCESSED]"); break; - case USBD_STATUS_FIFO: sprintf(StatusStr,"status=USBD_STATUS_FIFO]"); break; - - case USBD_STATUS_ENDPOINT_HALTED: sprintf(StatusStr,"status=USBD_STATUS_ENDPOINT_HALTED]"); break; - case USBD_STATUS_NO_MEMORY: sprintf(StatusStr,"status=USBD_STATUS_NO_MEMORY]"); break; - case USBD_STATUS_INVALID_URB_FUNCTION: sprintf(StatusStr,"status=USBD_STATUS_INVALID_URB_FUNCTION]"); break; - case USBD_STATUS_INVALID_PARAMETER: sprintf(StatusStr,"status=USBD_STATUS_INVALID_PARAMETER]"); break; - case USBD_STATUS_ERROR_BUSY: sprintf(StatusStr,"status=USBD_STATUS_ERROR_BUSY]"); break; - case USBD_STATUS_REQUEST_FAILED: sprintf(StatusStr,"status=USBD_STATUS_REQUEST_FAILED]"); break; - case USBD_STATUS_INVALID_PIPE_HANDLE: sprintf(StatusStr,"status=USBD_STATUS_INVALID_PIPE_HANDLE]"); break; - case USBD_STATUS_NO_BANDWIDTH: sprintf(StatusStr,"status=USBD_STATUS_NO_BANDWIDTH]"); break; - case USBD_STATUS_INTERNAL_HC_ERROR: sprintf(StatusStr,"status=USBD_STATUS_INTERNAL_HC_ERROR]"); break; - case USBD_STATUS_ERROR_SHORT_TRANSFER: sprintf(StatusStr,"status=USBD_STATUS_ERROR_SHORT_TRANSFER]"); break; - case USBD_STATUS_BAD_START_FRAME: sprintf(StatusStr,"status=USBD_STATUS_BAD_START_FRAME]"); break; - case USBD_STATUS_ISOCH_REQUEST_FAILED: sprintf(StatusStr,"status=USBD_STATUS_ISOCH_REQUEST_FAILED]"); break; - case USBD_STATUS_FRAME_CONTROL_OWNED: sprintf(StatusStr,"status=USBD_STATUS_FRAME_CONTROL_OWNED]"); break; - case USBD_STATUS_FRAME_CONTROL_NOT_OWNED:sprintf(StatusStr,"status=USBD_STATUS_FRAME_CONTROL_NOT_OWNED]"); break; - case USBD_STATUS_CANCELED: sprintf(StatusStr,"status=USBD_STATUS_CANCELED]"); break; - case USBD_STATUS_CANCELING: sprintf(StatusStr,"status=USBD_STATUS_CANCELING]"); break; - - default: sprintf(StatusStr,"status=UNKNOWN]"); break; - } - } - - sprintf(str, "%s%s", StateStr, StatusStr); - -} - -//______________________________________________________________________________ - -// This method is called from Open, just after ControlEndPt has been instantiated -// It also gets called whenever a different Alt Interface setting is made -void CCyUSBDevice::SetEndPointPtrs(void) -{ - if (Configs == 0) return; - if (Interfaces == 0) return; - - EndPoints = USBCfgs[CfgNum]->Interfaces[IntfcIndex]->EndPoints; - EndPoints[0] = ControlEndPt; - int eptCount = EndPointCount() - 1; - - IsocInEndPt = NULL; - IsocOutEndPt = NULL; - BulkInEndPt = NULL; - BulkOutEndPt = NULL; - InterruptInEndPt = NULL; - InterruptOutEndPt = NULL; - - for (int i=0; iAddress & 0x80; - UCHAR attrib = EndPoints[i+1]->Attributes; - - - EndPoints[i+1]->XferMode = XMODE_DIRECT; - - if ((IsocInEndPt == NULL) && (attrib == 1) && bIn) IsocInEndPt = (CCyIsocEndPoint *)EndPoints[i+1]; - if ((BulkInEndPt == NULL) && (attrib == 2) && bIn) BulkInEndPt = (CCyBulkEndPoint *)EndPoints[i+1]; - if ((InterruptInEndPt == NULL) && (attrib == 3) && bIn) InterruptInEndPt = (CCyInterruptEndPoint *)EndPoints[i+1]; - - if ((IsocOutEndPt == NULL) && (attrib == 1) && !bIn) IsocOutEndPt = (CCyIsocEndPoint *)EndPoints[i+1]; - if ((BulkOutEndPt == NULL) && (attrib == 2) && !bIn) BulkOutEndPt = (CCyBulkEndPoint *)EndPoints[i+1]; - if ((InterruptOutEndPt == NULL) && (attrib == 3) && !bIn) InterruptOutEndPt = (CCyInterruptEndPoint *)EndPoints[i+1]; - } - -} - -//______________________________________________________________________________ - -bool CCyUSBDevice::RegisterForPnpEvents(HANDLE Handle) -{ - DEV_BROADCAST_DEVICEINTERFACE dFilter = {0}; - dFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); - dFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; - dFilter.dbcc_classguid = DrvGuid; - - hDevNotification = RegisterDeviceNotification(Handle, (PVOID) &dFilter, DEVICE_NOTIFY_WINDOW_HANDLE); - if (!hDevNotification) - { - LastError = GetLastError(); - return false; - } - - return true; -} - - -//////////////////////////////////////////////////////////////////////////////// -// -// The USB Interface Class -// -//////////////////////////////////////////////////////////////////////////////// - - -// The Copy Constructor -CCyUSBInterface::CCyUSBInterface(CCyUSBInterface &ifc) -{ - bLength = ifc.bLength; - bDescriptorType = ifc.bDescriptorType; - bInterfaceNumber = ifc.bInterfaceNumber; - bAlternateSetting = ifc.bAlternateSetting; - bNumEndpoints = ifc.bNumEndpoints; - bInterfaceClass = ifc.bInterfaceClass; - bInterfaceSubClass = ifc.bInterfaceSubClass; - bInterfaceProtocol = ifc.bInterfaceProtocol; - iInterface = ifc.iInterface; - - wTotalLength = ifc.wTotalLength; - - int i; - - for (i=0; iAttributes == 0) { - CCyControlEndPoint *e = (CCyControlEndPoint*)ifc.EndPoints[i]; - EndPoints[i] = new CCyControlEndPoint(*e); - } - - if (ifc.EndPoints[i]->Attributes == 1) { - CCyIsocEndPoint *e = (CCyIsocEndPoint*)ifc.EndPoints[i]; - EndPoints[i] = new CCyIsocEndPoint(*e); - } - - if (ifc.EndPoints[i]->Attributes == 2) { - CCyBulkEndPoint *e = (CCyBulkEndPoint*)ifc.EndPoints[i]; - EndPoints[i] = new CCyBulkEndPoint(*e); - } - - if (ifc.EndPoints[i]->Attributes == 3) { - CCyInterruptEndPoint *e = (CCyInterruptEndPoint*)ifc.EndPoints[i]; - EndPoints[i] = new CCyInterruptEndPoint(*e); - } - - } - -} - - -CCyUSBInterface::CCyUSBInterface(HANDLE handle, PUSB_INTERFACE_DESCRIPTOR pIntfcDescriptor) -{ - - PUSB_ENDPOINT_DESCRIPTOR endPtDesc; - - bLength = pIntfcDescriptor->bLength; - bDescriptorType = pIntfcDescriptor->bDescriptorType; - bInterfaceNumber = pIntfcDescriptor->bInterfaceNumber; - bAlternateSetting = pIntfcDescriptor->bAlternateSetting; - bNumEndpoints = pIntfcDescriptor->bNumEndpoints; - bInterfaceClass = pIntfcDescriptor->bInterfaceClass; - bInterfaceSubClass = pIntfcDescriptor->bInterfaceSubClass; - bInterfaceProtocol = pIntfcDescriptor->bInterfaceProtocol; - iInterface = pIntfcDescriptor->iInterface; - - bAltSettings = 0; - wTotalLength = bLength; - - PUCHAR desc = (PUCHAR)pIntfcDescriptor + pIntfcDescriptor->bLength; - - int i; - int unexpected = 0; - - for (i=0; ibLength; - - // We leave slot [0] empty to hold THE obligatory EndPoint Zero control endpoint - if (endPtDesc->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE) { - switch (endPtDesc->bmAttributes ) { - case 0: - EndPoints[i+1] = new CCyControlEndPoint(handle, endPtDesc); - break; - case 1: - EndPoints[i+1] = new CCyIsocEndPoint(handle, endPtDesc); - break; - case 2: - EndPoints[i+1] = new CCyBulkEndPoint(handle, endPtDesc); - break; - case 3: - EndPoints[i+1] = new CCyInterruptEndPoint(handle, endPtDesc); - break; - } - - desc += endPtDesc->bLength; - } else { - - unexpected++; - if (unexpected < 12) { // Sanity check - prevent infinite loop - - // This may have been a class-specific descriptor (like HID). Skip it. - desc += endPtDesc->bLength; - - // Stay in the loop, grabbing the next descriptor - i--; - } - - } - - } - - -} - -CCyUSBInterface::CCyUSBInterface(HANDLE handle, PUSB_INTERFACE_DESCRIPTOR pIntfcDescriptor,UCHAR usb30Dummy) -{ - - PUSB_ENDPOINT_DESCRIPTOR endPtDesc; - - bLength = pIntfcDescriptor->bLength; - bDescriptorType = pIntfcDescriptor->bDescriptorType; - bInterfaceNumber = pIntfcDescriptor->bInterfaceNumber; - bAlternateSetting = pIntfcDescriptor->bAlternateSetting; - bNumEndpoints = pIntfcDescriptor->bNumEndpoints; - bInterfaceClass = pIntfcDescriptor->bInterfaceClass; - bInterfaceSubClass = pIntfcDescriptor->bInterfaceSubClass; - bInterfaceProtocol = pIntfcDescriptor->bInterfaceProtocol; - iInterface = pIntfcDescriptor->iInterface; - - bAltSettings = 0; - wTotalLength = bLength; - - PUCHAR desc = (PUCHAR)pIntfcDescriptor + pIntfcDescriptor->bLength; - - int i; - int unexpected = 0; - - for (i=0; ibLength; - - PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR ssendPtDesc = (PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR)desc; - wTotalLength += endPtDesc->bLength; - - // We leave slot [0] empty to hold THE obligatory EndPoint Zero control endpoint - if (ssendPtDesc != NULL) - bSSDec = (ssendPtDesc->bDescriptorType == USB_SUPERSPEED_ENDPOINT_COMPANION); - - if ((endPtDesc->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE) && bSSDec) - { - switch (endPtDesc->bmAttributes ) - { - case 0: - EndPoints[i+1] = new CCyControlEndPoint(handle, endPtDesc); - break; - case 1: - EndPoints[i+1] = new CCyIsocEndPoint(handle, endPtDesc,ssendPtDesc); - break; - case 2: - EndPoints[i+1] = new CCyBulkEndPoint(handle, endPtDesc,ssendPtDesc); - break; - case 3: - EndPoints[i+1] = new CCyInterruptEndPoint(handle, endPtDesc,ssendPtDesc); - break; - } - - desc += ssendPtDesc->bLength; - wTotalLength += ssendPtDesc->bLength; - - } - else if (endPtDesc->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE) - { - switch (endPtDesc->bmAttributes ) - { - case 0: - EndPoints[i+1] = new CCyControlEndPoint(handle, endPtDesc); - break; - case 1: - EndPoints[i+1] = new CCyIsocEndPoint(handle, endPtDesc); - break; - case 2: - EndPoints[i+1] = new CCyBulkEndPoint(handle, endPtDesc); - break; - case 3: - EndPoints[i+1] = new CCyInterruptEndPoint(handle, endPtDesc); - break; - } - - //desc += endPtDesc->bLength; // THis a bug for the composite device - - } - else - { - - unexpected++; - if (unexpected < 12) { // Sanity check - prevent infinite loop - - // This may have been a class-specific descriptor (like HID). Skip it. - desc += endPtDesc->bLength; - - // Stay in the loop, grabbing the next descriptor - i--; - } - - } - - } - - -} - -//______________________________________________________________________________ - -CCyUSBInterface::~CCyUSBInterface(void) { - - for (int i=0; ibLength; - bDescriptorType = pConfigDescr->bDescriptorType; - wTotalLength = pConfigDescr->wTotalLength; - bNumInterfaces = pConfigDescr->bNumInterfaces; - AltInterfaces = 0; - bConfigurationValue = pConfigDescr->bConfigurationValue; - iConfiguration = pConfigDescr->iConfiguration; - bmAttributes = pConfigDescr->bmAttributes; - MaxPower = pConfigDescr->MaxPower; - - int tLen = pConfigDescr->wTotalLength; - - PUCHAR desc = (PUCHAR)pConfigDescr + pConfigDescr->bLength; - int bytesConsumed = pConfigDescr->bLength; - - for (i=0; ibDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) { - Interfaces[i] = new CCyUSBInterface(handle, interfaceDesc); - i++; - AltInterfaces++; // Actually the total number of interfaces for the config - bytesConsumed += Interfaces[i-1]->wTotalLength; - } else { - // Unexpected descriptor type - // Just skip it and go on - could have thrown an exception instead - // since this indicates that the descriptor structure is invalid. - bytesConsumed += interfaceDesc->bLength; - } - - - desc = (PUCHAR) pConfigDescr + bytesConsumed; - - } while ((bytesConsumed < tLen) && (ibAltSettings = 0; - - for (int j=0; jbInterfaceNumber == Interfaces[j]->bInterfaceNumber) - Interfaces[i]->bAltSettings++; - - } - -} - - -CCyUSBConfig::CCyUSBConfig(HANDLE handle, PUSB_CONFIGURATION_DESCRIPTOR pConfigDescr,UCHAR usb30Dummy) -{ - - PUSB_INTERFACE_DESCRIPTOR interfaceDesc; - int i; - - bLength = pConfigDescr->bLength; - bDescriptorType = pConfigDescr->bDescriptorType; - wTotalLength = pConfigDescr->wTotalLength; - bNumInterfaces = pConfigDescr->bNumInterfaces; - AltInterfaces = 0; - bConfigurationValue = pConfigDescr->bConfigurationValue; - iConfiguration = pConfigDescr->iConfiguration; - bmAttributes = pConfigDescr->bmAttributes; - MaxPower = pConfigDescr->MaxPower; - - int tLen = pConfigDescr->wTotalLength; - - PUCHAR desc = (PUCHAR)pConfigDescr + pConfigDescr->bLength; - int bytesConsumed = pConfigDescr->bLength; - - for (i=0; ibDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) { - Interfaces[i] = new CCyUSBInterface(handle, interfaceDesc,usb30Dummy); - i++; - AltInterfaces++; // Actually the total number of interfaces for the config - bytesConsumed += Interfaces[i-1]->wTotalLength; - } else { - // Unexpected descriptor type - // Just skip it and go on - could have thrown an exception instead - // since this indicates that the descriptor structure is invalid. - bytesConsumed += interfaceDesc->bLength; - } - - - desc = (PUCHAR) pConfigDescr + bytesConsumed; - - } while ((bytesConsumed < tLen) && (ibAltSettings = 0; - - for (int j=0; jbInterfaceNumber == Interfaces[j]->bInterfaceNumber) - Interfaces[i]->bAltSettings++; - - } - -} - - -//______________________________________________________________________________ - -CCyUSBConfig::~CCyUSBConfig(void){ - - for (int i=0; iEndPoints[0] != 0) - { - delete Interfaces[i]->EndPoints[0]; - - for (int j=0; jEndPoints[0] = NULL; - } - - delete Interfaces[i]; - Interfaces[i] = NULL; - } - -} - -//////////////////////////////////////////////////////////////////////////////// -// -// The CCyEndPoint ABSTRACT Class -// -//////////////////////////////////////////////////////////////////////////////// - -CCyUSBEndPoint::CCyUSBEndPoint(void) -{ - hDevice = INVALID_HANDLE_VALUE; - - DscLen = 0; - DscType = 0; - Address = 0; - Attributes = 0; - MaxPktSize = 0; - Interval = 0; - TimeOut = 10000; // 10 Sec timeout is default - bIn = false; - XferMode = XMODE_DIRECT; - LastError = 0; - // Initialize the SS companion descriptor with zero, as this constructore will be called for usb2.0 device - ssdscLen =0; - ssdscType =0; - ssmaxburst=0; /* Maximum number of packets endpoint can send in one burst*/ - ssbmAttribute=0; // store endpoint attribute like for bulk it will be number of streams - ssbytesperinterval=0; -} - -// Copy constructor -CCyUSBEndPoint::CCyUSBEndPoint(CCyUSBEndPoint& ept) -{ - hDevice = ept.hDevice; - - DscLen = ept.DscLen; - DscType = ept.DscType; - Address = ept.Address; - Attributes = ept.Attributes; - MaxPktSize = ept.MaxPktSize; - Interval = ept.Interval; - TimeOut = ept.TimeOut; - bIn = ept.bIn; - XferMode = ept.XferMode; - ssdscLen =ept.ssdscLen; - ssdscType =ept.ssdscType; - ssmaxburst=ept.ssmaxburst; /* Maximum number of packets endpoint can send in one burst*/ - ssbmAttribute=ept.ssbmAttribute; // store endpoint attribute like for bulk it will be number of streams - ssbytesperinterval=ept.ssbytesperinterval; - LastError = 0; -} - -CCyUSBEndPoint::CCyUSBEndPoint(HANDLE hDev, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor) -{ - - hDevice = hDev; - - if (pEndPtDescriptor) { - PktsPerFrame = (pEndPtDescriptor->wMaxPacketSize & 0x1800) >> 11; - PktsPerFrame++; - - DscLen = pEndPtDescriptor->bLength; - DscType = pEndPtDescriptor->bDescriptorType; - Address = pEndPtDescriptor->bEndpointAddress; - Attributes = pEndPtDescriptor->bmAttributes; - MaxPktSize = (pEndPtDescriptor->wMaxPacketSize & 0x7ff) * PktsPerFrame; - Interval = pEndPtDescriptor->bInterval; - bIn = ((Address & 0x80) == 0x80); - } - - TimeOut = 10000; // 10 Sec timeout is default - - XferMode = XMODE_DIRECT; // Normally, use Direct xfers - - // Initialize the SS companion descriptor with zero, as this constructore will be called for usb2.0 device - ssdscLen =0; - ssdscType =0; - ssmaxburst=0; /* Maximum number of packets endpoint can send in one burst*/ - ssbmAttribute=0; // store endpoint attribute like for bulk it will be number of streams - ssbytesperinterval=0; - -} - - -CCyUSBEndPoint::CCyUSBEndPoint(HANDLE hDev, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor,USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR* SSEndPtDescriptor) -{ - - hDevice = hDev; - - if (pEndPtDescriptor) { - PktsPerFrame = (pEndPtDescriptor->wMaxPacketSize & 0x1800) >> 11; - PktsPerFrame++; - - DscLen = pEndPtDescriptor->bLength; - DscType = pEndPtDescriptor->bDescriptorType; - Address = pEndPtDescriptor->bEndpointAddress; - Attributes = pEndPtDescriptor->bmAttributes; - MaxPktSize = (pEndPtDescriptor->wMaxPacketSize & 0x7ff) * PktsPerFrame; - Interval = pEndPtDescriptor->bInterval; - bIn = ((Address & 0x80) == 0x80); - } - - TimeOut = 10000; // 10 Sec timeout is default - - XferMode = XMODE_DIRECT; // Normally, use Direct xfers - - if(SSEndPtDescriptor != NULL) - { - ssdscLen =SSEndPtDescriptor->bLength; - ssdscType =SSEndPtDescriptor->bDescriptorType; - ssmaxburst=SSEndPtDescriptor->bMaxBurst; /* Maximum number of packets endpoint can send in one burst*/ - MaxPktSize *=(ssmaxburst+1); - ssbmAttribute=SSEndPtDescriptor->bmAttributes; // store endpoint attribute like for bulk it will be number of streams - if((Attributes & 0x03) ==1) // MULT is valid for Isochronous transfer only - MaxPktSize*=((SSEndPtDescriptor->bmAttributes & 0x03)+1); // Adding the MULT fields. - - ssbytesperinterval=SSEndPtDescriptor->bBytesPerInterval; - - } - else - { - // Initialize the SS companion descriptor with zero - ssdscLen =0; - ssdscType =0; - ssmaxburst=0; /* Maximum number of packets endpoint can send in one burst*/ - ssbmAttribute=0; // store endpoint attribute like for bulk it will be number of streams - ssbytesperinterval=0; - } - -} - - -//______________________________________________________________________________ - -bool CCyUSBEndPoint::Reset(void) -{ - DWORD dwBytes = 0; - bool RetVal = false; - - RetVal = (DeviceIoControl(hDevice, - IOCTL_ADAPT_RESET_PIPE, - &Address, - sizeof(UCHAR), - NULL, - 0, - &dwBytes, - 0) !=0); - - if(!RetVal) LastError = GetLastError(); - return RetVal; -} - -//______________________________________________________________________________ - -bool CCyUSBEndPoint::Abort(void) -{ - DWORD dwBytes = 0; - bool RetVal = false; - OVERLAPPED ov; - - memset(&ov,0,sizeof(ov)); - ov.hEvent = CreateEvent(NULL,false,false,NULL); - - RetVal = (DeviceIoControl(hDevice, - IOCTL_ADAPT_ABORT_PIPE, - &Address, - sizeof(UCHAR), - NULL, - 0, - &dwBytes, - &ov)!=0); - if(!RetVal) - { - DWORD LastError = GetLastError(); - if(LastError == ERROR_IO_PENDING) - WaitForSingleObject(ov.hEvent,1000); - } - CloseHandle(ov.hEvent); - return true; - -} -//______________________________________________________________________________ - -bool CCyUSBEndPoint::XferData(PUCHAR buf, LONG &bufLen, CCyIsoPktInfo* pktInfos) -{ - - OVERLAPPED ovLapStatus; - memset(&ovLapStatus,0,sizeof(OVERLAPPED)); - - ovLapStatus.hEvent = CreateEvent(NULL, false, false, NULL); - - PUCHAR context = BeginDataXfer(buf, bufLen, &ovLapStatus); - bool wResult = WaitForIO(&ovLapStatus); - bool fResult = FinishDataXfer(buf, bufLen, &ovLapStatus, context, pktInfos); - - CloseHandle(ovLapStatus.hEvent); - - return wResult && fResult; -} - -//______________________________________________________________________________ - -bool CCyUSBEndPoint::XferData(PUCHAR buf, LONG &bufLen, CCyIsoPktInfo* pktInfos, bool pktMode) -{ - if ((bIn == false) || (pktMode == false)) - { - return XferData(buf, bufLen); - } - else - { - int size = 0; - LONG xferLen = (LONG)MaxPktSize; - bool status = true; - PUCHAR ptr = buf; - - while (status && (size < bufLen)) - { - if ((bufLen - size) < MaxPktSize) - xferLen = bufLen - size; - - status = XferData(ptr, xferLen); - if (status) - { - ptr += xferLen; - size += xferLen; - - if (xferLen < MaxPktSize) - break; - } - } - - bufLen = size; - if (bufLen > 0) - return true; - return status; - } -} - -//______________________________________________________________________________ - -bool CCyUSBEndPoint::FinishDataXfer(PUCHAR buf, LONG &bufLen, OVERLAPPED *ov, PUCHAR pXmitBuf, CCyIsoPktInfo* pktInfos) -{ - DWORD bytes = 0; - bool rResult = (GetOverlappedResult(hDevice, ov, &bytes, FALSE)!=0); - - PSINGLE_TRANSFER pTransfer = (PSINGLE_TRANSFER) pXmitBuf; - bufLen = (bytes) ? bytes - pTransfer->BufferOffset : 0; - bytesWritten = bufLen; - - UsbdStatus = pTransfer->UsbdStatus; - NtStatus = pTransfer->NtStatus; - - if (bIn && (XferMode == XMODE_BUFFERED) && (bufLen > 0)) { - UCHAR *ptr = (PUCHAR)pTransfer + pTransfer->BufferOffset; - memcpy (buf, ptr, bufLen); - } - - // If a buffer was provided, pass-back the Isoc packet info records - if (pktInfos && (bufLen > 0)) { - //ZeroMemory(pktInfos, pTransfer->IsoPacketLength); - PUCHAR pktPtr = pXmitBuf + pTransfer->IsoPacketOffset; - memcpy(pktInfos, pktPtr, pTransfer->IsoPacketLength); - } - -// delete[] pXmitBuf; // [] Changed in 1.5.1.3 - - return rResult && (UsbdStatus == 0) && (NtStatus == 0); -} - -//______________________________________________________________________________ - -PUCHAR CCyUSBEndPoint::BeginBufferedXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov) -{ - if ( hDevice == INVALID_HANDLE_VALUE ) return NULL; - - int iXmitBufSize = sizeof (SINGLE_TRANSFER) + bufLen; - PUCHAR pXmitBuf = new UCHAR[iXmitBufSize]; - ZeroMemory (pXmitBuf, sizeof(SINGLE_TRANSFER)); - - PSINGLE_TRANSFER pTransfer = (PSINGLE_TRANSFER) pXmitBuf; - pTransfer->ucEndpointAddress = Address; - pTransfer->IsoPacketLength = 0; - pTransfer->BufferOffset = sizeof (SINGLE_TRANSFER); - pTransfer->BufferLength = bufLen; - - // Copy buf into pXmitBuf - UCHAR *ptr = (PUCHAR)pXmitBuf + sizeof(SINGLE_TRANSFER); - memcpy (ptr, buf, bufLen); - - DWORD dwReturnBytes; - - DeviceIoControl (hDevice, - IOCTL_ADAPT_SEND_NON_EP0_TRANSFER, - pXmitBuf, - iXmitBufSize, - pXmitBuf, - iXmitBufSize, - &dwReturnBytes, - ov); - - UsbdStatus = pTransfer->UsbdStatus; - NtStatus = pTransfer->NtStatus; - - LastError = GetLastError(); - return pXmitBuf; -} - - - -//______________________________________________________________________________ -PUCHAR CCyUSBEndPoint::BeginDirectXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov) -{ - if ( hDevice == INVALID_HANDLE_VALUE ) return NULL; - - int iXmitBufSize = sizeof (SINGLE_TRANSFER); - PUCHAR pXmitBuf = (PUCHAR)ov + sizeof(OVERLAPPED); - ZeroMemory (pXmitBuf, iXmitBufSize); - - PSINGLE_TRANSFER pTransfer = (PSINGLE_TRANSFER) pXmitBuf; - pTransfer->ucEndpointAddress = Address; - pTransfer->IsoPacketLength = 0; - pTransfer->BufferOffset = 0; - pTransfer->BufferLength = 0; - - DWORD dwReturnBytes; - DeviceIoControl (hDevice, - IOCTL_ADAPT_SEND_NON_EP0_DIRECT, - pXmitBuf, - iXmitBufSize, - buf, - bufLen, - &dwReturnBytes, - ov); - - UsbdStatus = pTransfer->UsbdStatus; - NtStatus = pTransfer->NtStatus; - - LastError = GetLastError(); - return pXmitBuf; -} - - - -//______________________________________________________________________________ -// Unlike WaitForIO, this method does not record the bytes written or reset the -// endpoint if errors occurred. This method is called from the application level -// in conjunction with BeginDataXfer and FinishDataXfer - -bool CCyUSBEndPoint::WaitForXfer(OVERLAPPED *ov, ULONG tOut) -{ - - //if (LastError == ERROR_SUCCESS) return true; // The command completed - - //if (LastError == ERROR_IO_PENDING) - { - DWORD waitResult = WaitForSingleObject(ov->hEvent,tOut); - - if (waitResult == WAIT_TIMEOUT) return false; - - if (waitResult == WAIT_OBJECT_0) return true; - } - - return false; -} - -//______________________________________________________________________________ - -bool CCyUSBEndPoint::WaitForIO(OVERLAPPED *ovLapStatus) -{ - LastError = GetLastError(); - DWORD retcode =1; - - if (LastError == ERROR_SUCCESS) return true; // The command completed - - if (LastError == ERROR_IO_PENDING) { - DWORD waitResult = WaitForSingleObject(ovLapStatus->hEvent,TimeOut); - - if (waitResult == WAIT_OBJECT_0) return true; - - if (waitResult == WAIT_TIMEOUT) - { - Abort(); - //// Wait for the stalled command to complete - should be done already - //retcode = WaitForSingleObject(ovLapStatus->hEvent,50); // Wait for 50 milisecond - Sleep(50); - - //if(retcode == WAIT_TIMEOUT || retcode==WAIT_FAILED) - //{// Worst case condition , in multithreaded environment if user set time out to ZERO and cancel the IO the requiest, rarely first Abort() fail to cancel the IO, so reissueing second Abort(0. - //Abort(); - //retcode = WaitForSingleObject(ovLapStatus->hEvent,INFINITE); - - //} - } - } - - return (retcode==0) ? true:false; -} - -//______________________________________________________________________________ - -ULONG CCyUSBEndPoint::GetXferSize(void){ - - ULONG ulTransferSize; - DWORD BytesXfered; - - if (hDevice == INVALID_HANDLE_VALUE) return (ULONG) NULL; - - SET_TRANSFER_SIZE_INFO SetTransferInfo; - - ulTransferSize = 0; - SetTransferInfo.EndpointAddress = Address; - SetTransferInfo.TransferSize = ulTransferSize; - - BOOL bRetVal = DeviceIoControl(hDevice, - IOCTL_ADAPT_GET_TRANSFER_SIZE, - &SetTransferInfo, sizeof(SET_TRANSFER_SIZE_INFO), - &SetTransferInfo, sizeof(SET_TRANSFER_SIZE_INFO), - &BytesXfered, - NULL); - - if (bRetVal && BytesXfered >= sizeof(SET_TRANSFER_SIZE_INFO)) - ulTransferSize = SetTransferInfo.TransferSize; - else - LastError = GetLastError(); - - return ulTransferSize; -} - -//______________________________________________________________________________ - -void CCyUSBEndPoint::SetXferSize(ULONG xfer){ - - if (hDevice == INVALID_HANDLE_VALUE) return; - - DWORD BytesXfered; - SET_TRANSFER_SIZE_INFO SetTransferInfo; - - if(MaxPktSize==0) - return; - // Force a multiple of MaxPktSize - ULONG pkts = (xfer % MaxPktSize) ? 1+(xfer / MaxPktSize) : (xfer / MaxPktSize); - ULONG xferSize = pkts * MaxPktSize; - - SetTransferInfo.EndpointAddress = Address; - SetTransferInfo.TransferSize = xferSize; - - if(DeviceIoControl(hDevice, - IOCTL_ADAPT_SET_TRANSFER_SIZE, - &SetTransferInfo, sizeof(SET_TRANSFER_SIZE_INFO), - &SetTransferInfo, sizeof(SET_TRANSFER_SIZE_INFO), - &BytesXfered, - NULL)==false) - { - LastError = GetLastError(); - } - -} - - - -//////////////////////////////////////////////////////////////////////////////// -// -// The CCyControlEndPoint Class -// -//////////////////////////////////////////////////////////////////////////////// - -CCyControlEndPoint::CCyControlEndPoint(void):CCyUSBEndPoint() -{ - - Target = TGT_DEVICE; - ReqType = REQ_VENDOR; - Direction = DIR_TO_DEVICE; - - ReqCode = 0; - Value = 0; - Index = 0; - - XferMode = XMODE_BUFFERED; - -} - -// Copy Constructor -CCyControlEndPoint::CCyControlEndPoint(CCyControlEndPoint& ept):CCyUSBEndPoint(ept) -{ - - Target = ept.Target; - ReqType = ept.ReqType; - Direction = ept.Direction; - - ReqCode = ept.ReqCode; - Value = ept.Value; - Index = ept.Index; - - XferMode = ept.XferMode; -} - - -CCyControlEndPoint::CCyControlEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor) : -CCyUSBEndPoint(h, pEndPtDescriptor) -{ - Target = TGT_DEVICE; - ReqType = REQ_VENDOR; - Direction = DIR_TO_DEVICE; - - ReqCode = 0; - Value = 0; - Index = 0; - - XferMode = XMODE_BUFFERED; - -} - -//______________________________________________________________________________ - -bool CCyControlEndPoint::Read(PUCHAR buf, LONG &bufLen) -{ - Direction = DIR_FROM_DEVICE; - return XferData(buf, bufLen); -} - - -//______________________________________________________________________________ - -bool CCyControlEndPoint::Write(PUCHAR buf, LONG &bufLen) -{ - Direction = DIR_TO_DEVICE; - return XferData(buf, bufLen); -} - - -//______________________________________________________________________________ - -PUCHAR CCyControlEndPoint::BeginDataXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov) -{ - union { - struct { - UCHAR Recipient:5; - UCHAR Type:2; - UCHAR Direction:1; - } bmRequest; - - UCHAR bmReq; - }; - - if ( hDevice == INVALID_HANDLE_VALUE ) return NULL; - - bmRequest.Recipient = Target; - bmRequest.Type = ReqType; - bmRequest.Direction = Direction; - - bIn = (Direction == DIR_FROM_DEVICE); - - int iXmitBufSize = sizeof (SINGLE_TRANSFER) + bufLen; - UCHAR *pXmitBuf = new UCHAR[iXmitBufSize]; - ZeroMemory (pXmitBuf, sizeof(SINGLE_TRANSFER)); - - // The Control Endpoint has a 1 sec resolution on its timeout - // But, TimeOut is in milliseconds. - ULONG tmo = ((TimeOut > 0) && (TimeOut < 1000)) ? 1 : TimeOut / 1000; - - PSINGLE_TRANSFER pTransfer = (PSINGLE_TRANSFER) pXmitBuf; - pTransfer->SetupPacket.bmRequest = bmReq; - pTransfer->SetupPacket.bRequest = ReqCode; - pTransfer->SetupPacket.wValue = Value; - pTransfer->SetupPacket.wIndex = Index; - pTransfer->SetupPacket.wLength = (USHORT)bufLen; - pTransfer->SetupPacket.ulTimeOut = tmo; // Seconds, not milliseconds - pTransfer->ucEndpointAddress = 0x00; // control pipe - pTransfer->IsoPacketLength = 0; - pTransfer->BufferOffset = sizeof (SINGLE_TRANSFER); - pTransfer->BufferLength = bufLen; - - // Copy buf into pXmitBuf - UCHAR *ptr = pXmitBuf + sizeof (SINGLE_TRANSFER); - memcpy (ptr, buf, bufLen); - - DWORD dwReturnBytes; - DeviceIoControl (hDevice, - IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER, - pXmitBuf, - iXmitBufSize, - pXmitBuf, - iXmitBufSize, - &dwReturnBytes, - ov); - - // Note that this method leaves pXmitBuf allocated. It will get deleted in - // FinishDataXfer. - - LastError = GetLastError(); - return pXmitBuf; - -} - -//////////////////////////////////////////////////////////////////////////////// -// -// The CCyIsocEndPoint Class -// -//////////////////////////////////////////////////////////////////////////////// - -CCyIsocEndPoint::CCyIsocEndPoint(void) : CCyUSBEndPoint() -{ -} - -CCyIsocEndPoint::CCyIsocEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor) : -CCyUSBEndPoint(h, pEndPtDescriptor) -{ -} -CCyIsocEndPoint::CCyIsocEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor,USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR* SSEndPtDescriptor) : -CCyUSBEndPoint(h, pEndPtDescriptor,SSEndPtDescriptor) -{ -} - -//______________________________________________________________________________ - -PUCHAR CCyIsocEndPoint::BeginDataXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov) -{ - if ( hDevice == INVALID_HANDLE_VALUE ) return NULL; - - if (XferMode == XMODE_DIRECT) - return BeginDirectXfer(buf, bufLen, ov); - else - return BeginBufferedXfer(buf, bufLen, ov); - -} - -//______________________________________________________________________________ - -PUCHAR CCyIsocEndPoint::BeginBufferedXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov) -{ - if ( hDevice == INVALID_HANDLE_VALUE ) return NULL; - - int pkts; - if(MaxPktSize) - pkts = bufLen / MaxPktSize; // Number of packets implied by bufLen & pktSize - else - { - pkts = 0; - return NULL; - } - - if (bufLen % MaxPktSize) pkts++; - - if (pkts == 0) return NULL; - - int iXmitBufSize = sizeof (SINGLE_TRANSFER) + (pkts * sizeof(ISO_PACKET_INFO)) + bufLen; - UCHAR *pXmitBuf = new UCHAR[iXmitBufSize]; - ZeroMemory (pXmitBuf, sizeof(SINGLE_TRANSFER) + (pkts * sizeof(ISO_PACKET_INFO))); - - PSINGLE_TRANSFER pTransfer = (PSINGLE_TRANSFER) pXmitBuf; - pTransfer->ucEndpointAddress = Address; - pTransfer->IsoPacketOffset = sizeof (SINGLE_TRANSFER); - pTransfer->IsoPacketLength = pkts * sizeof(ISO_PACKET_INFO); - pTransfer->BufferOffset = sizeof (SINGLE_TRANSFER) + pTransfer->IsoPacketLength; - pTransfer->BufferLength = bufLen; - - // Copy buf into pXmitBuf - UCHAR *ptr = pXmitBuf + pTransfer->BufferOffset; - memcpy (ptr, buf, bufLen); - - DWORD dwReturnBytes = 0; - - DeviceIoControl (hDevice, - IOCTL_ADAPT_SEND_NON_EP0_TRANSFER, - pXmitBuf, - iXmitBufSize, - pXmitBuf, - iXmitBufSize, - &dwReturnBytes, - ov); - - // Note that this method leaves pXmitBuf allocated. It will get deleted in - // FinishDataXfer. - - UsbdStatus = pTransfer->UsbdStatus; - NtStatus = pTransfer->NtStatus; - - LastError = GetLastError(); - return pXmitBuf; -} - -//______________________________________________________________________________ - -PUCHAR CCyIsocEndPoint::BeginDirectXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov) -{ - if ( hDevice == INVALID_HANDLE_VALUE ) return NULL; - - int pkts; - if(MaxPktSize) - pkts = bufLen / MaxPktSize; // Number of packets implied by bufLen & pktSize - else - { - pkts = 0; - return NULL; - } - - if (bufLen % MaxPktSize) pkts++; - - if (pkts == 0) return NULL; - - int iXmitBufSize = sizeof (SINGLE_TRANSFER) + (pkts * sizeof(ISO_PACKET_INFO)); - UCHAR *pXmitBuf = new UCHAR[iXmitBufSize]; - ZeroMemory (pXmitBuf, iXmitBufSize); - - PSINGLE_TRANSFER pTransfer = (PSINGLE_TRANSFER) pXmitBuf; - pTransfer->ucEndpointAddress = Address; - pTransfer->IsoPacketOffset = sizeof (SINGLE_TRANSFER); - pTransfer->IsoPacketLength = pkts * sizeof(ISO_PACKET_INFO); - pTransfer->BufferOffset = 0; - pTransfer->BufferLength = 0; - - DWORD dwReturnBytes = 0; - DeviceIoControl (hDevice, - IOCTL_ADAPT_SEND_NON_EP0_DIRECT, - pXmitBuf, - iXmitBufSize, - buf, - bufLen, - &dwReturnBytes, - ov); - - // Note that this method leaves pXmitBuf allocated. It will get deleted in - // FinishDataXfer. - - UsbdStatus = pTransfer->UsbdStatus; - NtStatus = pTransfer->NtStatus; - - LastError = GetLastError(); - return pXmitBuf; -} - -//////////////////////////////////////////////////////////////////////////////// -// -// The CCyFX3Device Class -// -//////////////////////////////////////////////////////////////////////////////// -CCyFX3Device::CCyFX3Device() -{ -} -CCyFX3Device::~CCyFX3Device() -{ -} -bool CCyFX3Device::Ep0VendorCommand(vendorCmdData cmdData) -{ - ControlEndPt->Target = TGT_DEVICE ; - ControlEndPt->ReqType = REQ_VENDOR ; - ControlEndPt->ReqCode = cmdData.opCode ; - ControlEndPt->Direction = (cmdData.isRead) ? DIR_FROM_DEVICE : DIR_TO_DEVICE ; - - ControlEndPt->Value = (cmdData.addr & 0xFFFF); - ControlEndPt->Index = ((cmdData.addr >> 16) & 0xFFFF); - - int maxpkt = ControlEndPt->MaxPktSize; - - long len = cmdData.size; - - /* Handle the case where transfer length is 0 (used to send the Program Entry) */ - if (cmdData.size == 0) - return ControlEndPt->XferData(cmdData.buf, len, NULL); - else - { - bool bRetCode = false; - long Stagelen = 0; - int BufIndex = 0; - while (len > 0) - { - if (len >= 65535) - Stagelen = 65535; - else - Stagelen = (len) % 65535; - - /* Allocate the buffer */ - PUCHAR StageBuf = new UCHAR[Stagelen]; - - if (!cmdData.isRead) - { - /*write operation */ - for (int i = 0; i < Stagelen; i++) - StageBuf[i] = cmdData.buf[BufIndex + i]; - } - - bRetCode = ControlEndPt->XferData(StageBuf, Stagelen, NULL); - if (!bRetCode) - { - if(StageBuf) - delete[] StageBuf; - - return false; - } - - if (cmdData.isRead) - { - /*read operation */ - for (int i = 0; i < Stagelen; i++) - cmdData.buf[BufIndex + i] = StageBuf[i]; - } - - if(StageBuf) - delete[] StageBuf; - - len -= Stagelen; - BufIndex += Stagelen; - } - - } - - return true; -} - -//______________________________________________________________________________ - -/* Function to transmit data on the control endpoint. */ -bool CCyFX3Device::DownloadBufferToDevice(UINT start_addr, USHORT count, UCHAR *data_buf, UCHAR opCode) -{ - vendorCmdData cmdData; - cmdData.addr = start_addr; - - cmdData.isRead = 0; - cmdData.buf = data_buf; - cmdData.opCode = opCode; - cmdData.size = count; - - return Ep0VendorCommand(cmdData); -} - -//______________________________________________________________________________ - -/* Function to read data using control endpoint. */ -bool CCyFX3Device::UploadBufferFromDevice(UINT start_addr, USHORT count, UCHAR *data_buf, UCHAR opCode) -{ - vendorCmdData cmdData; - cmdData.addr = start_addr; - - cmdData.isRead = 1; - cmdData.buf = data_buf; - cmdData.opCode = opCode; - cmdData.size = count; - - return Ep0VendorCommand(cmdData); -} - -//______________________________________________________________________________ - -/* This function sends out the 0xA0 vendor request for transferring the control to -program entry point. -*/ -bool CCyFX3Device::SetProgramEntry (UCHAR opCode,UINT start_addr) -{ - vendorCmdData cmdData; - cmdData.addr = ((start_addr >> 16) | (start_addr << 16)); /* swap LSB and MSB */ - - cmdData.isRead = 0; - cmdData.buf = NULL; - cmdData.opCode = opCode; - cmdData.size = 0; - - return Ep0VendorCommand(cmdData); -} - -//______________________________________________________________________________ - -bool CCyFX3Device::IsBootLoaderRunning() -{ - /*Dire : in, Target : Device, ReqCode:0xA0,wValue:0x0000,wIndex:0x0000 */ - /* This function checks for bootloader,it will return false if it is not running. */ - UCHAR buf[1]; - long len = 1; - bool ret; - UCHAR opCode = 0xA0; // Vendore command - - vendorCmdData cmdData; - - cmdData.addr = 0x0000; - - cmdData.isRead = true; - cmdData.buf = buf; - cmdData.opCode = opCode; - cmdData.size = len; - - /* Value = isErase, index = sector number */ - ret = Ep0VendorCommand(cmdData); - return ret; -} - -//______________________________________________________________________________ - -FX3_FWDWNLOAD_ERROR_CODE CCyFX3Device::EraseSectorOfSPIFlash(UINT SectorNumber, UCHAR opCode) -{ - vendorCmdData cmdData; - bool ret; - UCHAR buf[1]; - UINT buflen = 0; - buf[0] = 1; - - cmdData.addr = (1 + (SectorNumber << 16)); - - cmdData.isRead = false; - cmdData.buf = buf; - cmdData.opCode = opCode; - cmdData.size = buflen; - - /* Value = isErase, index = sector number */ - ret = Ep0VendorCommand(cmdData); - if (ret) - { - /* Check the status of erase. Value should be 0 */ - buflen = 1; - cmdData.size = buflen; - while (buf[0] != 0) - { - cmdData.isRead = true; - cmdData.addr = (0 + (SectorNumber << 16)); - if (!Ep0VendorCommand(cmdData)) - return FAILED; - } - } - else - return FAILED; - - return SUCCESS; -} - -//______________________________________________________________________________ - -bool CCyFX3Device::WriteToSPIFlash(PUCHAR Buf, UINT buflen, UINT ByteAddress, UCHAR opCode) -{ - vendorCmdData cmdData; - cmdData.addr = ((ByteAddress / SPI_FLASH_PAGE_SIZE_IN_BYTE) << 16); // swap LSB and MSB - - cmdData.isRead = 0; - cmdData.buf = Buf; - cmdData.opCode = opCode; - cmdData.size = buflen; - - return Ep0VendorCommand(cmdData); -} - -//______________________________________________________________________________ - -FX3_FWDWNLOAD_ERROR_CODE CCyFX3Device::DownloadUserIMGtoSPIFLASH(PUCHAR buffer_p, UINT fw_size, UCHAR opCode) -{ - /* The size of the image needs to be rounded to a multiple of the SPI page size. */ - UINT ImageSizeInPage = (fw_size + SPI_FLASH_PAGE_SIZE_IN_BYTE - 1) / SPI_FLASH_PAGE_SIZE_IN_BYTE; - UINT TotalNumOfByteToWrote = ImageSizeInPage * SPI_FLASH_PAGE_SIZE_IN_BYTE; - /* Sectors needs to be erased in case of SPI. Sector size = 64k. Page Size = 256 bytes. 1 Sector = 256 pages. */ - /* Calculate the number of sectors needed to write firmware image and erase them. */ - UINT NumOfSector = fw_size / SPI_FLASH_SECTOR_SIZE_IN_BYTE; - if ((fw_size % SPI_FLASH_SECTOR_SIZE_IN_BYTE) != 0) - NumOfSector++; - - /* Erase the sectors */ - for (UINT i = 0; i < NumOfSector; i++) - { - if (EraseSectorOfSPIFlash(i, opCode) != SUCCESS) - return SPILASH_ERASE_FAILED; - } - - /*Write the firmware to the SPI flash */ - UINT numberOfBytesLeftToWrite = TotalNumOfByteToWrote; /* Current number of bytes left to write */ - - UINT FwFilePointer = 0; - UINT massStorageByteAddress = 0; /* Current Mass Storage Byte Address */ - - PUCHAR WriteBuf = new UCHAR[CYWB_BL_MAX_BUFFER_SIZE_WHEN_USING_EP0_TRANSPORT]; - - while (numberOfBytesLeftToWrite > 0) - { - UINT numberOfBytesToWrite = CYWB_BL_MAX_BUFFER_SIZE_WHEN_USING_EP0_TRANSPORT; - - if (numberOfBytesLeftToWrite < CYWB_BL_MAX_BUFFER_SIZE_WHEN_USING_EP0_TRANSPORT) - { - numberOfBytesToWrite = numberOfBytesLeftToWrite; - } - - /* Trigger a mass storage write... */ - for (UINT i = 0; i < numberOfBytesToWrite; i++) - { - if ((FwFilePointer + i) < fw_size) - WriteBuf[i] = buffer_p[i + FwFilePointer]; - } - opCode = 0xC2; // Operation code to Write to SPI - if (WriteToSPIFlash(WriteBuf, numberOfBytesToWrite, massStorageByteAddress, opCode) == false) - { - if(WriteBuf) - delete[] WriteBuf; - - return FAILED; - } - - /* Adjust pointers */ - numberOfBytesLeftToWrite -= numberOfBytesToWrite; - FwFilePointer += numberOfBytesToWrite; - massStorageByteAddress += numberOfBytesToWrite; - } - - if(WriteBuf) - delete[] WriteBuf; - - return SUCCESS; -} - -//______________________________________________________________________________ - -FX3_FWDWNLOAD_ERROR_CODE CCyFX3Device::DownloadUserIMGtoI2CE2PROM(PUCHAR buffer_p, UINT fw_size, UCHAR opCode) -{ - int STAGE_SIZE = BUFSIZE_UPORT; - PUCHAR downloadbuf = new UCHAR[STAGE_SIZE]; - - int NoOfStage = ((int)fw_size / STAGE_SIZE); - long LastStage = ((int)fw_size % STAGE_SIZE); - UINT DownloadAddress = 0; - long FwImagePtr = 0; - long StageSize = STAGE_SIZE; - - //Get the I2C addressing size - UCHAR ImgI2CSizeByte = buffer_p[2]; // the 2nd byte of the IMG file will tell us the I2EPROM internal addressing. - UINT AddresingStageSize = 0; - ImgI2CSizeByte = ((ImgI2CSizeByte >> 1) & 0x07); // Bit3:1 represent the addressing - bool IsMicroShipE2Prom = false; - - switch (ImgI2CSizeByte) - { - case 0: - case 1: - return I2CE2PROM_UNKNOWN_I2C_SIZE; - case 2: - AddresingStageSize = (4 * 1024); // 4KByte - break; - case 3: - AddresingStageSize = (8 * 1024); // 8KByte - break; - case 4: - AddresingStageSize = (16 * 1024); // 16KByte - break; - case 5: - AddresingStageSize = (32 * 1024); // 32KByte - break; - case 6: - AddresingStageSize = (64 * 1024); // 64KByte - break; - case 7: - IsMicroShipE2Prom = true; // 128KByte Addressing for Microchip. - AddresingStageSize = (64 * 1024); // 64KByte // case 7 represent 128Kbyte but it follow 64Kbyte addressing - break; - default: - { - if(downloadbuf) - delete[] downloadbuf; - - return I2CE2PROM_UNKNOWN_I2C_SIZE; - } - } - - - ControlEndPt->Target = TGT_DEVICE ; - ControlEndPt->ReqType = REQ_VENDOR ; - ControlEndPt->ReqCode = opCode ; - ControlEndPt->Direction = DIR_TO_DEVICE ; - - ControlEndPt->Value = (DownloadAddress & 0xFFFF); - ControlEndPt->Index = ((DownloadAddress >> 16) & 0xFFFF); - int maxpkt = ControlEndPt->MaxPktSize; - - for (int i = 0; i < NoOfStage; i++) - { - /* Copy data from main buffer to tmp buffer */ - for (long j = 0; j < STAGE_SIZE; j++) - downloadbuf[j] = buffer_p[FwImagePtr + j]; - - if (!ControlEndPt->XferData(downloadbuf, StageSize, NULL)) - { - if(downloadbuf) - delete[] downloadbuf; - - return FAILED; - } - - FwImagePtr += STAGE_SIZE; - ControlEndPt->Index += (WORD)StageSize; - - ///// - // Address calculation done in the below box - if (IsMicroShipE2Prom) - {//Microchip Addressing(0-(1-64),4(64 to 128),1(128 to 192 ),5(192 to 256)) - if (FwImagePtr >= (128 * 1024)) - { - if ((FwImagePtr % AddresingStageSize) == 0) - { - if (ControlEndPt->Value == 0x04) - ControlEndPt->Value = 0x01; - else - ControlEndPt->Value = 0x05; - - ControlEndPt->Index = 0; - } - } - else if ((FwImagePtr % AddresingStageSize) == 0) - { - ControlEndPt->Value = 0x04; - ControlEndPt->Index = 0; - } - } - else - {//ATMEL addressing sequential - if ((FwImagePtr % AddresingStageSize)==0) - {// Increament the Value field to represent the address and reset the Index value to zero. - ControlEndPt->Value += 0x01; - if(ControlEndPt->Value>=8) - ControlEndPt->Value = 0x0; //reset the Address to ZERO - - ControlEndPt->Index = 0; - } - } - ///// - - - } - - if (LastStage != 0) - { - /*check for last stage */ - - for (long j = 0; j < LastStage; j++) - downloadbuf[j] = buffer_p[FwImagePtr + j]; - - if ((LastStage % maxpkt) != 0) - { - /* make it multiple of max packet size */ - int diff = (maxpkt - (LastStage % maxpkt)); - for (int j = LastStage; j < (LastStage + diff); j++) - downloadbuf[j] = 0; - - LastStage += diff; - } - - if (!ControlEndPt->XferData(downloadbuf, LastStage, NULL)) - { - if(downloadbuf) - delete[] downloadbuf; - - return FAILED; - } - - /*Failure Case: - The device does not return failure message when file size is more than 128KByte and only one 128Byte E2PROM on the DVK. - Solution: - Read back the last stage data to confirm that all data transferred successfully.*/ - ControlEndPt->ReqCode = 0xBB; - ControlEndPt->Direction = DIR_FROM_DEVICE; - if (!ControlEndPt->XferData(downloadbuf, LastStage, NULL)) - { - if(downloadbuf) - delete[] downloadbuf; - - return FAILED; - } - } - - if(downloadbuf) - delete[] downloadbuf; - - return SUCCESS; -} - -//______________________________________________________________________________ - -FX3_FWDWNLOAD_ERROR_CODE CCyFX3Device::DownloadFwToRam(const UCHAR *buffer_p, UINT fw_size, UCHAR opCode) -{ - UCHAR downloadBuffer[BUFSIZE_UPORT]; - UCHAR uploadbuffer[BUFSIZE_UPORT]; - bool isTrue = true; - UINT ComputeCheckSum = 0; - UINT ExpectedCheckSum = 0; - INT fwImagePtr = 0; - UINT SectionLength = 0; - UINT SectionAddress; - UINT DownloadAddress; - UINT ProgramEntry; - - /* Initialize computed checksum */ - ComputeCheckSum = 0; - - /* Check "CY" signature (0x43,0x59) and download the firmware image */ - if ((buffer_p[fwImagePtr] != 0x43) || (buffer_p[fwImagePtr + 1] != 0x59)) - { /*signature doesn't match */ - return INVALID_FWSIGNATURE; - } - - /* Skip the two bytes signature and the following two bytes */ - fwImagePtr += 4; - - /* Download one section at a time to the device, compute checksum, and upload-verify it */ - while (isTrue) - { - /* Get section length (4 bytes) and convert it from 32-bit word count to byte count */ - CYWB_BL_4_BYTES_COPY(&SectionLength, &buffer_p[fwImagePtr]); - fwImagePtr += 4; - - SectionLength = SectionLength << 2; - - /* If length = 0, the transfer is complete */ - if (SectionLength == 0) break; - - /* Get section address (4 bytes) */ - CYWB_BL_4_BYTES_COPY(&SectionAddress, &buffer_p[fwImagePtr]); - fwImagePtr += 4; - - /* Download BUFSIZE_UPORT maximum bytes at a time */ - INT bytesLeftToDownload = SectionLength; - DownloadAddress = SectionAddress; - - while (bytesLeftToDownload > 0) - { - INT bytesToTransfer = BUFSIZE_UPORT; - if (bytesLeftToDownload < BUFSIZE_UPORT) - bytesToTransfer = bytesLeftToDownload; - - /* sanity check for incomplete fw with valid signatures. - Note: bytesToTransfer should never be greater then fw length i.e buflen */ - if (bytesToTransfer > (INT)fw_size) - return CORRUPT_FIRMWARE_IMAGE_FILE; - - memcpy(downloadBuffer, (void *)(buffer_p + fwImagePtr), bytesToTransfer); - - /* Compute checksum: Here transferLength is assumed to be a multiple of 4. If it is not, the checksum will fail anyway */ - for (INT index = 0; index < bytesToTransfer; index += 4) - { - UINT buf32bits = 0; - CYWB_BL_4_BYTES_COPY(&buf32bits, &downloadBuffer[index]); - ComputeCheckSum += buf32bits; - } - - /*The FPGA does not seem to always be reliable: if an error is encountered, try again twice */ - INT maxTryCount = 3; - for (INT tryCount = 1; tryCount <= maxTryCount; tryCount++) - { - /* Download one buffer worth of data to the device */ - if (!DownloadBufferToDevice(DownloadAddress, bytesToTransfer, downloadBuffer, opCode)) - { - /* Check if we exceeded the max try count */ - if (tryCount == maxTryCount) - { - /* Failure while downloading firmware to the device. Abort */ - return FAILED; - } - else - { - /* F/W buffer download failure. Trying writing/verifying current buffer again... */ - continue; - } - } - - memset (uploadbuffer, 0, bytesToTransfer); - - if (!UploadBufferFromDevice(DownloadAddress, bytesToTransfer, uploadbuffer, opCode)) - { - /* Check if we exceeded the max try count */ - if (tryCount == maxTryCount) - { - /* Failure while uploading firmware from the device for verification. Abort */ - return FAILED; - } - else - { - /* F/W buffer upload failure. Trying writing/verifying current buffer again... */ - continue; - } - } - - for (int count = 0; count < bytesToTransfer; count++) - { - if (downloadBuffer[count] != uploadbuffer[count]) - { - /* Check if we exceeded the max try count */ - if (tryCount == maxTryCount) - { - /* Uploaded firmware data does not match downloaded data. Abort */ - return FAILED; - } - else - { - /* Uploaded data does not match downloaded data. Trying writing/verifying current buffer again...*/ - continue; - } - } - } - } - - DownloadAddress += bytesToTransfer; - fwImagePtr += bytesToTransfer; - bytesLeftToDownload -= bytesToTransfer; - - /* Sanity check */ - if (fwImagePtr > (INT)fw_size) - return INCORRECT_IMAGE_LENGTH; - } - } - - /* Get Program Entry Address(4 bytes) */ - CYWB_BL_4_BYTES_COPY(&ProgramEntry, &buffer_p[fwImagePtr]); - fwImagePtr += 4; - - /* Get expected checksum (4 bytes) */ - CYWB_BL_4_BYTES_COPY(&ExpectedCheckSum, &buffer_p[fwImagePtr]); - fwImagePtr += 4; - - /* Compare computed checksum against expected value */ - if (ComputeCheckSum != ExpectedCheckSum) - { - /* CheckSum mismatch. Expected=0x" << std::hex << expectedCheckSum << " Computed=0x" << std::hex << computedCheckSum; */ - } - - /* Transfer execution to Program Entry */ - UCHAR dummyBuffer[1]; - // Few of the xHCI driver stack have issue with Control IN transfer,due to that below request fails , - // Control IN transfer is ZERO lenght packet , and it does not have any impact on execution of firmware. - //if (!DownloadBufferToDevice(ProgramEntry, 0, dummyBuffer, opCode)) - //{ - // /* Downloading Program Entry failed */ - // return FAILED; - //} - DownloadBufferToDevice(ProgramEntry, 0, dummyBuffer, opCode); - - return SUCCESS; -} - -//______________________________________________________________________________ - -FX3_FWDWNLOAD_ERROR_CODE CCyFX3Device::DownloadFw(char *fileName, FX3_FWDWNLOAD_MEDIA_TYPE enMediaType) -{ - UINT fwSize = 0; - PUCHAR FwImage; - FILE *FwImagePtr; - //int error; - -// error = fopen_s(&FwImagePtr, fileName, "rb"); - FwImagePtr = fopen( fileName, "rb"); - if (FwImagePtr == NULL) - return INVALID_FILE; - - /* Find the length of the image */ - fseek (FwImagePtr, 0, SEEK_END); - fwSize = ftell(FwImagePtr); - fseek (FwImagePtr, 0, SEEK_SET); - - /* Allocate memory for the image */ - FwImage = new unsigned char[fwSize]; - - if (FwImage == NULL) - return INVALID_FILE; - - if (fwSize <= 0) - { - fclose (FwImagePtr); - return INVALID_FILE; - } - - /* Read into buffer */ - fread (FwImage, fwSize, 1, FwImagePtr); - fclose (FwImagePtr); - - FX3_FWDWNLOAD_ERROR_CODE ErroCode = SUCCESS; - // call api to download the image - if (enMediaType == RAM) - ErroCode = DownloadFwToRam(FwImage, fwSize, 0xA0); - else if (enMediaType == I2CE2PROM) - ErroCode = DownloadUserIMGtoI2CE2PROM(FwImage, fwSize, 0xBA); - else if (enMediaType == SPIFLASH) - ErroCode = DownloadUserIMGtoSPIFLASH(FwImage, fwSize, 0xC4); - else - ErroCode = INVALID_MEDIA_TYPE; - - if(FwImage) - delete[] FwImage; - - return ErroCode; -} - -//______________________________________________________________________________ - -CCyIsoPktInfo* CCyIsocEndPoint::CreatePktInfos(LONG bufLen, int &packets) -{ - if(MaxPktSize==0) - return NULL; - - packets = bufLen / MaxPktSize; // Number of packets implied by bufLen & pktSize - if (bufLen % MaxPktSize) packets++; - - if (packets) { - CCyIsoPktInfo *isoPktInfos = new CCyIsoPktInfo[packets]; - return isoPktInfos; - } else - return NULL; - -} - -//////////////////////////////////////////////////////////////////////////////// -// -// The CCyBulkEndPoint Class -// -//////////////////////////////////////////////////////////////////////////////// - -CCyBulkEndPoint::CCyBulkEndPoint(void) : CCyUSBEndPoint() -{ -} - -CCyBulkEndPoint::CCyBulkEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor) : -CCyUSBEndPoint(h, pEndPtDescriptor) -{ - -} -CCyBulkEndPoint::CCyBulkEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor,USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR* SSEndPtDescriptor): -CCyUSBEndPoint(h, pEndPtDescriptor,SSEndPtDescriptor) -{ - -} -//______________________________________________________________________________ - -PUCHAR CCyBulkEndPoint::BeginDataXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov) -{ - if ( hDevice == INVALID_HANDLE_VALUE ) return NULL; - - if (XferMode == XMODE_DIRECT) - return BeginDirectXfer(buf, bufLen, ov); - else - return BeginBufferedXfer(buf, bufLen, ov); -} - - - -//////////////////////////////////////////////////////////////////////////////// -// -// The CCyInterruptEndPoint Class -// -//////////////////////////////////////////////////////////////////////////////// - -CCyInterruptEndPoint::CCyInterruptEndPoint(void) : CCyUSBEndPoint() -{ -} - -CCyInterruptEndPoint::CCyInterruptEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor) : -CCyUSBEndPoint(h, pEndPtDescriptor) -{ - -} -CCyInterruptEndPoint::CCyInterruptEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor,USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR* SSEndPtDescriptor): -CCyUSBEndPoint(h, pEndPtDescriptor,SSEndPtDescriptor) -{ -} - -//______________________________________________________________________________ - -PUCHAR CCyInterruptEndPoint::BeginDataXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov) -{ - if ( hDevice == INVALID_HANDLE_VALUE ) return NULL; - - if (XferMode == XMODE_DIRECT) - return BeginDirectXfer(buf, bufLen, ov); - else - return BeginBufferedXfer(buf, bufLen, ov); - -} -CCyUSBBOS::CCyUSBBOS(void) -{ - // initialize to null - pUSB20_DeviceExt = NULL; - pSS_DeviceCap = NULL; - pContainer_ID = NULL; -} -CCyUSBBOS::~CCyUSBBOS() -{ - if(pContainer_ID) - { - delete pContainer_ID; - pContainer_ID = NULL; - } - if(pUSB20_DeviceExt) - { - delete pUSB20_DeviceExt; - pUSB20_DeviceExt = NULL; - } - if(pSS_DeviceCap) - { - delete pSS_DeviceCap; - pSS_DeviceCap = NULL; - } -} - -CCyUSBBOS::CCyUSBBOS(HANDLE h,PUSB_BOS_DESCRIPTOR pBosDescrData) -{ - // initialize to null - pUSB20_DeviceExt = NULL; - pSS_DeviceCap = NULL; - pContainer_ID = NULL; - - bLength = pBosDescrData->bLength; - bDescriptorType = pBosDescrData->bDescriptorType; - bNumDeviceCaps = pBosDescrData->bNumDeviceCaps; - wTotalLength = pBosDescrData->wTotalLength; - - int totallen = wTotalLength; - totallen -=pBosDescrData->bLength; - - if (totallen < 0) - return; - - UCHAR* DevCap = (byte*)((byte*)pBosDescrData + pBosDescrData->bLength); // get nex descriptor - - for (int i = 0; i < bNumDeviceCaps; i++) - { - //check capability type - switch (DevCap[USB_BOS_DEVICE_CAPABILITY_TYPE_INDEX]) - { - case USB_BOS_CAPABILITY_TYPE_USB20_EXT: - { - PUSB_BOS_USB20_DEVICE_EXTENSION pUSB20_ext = (PUSB_BOS_USB20_DEVICE_EXTENSION)DevCap; - totallen -= pUSB20_ext->bLength; - DevCap = (byte *)DevCap +pUSB20_ext->bLength; - pUSB20_DeviceExt = new CCyBosUSB20Extesnion(h, pUSB20_ext); - break; - } - case USB_BOS_CAPABILITY_TYPE_SUPERSPEED_USB: - { - PUSB_BOS_SS_DEVICE_CAPABILITY pSS_Capability = (PUSB_BOS_SS_DEVICE_CAPABILITY)DevCap; - totallen -= pSS_Capability->bLength; - DevCap = (byte*)DevCap + pSS_Capability->bLength; - pSS_DeviceCap = new CCyBosSuperSpeedCapability(h, pSS_Capability); - break; - } - case USB_BOS_CAPABILITY_TYPE_CONTAINER_ID: - { - PUSB_BOS_CONTAINER_ID pUSB_ContainerID = (PUSB_BOS_CONTAINER_ID)DevCap; - totallen -= pUSB_ContainerID->bLength; - DevCap = (byte*)DevCap + pUSB_ContainerID->bLength; - pContainer_ID = new CCyBosContainerID(h, pUSB_ContainerID); - break; - } - default: - { - break; - } - } - if(totallen<0) - break; - } -} -CCyBosUSB20Extesnion::CCyBosUSB20Extesnion(void) -{} -CCyBosUSB20Extesnion::CCyBosUSB20Extesnion(HANDLE h,PUSB_BOS_USB20_DEVICE_EXTENSION pBosUsb20ExtDesc) -{ - bLength = pBosUsb20ExtDesc->bLength; - bDescriptorType = pBosUsb20ExtDesc->bDescriptorType; - bDevCapabilityType = pBosUsb20ExtDesc->bDevCapabilityType; - bmAttribute = pBosUsb20ExtDesc->bmAttribute; -} -CCyBosSuperSpeedCapability::CCyBosSuperSpeedCapability(void) -{} -CCyBosSuperSpeedCapability::CCyBosSuperSpeedCapability(HANDLE h,PUSB_BOS_SS_DEVICE_CAPABILITY pUSB_SuperSpeedUsb) -{ - bLength = pUSB_SuperSpeedUsb->bLength; - bDescriptorType = pUSB_SuperSpeedUsb->bDescriptorType; - bDevCapabilityType = pUSB_SuperSpeedUsb->bDevCapabilityType; - bFunctionalitySupporte = pUSB_SuperSpeedUsb->bFunctionalitySupporte; - SpeedsSuported = pUSB_SuperSpeedUsb->wSpeedsSuported; - bmAttribute = pUSB_SuperSpeedUsb->bmAttribute; - bU1DevExitLat = pUSB_SuperSpeedUsb->bU1DevExitLat; - bU2DevExitLat = pUSB_SuperSpeedUsb->bU2DevExitLat; -} -CCyBosContainerID::CCyBosContainerID(void) -{} -CCyBosContainerID::CCyBosContainerID(HANDLE handle, PUSB_BOS_CONTAINER_ID pUSB_ContainerID) -{ - bLength = pUSB_ContainerID->bLength; - bDescriptorType = pUSB_ContainerID->bDescriptorType; - bDevCapabilityType = pUSB_ContainerID->bDevCapabilityType; - for (int i = 0; i < USB_BOS_CAPABILITY_TYPE_CONTAINER_ID_SIZE; i++) - ContainerID[i] = pUSB_ContainerID->ContainerID[i]; -} diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/CyAPI.h b/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/CyAPI.h deleted file mode 100644 index 2e42075..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/CyAPI.h +++ /dev/null @@ -1,602 +0,0 @@ -/* - ## Cypress CyAPI C++ library header file (CyAPI.h) - ## ======================================================= - ## - ## Copyright Cypress Semiconductor Corporation, 2009-2012, - ## All Rights Reserved - ## UNPUBLISHED, LICENSED SOFTWARE. - ## - ## CONFIDENTIAL AND PROPRIETARY INFORMATION - ## WHICH IS THE PROPERTY OF CYPRESS. - ## - ## Use of this file is governed - ## by the license agreement included in the file - ## - ## /license/license.rtf - ## - ## where is the Cypress software - ## install root directory path. - ## - ## ======================================================= -*/ - -#ifndef CyUSBH -#define CyUSBH - -#include "cyusb30_def.h" - -/* Data straucture for the Vendor request and data */ -typedef struct vendorCmdData -{ - UCHAR *buf; /* Pointer to the data */ - UCHAR opCode; /* Vendor request code */ - UINT addr; /* Read/Write address */ - long size; /* Size of the read/write */ - bool isRead; /* Read or write */ -} vendorCmdData ; - -#ifndef __USB200_H__ -#define __USB200_H__ -#pragma pack(push,1) -typedef struct _USB_DEVICE_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - USHORT bcdUSB; - UCHAR bDeviceClass; - UCHAR bDeviceSubClass; - UCHAR bDeviceProtocol; - UCHAR bMaxPacketSize0; - USHORT idVendor; - USHORT idProduct; - USHORT bcdDevice; - UCHAR iManufacturer; - UCHAR iProduct; - UCHAR iSerialNumber; - UCHAR bNumConfigurations; -} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR; - -typedef struct _USB_ENDPOINT_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - UCHAR bEndpointAddress; - UCHAR bmAttributes; - USHORT wMaxPacketSize; - UCHAR bInterval; -} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR; - -typedef struct _USB_CONFIGURATION_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - USHORT wTotalLength; - UCHAR bNumInterfaces; - UCHAR bConfigurationValue; - UCHAR iConfiguration; - UCHAR bmAttributes; - UCHAR MaxPower; -} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR; - -typedef struct _USB_INTERFACE_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - UCHAR bInterfaceNumber; - UCHAR bAlternateSetting; - UCHAR bNumEndpoints; - UCHAR bInterfaceClass; - UCHAR bInterfaceSubClass; - UCHAR bInterfaceProtocol; - UCHAR iInterface; -} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR; - -typedef struct _USB_STRING_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - WCHAR bString[1]; -} USB_STRING_DESCRIPTOR, *PUSB_STRING_DESCRIPTOR; - -typedef struct _USB_COMMON_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; -} USB_COMMON_DESCRIPTOR, *PUSB_COMMON_DESCRIPTOR; -#pragma pack(pop) -#endif - -/*******************************************************************************/ -class CCyIsoPktInfo { -public: - LONG Status; - LONG Length; -}; - -/*******************************************************************************/ - - -/* {AE18AA60-7F6A-11d4-97DD-00010229B959} */ - -static GUID CYUSBDRV_GUID = {0xae18aa60, 0x7f6a, 0x11d4, {0x97, 0xdd, 0x0, 0x1, 0x2, 0x29, 0xb9, 0x59}}; - - -typedef enum {TGT_DEVICE, TGT_INTFC, TGT_ENDPT, TGT_OTHER } CTL_XFER_TGT_TYPE; -typedef enum {REQ_STD, REQ_CLASS, REQ_VENDOR } CTL_XFER_REQ_TYPE; -typedef enum {DIR_TO_DEVICE, DIR_FROM_DEVICE } CTL_XFER_DIR_TYPE; -typedef enum {XMODE_BUFFERED, XMODE_DIRECT } XFER_MODE_TYPE; - -const int MAX_ENDPTS = 32; -const int MAX_INTERFACES = 255; -const int USB_STRING_MAXLEN = 256; - -#define BUFSIZE_UPORT 2048 //4096 - CDT 130492 -typedef enum { RAM = 1, I2CE2PROM, SPIFLASH } FX3_FWDWNLOAD_MEDIA_TYPE ; -typedef enum { SUCCESS = 0, FAILED, INVALID_MEDIA_TYPE, INVALID_FWSIGNATURE, DEVICE_CREATE_FAILED, INCORRECT_IMAGE_LENGTH, INVALID_FILE, SPILASH_ERASE_FAILED, CORRUPT_FIRMWARE_IMAGE_FILE,I2CE2PROM_UNKNOWN_I2C_SIZE } FX3_FWDWNLOAD_ERROR_CODE; - -#define CYWB_BL_4_BYTES_COPY(destination,source) {memcpy((void *)(destination), (void *)(source), 4);} - -/******************************************************************************** -* -* The CCyEndPoint ABSTRACT Class -* -********************************************************************************/ -class CCyUSBEndPoint -{ -protected: - bool WaitForIO(OVERLAPPED *ovLapStatus); - - virtual PUCHAR BeginDirectXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov); - virtual PUCHAR BeginBufferedXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov); - -public: - - CCyUSBEndPoint(void); - CCyUSBEndPoint(CCyUSBEndPoint& ept); - CCyUSBEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor); - CCyUSBEndPoint(HANDLE hDev, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor,USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR* SSEndPtDescriptor); - - HANDLE hDevice; - - /* The fields of an EndPoint Descriptor */ - UCHAR DscLen; - UCHAR DscType; - UCHAR Address; - UCHAR Attributes; - USHORT MaxPktSize; - USHORT PktsPerFrame; - UCHAR Interval; - /* This are the fields for Super speed endpoint */ - UCHAR ssdscLen; - UCHAR ssdscType; - UCHAR ssmaxburst; /* Maximum number of packets endpoint can send in one burst */ - UCHAR ssbmAttribute; /* store endpoint attribute like for bulk it will be number of streams */ - USHORT ssbytesperinterval; - - /* Other fields */ - ULONG TimeOut; - ULONG UsbdStatus; - ULONG NtStatus; - - DWORD bytesWritten; - DWORD LastError; - bool bIn; - - XFER_MODE_TYPE XferMode; - - bool XferData(PUCHAR buf, LONG &len, CCyIsoPktInfo* pktInfos = NULL); - bool XferData(PUCHAR buf, LONG &bufLen, CCyIsoPktInfo* pktInfos, bool pktMode); - virtual PUCHAR BeginDataXfer(PUCHAR buf, LONG len, OVERLAPPED *ov) = 0; - virtual bool FinishDataXfer(PUCHAR buf, LONG &len, OVERLAPPED *ov, PUCHAR pXmitBuf, CCyIsoPktInfo* pktInfos = NULL); - bool WaitForXfer(OVERLAPPED *ov, ULONG tOut); - ULONG GetXferSize(void); - void SetXferSize(ULONG xfer); - - bool Reset(void); - bool Abort(void); -}; - - -/******************************************************************************** -* -* The Control Endpoint Class -* -********************************************************************************/ -class CCyControlEndPoint : public CCyUSBEndPoint -{ -public: - CCyControlEndPoint(void); - CCyControlEndPoint(CCyControlEndPoint& ept); - CCyControlEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor); - - CTL_XFER_TGT_TYPE Target; - CTL_XFER_REQ_TYPE ReqType; - CTL_XFER_DIR_TYPE Direction; - - UCHAR ReqCode; - WORD Value; - WORD Index; - - bool Read(PUCHAR buf, LONG &len); - bool Write(PUCHAR buf, LONG &len); - PUCHAR BeginDataXfer(PUCHAR buf, LONG len, OVERLAPPED *ov); -}; - - -/******************************************************************************** -* -* The Isoc Endpoint Class -* -********************************************************************************/ -class CCyIsocEndPoint : public CCyUSBEndPoint -{ - -protected: - virtual PUCHAR BeginDirectXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov); - virtual PUCHAR BeginBufferedXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov); - -public: - CCyIsocEndPoint(void); - CCyIsocEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor); - CCyIsocEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor,USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR* SSEndPtDescriptor); - - PUCHAR BeginDataXfer(PUCHAR buf, LONG len, OVERLAPPED *ov); - CCyIsoPktInfo* CreatePktInfos(LONG bufLen, int &packets); -}; - - -/******************************************************************************** -* -* The Bulk Endpoint Class -* -********************************************************************************/ -class CCyBulkEndPoint : public CCyUSBEndPoint -{ -public: - CCyBulkEndPoint(void); - CCyBulkEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor); - CCyBulkEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor,USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR* SSEndPtDescriptor); - - PUCHAR BeginDataXfer(PUCHAR buf, LONG len, OVERLAPPED *ov); -}; - - -/******************************************************************************** -* -* The Interrupt Endpoint Class -* -********************************************************************************/ -class CCyInterruptEndPoint : public CCyUSBEndPoint -{ -public: - CCyInterruptEndPoint(void); - CCyInterruptEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor); - CCyInterruptEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor,USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR* SSEndPtDescriptor); - - PUCHAR BeginDataXfer(PUCHAR buf, LONG len, OVERLAPPED *ov); -}; - - -/******************************************************************************** -* -* The Interface Class -* -********************************************************************************/ -class CCyUSBInterface -{ -public: - CCyUSBEndPoint *EndPoints[MAX_ENDPTS]; /* Holds pointers to all the interface's endpoints, - plus a pointer to the Control endpoint zero */ - UCHAR bLength; - UCHAR bDescriptorType; - UCHAR bInterfaceNumber; - UCHAR bAlternateSetting; - UCHAR bNumEndpoints; /* Not counting the control endpoint */ - UCHAR bInterfaceClass; - UCHAR bInterfaceSubClass; - UCHAR bInterfaceProtocol; - UCHAR iInterface; - - UCHAR bAltSettings; - USHORT wTotalLength; /* Needed in case Intfc has additional (non-endpt) descriptors */ - - CCyUSBInterface(HANDLE handle, PUSB_INTERFACE_DESCRIPTOR pIntfcDescriptor,UCHAR usb30Dummy); - CCyUSBInterface(HANDLE h, PUSB_INTERFACE_DESCRIPTOR pIntfcDescriptor); - CCyUSBInterface(CCyUSBInterface& ifc); /* Copy Constructor */ - ~CCyUSBInterface(void); - -}; - - -/******************************************************************************** -* -* The Config Class -* -********************************************************************************/ -class CCyUSBConfig -{ -public: - CCyUSBInterface *Interfaces[MAX_INTERFACES]; - - UCHAR bLength; - UCHAR bDescriptorType; - USHORT wTotalLength; - UCHAR bNumInterfaces; - UCHAR bConfigurationValue; - UCHAR iConfiguration; - UCHAR bmAttributes; - UCHAR MaxPower; - - UCHAR AltInterfaces; - - CCyUSBConfig(void); - CCyUSBConfig(CCyUSBConfig& cfg); /* Copy Constructor */ - CCyUSBConfig(HANDLE h, PUSB_CONFIGURATION_DESCRIPTOR pConfigDescr); - CCyUSBConfig(HANDLE h, PUSB_CONFIGURATION_DESCRIPTOR pConfigDescr,UCHAR usb30Dummy); - ~CCyUSBConfig(void); -}; - - -/******************************************************************************** -* -* The Bos USB20 Extesnion Class -* -********************************************************************************/ -class CCyBosUSB20Extesnion -{ -public: - UCHAR bLength; /* Descriptor length */ - UCHAR bDescriptorType; /* Descriptor Type */ - UCHAR bDevCapabilityType; /* Device capability type */ - UINT bmAttribute; /* Bitmap encoding for supprted feature and Link power managment supprted if set */ - - CCyBosUSB20Extesnion(void); - CCyBosUSB20Extesnion(HANDLE h,PUSB_BOS_USB20_DEVICE_EXTENSION BosUsb20ExtDesc); -}; - - -/******************************************************************************** -* -* The Bos SuperSpeed Capability Class -* -********************************************************************************/ -class CCyBosSuperSpeedCapability -{ -public: - UCHAR bLength; - UCHAR bDescriptorType; - UCHAR bDevCapabilityType; - UCHAR bmAttribute; - USHORT SpeedsSuported; - UCHAR bFunctionalitySupporte; - UCHAR bU1DevExitLat; - USHORT bU2DevExitLat; - - CCyBosSuperSpeedCapability(void); - CCyBosSuperSpeedCapability(HANDLE h,PUSB_BOS_SS_DEVICE_CAPABILITY pUSB_SuperSpeedUsb); - -}; - - -/******************************************************************************** -* -* The Bos Container ID Class -* -********************************************************************************/ -class CCyBosContainerID -{ -public: - UCHAR bLength; /* Descriptor length */ - UCHAR bDescriptorType; /* Descriptor Type */ - UCHAR bDevCapabilityType; /* Device capability type */ - UCHAR bReserved; /* no use */ - UCHAR ContainerID[USB_BOS_CAPABILITY_TYPE_CONTAINER_ID_SIZE]; /* UUID */ - - CCyBosContainerID(void); - CCyBosContainerID(HANDLE h,PUSB_BOS_CONTAINER_ID pContainerID); -}; - - -/******************************************************************************** -* -* The USB BOS Class -* -********************************************************************************/ -class CCyUSBBOS -{ -public: - - CCyBosContainerID *pContainer_ID; - CCyBosUSB20Extesnion *pUSB20_DeviceExt; - CCyBosSuperSpeedCapability *pSS_DeviceCap; - - UCHAR bLength; /* Descriptor length */ - UCHAR bDescriptorType; /* Descriptor Type */ - USHORT wTotalLength; /* Total length of descriptor ( icluding device capabilty */ - UCHAR bNumDeviceCaps; /* Number of device capability descriptors in BOS */ - - CCyUSBBOS(void); - CCyUSBBOS(HANDLE h,PUSB_BOS_DESCRIPTOR pBosDescrData); - ~CCyUSBBOS(); -}; - -/********************************************************************************* -* -* The USB Device Class - This is the main class that contains members of all the -* other classes. -* -* To use the library, create an instance of this Class and call it's Open method. -* -*********************************************************************************/ -class CCyUSBDevice -{ - /* The public members are accessible (i.e. corruptible) by the user of the library - * Algorithms of the class don't rely on any public members. Instead, they use the - * private members of the class for their calculations. */ - -public: - - CCyUSBDevice(HANDLE hnd = NULL, GUID guid = CYUSBDRV_GUID, BOOL bOpen = true); - ~CCyUSBDevice(void); - - CCyUSBEndPoint **EndPoints; /* Shortcut to USBCfgs[CfgNum]->Interfaces[IntfcIndex]->Endpoints */ - CCyUSBEndPoint *EndPointOf(UCHAR addr); - - CCyUSBBOS *UsbBos; - CCyIsocEndPoint *IsocInEndPt; - CCyIsocEndPoint *IsocOutEndPt; - CCyBulkEndPoint *BulkInEndPt; - CCyBulkEndPoint *BulkOutEndPt; - CCyControlEndPoint *ControlEndPt; - CCyInterruptEndPoint *InterruptInEndPt; - CCyInterruptEndPoint *InterruptOutEndPt; - - - USHORT StrLangID; - ULONG LastError; - ULONG UsbdStatus; - ULONG NtStatus; - ULONG DriverVersion; - ULONG USBDIVersion; - char DeviceName[USB_STRING_MAXLEN]; - char FriendlyName[USB_STRING_MAXLEN]; - wchar_t Manufacturer[USB_STRING_MAXLEN]; - wchar_t Product[USB_STRING_MAXLEN]; - wchar_t SerialNumber[USB_STRING_MAXLEN]; - - CHAR DevPath[USB_STRING_MAXLEN]; - - USHORT BcdUSB; - USHORT VendorID; - USHORT ProductID; - UCHAR USBAddress; - UCHAR DevClass; - UCHAR DevSubClass; - UCHAR DevProtocol; - INT MaxPacketSize; - USHORT BcdDevice; - - UCHAR ConfigValue; - UCHAR ConfigAttrib; - UCHAR MaxPower; - - UCHAR IntfcClass; - UCHAR IntfcSubClass; - UCHAR IntfcProtocol; - bool bHighSpeed; - bool bSuperSpeed; - - DWORD BytesXfered; - - UCHAR DeviceCount(void); - UCHAR ConfigCount(void); - UCHAR IntfcCount(void); - UCHAR AltIntfcCount(void); - UCHAR EndPointCount(void); - - void SetConfig(UCHAR cfg); - UCHAR Config(void) { return CfgNum; } /* Normally 0 */ - UCHAR Interface(void) { return IntfcNum; } /* Usually 0 */ - - /* No SetInterface method since only 1 intfc per device (per Windows) */ - UCHAR AltIntfc(void); - bool SetAltIntfc(UCHAR alt); - - GUID DriverGUID(void) { return DrvGuid; } - HANDLE DeviceHandle(void) { return hDevice; } - void UsbdStatusString(ULONG stat, PCHAR s); - bool CreateHandle(UCHAR dev); - void DestroyHandle(); - - bool Open(UCHAR dev); - void Close(void); - bool Reset(void); - bool ReConnect(void); - bool Suspend(void); - bool Resume(void); - bool IsOpen(void) { return (hDevice != INVALID_HANDLE_VALUE); } - - UCHAR PowerState(void); - - bool GetBosDescriptor(PUSB_BOS_DESCRIPTOR descr); - bool GetBosUSB20DeviceExtensionDescriptor(PUSB_BOS_USB20_DEVICE_EXTENSION descr); - bool GetBosContainedIDDescriptor(PUSB_BOS_CONTAINER_ID descr); - bool GetBosSSCapabilityDescriptor(PUSB_BOS_SS_DEVICE_CAPABILITY descr); - - void GetDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR descr); - void GetConfigDescriptor(PUSB_CONFIGURATION_DESCRIPTOR descr); - void GetIntfcDescriptor(PUSB_INTERFACE_DESCRIPTOR descr); - CCyUSBConfig GetUSBConfig(int index); - -private: - - USB_DEVICE_DESCRIPTOR USBDeviceDescriptor; - PUSB_CONFIGURATION_DESCRIPTOR USBConfigDescriptors[2]; - PUSB_BOS_DESCRIPTOR pUsbBosDescriptor; - - CCyUSBConfig *USBCfgs[2]; - - HANDLE hWnd; - HANDLE hDevice; - HANDLE hDevNotification; - HANDLE hHndNotification; - - GUID DrvGuid; - - UCHAR Devices; - UCHAR Interfaces; - UCHAR AltInterfaces; - UCHAR Configs; - - UCHAR DevNum; - UCHAR CfgNum; - UCHAR IntfcNum; /* The current selected interface's bInterfaceNumber */ - UCHAR IntfcIndex; /* The entry in the Config's interfaces table matching to IntfcNum and AltSetting */ - - bool GetInternalBosDescriptor(); - void GetDevDescriptor(void); - void GetCfgDescriptor(int descIndex); - void GetString(wchar_t *s, UCHAR sIndex); - void SetStringDescrLanguage(void); - void SetAltIntfcParams(UCHAR alt); - bool IoControl(ULONG cmd, PUCHAR buf, ULONG len); - - void SetEndPointPtrs(void); - void GetDeviceName(void); - void GetFriendlyName(void); - void GetDriverVer(void); - void GetUSBDIVer(void); - void GetSpeed(void); - void GetUSBAddress(void); - //void CloseEndPtHandles(void); - - bool RegisterForPnpEvents(HANDLE h); -}; - - -/******************************************************************************** -* -* The FX3 Device Class -* -********************************************************************************/ -class CCyFX3Device: public CCyUSBDevice -{ -public: - CCyFX3Device(void); - ~CCyFX3Device(void); - bool IsBootLoaderRunning(); - FX3_FWDWNLOAD_ERROR_CODE DownloadFw(char *fileName, FX3_FWDWNLOAD_MEDIA_TYPE enMediaType); - FX3_FWDWNLOAD_ERROR_CODE DownloadFwToRam(const UCHAR *buffer_p, UINT fw_size, UCHAR opCode = 0xA0); - -private: - - bool Ep0VendorCommand(vendorCmdData cmdData); - bool SetProgramEntry(UCHAR opCode,UINT start_addr); - - bool DownloadBufferToDevice(UINT start_addr, USHORT count, UCHAR *data_buf, UCHAR opCode); - bool UploadBufferFromDevice(UINT start_addr, USHORT count, UCHAR *data_buf, UCHAR opCode); - - FX3_FWDWNLOAD_ERROR_CODE DownloadUserIMGtoI2CE2PROM(PUCHAR buffer_p, UINT fw_size, UCHAR opCode); - FX3_FWDWNLOAD_ERROR_CODE DownloadUserIMGtoSPIFLASH(PUCHAR buffer_p, UINT fw_size, UCHAR opCode); - - FX3_FWDWNLOAD_ERROR_CODE EraseSectorOfSPIFlash(UINT SectorNumber, UCHAR opCode); - bool WriteToSPIFlash(PUCHAR Buf, UINT buflen, UINT ByteAddress, UCHAR opCode); -}; - -/********************************************************************************/ - -#endif diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/CyUSB30_def.h b/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/CyUSB30_def.h deleted file mode 100644 index 878349b..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/CyUSB30_def.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - ## Cypress CyAPI C++ library USB3.0 defination header file (CyUSB30_def.h) - ## ======================================================= - ## - ## Copyright Cypress Semiconductor Corporation, 2009-2012, - ## All Rights Reserved - ## UNPUBLISHED, LICENSED SOFTWARE. - ## - ## CONFIDENTIAL AND PROPRIETARY INFORMATION - ## WHICH IS THE PROPERTY OF CYPRESS. - ## - ## Use of this file is governed - ## by the license agreement included in the file - ## - ## /license/license.rtf - ## - ## where is the Cypress software - ## install root directory path. - ## - ## ======================================================= -*/ -#ifndef _CYUSB30_H -#define _CYUSB30_H - -//#pragma pack(1) -#pragma pack(push, 1) -// USB3.0 specific constant defination -#define BCDUSBJJMASK 0xFF00 //(0xJJMN JJ - Major version,M Minor version, N sub-minor vesion) -#define USB30MAJORVER 0x0300 -#define USB20MAJORVER 0x0200 - -#define USB_BOS_DESCRIPTOR_TYPE 0x0F -#define USB_DEVICE_CAPABILITY 0x10 -#define USB_SUPERSPEED_ENDPOINT_COMPANION 0x30 -#define USB_BOS_CAPABILITY_TYPE_Wireless_USB 0x01 -#define USB_BOS_CAPABILITY_TYPE_USB20_EXT 0x02 -#define USB_BOS_CAPABILITY_TYPE_SUPERSPEED_USB 0x03 -#define USB_BOS_CAPABILITY_TYPE_CONTAINER_ID 0x04 -#define USB_BOS_CAPABILITY_TYPE_CONTAINER_ID_SIZE 0x10 - -#define USB_BOS_DEVICE_CAPABILITY_TYPE_INDEX 0x2 -//constant defination -typedef struct _USB_BOS_DESCRIPTOR -{ - UCHAR bLength;/* Descriptor length*/ - UCHAR bDescriptorType;/* Descriptor Type */ - USHORT wTotalLength;/* Total length of descriptor ( icluding device capability*/ - UCHAR bNumDeviceCaps;/* Number of device capability descriptors in BOS */ -}USB_BOS_DESCRIPTOR,*PUSB_BOS_DESCRIPTOR; - -typedef struct _USB_BOS_USB20_DEVICE_EXTENSION -{ - UCHAR bLength;/* Descriptor length*/ - UCHAR bDescriptorType;/* Descriptor Type */ - UCHAR bDevCapabilityType;/* Device capability type*/ - UINT bmAttribute;// Bitmap encoding for supprted feature and Link power managment supprted if set -}USB_BOS_USB20_DEVICE_EXTENSION,*PUSB_BOS_USB20_DEVICE_EXTENSION; - -typedef struct _USB_BOS_SS_DEVICE_CAPABILITY -{ - UCHAR bLength;/* Descriptor length*/ - UCHAR bDescriptorType;/* Descriptor Type */ - UCHAR bDevCapabilityType;/* Device capability type*/ - UCHAR bmAttribute;// Bitmap encoding for supprted feature and Link power managment supprted if set - USHORT wSpeedsSuported;//low speed supported if set,full speed supported if set,high speed supported if set,super speed supported if set,15:4 nt used - UCHAR bFunctionalitySupporte; - UCHAR bU1DevExitLat;//U1 device exit latency - USHORT bU2DevExitLat;//U2 device exit latency -}USB_BOS_SS_DEVICE_CAPABILITY,*PUSB_BOS_SS_DEVICE_CAPABILITY; - -typedef struct _USB_BOS_CONTAINER_ID -{ - UCHAR bLength;/* Descriptor length*/ - UCHAR bDescriptorType;/* Descriptor Type */ - UCHAR bDevCapabilityType;/* Device capability type*/ - UCHAR bReserved; // no use - UCHAR ContainerID[USB_BOS_CAPABILITY_TYPE_CONTAINER_ID_SIZE];/* UUID */ -}USB_BOS_CONTAINER_ID,*PUSB_BOS_CONTAINER_ID; - -typedef struct _USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR -{ - UCHAR bLength; - UCHAR bDescriptorType; - UCHAR bMaxBurst; - UCHAR bmAttributes; - USHORT bBytesPerInterval; -}USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR,*PUSB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR; -#pragma pack(pop) -#endif /*_CYUSB30_H*/ - diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/UsbdStatus.h b/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/UsbdStatus.h deleted file mode 100644 index e2bbaa0..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/UsbdStatus.h +++ /dev/null @@ -1,46 +0,0 @@ - -// Note: see usbdi.h in the DDK for the USBD_STATUS source definitions -typedef LONG USBD_STATUS; -#define USBD_STATUS(Status) ((ULONG)(Status) & 0x0FFFFFFFL) -#define USBD_STATE(Status) ((ULONG)(Status) & 0xF0000000L) - -// HC status codes (Note: both error and stall bit are set) -#define USBD_STATUS_SUCCESS ((USBD_STATUS)0x00000000L) -#define USBD_STATUS_PENDING ((USBD_STATUS)0x40000000L) -#define USBD_STATUS_HALTED ((USBD_STATUS)0xC0000000L) -#define USBD_STATUS_ERROR ((USBD_STATUS)0x80000000L) - -#define USBD_STATUS_CRC ((USBD_STATUS)0xC0000001L) -#define USBD_STATUS_BTSTUFF ((USBD_STATUS)0xC0000002L) -#define USBD_STATUS_DATA_TOGGLE_MISMATCH ((USBD_STATUS)0xC0000003L) -#define USBD_STATUS_STALL_PID ((USBD_STATUS)0xC0000004L) -#define USBD_STATUS_DEV_NOT_RESPONDING ((USBD_STATUS)0xC0000005L) -#define USBD_STATUS_PID_CHECK_FAILURE ((USBD_STATUS)0xC0000006L) -#define USBD_STATUS_UNEXPECTED_PID ((USBD_STATUS)0xC0000007L) -#define USBD_STATUS_DATA_OVERRUN ((USBD_STATUS)0xC0000008L) -#define USBD_STATUS_DATA_UNDERRUN ((USBD_STATUS)0xC0000009L) -#define USBD_STATUS_RESERVED1 ((USBD_STATUS)0xC000000AL) -#define USBD_STATUS_RESERVED2 ((USBD_STATUS)0xC000000BL) -#define USBD_STATUS_BUFFER_OVERRUN ((USBD_STATUS)0xC000000CL) -#define USBD_STATUS_BUFFER_UNDERRUN ((USBD_STATUS)0xC000000DL) -#define USBD_STATUS_NOT_ACCESSED ((USBD_STATUS)0xC000000FL) -#define USBD_STATUS_FIFO ((USBD_STATUS)0xC0000010L) - -#define USBD_STATUS_ENDPOINT_HALTED ((USBD_STATUS)0xC0000030L) -#define USBD_STATUS_NO_MEMORY ((USBD_STATUS)0x80000100L) -#define USBD_STATUS_INVALID_URB_FUNCTION ((USBD_STATUS)0x80000200L) -#define USBD_STATUS_INVALID_PARAMETER ((USBD_STATUS)0x80000300L) -#define USBD_STATUS_ERROR_BUSY ((USBD_STATUS)0x80000400L) -#define USBD_STATUS_REQUEST_FAILED ((USBD_STATUS)0x80000500L) -#define USBD_STATUS_INVALID_PIPE_HANDLE ((USBD_STATUS)0x80000600L) -#define USBD_STATUS_NO_BANDWIDTH ((USBD_STATUS)0x80000700L) -#define USBD_STATUS_INTERNAL_HC_ERROR ((USBD_STATUS)0x80000800L) -#define USBD_STATUS_ERROR_SHORT_TRANSFER ((USBD_STATUS)0x80000900L) -#define USBD_STATUS_BAD_START_FRAME ((USBD_STATUS)0xC0000A00L) -#define USBD_STATUS_ISOCH_REQUEST_FAILED ((USBD_STATUS)0xC0000B00L) -#define USBD_STATUS_FRAME_CONTROL_OWNED ((USBD_STATUS)0xC0000C00L) -#define USBD_STATUS_FRAME_CONTROL_NOT_OWNED ((USBD_STATUS)0xC0000D00L) -#define USBD_STATUS_CANCELED ((USBD_STATUS)0x00010000L) -#define USBD_STATUS_CANCELING ((USBD_STATUS)0x00020000L) - - diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/VersionNo.h b/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/VersionNo.h deleted file mode 100644 index 50a937c..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/VersionNo.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - ## Cypress CyAPI C++ library version number header file (VersionNo.h) - ## ======================================================= - ## - ## Copyright Cypress Semiconductor Corporation, 2009-2012, - ## All Rights Reserved - ## UNPUBLISHED, LICENSED SOFTWARE. - ## - ## CONFIDENTIAL AND PROPRIETARY INFORMATION - ## WHICH IS THE PROPERTY OF CYPRESS. - ## - ## Use of this file is governed - ## by the license agreement included in the file - ## - ## /license/license.rtf - ## - ## where is the Cypress software - ## install root directory path. - ## - ## ======================================================= -*/ -#define FILEVER 1,2,1,0 -#define PRODUCTVER 1,2,1,0 -#define STRFILEVER "1, 2, 1, 0" -#define STRPRODUCTVER "1, 2, 1, 0" -#define STRFILEVER_ASSENBLY "1.2.1.0" diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/cyioctl.h b/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/cyioctl.h deleted file mode 100644 index 1a905b5..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/cyioctl.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - ## Cypress CyAPI C++ library IOCTL defination header file (cyioctl.h) - ## ======================================================= - ## - ## Copyright Cypress Semiconductor Corporation, 2009-2012, - ## All Rights Reserved - ## UNPUBLISHED, LICENSED SOFTWARE. - ## - ## CONFIDENTIAL AND PROPRIETARY INFORMATION - ## WHICH IS THE PROPERTY OF CYPRESS. - ## - ## Use of this file is governed - ## by the license agreement included in the file - ## - ## /license/license.rtf - ## - ## where is the Cypress software - ## install root directory path. - ## - ## ======================================================= -*/ -#ifndef __IOCTL_H__ -#define __IOCTL_H__ - - -#ifndef DRIVER - -#ifndef CTL_CODE -#include "devioctl.h" -#endif - -#ifndef BM_REQUEST_TYPE -#include "usb200.h" -#endif - -#include - -#define DIR_HOST_TO_DEVICE 0 -#define DIR_DEVICE_TO_HOST 1 - -#define DEVICE_SPEED_UNKNOWN 0x00000000 -#define DEVICE_SPEED_LOW_FULL 0x00000001 -#define DEVICE_SPEED_HIGH 0x00000002 -#define DEVICE_SPEED_SUPER 0x00000004 - -typedef struct _WORD_SPLIT { - UCHAR lowByte; - UCHAR hiByte; -} WORD_SPLIT, *PWORD_SPLIT; - -typedef struct _BM_REQ_TYPE { - UCHAR Recipient:2; - UCHAR Reserved:3; - UCHAR Type:2; - UCHAR Direction:1; -} BM_REQ_TYPE, *PBM_REQ_TYPE; - -typedef struct _SETUP_PACKET { - - union { - BM_REQ_TYPE bmReqType; - UCHAR bmRequest; - }; - - UCHAR bRequest; - - union { - WORD_SPLIT wVal; - USHORT wValue; - }; - - union { - WORD_SPLIT wIndx; - USHORT wIndex; - }; - - union { - WORD_SPLIT wLen; - USHORT wLength; - }; - - ULONG ulTimeOut; - -} SETUP_PACKET, *PSETUP_PACKET; - -#define USB_ISO_ID 0x4945 -#define USB_ISO_CMD_ASAP 0x8000 -#define USB_ISO_CMD_CURRENT_FRAME 0x8001 -#define USB_ISO_CMD_SET_FRAME 0x8002 - -typedef struct _ISO_ADV_PARAMS { - - USHORT isoId; - USHORT isoCmd; - - ULONG ulParam1; - ULONG ulParam2; - -} ISO_ADV_PARAMS, *PISO_ADV_PARAMS; - -typedef struct _ISO_PACKET_INFO { - ULONG Status; - ULONG Length; -} ISO_PACKET_INFO, *PISO_PACKET_INFO; - - -typedef struct _SINGLE_TRANSFER { - union { - SETUP_PACKET SetupPacket; - ISO_ADV_PARAMS IsoParams; - }; - - UCHAR reserved; - - UCHAR ucEndpointAddress; - ULONG NtStatus; - ULONG UsbdStatus; - ULONG IsoPacketOffset; - ULONG IsoPacketLength; - ULONG BufferOffset; - ULONG BufferLength; -} SINGLE_TRANSFER, *PSINGLE_TRANSFER; - -#endif // #ifndef DRIVER - -typedef struct _SET_TRANSFER_SIZE_INFO { - UCHAR EndpointAddress; - ULONG TransferSize; -} SET_TRANSFER_SIZE_INFO, *PSET_TRANSFER_SIZE_INFO; - - -// -// Macro to extract function out of the device io control code -// -#ifdef WIN_98_DDK -#define DEVICE_TYPE_FROM_CTL_CODE(ctrlCode) (((ULONG)(ctrlCode & 0xffff0000)) >> 16) -#endif -#define FUNCTION_FROM_CTL_CODE(ctrlCode) (((ULONG)(ctrlCode & 0x00003FFC)) >> 2) -#define ACCESS_FROM_CTL_CODE(ctrlCode) (((ULONG)(ctrlCode & 0x000C0000)) >> 14) -//#define METHOD_FROM_CTL_CODE(ctrlCode) (((ULONG)(ctrlCode & 0x00000003))) - - -#define IOCTL_ADAPT_INDEX 0x0000 - -// Get the driver version -#define IOCTL_ADAPT_GET_DRIVER_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Get the current USBDI version -#define IOCTL_ADAPT_GET_USBDI_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+1, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Get the current device alt interface settings from driver -#define IOCTL_ADAPT_GET_ALT_INTERFACE_SETTING CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+2, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Set the device interface and alt interface setting -#define IOCTL_ADAPT_SELECT_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+3, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Get device address from driver -#define IOCTL_ADAPT_GET_ADDRESS CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+4, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Get number of endpoints for current interface and alt interface setting from driver -#define IOCTL_ADAPT_GET_NUMBER_ENDPOINTS CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+5, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Get the current device power state -#define IOCTL_ADAPT_GET_DEVICE_POWER_STATE CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+6, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Set the device power state -#define IOCTL_ADAPT_SET_DEVICE_POWER_STATE CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+7, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Send a raw packet to endpoint 0 -#define IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+8, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Send/receive data to/from nonep0 -#define IOCTL_ADAPT_SEND_NON_EP0_TRANSFER CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+9, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Simulate a disconnect/reconnect -#define IOCTL_ADAPT_CYCLE_PORT CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+10, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Reset the pipe -#define IOCTL_ADAPT_RESET_PIPE CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+11, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Reset the device -#define IOCTL_ADAPT_RESET_PARENT_PORT CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+12, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Get the current transfer size of an endpoint (in number of bytes) -#define IOCTL_ADAPT_GET_TRANSFER_SIZE CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+13, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Set the transfer size of an endpoint (in number of bytes) -#define IOCTL_ADAPT_SET_TRANSFER_SIZE CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+14, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Return the name of the device -#define IOCTL_ADAPT_GET_DEVICE_NAME CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+15, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Return the "Friendly Name" of the device -#define IOCTL_ADAPT_GET_FRIENDLY_NAME CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+16, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Abort all outstanding transfers on the pipe -#define IOCTL_ADAPT_ABORT_PIPE CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+17, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Send/receive data to/from nonep0 w/ direct buffer acccess (no buffering) -#define IOCTL_ADAPT_SEND_NON_EP0_DIRECT CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+18, METHOD_NEITHER, FILE_ANY_ACCESS) - -// Return device speed -#define IOCTL_ADAPT_GET_DEVICE_SPEED CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+19, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// Get the current USB frame number -#define IOCTL_ADAPT_GET_CURRENT_FRAME CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_ADAPT_INDEX+20, METHOD_BUFFERED, FILE_ANY_ACCESS) - -#define NUMBER_OF_ADAPT_IOCTLS 21 // Last IOCTL_ADAPT_INDEX + 1 - - -#include - -#endif // __IOCTL_H__ diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/devioctl.h b/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/devioctl.h deleted file mode 100644 index f10aa95..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/devioctl.h +++ /dev/null @@ -1,184 +0,0 @@ -/***************************************************************************** -* * -* OpenNI 1.x Alpha * -* Copyright (C) 2012 PrimeSense Ltd. * -* * -* This file is part of OpenNI. * -* * -* Licensed under the Apache License, Version 2.0 (the "License"); * -* you may not use this file except in compliance with the License. * -* You may obtain a copy of the License at * -* * -* http://www.apache.org/licenses/LICENSE-2.0 * -* * -* Unless required by applicable law or agreed to in writing, software * -* distributed under the License is distributed on an "AS IS" BASIS, * -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * -* See the License for the specific language governing permissions and * -* limitations under the License. * -* * -*****************************************************************************/ -/*++ BUILD Version: 0004 // Increment this if a change has global effects - -Copyright (c) 1992-1999 Microsoft Corporation - -Module Name: - - devioctl.h - -Abstract: - - This module contains - - -Revision History: - - ---*/ - -// begin_winioctl - -#ifndef _DEVIOCTL_ -#define _DEVIOCTL_ - -// begin_ntddk begin_wdm begin_nthal begin_ntifs -// -// Define the various device type values. Note that values used by Microsoft -// Corporation are in the range 0-32767, and 32768-65535 are reserved for use -// by customers. -// - -#define DEVICE_TYPE ULONG - -#define FILE_DEVICE_BEEP 0x00000001 -#define FILE_DEVICE_CD_ROM 0x00000002 -#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 -#define FILE_DEVICE_CONTROLLER 0x00000004 -#define FILE_DEVICE_DATALINK 0x00000005 -#define FILE_DEVICE_DFS 0x00000006 -#define FILE_DEVICE_DISK 0x00000007 -#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 -#define FILE_DEVICE_FILE_SYSTEM 0x00000009 -#define FILE_DEVICE_INPORT_PORT 0x0000000a -#define FILE_DEVICE_KEYBOARD 0x0000000b -#define FILE_DEVICE_MAILSLOT 0x0000000c -#define FILE_DEVICE_MIDI_IN 0x0000000d -#define FILE_DEVICE_MIDI_OUT 0x0000000e -#define FILE_DEVICE_MOUSE 0x0000000f -#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 -#define FILE_DEVICE_NAMED_PIPE 0x00000011 -#define FILE_DEVICE_NETWORK 0x00000012 -#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 -#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 -#define FILE_DEVICE_NULL 0x00000015 -#define FILE_DEVICE_PARALLEL_PORT 0x00000016 -#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 -#define FILE_DEVICE_PRINTER 0x00000018 -#define FILE_DEVICE_SCANNER 0x00000019 -#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001a -#define FILE_DEVICE_SERIAL_PORT 0x0000001b -#define FILE_DEVICE_SCREEN 0x0000001c -#define FILE_DEVICE_SOUND 0x0000001d -#define FILE_DEVICE_STREAMS 0x0000001e -#define FILE_DEVICE_TAPE 0x0000001f -#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 -#define FILE_DEVICE_TRANSPORT 0x00000021 -#define FILE_DEVICE_UNKNOWN 0x00000022 -#define FILE_DEVICE_VIDEO 0x00000023 -#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 -#define FILE_DEVICE_WAVE_IN 0x00000025 -#define FILE_DEVICE_WAVE_OUT 0x00000026 -#define FILE_DEVICE_8042_PORT 0x00000027 -#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 -#define FILE_DEVICE_BATTERY 0x00000029 -#define FILE_DEVICE_BUS_EXTENDER 0x0000002a -#define FILE_DEVICE_MODEM 0x0000002b -#define FILE_DEVICE_VDM 0x0000002c -#define FILE_DEVICE_MASS_STORAGE 0x0000002d -#define FILE_DEVICE_SMB 0x0000002e -#define FILE_DEVICE_KS 0x0000002f -#define FILE_DEVICE_CHANGER 0x00000030 -#define FILE_DEVICE_SMARTCARD 0x00000031 -#define FILE_DEVICE_ACPI 0x00000032 -#define FILE_DEVICE_DVD 0x00000033 -#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 -#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035 -#define FILE_DEVICE_DFS_VOLUME 0x00000036 -#define FILE_DEVICE_SERENUM 0x00000037 -#define FILE_DEVICE_TERMSRV 0x00000038 -#define FILE_DEVICE_KSEC 0x00000039 -#define FILE_DEVICE_FIPS 0x0000003A -#define FILE_DEVICE_INFINIBAND 0x0000003B -#define FILE_DEVICE_VMBUS 0x0000003E -#define FILE_DEVICE_CRYPT_PROVIDER 0x0000003F -#define FILE_DEVICE_WPD 0x00000040 -#define FILE_DEVICE_BLUETOOTH 0x00000041 -#define FILE_DEVICE_MT_COMPOSITE 0x00000042 -#define FILE_DEVICE_MT_TRANSPORT 0x00000043 -#define FILE_DEVICE_BIOMETRIC 0x00000044 -#define FILE_DEVICE_PMI 0x00000045 - -// -// Macro definition for defining IOCTL and FSCTL function control codes. Note -// that function codes 0-2047 are reserved for Microsoft Corporation, and -// 2048-4095 are reserved for customers. -// - -#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ - ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ -) - -// -// Macro to extract device type out of the device io control code -// -#define DEVICE_TYPE_FROM_CTL_CODE(ctrlCode) (((ULONG)(ctrlCode & 0xffff0000)) >> 16) - -// -// Macro to extract buffering method out of the device io control code -// -#define METHOD_FROM_CTL_CODE(ctrlCode) ((ULONG)(ctrlCode & 3)) - -// -// Define the method codes for how buffers are passed for I/O and FS controls -// - -#define METHOD_BUFFERED 0 -#define METHOD_IN_DIRECT 1 -#define METHOD_OUT_DIRECT 2 -#define METHOD_NEITHER 3 - -// -// Define some easier to comprehend aliases: -// METHOD_DIRECT_TO_HARDWARE (writes, aka METHOD_IN_DIRECT) -// METHOD_DIRECT_FROM_HARDWARE (reads, aka METHOD_OUT_DIRECT) -// - -#define METHOD_DIRECT_TO_HARDWARE METHOD_IN_DIRECT -#define METHOD_DIRECT_FROM_HARDWARE METHOD_OUT_DIRECT - -// -// Define the access check value for any access -// -// -// The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in -// ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these -// constants *MUST* always be in sync. -// -// -// FILE_SPECIAL_ACCESS is checked by the NT I/O system the same as FILE_ANY_ACCESS. -// The file systems, however, may add additional access checks for I/O and FS controls -// that use this value. -// - - -#define FILE_ANY_ACCESS 0 -#define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS) -#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe -#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe - -// end_ntddk end_wdm end_nthal end_ntifs - -#endif // _DEVIOCTL_ - -// end_winioctl - diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/usb100.h b/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/usb100.h deleted file mode 100644 index 63c87b5..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/usb100.h +++ /dev/null @@ -1,270 +0,0 @@ -#ifndef __USB100_H__ -#define __USB100_H__ - - -#include - - -//bmRequest.Dir -#define BMREQUEST_HOST_TO_DEVICE 0 -#define BMREQUEST_DEVICE_TO_HOST 1 - -//bmRequest.Type -#define BMREQUEST_STANDARD 0 -#define BMREQUEST_CLASS 1 -#define BMREQUEST_VENDOR 2 - -//bmRequest.Recipient -#define BMREQUEST_TO_DEVICE 0 -#define BMREQUEST_TO_INTERFACE 1 -#define BMREQUEST_TO_ENDPOINT 2 -#define BMREQUEST_TO_OTHER 3 - - -#define MAXIMUM_USB_STRING_LENGTH 255 - -// values for the bits returned by the USB GET_STATUS command -#define USB_GETSTATUS_SELF_POWERED 0x01 -#define USB_GETSTATUS_REMOTE_WAKEUP_ENABLED 0x02 - - -#define USB_DEVICE_DESCRIPTOR_TYPE 0x01 -#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02 -#define USB_STRING_DESCRIPTOR_TYPE 0x03 -#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04 -#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05 - -// descriptor types defined by DWG documents -#define USB_RESERVED_DESCRIPTOR_TYPE 0x06 -#define USB_CONFIG_POWER_DESCRIPTOR_TYPE 0x07 -#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 0x08 - -#define USB_DESCRIPTOR_MAKE_TYPE_AND_INDEX(d, i) ((USHORT)((USHORT)d<<8 | i)) - -// -// Values for bmAttributes field of an -// endpoint descriptor -// - -#define USB_ENDPOINT_TYPE_MASK 0x03 - -#define USB_ENDPOINT_TYPE_CONTROL 0x00 -#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 -#define USB_ENDPOINT_TYPE_BULK 0x02 -#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 - - -// -// definitions for bits in the bmAttributes field of a -// configuration descriptor. -// -#define USB_CONFIG_POWERED_MASK 0xc0 - -#define USB_CONFIG_BUS_POWERED 0x80 -#define USB_CONFIG_SELF_POWERED 0x40 -#define USB_CONFIG_REMOTE_WAKEUP 0x20 - -// -// Endpoint direction bit, stored in address -// - -#define USB_ENDPOINT_DIRECTION_MASK 0x80 - -// test direction bit in the bEndpointAddress field of -// an endpoint descriptor. -#define USB_ENDPOINT_DIRECTION_OUT(addr) (!((addr) & USB_ENDPOINT_DIRECTION_MASK)) -#define USB_ENDPOINT_DIRECTION_IN(addr) ((addr) & USB_ENDPOINT_DIRECTION_MASK) - -// -// USB defined request codes -// see chapter 9 of the USB 1.0 specifcation for -// more information. -// - -// These are the correct values based on the USB 1.0 -// specification - -#define USB_REQUEST_GET_STATUS 0x00 -#define USB_REQUEST_CLEAR_FEATURE 0x01 - -#define USB_REQUEST_SET_FEATURE 0x03 - -#define USB_REQUEST_SET_ADDRESS 0x05 -#define USB_REQUEST_GET_DESCRIPTOR 0x06 -#define USB_REQUEST_SET_DESCRIPTOR 0x07 -#define USB_REQUEST_GET_CONFIGURATION 0x08 -#define USB_REQUEST_SET_CONFIGURATION 0x09 -#define USB_REQUEST_GET_INTERFACE 0x0A -#define USB_REQUEST_SET_INTERFACE 0x0B -#define USB_REQUEST_SYNC_FRAME 0x0C - - -// -// defined USB device classes -// - - -#define USB_DEVICE_CLASS_RESERVED 0x00 -#define USB_DEVICE_CLASS_AUDIO 0x01 -#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 -#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 -#define USB_DEVICE_CLASS_MONITOR 0x04 -#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05 -#define USB_DEVICE_CLASS_POWER 0x06 -#define USB_DEVICE_CLASS_PRINTER 0x07 -#define USB_DEVICE_CLASS_STORAGE 0x08 -#define USB_DEVICE_CLASS_HUB 0x09 -#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF - -// -// USB Core defined Feature selectors -// - -#define USB_FEATURE_ENDPOINT_STALL 0x0000 -#define USB_FEATURE_REMOTE_WAKEUP 0x0001 - -// -// USB DWG defined Feature selectors -// - -#define USB_FEATURE_INTERFACE_POWER_D0 0x0002 -#define USB_FEATURE_INTERFACE_POWER_D1 0x0003 -#define USB_FEATURE_INTERFACE_POWER_D2 0x0004 -#define USB_FEATURE_INTERFACE_POWER_D3 0x0005 - -typedef struct _USB_DEVICE_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - USHORT bcdUSB; - UCHAR bDeviceClass; - UCHAR bDeviceSubClass; - UCHAR bDeviceProtocol; - UCHAR bMaxPacketSize0; - USHORT idVendor; - USHORT idProduct; - USHORT bcdDevice; - UCHAR iManufacturer; - UCHAR iProduct; - UCHAR iSerialNumber; - UCHAR bNumConfigurations; -} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR; - -typedef struct _USB_ENDPOINT_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - UCHAR bEndpointAddress; - UCHAR bmAttributes; - USHORT wMaxPacketSize; - UCHAR bInterval; -} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR; - -typedef struct _USB_CONFIGURATION_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - USHORT wTotalLength; - UCHAR bNumInterfaces; - UCHAR bConfigurationValue; - UCHAR iConfiguration; - UCHAR bmAttributes; - UCHAR MaxPower; -} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR; - -typedef struct _USB_INTERFACE_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - UCHAR bInterfaceNumber; - UCHAR bAlternateSetting; - UCHAR bNumEndpoints; - UCHAR bInterfaceClass; - UCHAR bInterfaceSubClass; - UCHAR bInterfaceProtocol; - UCHAR iInterface; -} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR; - -typedef struct _USB_STRING_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - WCHAR bString[1]; -} USB_STRING_DESCRIPTOR, *PUSB_STRING_DESCRIPTOR; - -typedef struct _USB_COMMON_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; -} USB_COMMON_DESCRIPTOR, *PUSB_COMMON_DESCRIPTOR; - - -// -// Standard USB HUB definitions -// -// See Chapter 11 USB core specification -// - -typedef struct _USB_HUB_DESCRIPTOR { - UCHAR bDescriptorLength; // Length of this descriptor - UCHAR bDescriptorType; // Hub configuration type - UCHAR bNumberOfPorts; // number of ports on this hub - USHORT wHubCharacteristics; // Hub Charateristics - UCHAR bPowerOnToPowerGood; // port power on till power good in 2ms - UCHAR bHubControlCurrent; // max current in mA - // - // room for 255 ports power control and removable bitmask - UCHAR bRemoveAndPowerMask[64]; -} USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR; - - -// -// Structures defined by various DWG feature documents -// - - -// -// See DWG USB Feature Specification: Interface Power Management -// - -#define USB_SUPPORT_D0_COMMAND 0x01 -#define USB_SUPPORT_D1_COMMAND 0x02 -#define USB_SUPPORT_D2_COMMAND 0x04 -#define USB_SUPPORT_D3_COMMAND 0x08 - -#define USB_SUPPORT_D1_WAKEUP 0x10 -#define USB_SUPPORT_D2_WAKEUP 0x20 - - -typedef struct _USB_CONFIGURATION_POWER_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - UCHAR SelfPowerConsumedD0[3]; - UCHAR bPowerSummaryId; - UCHAR bBusPowerSavingD1; - UCHAR bSelfPowerSavingD1; - UCHAR bBusPowerSavingD2; - UCHAR bSelfPowerSavingD2; - UCHAR bBusPowerSavingD3; - UCHAR bSelfPowerSavingD3; - USHORT TransitionTimeFromD1; - USHORT TransitionTimeFromD2; - USHORT TransitionTimeFromD3; -} USB_CONFIGURATION_POWER_DESCRIPTOR, *PUSB_CONFIGURATION_POWER_DESCRIPTOR; - - -typedef struct _USB_INTERFACE_POWER_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - UCHAR bmCapabilitiesFlags; - UCHAR bBusPowerSavingD1; - UCHAR bSelfPowerSavingD1; - UCHAR bBusPowerSavingD2; - UCHAR bSelfPowerSavingD2; - UCHAR bBusPowerSavingD3; - UCHAR bSelfPowerSavingD3; - USHORT TransitionTimeFromD1; - USHORT TransitionTimeFromD2; - USHORT TransitionTimeFromD3; -} USB_INTERFACE_POWER_DESCRIPTOR, *PUSB_INTERFACE_POWER_DESCRIPTOR; - - -#include - - -#endif /* __USB100_H__ */ - diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/usb200.h b/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/usb200.h deleted file mode 100644 index c032c45..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/win32/CyAPI/usb200.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef __USB200_H__ -#define __USB200_H__ - -#include "usb100.h" - - -#include - -typedef enum _USB_DEVICE_SPEED { - UsbLowSpeed = 0, - UsbFullSpeed, - UsbHighSpeed -} USB_DEVICE_SPEED; - -typedef enum _USB_DEVICE_TYPE { - Usb11Device = 0, - Usb20Device -} USB_DEVICE_TYPE; - -// standard definiions for the port status -// word of the HUB port register - -#define USB_PORT_STATUS_CONNECT 0x0001 -#define USB_PORT_STATUS_ENABLE 0x0002 -#define USB_PORT_STATUS_SUSPEND 0x0004 -#define USB_PORT_STATUS_OVER_CURRENT 0x0008 -#define USB_PORT_STATUS_RESET 0x0010 -#define USB_PORT_STATUS_POWER 0x0100 -#define USB_PORT_STATUS_LOW_SPEED 0x0200 -#define USB_PORT_STATUS_HIGH_SPEED 0x0400 - -typedef union _BM_REQUEST_TYPE { - struct _BM { - UCHAR Recipient:2; - UCHAR Reserved:3; - UCHAR Type:2; - UCHAR Dir:1; - }; - UCHAR B; -} BM_REQUEST_TYPE, *PBM_REQUEST_TYPE; - -typedef struct _USB_DEFAULT_PIPE_SETUP_PACKET { - BM_REQUEST_TYPE bmRequestType; - UCHAR bRequest; - - union _wValue { - struct { - UCHAR LowByte; - UCHAR HiByte; - }; - USHORT W; - } wValue; - - union _wIndex { - struct { - UCHAR LowByte; - UCHAR HiByte; - }; - USHORT W; - } wIndex; - USHORT wLength; -} USB_DEFAULT_PIPE_SETUP_PACKET, *PUSB_DEFAULT_PIPE_SETUP_PACKET; - -// setup packet is eight bytes -- defined by spec -C_ASSERT(sizeof(USB_DEFAULT_PIPE_SETUP_PACKET) == 8); - - -#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 0x06 - -typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR { - UCHAR bLength; - UCHAR bDescriptorType; - USHORT bcdUSB; - UCHAR bDeviceClass; - UCHAR bDeviceSubClass; - UCHAR bDeviceProtocol; - UCHAR bMaxPacketSize0; - UCHAR bNumConfigurations; - UCHAR bReserved; -} USB_DEVICE_QUALIFIER_DESCRIPTOR, *PUSB_DEVICE_QUALIFIER_DESCRIPTOR; - - -typedef union _USB_HIGH_SPEED_MAXPACKET { - struct _MP { - USHORT MaxPacket:11; /* 0..10 */ - USHORT HSmux:2; /* 11..12 */ - USHORT Reserved:3; /* 13..15 */ - }; - USHORT us; -} USB_HIGH_SPEED_MAXPACKET, *PUSB_HIGH_SPEED_MAXPACKET; - -#define USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE 0x0B - -typedef struct _USB_INTERFACE_ASSOCIATION_DESCRIPTOR { - - UCHAR bLength; - UCHAR bDescriptorType; - UCHAR bFirstInterface; - UCHAR bInterfaceCount; - UCHAR bFunctionClass; - UCHAR bFunctionSubClass; - UCHAR bFunctionProtocol; - UCHAR iFunction; - -} USB_INTERFACE_ASSOCIATION_DESCRIPTOR, *PUSB_INTERFACE_ASSOCIATION_DESCRIPTOR; - - -#include - -#endif // __USB200_H__ - diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/win32/FX3handler.cpp b/source_modules/sddc_source/src/libsddc/Core/arch/win32/FX3handler.cpp deleted file mode 100644 index 8e72d49..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/win32/FX3handler.cpp +++ /dev/null @@ -1,456 +0,0 @@ -// -// FX3handler.cpp -// 2020 10 12 Oscar Steila ik1xpv -// loading arm code.img from resource by Howard Su and Hayati Ayguen -// This module was previous named: -// openFX3.cpp MIT License Copyright (c) 2016 Booya Corp. -// booyasdr@gmail.com, http://booyasdr.sf.net -// modified 2017 11 30 ik1xpv@gmail.com, http://www.steila.com/blog -// -#include -#include "FX3handler.h" -#include "./CyAPI/CyAPI.h" -#include "./CyAPI/cyioctl.h" -#define RES_BIN_FIRMWARE 2000 - - -fx3class* CreateUsbHandler() -{ - return new fx3handler(); -} - -fx3handler::fx3handler(): - fx3dev (nullptr), - Fx3IsOn (false) -{ - -} - - -fx3handler::~fx3handler() // reset USB device and exit -{ - DbgPrintf("\r\n~fx3handler\r\n"); - Close(); -} - -bool fx3handler::GetFx3Device() { - bool r = false; - if (fx3dev == nullptr) return r; // no device - int n = fx3dev->DeviceCount(); - if (n == 0) return r; // no one - - // Walk through all devices looking for VENDOR_ID/STREAMER_ID - for (int i = 0; i <= n; i++) { - fx3dev->Open(i); // go down the list of devices to find our device - if ((fx3dev->VendorID == VENDOR_ID) && (fx3dev->ProductID == STREAMER_ID)) - { - r = true; - break; - } - - if ((fx3dev->VendorID == VENDOR_ID) && (fx3dev->ProductID == BOOTLOADER_ID)) - { - r = true; - break; - } - } - if (r == false) - fx3dev->Close(); - return r; -} - -bool fx3handler::GetFx3DeviceStreamer(void) { // open class - bool r = false; - if (fx3dev == NULL) return r; - int n = fx3dev->DeviceCount(); - // Walk through all devices looking for VENDOR_ID/STREAMER_ID - if (n == 0) return r; - // go down the list of devices to find STREAMER_ID device - for (int i = 0; i <= n; i++) { - fx3dev->Open(i); - if ((fx3dev->VendorID == VENDOR_ID) && (fx3dev->ProductID == STREAMER_ID)) - { - r = true; - break; - } - } - if (r == false) - fx3dev->Close(); - return r; -} - -bool fx3handler::Open(uint8_t* fw_data, uint32_t fw_size) { - bool r = false; - fx3dev = new CCyFX3Device; // instantiate the device - if (fx3dev == nullptr) return r; // return if failed - int n = fx3dev->DeviceCount(); - if (n == 0) return r; // return if no devices connected - if (!GetFx3Device()) return r; // NO FX3 device connected - -#ifdef _DEBUG - if (!fx3dev->IsBootLoaderRunning()) { // if not bootloader device - Control(RESETFX3); // reset the fx3 firmware via CyU3PDeviceReset(false) - DbgPrintf("DEBUG - Reset Firmware\n"); - Sleep(300); - fx3dev->Close(); // close class - delete fx3dev; // destroy class - Sleep(300); - fx3dev = new CCyFX3Device; // create class - GetFx3Device(); // open class - } -#endif - - FX3_FWDWNLOAD_ERROR_CODE dlf = SUCCESS; - if (fx3dev->IsBootLoaderRunning()) - { - dlf = fx3dev->DownloadFwToRam(fw_data, fw_size); - Sleep(500); // wait for download to finish - } - - if (dlf != 0) - { - DbgPrintf("MISSING/OLD FIRMWARE\n"); - return false; - } - int x = 0; - int maxretry = 30; - CCyFX3Device* expdev = nullptr; - while (x++ < maxretry) // wait new firmware setup - { - bool r = false; - expdev = new CCyFX3Device; // instantiate the device - if (expdev != NULL) - int n = expdev->DeviceCount(); - if (n > 0) - { - expdev->Open(0); - // go down the list of devices to find our device - for (int i = 1; i <= n; i++) - { - if ((expdev->VendorID == VENDOR_ID) && (expdev->ProductID == STREAMER_ID)) - { - x = maxretry; //got it exit - } - } - } - expdev->Close(); // close class - delete expdev; // destroy class - } - GetFx3DeviceStreamer(); // open class with new ram firmware - if (!fx3dev->IsOpen()) { - DbgPrintf("Failed to open device\n"); - return r; - } - EndPt = fx3dev->BulkInEndPt; - if (!EndPt) { - DbgPrintf("No Bulk In end point\n"); - return r; // init failed - } - - long pktSize = EndPt->MaxPktSize; - EndPt->SetXferSize(transferSize); - long ppx = transferSize / pktSize; - DbgPrintf("buffer transferSize = %d. packet size = %ld. packets per transfer = %ld\n" - , transferSize, pktSize, ppx); - - uint8_t data[4]; - GetHardwareInfo((uint32_t*)&data); - - if (data[1] != FIRMWARE_VER_MAJOR || - data[2] != FIRMWARE_VER_MINOR) - { - DbgPrintf("Firmware version mismatch %d.%d != %d.%d (actual)\n", FIRMWARE_VER_MAJOR, FIRMWARE_VER_MINOR, data[1], data[2]); - Control(RESETFX3); - return false; - } - - Fx3IsOn = true; - return Fx3IsOn; // init success -} - - -using namespace std; - -bool fx3handler::Control(FX3Command command, UINT8 data) { // firmware control BBRF - long lgt = 1; - - fx3dev->ControlEndPt->ReqCode = command; - fx3dev->ControlEndPt->Value = (USHORT)0; - fx3dev->ControlEndPt->Index = (USHORT)0; - bool r = fx3dev->ControlEndPt->Write(&data, lgt); - DbgPrintf("FX3FWControl %x .%x %x\n", r, command, data); - if (r == false) - { - Close(); - } - return r; -} - -bool fx3handler::Control(FX3Command command, UINT32 data) { // firmware control BBRF - long lgt = 4; - - fx3dev->ControlEndPt->ReqCode = command; - fx3dev->ControlEndPt->Value = (USHORT)0; - fx3dev->ControlEndPt->Index = (USHORT)0; - bool r = fx3dev->ControlEndPt->Write((PUCHAR)&data, lgt); - DbgPrintf("FX3FWControl %x .%x %x\n", r, command, data); - if (r == false) - { - Close(); - } - return r; -} - -bool fx3handler::Control(FX3Command command, UINT64 data) { // firmware control BBRF - long lgt = 8; - - fx3dev->ControlEndPt->ReqCode = command; - fx3dev->ControlEndPt->Value = (USHORT)0; - fx3dev->ControlEndPt->Index = (USHORT)0; - bool r = fx3dev->ControlEndPt->Write((PUCHAR)&data, lgt); - DbgPrintf("FX3FWControl %x .%x %llx\n", r, command, data); - if (r == false) - { - Close(); - } - return r; -} - - -bool fx3handler::SetArgument(UINT16 index, UINT16 value) { // firmware control BBRF - long lgt = 1; - uint8_t data = 0; - - fx3dev->ControlEndPt->ReqCode = SETARGFX3; - fx3dev->ControlEndPt->Value = (USHORT)value; - fx3dev->ControlEndPt->Index = (USHORT)index; - bool r = fx3dev->ControlEndPt->Write((PUCHAR)&data, lgt); - DbgPrintf("SetArgument %x .%x (%x, %x)\n", r, SETARGFX3, index, value); - if (r == false) - { - Close(); - } - return r; -} - -bool fx3handler::GetHardwareInfo(UINT32* data) { // firmware control BBRF - long lgt = 4; - - fx3dev->ControlEndPt->ReqCode = TESTFX3; -#ifdef _DEBUG - fx3dev->ControlEndPt->Value = (USHORT) 1; -#else - fx3dev->ControlEndPt->Value = (USHORT) 0; -#endif - fx3dev->ControlEndPt->Index = (USHORT)0; - bool r = fx3dev->ControlEndPt->Read((PUCHAR)data, lgt); - DbgPrintf("GetHardwareInfo %x .%x %x\n", r, TESTFX3, *data); - if (r == false) - { - Close(); - } - return r; - -} - -bool fx3handler::ReadDebugTrace(uint8_t* pdata, uint8_t len) -{ - long lgt = len; - bool r; - fx3dev->ControlEndPt->ReqCode = READINFODEBUG; - fx3dev->ControlEndPt->Value = (USHORT) pdata[0]; // upstream char - r = fx3dev->ControlEndPt->Read((PUCHAR)pdata, lgt); - return r; -} - -bool fx3handler::SendI2cbytes(UINT8 i2caddr, UINT8 regaddr, PUINT8 pdata, UINT8 len) -{ - bool r = false; - LONG lgt = len; - fx3dev->ControlEndPt->ReqCode = I2CWFX3; - fx3dev->ControlEndPt->Value = (USHORT)i2caddr; - fx3dev->ControlEndPt->Index = (USHORT)regaddr; - Sleep(10); - r = fx3dev->ControlEndPt->Write(pdata, lgt); - if (r == false) - DbgPrintf("\nfx3FWSendI2cbytes 0x%02x regaddr 0x%02x 1data 0x%02x len 0x%02x \n", - i2caddr, regaddr, *pdata, len); - return r; -} - -bool fx3handler::ReadI2cbytes(UINT8 i2caddr, UINT8 regaddr, PUINT8 pdata, UINT8 len) -{ - bool r = false; - LONG lgt = len; - WORD saveValue, saveIndex; - saveValue = fx3dev->ControlEndPt->Value; - saveIndex = fx3dev->ControlEndPt->Index; - - fx3dev->ControlEndPt->ReqCode = I2CRFX3; - fx3dev->ControlEndPt->Value = (USHORT)i2caddr; - fx3dev->ControlEndPt->Index = (USHORT)regaddr; - r = fx3dev->ControlEndPt->Read(pdata, lgt); - if (r == false) - printf("fx3FWReadI2cbytes %x : %02x %02x %02x %02x : %02x\n", r, I2CRFX3, i2caddr, regaddr, len, *pdata); - fx3dev->ControlEndPt->Value = saveValue; - fx3dev->ControlEndPt->Index = saveIndex; - return r; -} - -bool fx3handler::Close() { - fx3dev->Close(); // close class - delete fx3dev; // destroy class - Fx3IsOn = false; - return true; -} - -#define BLOCK_TIMEOUT (80) // block 65.536 ms timeout is 80 - -struct ReadContext -{ - PUCHAR context; - OVERLAPPED overlap; - SINGLE_TRANSFER transfer; - uint8_t* buffer; - long size; -}; - -bool fx3handler::BeginDataXfer(UINT8 *buffer, long transferSize, void** context) -{ - ReadContext *readContext = (ReadContext *)(*context); - - if (!EndPt) - return false; - - if (*context == nullptr) - { - // first time call, allocate the context structure - readContext = new ReadContext; - *context = readContext; - memset(&readContext->overlap, 0, sizeof(readContext->overlap)); - readContext->overlap.hEvent = CreateEvent(NULL, false, false, NULL); - } - - readContext->buffer = buffer; - readContext->size = transferSize; - - readContext->context = EndPt->BeginDataXfer(readContext->buffer, transferSize, &readContext->overlap); - if (EndPt->NtStatus || EndPt->UsbdStatus) {// BeginDataXfer failed - DbgPrintf((char*)"Xfer request rejected. 1 STATUS = %ld %ld\n", EndPt->NtStatus, EndPt->UsbdStatus); - return false; - } - - return true; -} - -bool fx3handler::FinishDataXfer(void** context) -{ - ReadContext *readContext = (ReadContext *)(*context); - - if (!readContext) - { - return nullptr; - } - - if (!EndPt->WaitForXfer(&readContext->overlap, BLOCK_TIMEOUT)) { // block on transfer - DbgPrintf("WaitForXfer timeout. NTSTATUS = 0x%08X\n", EndPt->NtStatus); - EndPt->Abort(); // abort if timeout - return false; - } - - auto requested_size = readContext->size; - if (!EndPt->FinishDataXfer(readContext->buffer, readContext->size, &readContext->overlap, readContext->context)) { - DbgPrintf("FinishDataXfer Failed. NTSTATUS = 0x%08X\n", EndPt->NtStatus); - return false; - } - - if (readContext->size < requested_size) - DbgPrintf("only read %ld but requested %ld\n", readContext->size, requested_size); - - return true; -} - -void fx3handler::CleanupDataXfer(void** context) -{ - ReadContext *readContext = (ReadContext *)(*context); - - CloseHandle(readContext->overlap.hEvent); - delete (readContext); -} - -#define USB_READ_CONCURRENT 4 - -void fx3handler::AdcSamplesProcess() -{ - DbgPrintf("AdcSamplesProc thread runs\n"); - int buf_idx; // queue index - int read_idx; - void* contexts[USB_READ_CONCURRENT]; - - memset(contexts, 0, sizeof(contexts)); - - // Queue-up the first batch of transfer requests - for (int n = 0; n < USB_READ_CONCURRENT; n++) { - auto ptr = inputbuffer->peekWritePtr(n); - if (!BeginDataXfer((uint8_t*)ptr, transferSize, &contexts[n])) { - DbgPrintf("Xfer request rejected.\n"); - return; - } - } - - read_idx = 0; // context cycle index - buf_idx = 0; // buffer cycle index - - // The infinite xfer loop. - while (run) { - if (!FinishDataXfer(&contexts[read_idx])) { - break; - } - - inputbuffer->WriteDone(); - - // Re-submit this queue element to keep the queue full - auto ptr = inputbuffer->peekWritePtr(USB_READ_CONCURRENT - 1); - if (!BeginDataXfer((uint8_t*)ptr, transferSize, &contexts[read_idx])) { // BeginDataXfer failed - DbgPrintf("Xfer request rejected.\n"); - break; - } - - buf_idx = (buf_idx + 1) % QUEUE_SIZE; - read_idx = (read_idx + 1) % USB_READ_CONCURRENT; - } // End of the infinite loop - - for (int n = 0; n < USB_READ_CONCURRENT; n++) { - CleanupDataXfer(&contexts[n]); - } - - DbgPrintf("AdcSamplesProc thread_exit\n"); - return; // void * -} - -void fx3handler::StartStream(ringbuffer& input, int numofblock) -{ - // Allocate the context and buffers - inputbuffer = &input; - - // create the thread - this->numofblock = numofblock; - run = true; - adc_samples_thread = new std::thread( - [this]() { - this->AdcSamplesProcess(); - } - ); -} - -void fx3handler::StopStream() -{ - // set the flag - run = false; - adc_samples_thread->join(); - - // force exit the thread - inputbuffer = nullptr; - - delete adc_samples_thread; -} diff --git a/source_modules/sddc_source/src/libsddc/Core/arch/win32/FX3handler.h b/source_modules/sddc_source/src/libsddc/Core/arch/win32/FX3handler.h deleted file mode 100644 index 5d580ea..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/arch/win32/FX3handler.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef FX3HANDLER_H -#define FX3HANDLER_H - -// -// FX3handler.cpp -// 2020 10 12 Oscar Steila ik1xpv -// loading arm code.img from resource by Howard Su and Hayati Ayguen -// This module was previous named:openFX3.cpp -// MIT License Copyright (c) 2016 Booya Corp. -// booyasdr@gmail.com, http://booyasdr.sf.net -// modified 2017 11 30 ik1xpv@gmail.com, http://www.steila.com/blog -// - -#include -#include -#include -#include -#include -#include "sddc_config.h" - -#include "dsp/ringbuffer.h" - -#define VENDOR_ID (0x04B4) -#define STREAMER_ID (0x00F1) -#define BOOTLOADER_ID (0x00F3) - -#include "FX3Class.h" - -class CCyFX3Device; -class CCyUSBEndPoint; - -class fx3handler : public fx3class -{ -public: - fx3handler(); - virtual ~fx3handler(void); - bool Open(uint8_t* fw_data, uint32_t fw_size); - bool IsOn() { return Fx3IsOn; } - bool Control(FX3Command command, uint8_t data); - bool Control(FX3Command command, uint32_t data = 0); - bool Control(FX3Command command, uint64_t data); - bool SetArgument(uint16_t index, uint16_t value); - bool GetHardwareInfo(uint32_t* data); - bool ReadDebugTrace(uint8_t* pdata, uint8_t len); - void StartStream(ringbuffer& input, int numofblock); - void StopStream(); - -private: - bool SendI2cbytes(uint8_t i2caddr, uint8_t regaddr, uint8_t* pdata, uint8_t len); - bool ReadI2cbytes(uint8_t i2caddr, uint8_t regaddr, uint8_t* pdata, uint8_t len); - - bool BeginDataXfer(uint8_t *buffer, long transferSize, void** context); - bool FinishDataXfer(void** context); - void CleanupDataXfer(void** context); - - CCyFX3Device* fx3dev; - CCyUSBEndPoint* EndPt; - - std::thread *adc_samples_thread; - - bool GetFx3Device(); - bool GetFx3DeviceStreamer(); - bool Fx3IsOn; - bool Close(void); - void AdcSamplesProcess(); - - ringbuffer *inputbuffer; - int numofblock; - bool run; -}; - - -#endif // FX3HANDLER_H diff --git a/source_modules/sddc_source/src/libsddc/Core/dsp/ringbuffer.h b/source_modules/sddc_source/src/libsddc/Core/dsp/ringbuffer.h deleted file mode 100644 index 97f172b..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/dsp/ringbuffer.h +++ /dev/null @@ -1,191 +0,0 @@ -#pragma once - -#include -#include -#include - -const int default_count = 64; -const int spin_count = 100; -#define ALIGN (8) - -class ringbufferbase { -public: - ringbufferbase(int count) : - max_count(count), - read_index(0), - write_index(0), - emptyCount(0), - fullCount(0), - writeCount(0) - { - } - - int getFullCount() const { return fullCount; } - - int getEmptyCount() const { return emptyCount; } - - int getWriteCount() const { return writeCount; } - - void ReadDone() - { - std::unique_lock lk(mutex); - if ((write_index + 1) % max_count == read_index) - { - read_index = (read_index + 1) % max_count; - nonfullCV.notify_all(); - } - else - { - read_index = (read_index + 1) % max_count; - } - } - - void WriteDone() - { - std::unique_lock lk(mutex); - if (read_index == write_index) - { - write_index = (write_index + 1) % max_count; - nonemptyCV.notify_all(); - } - else - { - write_index = (write_index + 1) % max_count; - } - writeCount++; - } - - void Stop() - { - std::unique_lock lk(mutex); - read_index = 0; - write_index = max_count / 2; - nonfullCV.notify_all(); - nonemptyCV.notify_all(); - } - -protected: - - void WaitUntilNotEmpty() - { - // if not empty - for (int i = 0; i < spin_count; i++) - { - if (read_index != write_index) - return; - } - - if (read_index == write_index) - { - std::unique_lock lk(mutex); - - emptyCount++; - nonemptyCV.wait(lk, [this] { - return read_index != write_index; - }); - } - } - - void WaitUntilNotFull() - { - for (int i = 0; i < spin_count; i++) - { - if ((write_index + 1) % max_count != read_index) - return; - } - - if ((write_index + 1) % max_count == read_index) - { - std::unique_lock lk(mutex); - fullCount++; - nonfullCV.wait(lk, [this] { - return (write_index + 1) % max_count != read_index; - }); - } - } - - int max_count; - - volatile int read_index; - volatile int write_index; - -private: - int emptyCount; - int fullCount; - int writeCount; - - std::mutex mutex; - std::condition_variable nonemptyCV; - std::condition_variable nonfullCV; -}; - -template class ringbuffer : public ringbufferbase { - typedef T* TPtr; - -public: - ringbuffer(int count = default_count) : - ringbufferbase(count) - { - buffers = new TPtr[max_count]; - buffers[0] = nullptr; - } - - ~ringbuffer() - { - if (buffers[0]) - delete[] buffers[0]; - - delete[] buffers; - } - - void setBlockSize(int size) - { - if (block_size != size) - { - block_size = size; - - if (buffers[0]) - delete[] buffers[0]; - - int aligned_block_size = (block_size + ALIGN - 1) & (~(ALIGN - 1)); - - auto data = new T[max_count * aligned_block_size]; - - for (int i = 0; i < max_count; ++i) - { - buffers[i] = &data[i * aligned_block_size]; - } - } - } - - T* peekWritePtr(int offset) - { - return buffers[(write_index + max_count + offset) % max_count]; - } - - T* peekReadPtr(int offset) - { - return buffers[(read_index + max_count + offset) % max_count]; - } - - T* getWritePtr() - { - // if there is still space - WaitUntilNotFull(); - return buffers[(write_index) % max_count]; - } - - const T* getReadPtr() - { - WaitUntilNotEmpty(); - - return buffers[read_index]; - } - - int getBlockSize() const { return block_size; } - -private: - int block_size; - - TPtr* buffers; -}; \ No newline at end of file diff --git a/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq.cpp b/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq.cpp deleted file mode 100644 index 9840ae6..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq.cpp +++ /dev/null @@ -1,263 +0,0 @@ -#include "license.txt" -/* -The ADC input real stream of 16 bit samples (at Fs = 64 Msps in the example) is converted to: -- 32 Msps float Fs/2 complex stream, or -- 16 Msps float Fs/2 complex stream, or -- 8 Msps float Fs/2 complex stream, or -- 4 Msps float Fs/2 complex stream, or -- 2 Msps float Fs/2 complex stream. -The decimation factor is selectable from HDSDR GUI sampling rate selector - -The name r2iq as Real 2 I+Q stream - -*/ - -#include "fft_mt_r2iq.h" -#include "sddc_config.h" -#include "fftw3.h" -#include "RadioHandler.h" - -#include "fir.h" - -#include -#include - - -r2iqControlClass::r2iqControlClass() -{ - r2iqOn = false; - randADC = false; - sideband = false; - mdecimation = 0; - mratio[0] = 1; // 1,2,4,8,16 - for (int i = 1; i < NDECIDX; i++) - { - mratio[i] = mratio[i - 1] * 2; - } -} - -fft_mt_r2iq::fft_mt_r2iq() : - r2iqControlClass(), - filterHw(nullptr) -{ - mtunebin = halfFft / 4; - mfftdim[0] = halfFft; - for (int i = 1; i < NDECIDX; i++) - { - mfftdim[i] = mfftdim[i - 1] / 2; - } - GainScale = 0.0f; - -#ifndef NDEBUG - int mratio = 1; // 1,2,4,8,16,.. - const float Astop = 120.0f; - const float relPass = 0.85f; // 85% of Nyquist should be usable - const float relStop = 1.1f; // 'some' alias back into transition band is OK - printf("\n***************************************************************************\n"); - printf("Filter tap estimation, Astop = %.1f dB, relPass = %.2f, relStop = %.2f\n", Astop, relPass, relStop); - for (int d = 0; d < NDECIDX; d++) - { - float Bw = 64.0f / mratio; - int ntaps = KaiserWindow(0, Astop, relPass * Bw / 128.0f, relStop * Bw / 128.0f, nullptr); - printf("decimation %2d: KaiserWindow(Astop = %.1f dB, Fpass = %.3f,Fstop = %.3f, Bw %.3f @ %f ) => %d taps\n", - d, Astop, relPass * Bw, relStop * Bw, Bw, 128.0f, ntaps); - mratio = mratio * 2; - } - printf("***************************************************************************\n"); -#endif - -} - -fft_mt_r2iq::~fft_mt_r2iq() -{ - if (filterHw == nullptr) - return; - - fftwf_export_wisdom_to_filename("wisdom"); - - for (int d = 0; d < NDECIDX; d++) - { - fftwf_free(filterHw[d]); // 4096 - } - fftwf_free(filterHw); - - fftwf_destroy_plan(plan_t2f_r2c); - for (int d = 0; d < NDECIDX; d++) - { - fftwf_destroy_plan(plans_f2t_c2c[d]); - } - - for (unsigned t = 0; t < processor_count; t++) { - auto th = threadArgs[t]; - fftwf_free(th->ADCinTime); - fftwf_free(th->ADCinFreq); - fftwf_free(th->inFreqTmp); - - delete threadArgs[t]; - } -} - - -float fft_mt_r2iq::setFreqOffset(float offset) -{ - // align to 1/4 of halfft - this->mtunebin = int(offset * halfFft / 4) * 4; // mtunebin step 4 bin ? - float delta = ((float)this->mtunebin / halfFft) - offset; - float ret = delta * getRatio(); // ret increases with higher decimation - DbgPrintf("offset %f mtunebin %d delta %f (%f)\n", offset, this->mtunebin, delta, ret); - return ret; -} - -void fft_mt_r2iq::TurnOn() { - this->r2iqOn = true; - this->bufIdx = 0; - this->lastThread = threadArgs[0]; - - for (unsigned t = 0; t < processor_count; t++) { - r2iq_thread[t] = std::thread( - [this] (void* arg) - { return this->r2iqThreadf((r2iqThreadArg*)arg); }, (void*)threadArgs[t]); - } -} - -void fft_mt_r2iq::TurnOff(void) { - this->r2iqOn = false; - - inputbuffer->Stop(); - outputbuffer->Stop(); - for (unsigned t = 0; t < processor_count; t++) { - r2iq_thread[t].join(); - } -} - -bool fft_mt_r2iq::IsOn(void) { return(this->r2iqOn); } - -void fft_mt_r2iq::Init(float gain, ringbuffer *input, ringbuffer* obuffers) -{ - this->inputbuffer = input; // set to the global exported by main_loop - this->outputbuffer = obuffers; // set to the global exported by main_loop - - this->GainScale = gain; - - fftwf_import_wisdom_from_filename("wisdom"); - - // Get the processor count - processor_count = std::thread::hardware_concurrency() - 1; - if (processor_count == 0) - processor_count = 1; - if (processor_count > N_MAX_R2IQ_THREADS) - processor_count = N_MAX_R2IQ_THREADS; - - { - fftwf_plan filterplan_t2f_c2c; // time to frequency fft - - DbgPrintf((char *) "r2iqCntrl initialization\n"); - - - // DbgPrintf((char *) "RandTable generated\n"); - - // filters - fftwf_complex *pfilterht; // time filter ht - pfilterht = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*halfFft); // halfFft - filterHw = (fftwf_complex**)fftwf_malloc(sizeof(fftwf_complex*)*NDECIDX); - for (int d = 0; d < NDECIDX; d++) - { - filterHw[d] = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*halfFft); // halfFft - } - - filterplan_t2f_c2c = fftwf_plan_dft_1d(halfFft, pfilterht, filterHw[0], FFTW_FORWARD, FFTW_MEASURE); - float *pht = new float[halfFft / 4 + 1]; - const float Astop = 120.0f; - const float relPass = 0.85f; // 85% of Nyquist should be usable - const float relStop = 1.1f; // 'some' alias back into transition band is OK - for (int d = 0; d < NDECIDX; d++) // @todo when increasing NDECIDX - { - // @todo: have dynamic bandpass filter size - depending on decimation - // to allow same stopband-attenuation for all decimations - float Bw = 64.0f / mratio[d]; - // Bw *= 0.8f; // easily visualize Kaiser filter's response - KaiserWindow(halfFft / 4 + 1, Astop, relPass * Bw / 128.0f, relStop * Bw / 128.0f, pht); - - float gainadj = gain * 2048.0f / (float)FFTN_R_ADC; // reference is FFTN_R_ADC == 2048 - - for (int t = 0; t < halfFft; t++) - { - pfilterht[t][0] = pfilterht[t][1]= 0.0F; - } - - for (int t = 0; t < (halfFft/4+1); t++) - { - pfilterht[halfFft-1-t][0] = gainadj * pht[t]; - } - - fftwf_execute_dft(filterplan_t2f_c2c, pfilterht, filterHw[d]); - } - delete[] pht; - fftwf_destroy_plan(filterplan_t2f_c2c); - fftwf_free(pfilterht); - - for (unsigned t = 0; t < processor_count; t++) { - r2iqThreadArg *th = new r2iqThreadArg(); - threadArgs[t] = th; - - th->ADCinTime = (float*)fftwf_malloc(sizeof(float) * (halfFft + transferSize / 2)); // 2048 - - th->ADCinFreq = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*(halfFft + 1)); // 1024+1 - th->inFreqTmp = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*(halfFft)); // 1024 - } - - plan_t2f_r2c = fftwf_plan_dft_r2c_1d(2 * halfFft, threadArgs[0]->ADCinTime, threadArgs[0]->ADCinFreq, FFTW_MEASURE); - for (int d = 0; d < NDECIDX; d++) - { - plans_f2t_c2c[d] = fftwf_plan_dft_1d(mfftdim[d], threadArgs[0]->inFreqTmp, threadArgs[0]->inFreqTmp, FFTW_BACKWARD, FFTW_MEASURE); - } - } -} - -#ifdef _WIN32 - // Windows - #include - #define cpuid(info, x) __cpuidex(info, x, 0) -#else - // GCC Intrinsics - #include - #define cpuid(info, x) __cpuid_count(x, 0, info[0], info[1], info[2], info[3]) -#endif - -void * fft_mt_r2iq::r2iqThreadf(r2iqThreadArg *th) -{ -#ifdef NO_SIMD_OPTIM - DbgPrintf("Hardware Capability: all SIMD features (AVX, AVX2, AVX512) deactivated\n"); - return r2iqThreadf_def(th); -#else - int info[4]; - bool HW_AVX = false; - bool HW_AVX2 = false; - bool HW_AVX512F = false; - - cpuid(info, 0); - int nIds = info[0]; - - if (nIds >= 0x00000001){ - cpuid(info,0x00000001); - HW_AVX = (info[2] & ((int)1 << 28)) != 0; - } - if (nIds >= 0x00000007){ - cpuid(info,0x00000007); - HW_AVX2 = (info[1] & ((int)1 << 5)) != 0; - - HW_AVX512F = (info[1] & ((int)1 << 16)) != 0; - } - - DbgPrintf("Hardware Capability: AVX:%d AVX2:%d AVX512:%d\n", HW_AVX, HW_AVX2, HW_AVX512F); - - if (HW_AVX512F) - return r2iqThreadf_avx512(th); - else if (HW_AVX2) - return r2iqThreadf_avx2(th); - else if (HW_AVX) - return r2iqThreadf_avx(th); - else - return r2iqThreadf_def(th); -#endif -} diff --git a/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq.h b/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq.h deleted file mode 100644 index e20a619..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq.h +++ /dev/null @@ -1,127 +0,0 @@ -#pragma once - -#include "r2iq.h" -#include "fftw3.h" -#include "sddc_config.h" -#include -#include - -// use up to this many threads -#define N_MAX_R2IQ_THREADS 1 -#define PRINT_INPUT_RANGE 0 - -static const int halfFft = FFTN_R_ADC / 2; // half the size of the first fft at ADC 64Msps real rate (2048) -static const int fftPerBuf = transferSize / sizeof(short) / (3 * halfFft / 2) + 1; // number of ffts per buffer with 256|768 overlap - -class fft_mt_r2iq : public r2iqControlClass -{ -public: - fft_mt_r2iq(); - virtual ~fft_mt_r2iq(); - - float setFreqOffset(float offset); - - void Init(float gain, ringbuffer* buffers, ringbuffer* obuffers); - void TurnOn(); - void TurnOff(void); - bool IsOn(void); - -protected: - - template void convert_float(const int16_t *input, float* output, int size) - { - for(int m = 0; m < size; m++) - { - int16_t val; - if (rand && (input[m] & 1)) - { - val = input[m] ^ (-2); - } - else - { - val = input[m]; - } - output[m] = float(val); - } - } - - void shift_freq(fftwf_complex* dest, const fftwf_complex* source1, const fftwf_complex* source2, int start, int end) - { - for (int m = start; m < end; m++) - { - // besides circular shift, do complex multiplication with the lowpass filter's spectrum - dest[m][0] = source1[m][0] * source2[m][0] - source1[m][1] * source2[m][1]; - dest[m][1] = source1[m][1] * source2[m][0] + source1[m][0] * source2[m][1]; - } - } - - template void copy(fftwf_complex* dest, const fftwf_complex* source, int count) - { - if (flip) - { - for (int i = 0; i < count; i++) - { - dest[i][0] = source[i][0]; - dest[i][1] = -source[i][1]; - } - } - else - { - for (int i = 0; i < count; i++) - { - dest[i][0] = source[i][0]; - dest[i][1] = source[i][1]; - } - } - } - -private: - ringbuffer* inputbuffer; // pointer to input buffers - ringbuffer* outputbuffer; // pointer to ouput buffers - int bufIdx; // index to next buffer to be processed - r2iqThreadArg* lastThread; - - float GainScale; - int mfftdim [NDECIDX]; // FFT N dimensions: mfftdim[k] = halfFft / 2^k - int mtunebin; - - void *r2iqThreadf(r2iqThreadArg *th); // thread function - - void * r2iqThreadf_def(r2iqThreadArg *th); - void * r2iqThreadf_avx(r2iqThreadArg *th); - void * r2iqThreadf_avx2(r2iqThreadArg *th); - void * r2iqThreadf_avx512(r2iqThreadArg *th); - - fftwf_complex **filterHw; // Hw complex to each decimation ratio - - fftwf_plan plan_t2f_r2c; // fftw plan buffers Freq to Time complex to complex per decimation ratio - fftwf_plan *plan_f2t_c2c; // fftw plan buffers Time to Freq real to complex per buffer - fftwf_plan plans_f2t_c2c[NDECIDX]; - - uint32_t processor_count; - r2iqThreadArg* threadArgs[N_MAX_R2IQ_THREADS]; - std::mutex mutexR2iqControl; // r2iq control lock - std::thread r2iq_thread[N_MAX_R2IQ_THREADS]; // thread pointers -}; - -// assure, that ADC is not oversteered? -struct r2iqThreadArg { - - r2iqThreadArg() - { -#if PRINT_INPUT_RANGE - MinMaxBlockCount = 0; - MinValue = 0; - MaxValue = 0; -#endif - } - - float *ADCinTime; // point to each threads input buffers [nftt][n] - fftwf_complex *ADCinFreq; // buffers in frequency - fftwf_complex *inFreqTmp; // tmp decimation output buffers (after tune shift) -#if PRINT_INPUT_RANGE - int MinMaxBlockCount; - int16_t MinValue; - int16_t MaxValue; -#endif -}; \ No newline at end of file diff --git a/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_avx.cpp b/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_avx.cpp deleted file mode 100644 index 77d2391..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_avx.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "fft_mt_r2iq.h" -#include "sddc_config.h" -#include "fftw3.h" -#include "RadioHandler.h" - -void * fft_mt_r2iq::r2iqThreadf_avx(r2iqThreadArg *th) -{ - #include "fft_mt_r2iq_impl.hpp" -} \ No newline at end of file diff --git a/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_avx2.cpp b/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_avx2.cpp deleted file mode 100644 index a5f83fe..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_avx2.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "fft_mt_r2iq.h" -#include "sddc_config.h" -#include "fftw3.h" -#include "RadioHandler.h" - -void * fft_mt_r2iq::r2iqThreadf_avx2(r2iqThreadArg *th) -{ - #include "fft_mt_r2iq_impl.hpp" -} \ No newline at end of file diff --git a/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_avx512.cpp b/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_avx512.cpp deleted file mode 100644 index 873aa23..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_avx512.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "fft_mt_r2iq.h" -#include "sddc_config.h" -#include "fftw3.h" -#include "RadioHandler.h" - -void * fft_mt_r2iq::r2iqThreadf_avx512(r2iqThreadArg *th) -{ - #include "fft_mt_r2iq_impl.hpp" -} \ No newline at end of file diff --git a/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_def.cpp b/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_def.cpp deleted file mode 100644 index b4d1a92..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_def.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "fft_mt_r2iq.h" -#include "sddc_config.h" -#include "fftw3.h" -#include "RadioHandler.h" - -void * fft_mt_r2iq::r2iqThreadf_def(r2iqThreadArg *th) -{ - #include "fft_mt_r2iq_impl.hpp" -} \ No newline at end of file diff --git a/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_impl.hpp b/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_impl.hpp deleted file mode 100644 index 7d9662b..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/fft_mt_r2iq_impl.hpp +++ /dev/null @@ -1,171 +0,0 @@ - -{ - const int decimate = this->mdecimation; - const int mfft = this->mfftdim[decimate]; // = halfFft / 2^mdecimation - const fftwf_complex* filter = filterHw[decimate]; - const bool lsb = this->getSideband(); - const auto filter2 = &filter[halfFft - mfft / 2]; - - plan_f2t_c2c = &plans_f2t_c2c[decimate]; - fftwf_complex* pout = nullptr; - int decimate_count = 0; - - while (r2iqOn) { - const int16_t *dataADC; // pointer to input data - const int16_t *endloop; // pointer to end data to be copied to beginning - - const int _mtunebin = this->mtunebin; // Update LO tune is possible during run - - { - std::unique_lock lk(mutexR2iqControl); - dataADC = inputbuffer->getReadPtr(); - - if (!r2iqOn) - return 0; - - this->bufIdx = (this->bufIdx + 1) % QUEUE_SIZE; - - endloop = inputbuffer->peekReadPtr(-1) + transferSamples - halfFft; - } - - auto inloop = th->ADCinTime; - - // @todo: move the following int16_t conversion to (32-bit) float - // directly inside the following loop (for "k < fftPerBuf") - // just before the forward fft "fftwf_execute_dft_r2c" is called - // idea: this should improve cache/memory locality -#if PRINT_INPUT_RANGE - std::pair blockMinMax = std::make_pair(0, 0); -#endif - if (!this->getRand()) // plain samples no ADC rand set - { - convert_float(endloop, inloop, halfFft); -#if PRINT_INPUT_RANGE - auto minmax = std::minmax_element(dataADC, dataADC + transferSamples); - blockMinMax.first = *minmax.first; - blockMinMax.second = *minmax.second; -#endif - convert_float(dataADC, inloop + halfFft, transferSamples); - } - else - { - convert_float(endloop, inloop, halfFft); - convert_float(dataADC, inloop + halfFft, transferSamples); - } - -#if PRINT_INPUT_RANGE - th->MinValue = std::min(blockMinMax.first, th->MinValue); - th->MaxValue = std::max(blockMinMax.second, th->MaxValue); - ++th->MinMaxBlockCount; - if (th->MinMaxBlockCount * processor_count / 3 >= DEFAULT_TRANSFERS_PER_SEC ) - { - float minBits = (th->MinValue < 0) ? (log10f((float)(-th->MinValue)) / log10f(2.0f)) : -1.0f; - float maxBits = (th->MaxValue > 0) ? (log10f((float)(th->MaxValue)) / log10f(2.0f)) : -1.0f; - printf("r2iq: min = %d (%.1f bits) %.2f%%, max = %d (%.1f bits) %.2f%%\n", - (int)th->MinValue, minBits, th->MinValue *-100.0f / 32768.0f, - (int)th->MaxValue, maxBits, th->MaxValue * 100.0f / 32768.0f); - th->MinValue = 0; - th->MaxValue = 0; - th->MinMaxBlockCount = 0; - } -#endif - dataADC = nullptr; - inputbuffer->ReadDone(); - // decimate in frequency plus tuning - - if (decimate_count == 0) - pout = (fftwf_complex*)outputbuffer->getWritePtr(); - - decimate_count = (decimate_count + 1) & ((1 << decimate) - 1); - - // Calculate the parameters for the first half - const auto count = std::min(mfft/2, halfFft - _mtunebin); - const auto source = &th->ADCinFreq[_mtunebin]; - - // Calculate the parameters for the second half - const auto start = std::max(0, mfft / 2 - _mtunebin); - const auto source2 = &th->ADCinFreq[_mtunebin - mfft / 2]; - const auto dest = &th->inFreqTmp[mfft / 2]; - for (int k = 0; k < fftPerBuf; k++) - { - // core of fast convolution including filter and decimation - // main part is 'overlap-scrap' (IMHO better name for 'overlap-save'), see - // https://en.wikipedia.org/wiki/Overlap%E2%80%93save_method - { - // FFT first stage: time to frequency, real to complex - // 'full' transformation size: 2 * halfFft - fftwf_execute_dft_r2c(plan_t2f_r2c, th->ADCinTime + (3 * halfFft / 2) * k, th->ADCinFreq); - // result now in th->ADCinFreq[] - - // circular shift (mixing in full bins) and low/bandpass filtering (complex multiplication) - { - // circular shift tune fs/2 first half array into th->inFreqTmp[] - shift_freq(th->inFreqTmp, source, filter, 0, count); - if (mfft / 2 != count) - memset(th->inFreqTmp[count], 0, sizeof(float) * 2 * (mfft / 2 - count)); - - // circular shift tune fs/2 second half array - shift_freq(dest, source2, filter2, start, mfft/2); - if (start != 0) - memset(th->inFreqTmp[mfft / 2], 0, sizeof(float) * 2 * start); - } - // result now in th->inFreqTmp[] - - // 'shorter' inverse FFT transform (decimation); frequency (back) to COMPLEX time domain - // transform size: mfft = mfftdim[k] = halfFft / 2^k with k = mdecimation - fftwf_execute_dft(*plan_f2t_c2c, th->inFreqTmp, th->inFreqTmp); // c2c decimation - // result now in th->inFreqTmp[] - } - - // postprocessing - // @todo: is it possible to .. - // 1) - // let inverse FFT produce/save it's result directly - // in "this->obuffers[modx] + offset" (pout) - // ( obuffers[] would need to have additional space ..; - // need to move 'scrap' of 'ovelap-scrap'? ) - // at least FFTW would allow so, - // see http://www.fftw.org/fftw3_doc/New_002darray-Execute-Functions.html - // attention: multithreading! - // 2) - // could mirroring (lower sideband) get calculated together - // with fine mixer - modifying the mixer frequency? (fs - fc)/fs - // (this would reduce one memory pass) - if (lsb) // lower sideband - { - // mirror just by negating the imaginary Q of complex I/Q - if (k == 0) - { - copy(pout, &th->inFreqTmp[mfft / 4], mfft/2); - } - else - { - copy(pout + mfft / 2 + (3 * mfft / 4) * (k - 1), &th->inFreqTmp[0], (3 * mfft / 4)); - } - } - else // upper sideband - { - if (k == 0) - { - copy(pout, &th->inFreqTmp[mfft / 4], mfft/2); - } - else - { - copy(pout + mfft / 2 + (3 * mfft / 4) * (k - 1), &th->inFreqTmp[0], (3 * mfft / 4)); - } - } - // result now in this->obuffers[] - } - - if (decimate_count == 0) { - outputbuffer->WriteDone(); - pout = nullptr; - } - else - { - pout += mfft / 2 + (3 * mfft / 4) * (fftPerBuf - 1); - } - } // while(run) -// DbgPrintf((char *) "r2iqThreadf idx %d pthread_exit %u\n",(int)th->t, pthread_self()); - return 0; -} diff --git a/source_modules/sddc_source/src/libsddc/Core/fir.cpp b/source_modules/sddc_source/src/libsddc/Core/fir.cpp deleted file mode 100644 index 41a66d0..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/fir.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include "fir.h" -#include - -#define K_PI 3.141592653f -#define K_2PI (2*K_PI) - -static float Izero(float x) -{ - float x2 = x / 2.0f; - float sum = 1.0f; - float ds = 1.0f; - float di = 1.0f; - float errorlimit = 1e-9f; - float tmp; - do - { - tmp = x2 / di; - tmp *= tmp; - ds *= tmp; - sum += ds; - di += 1.0; - } while (ds >= errorlimit * sum); - //qDebug()<<"x="< -#include -#include -#include -#include -#include - -//#define HAVE_SYS_TIMES - -#ifdef HAVE_SYS_TIMES -# include -# include -#endif - -#define BENCH_REF_TRIG_FUNC 1 -#define BENCH_OUT_OF_PLACE_ALGOS 0 -#define BENCH_INPLACE_ALGOS 1 - -#define SAVE_BY_DEFAULT 1 -#define SAVE_LIMIT_MSPS 16 - -#if 1 - #define BENCH_FILE_SHIFT_MATH_CC "A_shift_math_cc.bin" - #define BENCH_FILE_ADD_FAST_CC "C_shift_addfast_cc.bin" - #define BENCH_FILE_ADD_FAST_INP_C "C_shift_addfast_inp_c.bin" - #define BENCH_FILE_UNROLL_INP_C "D_shift_unroll_inp_c.bin" - #define BENCH_FILE_LTD_UNROLL_INP_C "E_shift_limited_unroll_inp_c.bin" - #define BENCH_FILE_LTD_UNROLL_A_SSE_INP_C "F_shift_limited_unroll_A_sse_inp_c.bin" - #define BENCH_FILE_LTD_UNROLL_B_SSE_INP_C "G_shift_limited_unroll_B_sse_inp_c.bin" - #define BENCH_FILE_LTD_UNROLL_C_SSE_INP_C "H_shift_limited_unroll_C_sse_inp_c.bin" - #define BENCH_FILE_REC_OSC_CC "" - #define BENCH_FILE_REC_OSC_INP_C "I_shift_recursive_osc_inp_c.bin" - #define BENCH_FILE_REC_OSC_SSE_INP_C "J_shift_recursive_osc_sse_inp_c.bin" -#else - #define BENCH_FILE_SHIFT_MATH_CC "" - #define BENCH_FILE_ADD_FAST_CC "" - #define BENCH_FILE_ADD_FAST_INP_C "" - #define BENCH_FILE_UNROLL_INP_C "" - #define BENCH_FILE_LTD_UNROLL_INP_C "" - #define BENCH_FILE_LTD_UNROLL_A_SSE_INP_C "" - #define BENCH_FILE_LTD_UNROLL_B_SSE_INP_C "" - #define BENCH_FILE_LTD_UNROLL_C_SSE_INP_C "" - #define BENCH_FILE_REC_OSC_CC "" - #define BENCH_FILE_REC_OSC_INP_C "" - #define BENCH_FILE_REC_OSC_SSE_INP_C "" -#endif - - - -#if defined(HAVE_SYS_TIMES) - static double ttclk = 0.; - - static double uclock_sec(int find_start) - { - struct tms t0, t; - if (ttclk == 0.) - { - ttclk = sysconf(_SC_CLK_TCK); - fprintf(stderr, "sysconf(_SC_CLK_TCK) => %f\n", ttclk); - } - times(&t); - if (find_start) - { - t0 = t; - while (t0.tms_utime == t.tms_utime) - times(&t); - } - /* use only the user time of this process - not realtime, which depends on OS-scheduler .. */ - return ((double)t.tms_utime) / ttclk; - } - -#elif 0 - // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesstimes - double uclock_sec(int find_start) - { - FILETIME a, b, c, d; - if (GetProcessTimes(GetCurrentProcess(), &a, &b, &c, &d) != 0) - { - // Returns total user time. - // Can be tweaked to include kernel times as well. - return - (double)(d.dwLowDateTime | - ((unsigned long long)d.dwHighDateTime << 32)) * 0.0000001; - } - else { - // Handle error - return 0; - } - } - -#else - double uclock_sec(int find_start) - { return (double)clock()/(double)CLOCKS_PER_SEC; } -#endif - - -void save(complexf * d, int B, int N, const char * fn) -{ - if (!fn || !fn[0]) - { - if (! SAVE_BY_DEFAULT) - return; - fn = "bench.bin"; - } - FILE* f; - fopen_s(&f, fn, "wb"); - if (!f) { - fprintf(stderr, "error writing result to %s\n", fn); - return; - }else - printf( "saving to %s\n", fn); - - if ( N >= SAVE_LIMIT_MSPS * 1024 * 1024 ) - N = SAVE_LIMIT_MSPS * 1024 * 1024; - for (int off = 0; off + B <= N; off += B) - { - fwrite(d+off, sizeof(complexf), B, f); - } - fclose(f); -} - - -double bench_shift_math_cc(int B, int N) { - double t0, t1, tstop, T, nI; - int iter, off; - float phase = 0.0F; - complexf *input = (complexf *)malloc(N * sizeof(complexf)); - complexf *output = (complexf *)malloc(N * sizeof(complexf)); - shift_recursive_osc_t gen_state; - shift_recursive_osc_conf_t gen_conf; - - shift_recursive_osc_init(0.001F, 0.0F, &gen_conf, &gen_state); - gen_recursive_osc_c(input, N, &gen_conf, &gen_state); - - iter = 0; - off = 0; - t0 = uclock_sec(1); - tstop = t0 + 0.5; /* benchmark duration: 500 ms */ - do { - // work - phase = shift_math_cc(input+off, output+off, B, -0.0009F, phase); - off += B; - ++iter; - t1 = uclock_sec(0); - } while ( t1 < tstop && off + B < N ); - - save(output, B, off, BENCH_FILE_SHIFT_MATH_CC); - - free(input); - free(output); - T = ( t1 - t0 ); /* duration per fft() */ - printf("processed %f Msamples in %f ms\n", off * 1E-6, T*1E3); - nI = ((double)iter) * B; /* number of iterations "normalized" to O(N) = N */ - return (nI / T); /* normalized iterations per second */ -} - - -double bench_shift_table_cc(int B, int N) { - double t0, t1, tstop, T, nI; - int iter, off; - int table_size=65536; - float phase = 0.0F; - complexf *input = (complexf *)malloc(N * sizeof(complexf)); - complexf *output = (complexf *)malloc(N * sizeof(complexf)); - shift_recursive_osc_t gen_state; - shift_recursive_osc_conf_t gen_conf; - - shift_table_data_t table_data = shift_table_init(table_size); - - shift_recursive_osc_init(0.001F, 0.0F, &gen_conf, &gen_state); - gen_recursive_osc_c(input, N, &gen_conf, &gen_state); - - iter = 0; - off = 0; - t0 = uclock_sec(1); - tstop = t0 + 0.5; /* benchmark duration: 500 ms */ - do { - // work - phase = shift_table_cc(input+off, output+off, B, -0.0009F, table_data, phase); - - off += B; - ++iter; - t1 = uclock_sec(0); - } while ( t1 < tstop && off + B < N ); - - save(output, B, off, NULL); - free(input); - free(output); - T = ( t1 - t0 ); /* duration per fft() */ - printf("processed %f Msamples in %f ms\n", off * 1E-6, T*1E3); - nI = ((double)iter) * B; /* number of iterations "normalized" to O(N) = N */ - return (nI / T); /* normalized iterations per second */ -} - - -double bench_shift_addfast(int B, int N) { - double t0, t1, tstop, T, nI; - int iter, off; - float phase = 0.0F; - complexf *input = (complexf *)malloc(N * sizeof(complexf)); - complexf *output = (complexf *)malloc(N * sizeof(complexf)); - shift_recursive_osc_t gen_state; - shift_recursive_osc_conf_t gen_conf; - shift_addfast_data_t state = shift_addfast_init(-0.0009F); - - shift_recursive_osc_init(0.001F, 0.0F, &gen_conf, &gen_state); - gen_recursive_osc_c(input, N, &gen_conf, &gen_state); - - iter = 0; - off = 0; - t0 = uclock_sec(1); - tstop = t0 + 0.5; /* benchmark duration: 500 ms */ - do { - // work - phase = shift_addfast_cc(input+off, output+off, B, &state, phase); - - off += B; - ++iter; - t1 = uclock_sec(0); - } while ( t1 < tstop && off + B < N ); - - save(output, B, off, BENCH_FILE_ADD_FAST_CC); - - free(input); - free(output); - T = ( t1 - t0 ); /* duration per fft() */ - printf("processed %f Msamples in %f ms\n", off * 1E-6, T*1E3); - nI = ((double)iter) * B; /* number of iterations "normalized" to O(N) = N */ - return (nI / T); /* normalized iterations per second */ -} - -double bench_shift_addfast_inp(int B, int N) { - double t0, t1, tstop, T, nI; - int iter, off; - float phase = 0.0F; - complexf *input = (complexf *)malloc(N * sizeof(complexf)); - shift_recursive_osc_t gen_state; - shift_recursive_osc_conf_t gen_conf; - shift_addfast_data_t state = shift_addfast_init(-0.0009F); - - shift_recursive_osc_init(0.001F, 0.0F, &gen_conf, &gen_state); - gen_recursive_osc_c(input, N, &gen_conf, &gen_state); - - iter = 0; - off = 0; - t0 = uclock_sec(1); - tstop = t0 + 0.5; /* benchmark duration: 500 ms */ - do { - // work - phase = shift_addfast_inp_c(input+off, B, &state, phase); - - off += B; - ++iter; - t1 = uclock_sec(0); - } while ( t1 < tstop && off + B < N ); - - save(input, B, off, BENCH_FILE_ADD_FAST_INP_C); - - free(input); - T = ( t1 - t0 ); /* duration per fft() */ - printf("processed %f Msamples in %f ms\n", off * 1E-6, T*1E3); - nI = ((double)iter) * B; /* number of iterations "normalized" to O(N) = N */ - return (nI / T); /* normalized iterations per second */ -} - - -double bench_shift_unroll_oop(int B, int N) { - double t0, t1, tstop, T, nI; - int iter, off; - float phase = 0.0F; - complexf *input = (complexf *)malloc(N * sizeof(complexf)); - complexf *output = (complexf *)malloc(N * sizeof(complexf)); - shift_recursive_osc_t gen_state; - shift_recursive_osc_conf_t gen_conf; - shift_unroll_data_t state = shift_unroll_init(-0.0009F, B); - - shift_recursive_osc_init(0.001F, 0.0F, &gen_conf, &gen_state); - gen_recursive_osc_c(input, N, &gen_conf, &gen_state); - - iter = 0; - off = 0; - t0 = uclock_sec(1); - tstop = t0 + 0.5; /* benchmark duration: 500 ms */ - do { - // work - phase = shift_unroll_cc(input+off, output+off, B, &state, phase); - - off += B; - ++iter; - t1 = uclock_sec(0); - } while ( t1 < tstop && off + B < N ); - - save(output, B, off, NULL); - free(input); - free(output); - T = ( t1 - t0 ); /* duration per fft() */ - printf("processed %f Msamples in %f ms\n", off * 1E-6, T*1E3); - nI = ((double)iter) * B; /* number of iterations "normalized" to O(N) = N */ - return (nI / T); /* normalized iterations per second */ -} - -double bench_shift_unroll_inp(int B, int N) { - double t0, t1, tstop, T, nI; - int iter, off; - float phase = 0.0F; - complexf *input = (complexf *)malloc(N * sizeof(complexf)); - shift_recursive_osc_t gen_state; - shift_recursive_osc_conf_t gen_conf; - shift_unroll_data_t state = shift_unroll_init(-0.0009F, B); - - shift_recursive_osc_init(0.001F, 0.0F, &gen_conf, &gen_state); - gen_recursive_osc_c(input, N, &gen_conf, &gen_state); - - iter = 0; - off = 0; - t0 = uclock_sec(1); - tstop = t0 + 0.5; /* benchmark duration: 500 ms */ - do { - // work - phase = shift_unroll_inp_c(input+off, B, &state, phase); - - off += B; - ++iter; - t1 = uclock_sec(0); - } while ( t1 < tstop && off + B < N ); - - save(input, B, off, BENCH_FILE_UNROLL_INP_C); - - free(input); - T = ( t1 - t0 ); /* duration per fft() */ - printf("processed %f Msamples in %f ms\n", off * 1E-6, T*1E3); - nI = ((double)iter) * B; /* number of iterations "normalized" to O(N) = N */ - return (nI / T); /* normalized iterations per second */ -} - - - -double bench_shift_limited_unroll_oop(int B, int N) { - double t0, t1, tstop, T, nI; - int iter, off; - complexf *input = (complexf *)malloc(N * sizeof(complexf)); - complexf *output = (complexf *)malloc(N * sizeof(complexf)); - shift_recursive_osc_t gen_state; - shift_recursive_osc_conf_t gen_conf; - shift_limited_unroll_data_t state = shift_limited_unroll_init(-0.0009F); - - shift_recursive_osc_init(0.001F, 0.0F, &gen_conf, &gen_state); - gen_recursive_osc_c(input, N, &gen_conf, &gen_state); - - iter = 0; - off = 0; - t0 = uclock_sec(1); - tstop = t0 + 0.5; /* benchmark duration: 500 ms */ - do { - // work - shift_limited_unroll_cc(input+off, output+off, B, &state); - - off += B; - ++iter; - t1 = uclock_sec(0); - } while ( t1 < tstop && off + B < N ); - - save(output, B, off, NULL); - free(input); - free(output); - T = ( t1 - t0 ); /* duration per fft() */ - printf("processed %f Msamples in %f ms\n", off * 1E-6, T*1E3); - nI = ((double)iter) * B; /* number of iterations "normalized" to O(N) = N */ - return (nI / T); /* normalized iterations per second */ -} - - -double bench_shift_limited_unroll_inp(int B, int N) { - double t0, t1, tstop, T, nI; - int iter, off; - complexf *input = (complexf *)malloc(N * sizeof(complexf)); - shift_recursive_osc_t gen_state; - shift_recursive_osc_conf_t gen_conf; - shift_limited_unroll_data_t state = shift_limited_unroll_init(-0.0009F); - - shift_recursive_osc_init(0.001F, 0.0F, &gen_conf, &gen_state); - gen_recursive_osc_c(input, N, &gen_conf, &gen_state); - - iter = 0; - off = 0; - t0 = uclock_sec(1); - tstop = t0 + 0.5; /* benchmark duration: 500 ms */ - do { - // work - shift_limited_unroll_inp_c(input+off, B, &state); - - off += B; - ++iter; - t1 = uclock_sec(0); - } while ( t1 < tstop && off + B < N ); - - save(input, B, off, BENCH_FILE_LTD_UNROLL_INP_C); - - free(input); - T = ( t1 - t0 ); /* duration per fft() */ - printf("processed %f Msamples in %f ms\n", off * 1E-6, T*1E3); - nI = ((double)iter) * B; /* number of iterations "normalized" to O(N) = N */ - return (nI / T); /* normalized iterations per second */ -} - - -double bench_shift_limited_unroll_A_sse_inp(int B, int N) { - double t0, t1, tstop, T, nI; - int iter, off; - complexf *input = (complexf *)malloc(N * sizeof(complexf)); - shift_recursive_osc_t gen_state; - shift_recursive_osc_conf_t gen_conf; - shift_limited_unroll_A_sse_data_t *state = malloc(sizeof(shift_limited_unroll_A_sse_data_t)); - - *state = shift_limited_unroll_A_sse_init(-0.0009F, 0.0F); - - shift_recursive_osc_init(0.001F, 0.0F, &gen_conf, &gen_state); - gen_recursive_osc_c(input, N, &gen_conf, &gen_state); - - iter = 0; - off = 0; - t0 = uclock_sec(1); - tstop = t0 + 0.5; /* benchmark duration: 500 ms */ - do { - // work - shift_limited_unroll_A_sse_inp_c(input+off, B, state); - - off += B; - ++iter; - t1 = uclock_sec(0); - } while ( t1 < tstop && off + B < N ); - - save(input, B, off, BENCH_FILE_LTD_UNROLL_A_SSE_INP_C); - - free(input); - T = ( t1 - t0 ); /* duration per fft() */ - printf("processed %f Msamples in %f ms\n", off * 1E-6, T*1E3); - nI = ((double)iter) * B; /* number of iterations "normalized" to O(N) = N */ - return (nI / T); /* normalized iterations per second */ -} - -double bench_shift_limited_unroll_B_sse_inp(int B, int N) { - double t0, t1, tstop, T, nI; - int iter, off; - complexf *input = (complexf *)malloc(N * sizeof(complexf)); - shift_recursive_osc_t gen_state; - shift_recursive_osc_conf_t gen_conf; - shift_limited_unroll_B_sse_data_t *state = malloc(sizeof(shift_limited_unroll_B_sse_data_t)); - - *state = shift_limited_unroll_B_sse_init(-0.0009F, 0.0F); - - shift_recursive_osc_init(0.001F, 0.0F, &gen_conf, &gen_state); - //shift_recursive_osc_init(0.0F, 0.0F, &gen_conf, &gen_state); - gen_recursive_osc_c(input, N, &gen_conf, &gen_state); - - iter = 0; - off = 0; - t0 = uclock_sec(1); - tstop = t0 + 0.5; /* benchmark duration: 500 ms */ - do { - // work - shift_limited_unroll_B_sse_inp_c(input+off, B, state); - - off += B; - ++iter; - t1 = uclock_sec(0); - } while ( t1 < tstop && off + B < N ); - - save(input, B, off, BENCH_FILE_LTD_UNROLL_B_SSE_INP_C); - - free(input); - T = ( t1 - t0 ); /* duration per fft() */ - printf("processed %f Msamples in %f ms\n", off * 1E-6, T*1E3); - nI = ((double)iter) * B; /* number of iterations "normalized" to O(N) = N */ - return (nI / T); /* normalized iterations per second */ -} - -double bench_shift_limited_unroll_C_sse_inp(int B, int N) { - double t0, t1, tstop, T, nI; - int iter, off; - complexf *input = (complexf *)malloc(N * sizeof(complexf)); - shift_recursive_osc_t gen_state; - shift_recursive_osc_conf_t gen_conf; - shift_limited_unroll_C_sse_data_t *state = malloc(sizeof(shift_limited_unroll_C_sse_data_t)); - - *state = shift_limited_unroll_C_sse_init(-0.0009F, 0.0F); - - shift_recursive_osc_init(0.001F, 0.0F, &gen_conf, &gen_state); - gen_recursive_osc_c(input, N, &gen_conf, &gen_state); - - iter = 0; - off = 0; - t0 = uclock_sec(1); - tstop = t0 + 0.5; /* benchmark duration: 500 ms */ - do { - // work - shift_limited_unroll_C_sse_inp_c(input+off, B, state); - - off += B; - ++iter; - t1 = uclock_sec(0); - } while ( t1 < tstop && off + B < N ); - - save(input, B, off, BENCH_FILE_LTD_UNROLL_C_SSE_INP_C); - - free(input); - T = ( t1 - t0 ); /* duration per fft() */ - printf("processed %f Msamples in %f ms\n", off * 1E-6, T*1E3); - nI = ((double)iter) * B; /* number of iterations "normalized" to O(N) = N */ - return (nI / T); /* normalized iterations per second */ -} - - -double bench_shift_rec_osc_cc_oop(int B, int N) { - double t0, t1, tstop, T, nI; - int iter, off; - float phase = 0.0F; - complexf *input = (complexf *)malloc(N * sizeof(complexf)); - complexf *output = (complexf *)malloc(N * sizeof(complexf)); - shift_recursive_osc_t gen_state, shift_state; - shift_recursive_osc_conf_t gen_conf, shift_conf; - - shift_recursive_osc_init(-0.0009F, 0.0F, &shift_conf, &shift_state); - shift_recursive_osc_init(0.001F, 0.0F, &gen_conf, &gen_state); - gen_recursive_osc_c(input, N, &gen_conf, &gen_state); - - iter = 0; - off = 0; - t0 = uclock_sec(1); - tstop = t0 + 0.5; /* benchmark duration: 500 ms */ - do { - // work - shift_recursive_osc_cc(input+off, output+off, B, &shift_conf, &shift_state); - - off += B; - ++iter; - t1 = uclock_sec(0); - } while ( t1 < tstop && off + B < N ); - - save(input, B, off, BENCH_FILE_REC_OSC_CC); - - save(output, B, off, NULL); - free(input); - free(output); - T = ( t1 - t0 ); /* duration per fft() */ - printf("processed %f Msamples in %f ms\n", off * 1E-6, T*1E3); - nI = ((double)iter) * B; /* number of iterations "normalized" to O(N) = N */ - return (nI / T); /* normalized iterations per second */ -} - - -double bench_shift_rec_osc_cc_inp(int B, int N) { - double t0, t1, tstop, T, nI; - int iter, off; - float phase = 0.0F; - complexf *input = (complexf *)malloc(N * sizeof(complexf)); - shift_recursive_osc_t gen_state, shift_state; - shift_recursive_osc_conf_t gen_conf, shift_conf; - - shift_recursive_osc_init(0.001F, 0.0F, &gen_conf, &gen_state); - gen_recursive_osc_c(input, N, &gen_conf, &gen_state); - shift_recursive_osc_init(-0.0009F, 0.0F, &shift_conf, &shift_state); - - iter = 0; - off = 0; - t0 = uclock_sec(1); - tstop = t0 + 0.5; /* benchmark duration: 500 ms */ - do { - // work - shift_recursive_osc_inp_c(input+off, B, &shift_conf, &shift_state); - - off += B; - ++iter; - t1 = uclock_sec(0); - } while ( t1 < tstop && off + B < N ); - - save(input, B, off, BENCH_FILE_REC_OSC_INP_C); - free(input); - T = ( t1 - t0 ); /* duration per fft() */ - printf("processed %f Msamples in %f ms\n", off * 1E-6, T*1E3); - nI = ((double)iter) * B; /* number of iterations "normalized" to O(N) = N */ - return (nI / T); /* normalized iterations per second */ -} - - -double bench_shift_rec_osc_sse_c_inp(int B, int N) { - double t0, t1, tstop, T, nI; - int iter, off; - float phase = 0.0F; - complexf *input = (complexf *)malloc(N * sizeof(complexf)); - shift_recursive_osc_t gen_state; - shift_recursive_osc_conf_t gen_conf; - - shift_recursive_osc_sse_t *shift_state = malloc(sizeof(shift_recursive_osc_sse_t)); - shift_recursive_osc_sse_conf_t shift_conf; - - shift_recursive_osc_init(0.001F, 0.0F, &gen_conf, &gen_state); - gen_recursive_osc_c(input, N, &gen_conf, &gen_state); - - shift_recursive_osc_sse_init(-0.0009F, 0.0F, &shift_conf, shift_state); - - iter = 0; - off = 0; - t0 = uclock_sec(1); - tstop = t0 + 0.5; /* benchmark duration: 500 ms */ - do { - // work - shift_recursive_osc_sse_inp_c(input+off, B, &shift_conf, shift_state); - - off += B; - ++iter; - t1 = uclock_sec(0); - } while ( t1 < tstop && off + B < N ); - - save(input, B, off, BENCH_FILE_REC_OSC_SSE_INP_C); - free(input); - T = ( t1 - t0 ); /* duration per fft() */ - printf("processed %f Msamples in %f ms\n", off * 1E-6, T*1E3); - nI = ((double)iter) * B; /* number of iterations "normalized" to O(N) = N */ - return (nI / T); /* normalized iterations per second */ -} - - - -int main(int argc, char **argv) -{ - double rt; - - // process up to 64 MSample (512 MByte) in blocks of 8 kSamples (=64 kByte) - int B = 8 * 1024; - int N = 64 * 1024 * 1024; - int showUsage = 0; - - if (argc == 1) - showUsage = 1; - - if (1 < argc) - B = atoi(argv[1]); - if (2 < argc) - N = atoi(argv[2]) * 1024 * 1024; - - if ( !B || !N || showUsage ) - { - fprintf(stderr, "%s [ [] ]\n", argv[0]); - if ( !B || !N ) - return 0; - } - - fprintf(stderr, "processing up to N = %d MSamples with blocke length of %d samples\n", - N / (1024 * 1024), B ); - - -#if BENCH_REF_TRIG_FUNC - printf("\nstarting bench of shift_math_cc (out-of-place) with trig functions ..\n"); - rt = bench_shift_math_cc(B, N); - printf(" %f MSamples/sec\n\n", rt * 1E-6); -#endif - -#if BENCH_OUT_OF_PLACE_ALGOS - printf("starting bench of shift_table_cc (out-of-place) ..\n"); - rt = bench_shift_table_cc(B, N); - printf(" %f MSamples/sec\n\n", rt * 1E-6); - - printf("starting bench of shift_addfast_cc (out-of-place) ..\n"); - rt = bench_shift_addfast(B, N); - printf(" %f MSamples/sec\n\n", rt * 1E-6); - - printf("\nstarting bench of shift_unroll_cc (out-of-place) ..\n"); - rt = bench_shift_unroll_oop(B, N); - printf(" %f MSamples/sec\n\n", rt * 1E-6); - - printf("\nstarting bench of shift_limited_unroll_cc (out-of-place) ..\n"); - rt = bench_shift_limited_unroll_oop(B, N); - printf(" %f MSamples/sec\n\n", rt * 1E-6); - - printf("\nstarting bench of shift_recursive_osc_cc (out-of-place) ..\n"); - rt = bench_shift_rec_osc_cc_oop(B, N); - printf(" %f MSamples/sec\n\n", rt * 1E-6); -#endif - -#if BENCH_INPLACE_ALGOS - - printf("starting bench of shift_addfast_inp_c in-place ..\n"); - rt = bench_shift_addfast_inp(B, N); - printf(" %f MSamples/sec\n\n", rt * 1E-6); - - printf("starting bench of shift_unroll_inp_c in-place ..\n"); - rt = bench_shift_unroll_inp(B, N); - printf(" %f MSamples/sec\n\n", rt * 1E-6); - - printf("starting bench of shift_limited_unroll_inp_c in-place ..\n"); - rt = bench_shift_limited_unroll_inp(B, N); - printf(" %f MSamples/sec\n\n", rt * 1E-6); - - if ( have_sse_shift_mixer_impl() ) - { - printf("starting bench of shift_limited_unroll_A_sse_inp_c in-place ..\n"); - rt = bench_shift_limited_unroll_A_sse_inp(B, N); - printf(" %f MSamples/sec\n\n", rt * 1E-6); - - printf("starting bench of shift_limited_unroll_B_sse_inp_c in-place ..\n"); - rt = bench_shift_limited_unroll_B_sse_inp(B, N); - printf(" %f MSamples/sec\n\n", rt * 1E-6); - - printf("starting bench of shift_limited_unroll_C_sse_inp_c in-place ..\n"); - rt = bench_shift_limited_unroll_C_sse_inp(B, N); - printf(" %f MSamples/sec\n\n", rt * 1E-6); - } - - printf("starting bench of shift_recursive_osc_cc in-place ..\n"); - rt = bench_shift_rec_osc_cc_inp(B, N); - printf(" %f MSamples/sec\n\n", rt * 1E-6); - - if ( have_sse_shift_mixer_impl() ) - { - printf("starting bench of shift_recursive_osc_sse_c in-place ..\n"); - rt = bench_shift_rec_osc_sse_c_inp(B, N); - printf(" %f MSamples/sec\n\n", rt * 1E-6); - } -#endif - - return 0; -} - diff --git a/source_modules/sddc_source/src/libsddc/Core/pffft/fmv.h b/source_modules/sddc_source/src/libsddc/Core/pffft/fmv.h deleted file mode 100644 index 0aa439d..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/pffft/fmv.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef FMV_H - -#if HAVE_FUNC_ATTRIBUTE_IFUNC -#if defined(__has_attribute) -#if __has_attribute(target_clones) -#if defined(__x86_64) - -// see https://gcc.gnu.org/wiki/FunctionMultiVersioning -#define PF_TARGET_CLONES __attribute__((target_clones("avx","sse4.2","sse3","sse2","sse","default"))) -#define HAVE_PF_TARGET_CLONES 1 -#endif -#endif -#endif -#endif - -#ifndef PF_TARGET_CLONES -#define PF_TARGET_CLONES -#endif - -#endif diff --git a/source_modules/sddc_source/src/libsddc/Core/pffft/pf_mixer.cpp b/source_modules/sddc_source/src/libsddc/Core/pffft/pf_mixer.cpp deleted file mode 100644 index 58ff1a5..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/pffft/pf_mixer.cpp +++ /dev/null @@ -1,1148 +0,0 @@ -/* -This software is part of pffft/pfdsp, a set of simple DSP routines. - -Copyright (c) 2014, Andras Retzler -Copyright (c) 2020 Hayati Ayguen -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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. - * Neither the name of the copyright holder nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL ANDRAS RETZLER 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. -*/ - -/* include own header first, to see missing includes */ -#include "pf_mixer.h" -#include "fmv.h" - -#include -#include -#include - -//they dropped M_PI in C99, so we define it: -#define PI ((float)3.14159265358979323846) - -//apply to pointers: -#define iof(complexf_input_p,i) (*(((float*)complexf_input_p)+2*(i))) -#define qof(complexf_input_p,i) (*(((float*)complexf_input_p)+2*(i)+1)) - -#define USE_ALIGNED_ADDRESSES 0 - - - -/* - _____ _____ _____ __ _ _ - | __ \ / ____| __ \ / _| | | (_) - | | | | (___ | |__) | | |_ _ _ _ __ ___| |_ _ ___ _ __ ___ - | | | |\___ \| ___/ | _| | | | '_ \ / __| __| |/ _ \| '_ \/ __| - | |__| |____) | | | | | |_| | | | | (__| |_| | (_) | | | \__ \ - |_____/|_____/|_| |_| \__,_|_| |_|\___|\__|_|\___/|_| |_|___/ - -*/ - - -#if defined(__GNUC__) -# define ALWAYS_INLINE(return_type) inline return_type __attribute__ ((always_inline)) -# define RESTRICT __restrict -#elif defined(_MSC_VER) -# define ALWAYS_INLINE(return_type) __forceinline return_type -# define RESTRICT __restrict -#endif - - -#ifndef PFFFT_SIMD_DISABLE -#if (defined(__x86_64__) || defined(_M_X64) || defined(i386) || defined(_M_IX86)) - #pragma message("Manual SSE x86/x64 optimizations are ON") - #include - #define HAVE_SSE_INTRINSICS 1 - -#elif defined(PFFFT_ENABLE_NEON) && defined(__arm__) - #pragma message "Manual NEON (arm32) optimizations are ON" - #include "sse2neon.h" - #define HAVE_SSE_INTRINSICS 1 - -#elif defined(PFFFT_ENABLE_NEON) && defined(__aarch64__) - #pragma message "Manual NEON (aarch64) optimizations are ON" - #include "sse2neon.h" - #define HAVE_SSE_INTRINSICS 1 - -#endif -#endif - -#ifdef HAVE_SSE_INTRINSICS - -typedef __m128 v4sf; -# define SIMD_SZ 4 - -typedef union v4_union { - __m128 v; - float f[4]; -} v4_union; - -#define VMUL(a,b) _mm_mul_ps(a,b) -#define VDIV(a,b) _mm_div_ps(a,b) -#define VADD(a,b) _mm_add_ps(a,b) -#define VSUB(a,b) _mm_sub_ps(a,b) -#define LD_PS1(s) _mm_set1_ps(s) -#define VLOAD_UNALIGNED(ptr) _mm_loadu_ps((const float *)(ptr)) -#define VLOAD_ALIGNED(ptr) _mm_load_ps((const float *)(ptr)) -#define VSTORE_UNALIGNED(ptr, v) _mm_storeu_ps((float*)(ptr), v) -#define VSTORE_ALIGNED(ptr, v) _mm_store_ps((float*)(ptr), v) -#define INTERLEAVE2(in1, in2, out1, out2) { __m128 tmp__ = _mm_unpacklo_ps(in1, in2); out2 = _mm_unpackhi_ps(in1, in2); out1 = tmp__; } -#define UNINTERLEAVE2(in1, in2, out1, out2) { __m128 tmp__ = _mm_shuffle_ps(in1, in2, _MM_SHUFFLE(2,0,2,0)); out2 = _mm_shuffle_ps(in1, in2, _MM_SHUFFLE(3,1,3,1)); out1 = tmp__; } - -#if USE_ALIGNED_ADDRESSES - #define VLOAD(ptr) _mm_load_ps((const float *)(ptr)) - #define VSTORE(ptr, v) _mm_store_ps((float*)(ptr), v) -#else - #define VLOAD(ptr) _mm_loadu_ps((const float *)(ptr)) - #define VSTORE(ptr, v) _mm_storeu_ps((float*)(ptr), v) -#endif - - -int have_sse_shift_mixer_impl() -{ - return 1; -} - -#else - -int have_sse_shift_mixer_impl() -{ - return 0; -} - -#endif - - -/*********************************************************************/ - -/**************/ -/*** ALGO A ***/ -/**************/ - -PF_TARGET_CLONES -float shift_math_cc(complexf *input, complexf* output, int input_size, float rate, float starting_phase) -{ - rate*=2; - //Shifts the complex spectrum. Basically a complex mixer. This version uses cmath. - float phase=starting_phase; - float phase_increment=rate*PI; - float cosval, sinval; - for(int i=0;i2*PI) phase-=2*PI; //@shift_math_cc: normalize phase - while(phase<0) phase+=2*PI; - } - return phase; -} - -/*********************************************************************/ - -/**************/ -/*** ALGO B ***/ -/**************/ - -shift_table_data_t shift_table_init(int table_size) -{ - shift_table_data_t output; - output.table=(float*)malloc(sizeof(float)*table_size); - output.table_size=table_size; - for(int i=0;i1)?-1:1; //in quadrant 2 and 3 - cos_sign=(quadrant&&quadrant<3)?-1:1; //in quadrant 1 and 2 - sinval=sin_sign*table_data.table[sin_index]; - cosval=cos_sign*table_data.table[cos_index]; - //we multiply two complex numbers. - //how? enter this to maxima (software) for explanation: - // (a+b*%i)*(c+d*%i), rectform; - iof(output,i)=cosval*iof(input,i)-sinval*qof(input,i); - qof(output,i)=sinval*iof(input,i)+cosval*qof(input,i); - phase+=phase_increment; - while(phase>2*PI) phase-=2*PI; //@shift_math_cc: normalize phase - while(phase<0) phase+=2*PI; - } - return phase; -} - -/*********************************************************************/ - -/**************/ -/*** ALGO C ***/ -/**************/ - -shift_addfast_data_t shift_addfast_init(float rate) -{ - shift_addfast_data_t output; - output.phase_increment=2*rate*PI; - for(int i=0;i<4;i++) - { - output.dsin[i]=sinf(output.phase_increment*(i+1)); - output.dcos[i]=cosf(output.phase_increment*(i+1)); - } - return output; -} - -#define SADF_L1(j) \ - cos_vals_ ## j = cos_start * dcos_ ## j - sin_start * dsin_ ## j; \ - sin_vals_ ## j = sin_start * dcos_ ## j + cos_start * dsin_ ## j; -#define SADF_L2(j) \ - iof(output,4*i+j)=(cos_vals_ ## j)*iof(input,4*i+j)-(sin_vals_ ## j)*qof(input,4*i+j); \ - qof(output,4*i+j)=(sin_vals_ ## j)*iof(input,4*i+j)+(cos_vals_ ## j)*qof(input,4*i+j); - -PF_TARGET_CLONES -float shift_addfast_cc(complexf *input, complexf* output, int input_size, shift_addfast_data_t* d, float starting_phase) -{ - //input_size should be multiple of 4 - //fprintf(stderr, "shift_addfast_cc: input_size = %d\n", input_size); - float cos_start=cosf(starting_phase); - float sin_start=sinf(starting_phase); - float cos_vals_0, cos_vals_1, cos_vals_2, cos_vals_3, - sin_vals_0, sin_vals_1, sin_vals_2, sin_vals_3, - dsin_0 = d->dsin[0], dsin_1 = d->dsin[1], dsin_2 = d->dsin[2], dsin_3 = d->dsin[3], - dcos_0 = d->dcos[0], dcos_1 = d->dcos[1], dcos_2 = d->dcos[2], dcos_3 = d->dcos[3]; - - for(int i=0;iphase_increment; - while(starting_phase>PI) starting_phase-=2*PI; - while(starting_phase<-PI) starting_phase+=2*PI; - return starting_phase; -} - -#undef SADF_L2 - - -#define SADF_L2(j) \ - tmp_inp_cos = iof(in_out,4*i+j); \ - tmp_inp_sin = qof(in_out,4*i+j); \ - iof(in_out,4*i+j)=(cos_vals_ ## j)*tmp_inp_cos - (sin_vals_ ## j)*tmp_inp_sin; \ - qof(in_out,4*i+j)=(sin_vals_ ## j)*tmp_inp_cos + (cos_vals_ ## j)*tmp_inp_sin; - -PF_TARGET_CLONES -float shift_addfast_inp_c(complexf *in_out, int N_cplx, shift_addfast_data_t* d, float starting_phase) -{ - //input_size should be multiple of 4 - //fprintf(stderr, "shift_addfast_cc: input_size = %d\n", input_size); - float cos_start=cosf(starting_phase); - float sin_start=sinf(starting_phase); - float tmp_inp_cos, tmp_inp_sin, - cos_vals_0, cos_vals_1, cos_vals_2, cos_vals_3, - sin_vals_0, sin_vals_1, sin_vals_2, sin_vals_3, - dsin_0 = d->dsin[0], dsin_1 = d->dsin[1], dsin_2 = d->dsin[2], dsin_3 = d->dsin[3], - dcos_0 = d->dcos[0], dcos_1 = d->dcos[1], dcos_2 = d->dcos[2], dcos_3 = d->dcos[3]; - - for(int i=0;iphase_increment; - while(starting_phase>PI) starting_phase-=2*PI; - while(starting_phase<-PI) starting_phase+=2*PI; - return starting_phase; -} - -#undef SADF_L1 -#undef SADF_L2 - - -/*********************************************************************/ - -/**************/ -/*** ALGO D ***/ -/**************/ - -shift_unroll_data_t shift_unroll_init(float rate, int size) -{ - shift_unroll_data_t output; - output.phase_increment=2*rate*PI; - output.size = size; - output.dsin=(float*)malloc(sizeof(float)*size); - output.dcos=(float*)malloc(sizeof(float)*size); - float myphase = 0; - for(int i=0;iPI) myphase-=2*PI; - while(myphase<-PI) myphase+=2*PI; - output.dsin[i]=sinf(myphase); - output.dcos[i]=cosf(myphase); - } - return output; -} - -void shift_unroll_deinit(shift_unroll_data_t* d) -{ - if (!d) - return; - free(d->dsin); - free(d->dcos); - d->dsin = NULL; - d->dcos = NULL; -} - -PF_TARGET_CLONES -float shift_unroll_cc(complexf *input, complexf* output, int input_size, shift_unroll_data_t* d, float starting_phase) -{ - //input_size should be multiple of 4 - //fprintf(stderr, "shift_addfast_cc: input_size = %d\n", input_size); - float cos_start = cosf(starting_phase); - float sin_start = sinf(starting_phase); - float cos_val = cos_start, sin_val = sin_start; - for(int i=0;idcos[i] - sin_start * d->dsin[i]; - sin_val = sin_start * d->dcos[i] + cos_start * d->dsin[i]; - } - starting_phase+=input_size*d->phase_increment; - while(starting_phase>PI) starting_phase-=2*PI; - while(starting_phase<-PI) starting_phase+=2*PI; - return starting_phase; -} - -PF_TARGET_CLONES -float shift_unroll_inp_c(complexf* in_out, int size, shift_unroll_data_t* d, float starting_phase) -{ - float cos_start = cosf(starting_phase); - float sin_start = sinf(starting_phase); - float cos_val = cos_start, sin_val = sin_start; - for(int i=0;idcos[i] - sin_start * d->dsin[i]; - sin_val = sin_start * d->dcos[i] + cos_start * d->dsin[i]; - } - starting_phase += size * d->phase_increment; - while(starting_phase>PI) starting_phase-=2*PI; - while(starting_phase<-PI) starting_phase+=2*PI; - return starting_phase; -} - - -/*********************************************************************/ - -/**************/ -/*** ALGO E ***/ -/**************/ - -shift_limited_unroll_data_t shift_limited_unroll_init(float rate) -{ - shift_limited_unroll_data_t output; - output.phase_increment=2*rate*PI; - float myphase = 0; - for(int i=0; i < PF_SHIFT_LIMITED_UNROLL_SIZE; i++) - { - myphase += output.phase_increment; - while(myphase>PI) myphase-=2*PI; - while(myphase<-PI) myphase+=2*PI; - output.dcos[i] = cosf(myphase); - output.dsin[i] = sinf(myphase); - } - output.complex_phase.i = 1.0F; - output.complex_phase.q = 0.0F; - return output; -} - -PF_TARGET_CLONES -void shift_limited_unroll_cc(const complexf *input, complexf* output, int size, shift_limited_unroll_data_t* d) -{ - float cos_start = d->complex_phase.i; - float sin_start = d->complex_phase.q; - float cos_val = cos_start, sin_val = sin_start, mag; - while (size > 0) - { - int N = (size >= PF_SHIFT_LIMITED_UNROLL_SIZE) ? PF_SHIFT_LIMITED_UNROLL_SIZE : size; - for(int i=0;idcos[PF_SHIFT_LIMITED_SIMD_SZ*i+j] - sin_start * d->dsin[PF_SHIFT_LIMITED_SIMD_SZ*i+j]; - sin_val = sin_start * d->dcos[PF_SHIFT_LIMITED_SIMD_SZ*i+j] + cos_start * d->dsin[PF_SHIFT_LIMITED_SIMD_SZ*i+j]; - } - } - // "starts := vals := vals / |vals|" - mag = sqrtf(cos_val * cos_val + sin_val * sin_val); - cos_val /= mag; - sin_val /= mag; - cos_start = cos_val; - sin_start = sin_val; - - input += PF_SHIFT_LIMITED_UNROLL_SIZE; - output += PF_SHIFT_LIMITED_UNROLL_SIZE; - size -= PF_SHIFT_LIMITED_UNROLL_SIZE; - } - d->complex_phase.i = cos_val; - d->complex_phase.q = sin_val; -} - -PF_TARGET_CLONES -void shift_limited_unroll_inp_c(complexf* in_out, int N_cplx, shift_limited_unroll_data_t* d) -{ - float inp_i[PF_SHIFT_LIMITED_SIMD_SZ]; - float inp_q[PF_SHIFT_LIMITED_SIMD_SZ]; - // "vals := starts := phase_state" - float cos_start = d->complex_phase.i; - float sin_start = d->complex_phase.q; - float cos_val = cos_start, sin_val = sin_start, mag; - while (N_cplx) - { - int N = (N_cplx >= PF_SHIFT_LIMITED_UNROLL_SIZE) ? PF_SHIFT_LIMITED_UNROLL_SIZE : N_cplx; - for(int i=0;idcos[PF_SHIFT_LIMITED_SIMD_SZ*i+j] - sin_start * d->dsin[PF_SHIFT_LIMITED_SIMD_SZ*i+j]; - sin_val = sin_start * d->dcos[PF_SHIFT_LIMITED_SIMD_SZ*i+j] + cos_start * d->dsin[PF_SHIFT_LIMITED_SIMD_SZ*i+j]; - } - } - // "starts := vals := vals / |vals|" - mag = sqrtf(cos_val * cos_val + sin_val * sin_val); - cos_val /= mag; - sin_val /= mag; - cos_start = cos_val; - sin_start = sin_val; - - in_out += PF_SHIFT_LIMITED_UNROLL_SIZE; - N_cplx -= PF_SHIFT_LIMITED_UNROLL_SIZE; - } - // "phase_state := starts" - d->complex_phase.i = cos_start; - d->complex_phase.q = sin_start; -} - - -#ifdef HAVE_SSE_INTRINSICS - -/*********************************************************************/ - -/**************/ -/*** ALGO F ***/ -/**************/ - -shift_limited_unroll_A_sse_data_t shift_limited_unroll_A_sse_init(float relative_freq, float phase_start_rad) -{ - shift_limited_unroll_A_sse_data_t output; - float myphase; - - output.phase_increment = 2*relative_freq*PI; - - myphase = 0.0F; - for (int i = 0; i < PF_SHIFT_LIMITED_UNROLL_SIZE + PF_SHIFT_LIMITED_SIMD_SZ; i += PF_SHIFT_LIMITED_SIMD_SZ) - { - for (int k = 0; k < PF_SHIFT_LIMITED_SIMD_SZ; k++) - { - myphase += output.phase_increment; - while(myphase>PI) myphase-=2*PI; - while(myphase<-PI) myphase+=2*PI; - } - output.dcos[i] = cosf(myphase); - output.dsin[i] = sinf(myphase); - for (int k = 1; k < PF_SHIFT_LIMITED_SIMD_SZ; k++) - { - output.dcos[i+k] = output.dcos[i]; - output.dsin[i+k] = output.dsin[i]; - } - } - - output.dcos_blk = 0.0F; - output.dsin_blk = 0.0F; - - myphase = phase_start_rad; - for (int i = 0; i < PF_SHIFT_LIMITED_SIMD_SZ; i++) - { - output.phase_state_i[i] = cosf(myphase); - output.phase_state_q[i] = sinf(myphase); - myphase += output.phase_increment; - while(myphase>PI) myphase-=2*PI; - while(myphase<-PI) myphase+=2*PI; - } - return output; -} - - -PF_TARGET_CLONES -void shift_limited_unroll_A_sse_inp_c(complexf* in_out, int N_cplx, shift_limited_unroll_A_sse_data_t* d) -{ - // "vals := starts := phase_state" - __m128 cos_starts = VLOAD( &d->phase_state_i[0] ); - __m128 sin_starts = VLOAD( &d->phase_state_q[0] ); - __m128 cos_vals = cos_starts; - __m128 sin_vals = sin_starts; - __m128 inp_re, inp_im; - __m128 product_re, product_im; - __m128 interl_prod_a, interl_prod_b; - __m128 * RESTRICT p_trig_cos_tab; - __m128 * RESTRICT p_trig_sin_tab; - __m128 * RESTRICT u = (__m128*)in_out; - - while (N_cplx) - { - const int NB = (N_cplx >= PF_SHIFT_LIMITED_UNROLL_SIZE) ? PF_SHIFT_LIMITED_UNROLL_SIZE : N_cplx; - int B = NB; - p_trig_cos_tab = (__m128*)( &d->dcos[0] ); - p_trig_sin_tab = (__m128*)( &d->dsin[0] ); - while (B) - { - // complex multiplication of 4 complex values from/to in_out[] - // == u[0..3] *= (cos_val[0..3] + i * sin_val[0..3]): - // "out[] = inp[] * vals" - UNINTERLEAVE2(VLOAD(u), VLOAD(u+1), inp_re, inp_im); /* inp_re = all reals; inp_im = all imags */ - product_re = VSUB( VMUL(inp_re, cos_vals), VMUL(inp_im, sin_vals) ); - product_im = VADD( VMUL(inp_im, cos_vals), VMUL(inp_re, sin_vals) ); - INTERLEAVE2( product_re, product_im, interl_prod_a, interl_prod_b); - VSTORE(u, interl_prod_a); - VSTORE(u+1, interl_prod_b); - u += 2; - // calculate complex phasor for next iteration - // cos_val = cos_start * d->dcos[PF_SHIFT_LIMITED_SIMD_SZ*i+j] - sin_start * d->dsin[PF_SHIFT_LIMITED_SIMD_SZ*i+j]; - // sin_val = sin_start * d->dcos[PF_SHIFT_LIMITED_SIMD_SZ*i+j] + cos_start * d->dsin[PF_SHIFT_LIMITED_SIMD_SZ*i+j]; - // cos_val[]/sin_val[] .. can't fade towards 0 inside this while loop :-) - // "vals := d[] * starts" - inp_re = VLOAD(p_trig_cos_tab); - inp_im = VLOAD(p_trig_sin_tab); - cos_vals = VSUB( VMUL(inp_re, cos_starts), VMUL(inp_im, sin_starts) ); - sin_vals = VADD( VMUL(inp_im, cos_starts), VMUL(inp_re, sin_starts) ); - ++p_trig_cos_tab; - ++p_trig_sin_tab; - B -= 4; - } - N_cplx -= NB; - /* normalize d->phase_state_i[]/d->phase_state_q[], that magnitude does not fade towards 0 ! */ - /* re-use product_re[]/product_im[] for normalization */ - // "starts := vals := vals / |vals|" - product_re = VADD( VMUL(cos_vals, cos_vals), VMUL(sin_vals, sin_vals) ); -#if 0 - // more spikes in spectrum! at PF_SHIFT_LIMITED_UNROLL_SIZE = 64 - // higher spikes in spectrum at PF_SHIFT_LIMITED_UNROLL_SIZE = 16 - product_im = _mm_rsqrt_ps(product_re); - cos_starts = cos_vals = VMUL(cos_vals, product_im); - sin_starts = sin_vals = VMUL(sin_vals, product_im); -#else - // spectrally comparable to shift_match_cc() with PF_SHIFT_LIMITED_UNROLL_SIZE = 64 - but slower! - // spectrally comparable to shift_match_cc() with PF_SHIFT_LIMITED_UNROLL_SIZE = 128 - fast again - product_im = _mm_sqrt_ps(product_re); - cos_starts = cos_vals = VDIV(cos_vals, product_im); - sin_starts = sin_vals = VDIV(sin_vals, product_im); -#endif - } - // "phase_state := starts" - VSTORE( &d->phase_state_i[0], cos_starts ); - VSTORE( &d->phase_state_q[0], sin_starts ); -} - - -/*********************************************************************/ - -/**************/ -/*** ALGO G ***/ -/**************/ - -shift_limited_unroll_B_sse_data_t shift_limited_unroll_B_sse_init(float relative_freq, float phase_start_rad) -{ - shift_limited_unroll_B_sse_data_t output; - float myphase; - - output.phase_increment = 2*relative_freq*PI; - - myphase = 0.0F; - for (int i = 0; i < PF_SHIFT_LIMITED_UNROLL_SIZE + PF_SHIFT_LIMITED_SIMD_SZ; i += PF_SHIFT_LIMITED_SIMD_SZ) - { - for (int k = 0; k < PF_SHIFT_LIMITED_SIMD_SZ; k++) - { - myphase += output.phase_increment; - while(myphase>PI) myphase-=2*PI; - while(myphase<-PI) myphase+=2*PI; - } - output.dtrig[i+0] = cosf(myphase); - output.dtrig[i+1] = sinf(myphase); - output.dtrig[i+2] = output.dtrig[i+0]; - output.dtrig[i+3] = output.dtrig[i+1]; - } - - output.dcos_blk = 0.0F; - output.dsin_blk = 0.0F; - - myphase = phase_start_rad; - for (int i = 0; i < PF_SHIFT_LIMITED_SIMD_SZ; i++) - { - output.phase_state_i[i] = cosf(myphase); - output.phase_state_q[i] = sinf(myphase); - myphase += output.phase_increment; - while(myphase>PI) myphase-=2*PI; - while(myphase<-PI) myphase+=2*PI; - } - return output; -} - - -PF_TARGET_CLONES -void shift_limited_unroll_B_sse_inp_c(complexf* in_out, int N_cplx, shift_limited_unroll_B_sse_data_t* d) -{ - // "vals := starts := phase_state" - __m128 cos_starts = VLOAD( &d->phase_state_i[0] ); - __m128 sin_starts = VLOAD( &d->phase_state_q[0] ); - __m128 cos_vals = cos_starts; - __m128 sin_vals = sin_starts; - __m128 inp_re, inp_im; - __m128 product_re, product_im; - __m128 interl_prod_a, interl_prod_b; - __m128 * RESTRICT p_trig_tab; - __m128 * RESTRICT u = (__m128*)in_out; - - while (N_cplx) - { - const int NB = (N_cplx >= PF_SHIFT_LIMITED_UNROLL_SIZE) ? PF_SHIFT_LIMITED_UNROLL_SIZE : N_cplx; - int B = NB; - p_trig_tab = (__m128*)( &d->dtrig[0] ); - while (B) - { - // complex multiplication of 4 complex values from/to in_out[] - // == u[0..3] *= (cos_val[0..3] + i * sin_val[0..3]): - // "out[] = inp[] * vals" - UNINTERLEAVE2(VLOAD(u), VLOAD(u+1), inp_re, inp_im); /* inp_re = all reals; inp_im = all imags */ - product_re = VSUB( VMUL(inp_re, cos_vals), VMUL(inp_im, sin_vals) ); - product_im = VADD( VMUL(inp_im, cos_vals), VMUL(inp_re, sin_vals) ); - INTERLEAVE2( product_re, product_im, interl_prod_a, interl_prod_b); - VSTORE(u, interl_prod_a); - VSTORE(u+1, interl_prod_b); - u += 2; - // calculate complex phasor for next iteration - // cos_val = cos_start * d->dcos[PF_SHIFT_LIMITED_SIMD_SZ*i+j] - sin_start * d->dsin[PF_SHIFT_LIMITED_SIMD_SZ*i+j]; - // sin_val = sin_start * d->dcos[PF_SHIFT_LIMITED_SIMD_SZ*i+j] + cos_start * d->dsin[PF_SHIFT_LIMITED_SIMD_SZ*i+j]; - // cos_val[]/sin_val[] .. can't fade towards 0 inside this while loop :-) - // "vals := d[] * starts" - product_re = VLOAD(p_trig_tab); - UNINTERLEAVE2(product_re, product_re, inp_re, inp_im); /* inp_re = all reals; inp_im = all imags */ - cos_vals = VSUB( VMUL(inp_re, cos_starts), VMUL(inp_im, sin_starts) ); - sin_vals = VADD( VMUL(inp_im, cos_starts), VMUL(inp_re, sin_starts) ); - ++p_trig_tab; - B -= 4; - } - N_cplx -= NB; - /* normalize d->phase_state_i[]/d->phase_state_q[], that magnitude does not fade towards 0 ! */ - /* re-use product_re[]/product_im[] for normalization */ - // "starts := vals := vals / |vals|" - product_re = VADD( VMUL(cos_vals, cos_vals), VMUL(sin_vals, sin_vals) ); -#if 0 - // more spikes in spectrum! at PF_SHIFT_LIMITED_UNROLL_SIZE = 64 - // higher spikes in spectrum at PF_SHIFT_LIMITED_UNROLL_SIZE = 16 - product_im = _mm_rsqrt_ps(product_re); - cos_starts = cos_vals = VMUL(cos_vals, product_im); - sin_starts = sin_vals = VMUL(sin_vals, product_im); -#else - // spectrally comparable to shift_match_cc() with PF_SHIFT_LIMITED_UNROLL_SIZE = 64 - but slower! - // spectrally comparable to shift_match_cc() with PF_SHIFT_LIMITED_UNROLL_SIZE = 128 - fast again - product_im = _mm_sqrt_ps(product_re); - cos_starts = cos_vals = VDIV(cos_vals, product_im); - sin_starts = sin_vals = VDIV(sin_vals, product_im); -#endif - } - // "phase_state := starts" - VSTORE( &d->phase_state_i[0], cos_starts ); - VSTORE( &d->phase_state_q[0], sin_starts ); -} - - -/*********************************************************************/ - - -/**************/ -/*** ALGO H ***/ -/**************/ - -shift_limited_unroll_C_sse_data_t shift_limited_unroll_C_sse_init(float relative_freq, float phase_start_rad) -{ - shift_limited_unroll_C_sse_data_t output; - float myphase; - - output.phase_increment = 2*relative_freq*PI; - - myphase = 0.0F; - for (int i = 0; i < PF_SHIFT_LIMITED_UNROLL_SIZE + PF_SHIFT_LIMITED_SIMD_SZ; i += PF_SHIFT_LIMITED_SIMD_SZ) - { - for (int k = 0; k < PF_SHIFT_LIMITED_SIMD_SZ; k++) - { - myphase += output.phase_increment; - while(myphase>PI) myphase-=2*PI; - while(myphase<-PI) myphase+=2*PI; - } - output.dinterl_trig[2*i] = cosf(myphase); - output.dinterl_trig[2*i+4] = sinf(myphase); - for (int k = 1; k < PF_SHIFT_LIMITED_SIMD_SZ; k++) - { - output.dinterl_trig[2*i+k] = output.dinterl_trig[2*i]; - output.dinterl_trig[2*i+k+4] = output.dinterl_trig[2*i+4]; - } - } - - output.dcos_blk = 0.0F; - output.dsin_blk = 0.0F; - - myphase = phase_start_rad; - for (int i = 0; i < PF_SHIFT_LIMITED_SIMD_SZ; i++) - { - output.phase_state_i[i] = cosf(myphase); - output.phase_state_q[i] = sinf(myphase); - myphase += output.phase_increment; - while(myphase>PI) myphase-=2*PI; - while(myphase<-PI) myphase+=2*PI; - } - return output; -} - - -PF_TARGET_CLONES -void shift_limited_unroll_C_sse_inp_c(complexf* in_out, int N_cplx, shift_limited_unroll_C_sse_data_t* d) -{ - // "vals := starts := phase_state" - __m128 cos_starts = VLOAD( &d->phase_state_i[0] ); - __m128 sin_starts = VLOAD( &d->phase_state_q[0] ); - __m128 cos_vals = cos_starts; - __m128 sin_vals = sin_starts; - __m128 inp_re, inp_im; - __m128 product_re, product_im; - __m128 interl_prod_a, interl_prod_b; - __m128 * RESTRICT p_trig_tab; - __m128 * RESTRICT u = (__m128*)in_out; - - while (N_cplx) - { - const int NB = (N_cplx >= PF_SHIFT_LIMITED_UNROLL_SIZE) ? PF_SHIFT_LIMITED_UNROLL_SIZE : N_cplx; - int B = NB; - p_trig_tab = (__m128*)( &d->dinterl_trig[0] ); - while (B) - { - // complex multiplication of 4 complex values from/to in_out[] - // == u[0..3] *= (cos_val[0..3] + i * sin_val[0..3]): - // "out[] = inp[] * vals" - UNINTERLEAVE2(VLOAD(u), VLOAD(u+1), inp_re, inp_im); /* inp_re = all reals; inp_im = all imags */ - product_re = VSUB( VMUL(inp_re, cos_vals), VMUL(inp_im, sin_vals) ); - product_im = VADD( VMUL(inp_im, cos_vals), VMUL(inp_re, sin_vals) ); - INTERLEAVE2( product_re, product_im, interl_prod_a, interl_prod_b); - VSTORE(u, interl_prod_a); - VSTORE(u+1, interl_prod_b); - u += 2; - // calculate complex phasor for next iteration - // cos_val = cos_start * d->dcos[PF_SHIFT_LIMITED_SIMD_SZ*i+j] - sin_start * d->dsin[PF_SHIFT_LIMITED_SIMD_SZ*i+j]; - // sin_val = sin_start * d->dcos[PF_SHIFT_LIMITED_SIMD_SZ*i+j] + cos_start * d->dsin[PF_SHIFT_LIMITED_SIMD_SZ*i+j]; - // cos_val[]/sin_val[] .. can't fade towards 0 inside this while loop :-) - // "vals := d[] * starts" - inp_re = VLOAD(p_trig_tab); - inp_im = VLOAD(p_trig_tab+1); - cos_vals = VSUB( VMUL(inp_re, cos_starts), VMUL(inp_im, sin_starts) ); - sin_vals = VADD( VMUL(inp_im, cos_starts), VMUL(inp_re, sin_starts) ); - p_trig_tab += 2; - B -= 4; - } - N_cplx -= NB; - /* normalize d->phase_state_i[]/d->phase_state_q[], that magnitude does not fade towards 0 ! */ - /* re-use product_re[]/product_im[] for normalization */ - // "starts := vals := vals / |vals|" - product_re = VADD( VMUL(cos_vals, cos_vals), VMUL(sin_vals, sin_vals) ); -#if 0 - // more spikes in spectrum! at PF_SHIFT_LIMITED_UNROLL_SIZE = 64 - // higher spikes in spectrum at PF_SHIFT_LIMITED_UNROLL_SIZE = 16 - product_im = _mm_rsqrt_ps(product_re); - cos_starts = cos_vals = VMUL(cos_vals, product_im); - sin_starts = sin_vals = VMUL(sin_vals, product_im); -#else - // spectrally comparable to shift_match_cc() with PF_SHIFT_LIMITED_UNROLL_SIZE = 64 - but slower! - // spectrally comparable to shift_match_cc() with PF_SHIFT_LIMITED_UNROLL_SIZE = 128 - fast again - product_im = _mm_sqrt_ps(product_re); - cos_starts = cos_vals = VDIV(cos_vals, product_im); - sin_starts = sin_vals = VDIV(sin_vals, product_im); -#endif - } - // "phase_state := starts" - VSTORE( &d->phase_state_i[0], cos_starts ); - VSTORE( &d->phase_state_q[0], sin_starts ); -} - - -#else - -/*********************************************************************/ - -shift_limited_unroll_A_sse_data_t shift_limited_unroll_A_sse_init(float relative_freq, float phase_start_rad) { - assert(0); - shift_limited_unroll_A_sse_data_t r; - return r; -} -shift_limited_unroll_B_sse_data_t shift_limited_unroll_B_sse_init(float relative_freq, float phase_start_rad) { - assert(0); - shift_limited_unroll_B_sse_data_t r; - return r; -} -shift_limited_unroll_C_sse_data_t shift_limited_unroll_C_sse_init(float relative_freq, float phase_start_rad) { - assert(0); - shift_limited_unroll_C_sse_data_t r; - return r; -} - -void shift_limited_unroll_A_sse_inp_c(complexf* in_out, int N_cplx, shift_limited_unroll_A_sse_data_t* d) { - assert(0); -} -void shift_limited_unroll_B_sse_inp_c(complexf* in_out, int N_cplx, shift_limited_unroll_B_sse_data_t* d) { - assert(0); -} -void shift_limited_unroll_C_sse_inp_c(complexf* in_out, int N_cplx, shift_limited_unroll_C_sse_data_t* d) { - assert(0); -} - -#endif - - -/*********************************************************************/ - -/**************/ -/*** ALGO I ***/ -/**************/ - -void shift_recursive_osc_update_rate(float rate, shift_recursive_osc_conf_t *conf, shift_recursive_osc_t* state) -{ - // constants for single phase step - float phase_increment_s = rate*PI; - float k1 = tanf(0.5f*phase_increment_s); - float k2 = 2*k1 /(1 + k1 * k1); - for (int j=1; ju_cos[j] = state->u_cos[j-1]; - state->v_sin[j] = state->v_sin[j-1]; - // small steps - tmp = state->u_cos[j] - k1 * state->v_sin[j]; - state->v_sin[j] += k2 * tmp; - state->u_cos[j] = tmp - k1 * state->v_sin[j]; - } - - // constants for PF_SHIFT_RECURSIVE_SIMD_SZ times phase step - float phase_increment_b = phase_increment_s * PF_SHIFT_RECURSIVE_SIMD_SZ; - while(phase_increment_b > PI) phase_increment_b-=2*PI; - while(phase_increment_b < -PI) phase_increment_b+=2*PI; - conf->k1 = tanf(0.5f*phase_increment_b); - conf->k2 = 2*conf->k1 / (1 + conf->k1 * conf->k1); -} - -void shift_recursive_osc_init(float rate, float starting_phase, shift_recursive_osc_conf_t *conf, shift_recursive_osc_t *state) -{ - if (starting_phase != 0.0F) - { - state->u_cos[0] = cosf(starting_phase); - state->v_sin[0] = sinf(starting_phase); - } - else - { - state->u_cos[0] = 1.0F; - state->v_sin[0] = 0.0F; - } - shift_recursive_osc_update_rate(rate, conf, state); -} - - -PF_TARGET_CLONES -void shift_recursive_osc_cc(const complexf *input, complexf* output, - int size, const shift_recursive_osc_conf_t *conf, shift_recursive_osc_t* state_ext) -{ - float tmp[PF_SHIFT_RECURSIVE_SIMD_SZ]; - float inp_i[PF_SHIFT_RECURSIVE_SIMD_SZ]; - float inp_q[PF_SHIFT_RECURSIVE_SIMD_SZ]; - shift_recursive_osc_t state = *state_ext; - const float k1 = conf->k1; - const float k2 = conf->k2; - for(int i=0;ik1; - const float k2 = conf->k2; - for(int i=0;ik1; - const float k2 = conf->k2; - for(int i=0;iu_cos[j] = state->u_cos[j-1]; - state->v_sin[j] = state->v_sin[j-1]; - // small steps - tmp = state->u_cos[j] - k1 * state->v_sin[j]; - state->v_sin[j] += k2 * tmp; - state->u_cos[j] = tmp - k1 * state->v_sin[j]; - } - - // constants for PF_SHIFT_RECURSIVE_SIMD_SSE_SZ times phase step - float phase_increment_b = phase_increment_s * PF_SHIFT_RECURSIVE_SIMD_SSE_SZ; - while(phase_increment_b > PI) phase_increment_b-=2*PI; - while(phase_increment_b < -PI) phase_increment_b+=2*PI; - conf->k1 = tanf(0.5f*phase_increment_b); - conf->k2 = 2*conf->k1 / (1 + conf->k1 * conf->k1); -} - - -void shift_recursive_osc_sse_init(float rate, float starting_phase, shift_recursive_osc_sse_conf_t *conf, shift_recursive_osc_sse_t *state) -{ - if (starting_phase != 0.0F) - { - state->u_cos[0] = cosf(starting_phase); - state->v_sin[0] = sinf(starting_phase); - } - else - { - state->u_cos[0] = 1.0F; - state->v_sin[0] = 0.0F; - } - shift_recursive_osc_sse_update_rate(rate, conf, state); -} - - -PF_TARGET_CLONES -void shift_recursive_osc_sse_inp_c(complexf* in_out, - int N_cplx, const shift_recursive_osc_sse_conf_t *conf, shift_recursive_osc_sse_t* state_ext) -{ - const __m128 k1 = LD_PS1( conf->k1 ); - const __m128 k2 = LD_PS1( conf->k2 ); - __m128 u_cos = VLOAD( &state_ext->u_cos[0] ); - __m128 v_sin = VLOAD( &state_ext->v_sin[0] ); - __m128 inp_re, inp_im; - __m128 product_re, product_im; - __m128 interl_prod_a, interl_prod_b; - __m128 * RESTRICT u = (__m128*)in_out; - - while (N_cplx) - { - //inp_i[j] = in_out[PF_SHIFT_RECURSIVE_SIMD_SSE_SZ*i+j].i; - //inp_q[j] = in_out[PF_SHIFT_RECURSIVE_SIMD_SSE_SZ*i+j].q; - UNINTERLEAVE2(VLOAD(u), VLOAD(u+1), inp_re, inp_im); /* inp_re = all reals; inp_im = all imags */ - - //we multiply two complex numbers - similar to shift_math_cc - //iof(in_out,PF_SHIFT_RECURSIVE_SIMD_SSE_SZ*i+j) = state.u_cos[j] * inp_i[j] - state.v_sin[j] * inp_q[j]; - //qof(in_out,PF_SHIFT_RECURSIVE_SIMD_SSE_SZ*i+j) = state.v_sin[j] * inp_i[j] + state.u_cos[j] * inp_q[j]; - product_re = VSUB( VMUL(inp_re, u_cos), VMUL(inp_im, v_sin) ); - product_im = VADD( VMUL(inp_im, u_cos), VMUL(inp_re, v_sin) ); - INTERLEAVE2( product_re, product_im, interl_prod_a, interl_prod_b); - VSTORE(u, interl_prod_a); - VSTORE(u+1, interl_prod_b); - u += 2; - - // update complex phasor - like incrementing phase - // tmp[j] = state.u_cos[j] - k1 * state.v_sin[j]; - product_re = VSUB( u_cos, VMUL(k1, v_sin) ); - // state.v_sin[j] += k2 * tmp[j]; - v_sin = VADD( v_sin, VMUL(k2, product_re) ); - // state.u_cos[j] = tmp[j] - k1 * state.v_sin[j]; - u_cos = VSUB( product_re, VMUL(k1, v_sin) ); - - N_cplx -= 4; - } - VSTORE( &state_ext->u_cos[0], u_cos ); - VSTORE( &state_ext->v_sin[0], v_sin ); -} - -#else - -void shift_recursive_osc_sse_update_rate(float rate, shift_recursive_osc_sse_conf_t *conf, shift_recursive_osc_sse_t* state) -{ - assert(0); -} - -void shift_recursive_osc_sse_init(float rate, float starting_phase, shift_recursive_osc_sse_conf_t *conf, shift_recursive_osc_sse_t *state) -{ - assert(0); -} - - -void shift_recursive_osc_sse_inp_c(complexf* in_out, - int N_cplx, const shift_recursive_osc_sse_conf_t *conf, shift_recursive_osc_sse_t* state_ext) -{ - assert(0); -} - -#endif - diff --git a/source_modules/sddc_source/src/libsddc/Core/pffft/pf_mixer.h b/source_modules/sddc_source/src/libsddc/Core/pffft/pf_mixer.h deleted file mode 100644 index e4987a4..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/pffft/pf_mixer.h +++ /dev/null @@ -1,283 +0,0 @@ -/* -This software is part of pffft/pfdsp, a set of simple DSP routines. - -Copyright (c) 2014, Andras Retzler -Copyright (c) 2020 Hayati Ayguen -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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. - * Neither the name of the copyright holder nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL ANDRAS RETZLER 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. -*/ - -#ifndef _PF_MIXER_H_ -#define _PF_MIXER_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - _____ _ - / ____| | | - | | ___ _ __ ___ _ __ | | _____ __ - | | / _ \| '_ ` _ \| '_ \| |/ _ \ \/ / - | |___| (_) | | | | | | |_) | | __/> < - \_____\___/|_| |_| |_| .__/|_|\___/_/\_\ - | | - |_| -*/ - -typedef struct complexf_s { float i; float q; } complexf; - -// ================================================================================= - -int have_sse_shift_mixer_impl(); - - -/*********************************************************************/ - -/**************/ -/*** ALGO A ***/ -/**************/ - -float shift_math_cc(complexf *input, complexf* output, int input_size, float rate, float starting_phase); - - -/*********************************************************************/ - -/**************/ -/*** ALGO B ***/ -/**************/ - -typedef struct shift_table_data_s -{ - float* table; - int table_size; -} shift_table_data_t; - -void shift_table_deinit(shift_table_data_t table_data); -shift_table_data_t shift_table_init(int table_size); -float shift_table_cc(complexf* input, complexf* output, int input_size, float rate, shift_table_data_t table_data, float starting_phase); - -/*********************************************************************/ - -/**************/ -/*** ALGO C ***/ -/**************/ - -typedef struct shift_addfast_data_s -{ - float dsin[4]; - float dcos[4]; - float phase_increment; -} shift_addfast_data_t; - -shift_addfast_data_t shift_addfast_init(float rate); -float shift_addfast_cc(complexf *input, complexf* output, int input_size, shift_addfast_data_t* d, float starting_phase); -float shift_addfast_inp_c(complexf *in_out, int N_cplx, shift_addfast_data_t* d, float starting_phase); - - -/*********************************************************************/ - -/**************/ -/*** ALGO D ***/ -/**************/ - -typedef struct shift_unroll_data_s -{ - float* dsin; - float* dcos; - float phase_increment; - int size; -} shift_unroll_data_t; - -shift_unroll_data_t shift_unroll_init(float rate, int size); -void shift_unroll_deinit(shift_unroll_data_t* d); -float shift_unroll_cc(complexf *input, complexf* output, int size, shift_unroll_data_t* d, float starting_phase); -float shift_unroll_inp_c(complexf* in_out, int size, shift_unroll_data_t* d, float starting_phase); - - -/*********************************************************************/ - -/**************/ -/*** ALGO E ***/ -/**************/ - -/* similar to shift_unroll_cc() - but, have fixed and limited precalc size - * idea: smaller cache usage by table - * size must be multiple of CSDR_SHIFT_LIMITED_SIMD (= 4) - */ -#define PF_SHIFT_LIMITED_UNROLL_SIZE 128 -#define PF_SHIFT_LIMITED_SIMD_SZ 4 - -typedef struct shift_limited_unroll_data_s -{ - float dcos[PF_SHIFT_LIMITED_UNROLL_SIZE]; - float dsin[PF_SHIFT_LIMITED_UNROLL_SIZE]; - complexf complex_phase; - float phase_increment; -} shift_limited_unroll_data_t; - -shift_limited_unroll_data_t shift_limited_unroll_init(float rate); -/* size must be multiple of PF_SHIFT_LIMITED_SIMD_SZ */ -/* starting_phase for next call is kept internal in state */ -void shift_limited_unroll_cc(const complexf *input, complexf* output, int size, shift_limited_unroll_data_t* d); -void shift_limited_unroll_inp_c(complexf* in_out, int size, shift_limited_unroll_data_t* d); - - -/*********************************************************************/ - -/**************/ -/*** ALGO F ***/ -/**************/ - -typedef struct shift_limited_unroll_A_sse_data_s -{ - /* small/limited trig table */ - float dcos[PF_SHIFT_LIMITED_UNROLL_SIZE+PF_SHIFT_LIMITED_SIMD_SZ]; - float dsin[PF_SHIFT_LIMITED_UNROLL_SIZE+PF_SHIFT_LIMITED_SIMD_SZ]; - /* 4 times complex phase */ - float phase_state_i[PF_SHIFT_LIMITED_SIMD_SZ]; - float phase_state_q[PF_SHIFT_LIMITED_SIMD_SZ]; - /* N_cplx_per_block times increment - for future parallel variants */ - float dcos_blk; - float dsin_blk; - /* */ - float phase_increment; -} shift_limited_unroll_A_sse_data_t; - -shift_limited_unroll_A_sse_data_t shift_limited_unroll_A_sse_init(float relative_freq, float phase_start_rad); -void shift_limited_unroll_A_sse_inp_c(complexf* in_out, int N_cplx, shift_limited_unroll_A_sse_data_t* d); - - -/*********************************************************************/ - -/**************/ -/*** ALGO G ***/ -/**************/ - -typedef struct shift_limited_unroll_B_sse_data_s -{ - /* small/limited trig table */ - float dtrig[PF_SHIFT_LIMITED_UNROLL_SIZE+PF_SHIFT_LIMITED_SIMD_SZ]; - /* 4 times complex phase */ - float phase_state_i[PF_SHIFT_LIMITED_SIMD_SZ]; - float phase_state_q[PF_SHIFT_LIMITED_SIMD_SZ]; - /* N_cplx_per_block times increment - for future parallel variants */ - float dcos_blk; - float dsin_blk; - /* */ - float phase_increment; -} shift_limited_unroll_B_sse_data_t; - -shift_limited_unroll_B_sse_data_t shift_limited_unroll_B_sse_init(float relative_freq, float phase_start_rad); -void shift_limited_unroll_B_sse_inp_c(complexf* in_out, int N_cplx, shift_limited_unroll_B_sse_data_t* d); - -/*********************************************************************/ - -/**************/ -/*** ALGO H ***/ -/**************/ - -typedef struct shift_limited_unroll_C_sse_data_s -{ - /* small/limited trig table - interleaved: 4 cos, 4 sin, 4 cos, .. */ - float dinterl_trig[2*(PF_SHIFT_LIMITED_UNROLL_SIZE+PF_SHIFT_LIMITED_SIMD_SZ)]; - /* 4 times complex phase */ - float phase_state_i[PF_SHIFT_LIMITED_SIMD_SZ]; - float phase_state_q[PF_SHIFT_LIMITED_SIMD_SZ]; - /* N_cplx_per_block times increment - for future parallel variants */ - float dcos_blk; - float dsin_blk; - /* */ - float phase_increment; -} shift_limited_unroll_C_sse_data_t; - -shift_limited_unroll_C_sse_data_t shift_limited_unroll_C_sse_init(float relative_freq, float phase_start_rad); -void shift_limited_unroll_C_sse_inp_c(complexf* in_out, int N_cplx, shift_limited_unroll_C_sse_data_t* d); - - - -/*********************************************************************/ - -/**************/ -/*** ALGO I ***/ -/**************/ - -/* Recursive Quadrature Oscillator functions "recursive_osc" - * see https://www.vicanek.de/articles/QuadOsc.pdf - */ -#define PF_SHIFT_RECURSIVE_SIMD_SZ 8 -typedef struct shift_recursive_osc_s -{ - float u_cos[PF_SHIFT_RECURSIVE_SIMD_SZ]; - float v_sin[PF_SHIFT_RECURSIVE_SIMD_SZ]; -} shift_recursive_osc_t; - -typedef struct shift_recursive_osc_conf_s -{ - float k1; - float k2; -} shift_recursive_osc_conf_t; - -void shift_recursive_osc_init(float rate, float starting_phase, shift_recursive_osc_conf_t *conf, shift_recursive_osc_t *state); -void shift_recursive_osc_update_rate(float rate, shift_recursive_osc_conf_t *conf, shift_recursive_osc_t* state); - -/* size must be multiple of PF_SHIFT_LIMITED_SIMD_SZ */ -/* starting_phase for next call is kept internal in state */ -void shift_recursive_osc_cc(const complexf *input, complexf* output, int size, const shift_recursive_osc_conf_t *conf, shift_recursive_osc_t* state); -void shift_recursive_osc_inp_c(complexf* output, int size, const shift_recursive_osc_conf_t *conf, shift_recursive_osc_t* state); -void gen_recursive_osc_c(complexf* output, int size, const shift_recursive_osc_conf_t *conf, shift_recursive_osc_t* state); - -/*********************************************************************/ - -/**************/ -/*** ALGO J ***/ -/**************/ - -#define PF_SHIFT_RECURSIVE_SIMD_SSE_SZ 4 -typedef struct shift_recursive_osc_sse_s -{ - float u_cos[PF_SHIFT_RECURSIVE_SIMD_SSE_SZ]; - float v_sin[PF_SHIFT_RECURSIVE_SIMD_SSE_SZ]; -} shift_recursive_osc_sse_t; - -typedef struct shift_recursive_osc_sse_conf_s -{ - float k1; - float k2; -} shift_recursive_osc_sse_conf_t; - -void shift_recursive_osc_sse_init(float rate, float starting_phase, shift_recursive_osc_sse_conf_t *conf, shift_recursive_osc_sse_t *state); -void shift_recursive_osc_sse_update_rate(float rate, shift_recursive_osc_sse_conf_t *conf, shift_recursive_osc_sse_t* state); -void shift_recursive_osc_sse_inp_c(complexf* in_out, int N_cplx, const shift_recursive_osc_sse_conf_t *conf, shift_recursive_osc_sse_t* state_ext); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/source_modules/sddc_source/src/libsddc/Core/r2iq.h b/source_modules/sddc_source/src/libsddc/Core/r2iq.h deleted file mode 100644 index 7c5bb87..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/r2iq.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef R2IQ_H -#define R2IQ_H -#include "license.txt" - -#define NDECIDX 7 //number of srate - -#include -#include -#include -#include - -#include "dsp/ringbuffer.h" - -struct r2iqThreadArg; - -class r2iqControlClass { -public: - r2iqControlClass(); - virtual ~r2iqControlClass() {} - - int getRatio() {return mratio [mdecimation];} - - void updateRand(bool v) { this->randADC = v; } - bool getRand() const { return this->randADC; } - - void setSideband(bool lsb) { this->sideband = lsb; } - bool getSideband() const { return this->sideband; } - - void setDecimate(int dec) {this->mdecimation = dec; } - - virtual void Init(float gain, ringbuffer* input, ringbuffer* obuffers) {} - virtual void TurnOn() { this->r2iqOn = true; } - virtual void TurnOff(void) { this->r2iqOn = false; } - virtual bool IsOn(void) { return this->r2iqOn; } - virtual void DataReady(void) {} - virtual float setFreqOffset(float offset) { return 0; }; - -protected: - int mdecimation ; // selected decimation ratio - // 64 Msps: 0 => 32Msps, 1=> 16Msps, 2 = 8Msps, 3 = 4Msps, 4 = 2Msps - // 128 Msps: 0 => 64Msps, 1 => 32Msps, 2=> 16Msps, 3 = 8Msps, 4 = 4Msps, 5 = 2Msps - bool r2iqOn; // r2iq on flag - int mratio [NDECIDX]; // ratio - -private: - bool randADC; // randomized ADC output - bool sideband; -}; - -#endif diff --git a/source_modules/sddc_source/src/libsddc/Core/radio/BBRF103Radio.cpp b/source_modules/sddc_source/src/libsddc/Core/radio/BBRF103Radio.cpp deleted file mode 100644 index 6e47b25..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/radio/BBRF103Radio.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#include "RadioHandler.h" - -#define R820T_FREQ (32000000) // R820T reference frequency -#define R820T2_IF_CARRIER (4570000) - -const float BBRF103Radio::steps[BBRF103Radio::step_size] = { - 0.0f, 0.9f, 1.4f, 2.7f, 3.7f, 7.7f, 8.7f, 12.5f, 14.4f, 15.7f, - 16.6f, 19.7f, 20.7f, 22.9f, 25.4f, 28.0f, 29.7f, 32.8f, - 33.8f, 36.4f, 37.2f, 38.6f, 40.2f, 42.1f, 43.4f, 43.9f, - 44.5f, 48.0f, 49.6f -}; - -const float BBRF103Radio::if_steps[BBRF103Radio::if_step_size] = { - -4.7f, -2.1f, 0.5f, 3.5f, 7.7f, 11.2f, 13.6f, 14.9f, 16.3f, 19.5f, 23.1f, 26.5f, 30.0f, 33.7f, 37.2f, 40.8f -}; - -const float BBRF103Radio::hfsteps[3] = { - -20.0f, -10.0f, 0.0f -}; - -BBRF103Radio::BBRF103Radio(fx3class* fx3) - : RadioHardware(fx3) -{ - -} - -void BBRF103Radio::Initialize(uint32_t adc_rate) -{ - this->SampleRate = adc_rate; - Fx3->Control(STARTADC, adc_rate); -} - -rf_mode BBRF103Radio::PrepareLo(uint64_t freq) -{ - if (freq < 10 * 1000) return NOMODE; - if (freq > 1750 * 1000 * 1000) return NOMODE; - - if ( freq >= this->SampleRate / 2) - return VHFMODE; - else - return HFMODE; -} - -bool BBRF103Radio::UpdatemodeRF(rf_mode mode) -{ - if (mode == VHFMODE) - { - // switch to VHF Attenna - FX3UnsetGPIO(ATT_SEL0 | ATT_SEL1); - - // Initialize Tuner - return Fx3->Control(TUNERINIT, (uint32_t)R820T_FREQ); - } - - else if (mode == HFMODE ) // (mode == HFMODE || mode == VLFMODE) no more VLFMODE - { - // Stop Tuner - Fx3->Control(TUNERSTDBY); - - // switch to HF Attenna - return FX3SetGPIO(ATT_SEL0 | ATT_SEL1); - } - - return false; -} - -bool BBRF103Radio::UpdateattRF(int att) -{ - if (gpios & (ATT_SEL0 | ATT_SEL1)) { - // this is in HF mode - if (att > 2) att = 2; - if (att < 0) att = 0; - switch (att) - { - case 1: //11 - gpios |= ATT_SEL0 | ATT_SEL1; - break; - case 0: //01 - gpios |= ATT_SEL0; - gpios &= ~ATT_SEL1; - break; - case 2: //10 - default: - gpios |= ATT_SEL1; - gpios &= ~ATT_SEL0; - break; - } - return Fx3->Control(GPIOFX3, gpios); - } - else { - uint16_t index = att; - // this is in VHF mode - return Fx3->SetArgument(R82XX_ATTENUATOR, index); - } -} - -uint64_t BBRF103Radio::TuneLo(uint64_t freq) -{ - if (gpios & (ATT_SEL0 | ATT_SEL1)) { - // this is in HF mode - return 0; - } - else { - // this is in VHF mode - Fx3->Control(TUNERTUNE, freq); - return freq - R820T2_IF_CARRIER; - } -} - -int BBRF103Radio::getRFSteps(const float** steps ) -{ - if (gpios & (ATT_SEL0 | ATT_SEL1)) { - *steps = this->hfsteps; - return 3; - } - else - { - *steps = this->steps; - return step_size; - } -} - -int BBRF103Radio::getIFSteps(const float** steps ) -{ - if (gpios & (ATT_SEL0 | ATT_SEL1)) { - return 0; - } - else - { - *steps = this->if_steps; - return if_step_size; - } -} - -bool BBRF103Radio::UpdateGainIF(int attIndex) -{ - if (gpios & (ATT_SEL0 | ATT_SEL1)) { - // this is in HF mode - return false; - } - else { - // this is in VHF mode - return Fx3->SetArgument(R82XX_VGA, (uint16_t)attIndex); - } -} \ No newline at end of file diff --git a/source_modules/sddc_source/src/libsddc/Core/radio/HF103Radio.cpp b/source_modules/sddc_source/src/libsddc/Core/radio/HF103Radio.cpp deleted file mode 100644 index bebd482..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/radio/HF103Radio.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "RadioHandler.h" - -HF103Radio::HF103Radio(fx3class* fx3) - : RadioHardware(fx3) -{ - // initialize steps - for (uint8_t i = 0 ; i < step_size; i++) { - this->steps[step_size - i - 1] = -( - ((i & 0x01) != 0) * 0.5f + - ((i & 0x02) != 0) * 1.0f + - ((i & 0x04) != 0) * 2.0f + - ((i & 0x08) != 0) * 4.0f + - ((i & 0x010) != 0) * 8.0f + - ((i & 0x020) != 0) * 16.0f - ); - } -} - -rf_mode HF103Radio::PrepareLo(uint64_t freq) -{ - if (freq > 32 * 1000 * 1000) return NOMODE; - - return HFMODE; -} - -bool HF103Radio::UpdatemodeRF(rf_mode mode) -{ - if (mode == VHFMODE) - return false; - - return true; -} - -bool HF103Radio::UpdateattRF(int att) -{ - if (att > step_size - 1) att = step_size - 1; - if (att < 0) att = 0; - uint8_t d = step_size - att - 1; - - DbgPrintf("UpdateattRF %f \n", this->steps[att]); - - return Fx3->SetArgument(DAT31_ATT, d); -} - -int HF103Radio::getRFSteps(const float** steps ) -{ - *steps = this->steps; - - return step_size; -} diff --git a/source_modules/sddc_source/src/libsddc/Core/radio/RX888R2Radio.cpp b/source_modules/sddc_source/src/libsddc/Core/radio/RX888R2Radio.cpp deleted file mode 100644 index a7d1e93..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/radio/RX888R2Radio.cpp +++ /dev/null @@ -1,178 +0,0 @@ -#include "RadioHandler.h" - -#define R828D_FREQ (16000000) // R820T reference frequency -#define R828D_IF_CARRIER (4570000) - -#define HIGH_MODE 0x80 -#define LOW_MODE 0x00 - -#define GAIN_SWEET_POINT 18 -#define HIGH_GAIN_RATIO (0.409f) -#define LOW_GAIN_RATIO (0.059f) - -#define MODE HIGH_MODE - -const float RX888R2Radio::vhf_rf_steps[RX888R2Radio::vhf_rf_step_size] = { - 0.0f, 0.9f, 1.4f, 2.7f, 3.7f, 7.7f, 8.7f, 12.5f, 14.4f, 15.7f, - 16.6f, 19.7f, 20.7f, 22.9f, 25.4f, 28.0f, 29.7f, 32.8f, - 33.8f, 36.4f, 37.2f, 38.6f, 40.2f, 42.1f, 43.4f, 43.9f, - 44.5f, 48.0f, 49.6f}; - -const float RX888R2Radio::vhf_if_steps[RX888R2Radio::vhf_if_step_size] = { - -4.7f, -2.1f, 0.5f, 3.5f, 7.7f, 11.2f, 13.6f, 14.9f, 16.3f, 19.5f, 23.1f, 26.5f, 30.0f, 33.7f, 37.2f, 40.8f}; - -RX888R2Radio::RX888R2Radio(fx3class *fx3) - : RadioHardware(fx3) -{ - for (uint8_t i = 0; i < hf_rf_step_size; i++) - { - this->hf_rf_steps[hf_rf_step_size - i - 1] = -( - ((i & 0x01) != 0) * 0.5f + - ((i & 0x02) != 0) * 1.0f + - ((i & 0x04) != 0) * 2.0f + - ((i & 0x08) != 0) * 4.0f + - ((i & 0x010) != 0) * 8.0f + - ((i & 0x020) != 0) * 16.0f); - } - - for (uint8_t i = 0; i < hf_if_step_size; i++) - { - if (i > GAIN_SWEET_POINT) - this->hf_if_steps[i] = 20.0f * log10f(HIGH_GAIN_RATIO * (i - GAIN_SWEET_POINT + 3)); - else - this->hf_if_steps[i] = 20.0f * log10f(LOW_GAIN_RATIO * (i + 1)); - } -} - -void RX888R2Radio::Initialize(uint32_t adc_rate) -{ - SampleRate = adc_rate; - Fx3->Control(STARTADC, adc_rate); -} - -rf_mode RX888R2Radio::PrepareLo(uint64_t freq) -{ - if (freq < 10 * 1000) return NOMODE; - if (freq > 1750 * 1000 * 1000) return NOMODE; - - if ( freq >= this->SampleRate / 2) - return VHFMODE; - else - return HFMODE; -} - -bool RX888R2Radio::UpdatemodeRF(rf_mode mode) -{ - if (mode == VHFMODE) - { - // disable HF by set max ATT - UpdateattRF(0); // max att 0 -> -31.5 dB - - // switch to VHF Attenna - FX3SetGPIO(VHF_EN); - - // high gain, 0db - uint8_t gain = 0x80 | 3; - Fx3->SetArgument(AD8340_VGA, gain); - // Enable Tuner reference clock - uint32_t ref = R828D_FREQ; - return Fx3->Control(TUNERINIT, ref); // Initialize Tuner - } - else if (mode == HFMODE) - { - Fx3->Control(TUNERSTDBY); // Stop Tuner - - return FX3UnsetGPIO(VHF_EN); // switch to HF Attenna - } - - return false; -} - -bool RX888R2Radio::UpdateattRF(int att) -{ - if (!(gpios & VHF_EN)) - { - // hf mode - if (att > hf_rf_step_size - 1) - att = hf_rf_step_size - 1; - if (att < 0) - att = 0; - uint8_t d = hf_rf_step_size - att - 1; - - DbgPrintf("UpdateattRF %f \n", this->hf_rf_steps[att]); - - return Fx3->SetArgument(DAT31_ATT, d); - } - else - { - uint16_t index = att; - // this is in VHF mode - return Fx3->SetArgument(R82XX_ATTENUATOR, index); - } -} - -uint64_t RX888R2Radio::TuneLo(uint64_t freq) -{ - if (!(gpios & VHF_EN)) - { - // this is in HF mode - return 0; - } - else - { - // this is in VHF mode - Fx3->Control(TUNERTUNE, freq); - return freq - R828D_IF_CARRIER; - } -} - -int RX888R2Radio::getRFSteps(const float **steps) -{ - if (!(gpios & VHF_EN)) - { - // hf mode - *steps = this->hf_rf_steps; - return hf_rf_step_size; - } - else - { - *steps = this->vhf_rf_steps; - return vhf_rf_step_size; - } -} - -int RX888R2Radio::getIFSteps(const float **steps) -{ - if (!(gpios & VHF_EN)) - { - *steps = this->hf_if_steps; - return hf_if_step_size; - } - else - { - *steps = this->vhf_if_steps; - return vhf_if_step_size; - } -} - -bool RX888R2Radio::UpdateGainIF(int gain_index) -{ - if (!(gpios & VHF_EN)) - { - // this is in HF mode - uint8_t gain; - if (gain_index > GAIN_SWEET_POINT) - gain = HIGH_MODE | (gain_index - GAIN_SWEET_POINT + 3); - else - gain = LOW_MODE | (gain_index + 1); - - DbgPrintf("UpdateGainIF %d \n", gain); - - return Fx3->SetArgument(AD8340_VGA, gain); - } - else - { - // this is in VHF mode - return Fx3->SetArgument(R82XX_VGA, (uint16_t)gain_index); - } -} \ No newline at end of file diff --git a/source_modules/sddc_source/src/libsddc/Core/radio/RX888R3Radio.cpp b/source_modules/sddc_source/src/libsddc/Core/radio/RX888R3Radio.cpp deleted file mode 100644 index 807c23b..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/radio/RX888R3Radio.cpp +++ /dev/null @@ -1,210 +0,0 @@ -#include "RadioHandler.h" - -#define REFCLK_FREQ (27000000) // R820T reference frequency -#define IF_FREQ (20000000) - -#define HIGH_MODE 0x80 -#define LOW_MODE 0x00 - -#define GAIN_SWEET_POINT 18 -#define HIGH_GAIN_RATIO (0.409f) -#define LOW_GAIN_RATIO (0.059f) - -#define MODE HIGH_MODE - -const float RX888R3Radio::vhf_rf_steps[RX888R3Radio::vhf_rf_step_size] = { - 0.0f, 0.9f, 1.4f, 2.7f, 3.7f, 7.7f, 8.7f, 12.5f, 14.4f, 15.7f, - 16.6f, 19.7f, 20.7f, 22.9f, 25.4f, 28.0f, 29.7f, 32.8f, - 33.8f, 36.4f, 37.2f, 38.6f, 40.2f, 42.1f, 43.4f, 43.9f, - 44.5f, 48.0f, 49.6f}; - -const float RX888R3Radio::vhf_if_steps[RX888R3Radio::vhf_if_step_size] = { - -4.7f, -2.1f, 0.5f, 3.5f, 7.7f, 11.2f, 13.6f, 14.9f, 16.3f, 19.5f, 23.1f, 26.5f, 30.0f, 33.7f, 37.2f, 40.8f}; - -RX888R3Radio::RX888R3Radio(fx3class *fx3) - : RadioHardware(fx3) -{ - for (uint8_t i = 0; i < hf_rf_step_size; i++) - { - this->hf_rf_steps[hf_rf_step_size - i - 1] = -( - ((i & 0x01) != 0) * 0.5f + - ((i & 0x02) != 0) * 1.0f + - ((i & 0x04) != 0) * 2.0f + - ((i & 0x08) != 0) * 4.0f + - ((i & 0x010) != 0) * 8.0f + - ((i & 0x020) != 0) * 16.0f); - } - - for (uint8_t i = 0; i < hf_if_step_size; i++) - { - if (i > GAIN_SWEET_POINT) - this->hf_if_steps[i] = 20.0f * log10f(HIGH_GAIN_RATIO * (i - GAIN_SWEET_POINT + 3)); - else - this->hf_if_steps[i] = 20.0f * log10f(LOW_GAIN_RATIO * (i + 1)); - } -} - -void RX888R3Radio::Initialize(uint32_t adc_rate) -{ - SampleRate = adc_rate; - Fx3->Control(STARTADC, adc_rate); -} - -rf_mode RX888R3Radio::PrepareLo(uint64_t freq) -{ - if (freq < 10 * 1000) return NOMODE; - if (freq > 2150ll * 1000 * 1000) return NOMODE; - - if ( freq >= 220 * 1000 * 1000) - return VHFMODE; - else - return HFMODE; -} - -bool RX888R3Radio::UpdatemodeRF(rf_mode mode) -{ - if (mode == VHFMODE) - { - // disable HF by set max ATT - UpdateattRF(0); // max att 0 -> -31.5 dB - - // switch to VHF Attenna - FX3SetGPIO(VHF_EN); - - // high gain, 0db - uint8_t gain = 0x80 | 3; - Fx3->SetArgument(AD8340_VGA, gain); - // Enable Tuner reference clock - uint32_t ref = REFCLK_FREQ; - return Fx3->Control(TUNERINIT, ref); // Initialize Tuner - } - else if (mode == HFMODE) - { - Fx3->Control(TUNERSTDBY); // Stop Tuner - - return FX3UnsetGPIO(VHF_EN); // switch to HF Attenna - } - - return false; -} - -bool RX888R3Radio::UpdateattRF(int att) -{ - if (!(gpios & VHF_EN)) - { - // hf mode - if (att > hf_rf_step_size - 1) - att = hf_rf_step_size - 1; - if (att < 0) - att = 0; - uint8_t d = hf_rf_step_size - att - 1; - - DbgPrintf("UpdateattRF %f \n", this->hf_rf_steps[att]); - - return Fx3->SetArgument(DAT31_ATT, d); - } - else - { - // uint16_t index = att; - // this is in VHF mode - // return Fx3->SetArgument(R82XX_ATTENUATOR, index); - return false; - } -} - -#define M(x) ((x)*1000000) - -uint64_t RX888R3Radio::TuneLo(uint64_t freq) -{ - if (!(gpios & VHF_EN)) - { - // this is in HF mode - // set bpf - int sel; - // set preselector - if (freq > M(64) && freq <= M(128)) - sel = 0b001; // FM undersampling - else if (SampleRate < M(32)) - sel = 0b101; - else - sel = 0b011; - - Fx3->SetArgument(PRESELECTOR, sel); - - if (freq < M(64)) - return 0; - else if (freq < M(128)) - return M(64); - else if (freq < M(192)) - return M(64 * 2); - else if (freq < M(256)) - return M(64 * 3); - - return 0; - } - else - { - // this is in VHF mode - uint64_t targetVCO = freq + IF_FREQ; - - uint32_t hardwareVCO = targetVCO / 1000000; // convert to MHz - int offset = targetVCO % 1000000; - - DbgPrintf("Target VCO = %luHZ, hardware VCO= %dMHX, Actual IF = %dHZ\n", freq + IF_FREQ, hardwareVCO, IF_FREQ - offset); - - Fx3->Control(TUNERTUNE, hardwareVCO); - return freq - (IF_FREQ - offset); - } -} - -int RX888R3Radio::getRFSteps(const float **steps) -{ - if (!(gpios & VHF_EN)) - { - // hf mode - *steps = this->hf_rf_steps; - return hf_rf_step_size; - } - else - { - *steps = this->vhf_rf_steps; - return vhf_rf_step_size; - } -} - -int RX888R3Radio::getIFSteps(const float **steps) -{ - if (!(gpios & VHF_EN)) - { - *steps = this->hf_if_steps; - return hf_if_step_size; - } - else - { - *steps = this->vhf_if_steps; - return vhf_if_step_size; - } -} - -bool RX888R3Radio::UpdateGainIF(int gain_index) -{ - if (!(gpios & VHF_EN)) - { - // this is in HF mode - uint8_t gain; - if (gain_index > GAIN_SWEET_POINT) - gain = HIGH_MODE | (gain_index - GAIN_SWEET_POINT + 3); - else - gain = LOW_MODE | (gain_index + 1); - - DbgPrintf("UpdateGainIF %d \n", gain); - - return Fx3->SetArgument(AD8340_VGA, gain); - } - else - { - // this is in VHF mode - // return Fx3->SetArgument(R82XX_VGA, (uint16_t)gain_index); - return false; - } -} \ No newline at end of file diff --git a/source_modules/sddc_source/src/libsddc/Core/radio/RX888Radio.cpp b/source_modules/sddc_source/src/libsddc/Core/radio/RX888Radio.cpp deleted file mode 100644 index d16cb07..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/radio/RX888Radio.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "RadioHandler.h" diff --git a/source_modules/sddc_source/src/libsddc/Core/radio/RX999Radio.cpp b/source_modules/sddc_source/src/libsddc/Core/radio/RX999Radio.cpp deleted file mode 100644 index 1cfeeef..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/radio/RX999Radio.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#include "RadioHandler.h" - -#define ADC_FREQ (128u*1000*1000) -#define IF_FREQ (ADC_FREQ / 4) - -#define HIGH_MODE 0x80 -#define LOW_MODE 0x00 - -#define MODE HIGH_MODE - -RX999Radio::RX999Radio(fx3class *fx3) - : RadioHardware(fx3) -{ - // high mode gain = 0.409, start=-30 - // low mode gain = 0.059, start = -30 -#if (MODE == HIGH_MODE) - float ratio = 0.409f; -#else - float ratio = 0.059f; -#endif - for (uint8_t i = 0; i < if_step_size; i++) - { - this->if_steps[i] = -30.0f + ratio * (i + 1); - } -} - -void RX999Radio::Initialize(uint32_t adc_rate) -{ - SampleRate = adc_rate; - Fx3->Control(STARTADC, adc_rate); -} - - -rf_mode RX999Radio::PrepareLo(uint64_t freq) -{ - if (freq < 10 * 1000) return NOMODE; - if (freq > 6000ll * 1000 * 1000) return NOMODE; - - if ( freq >= this->SampleRate / 2) - return VHFMODE; - else - return HFMODE; -} - -bool RX999Radio::UpdatemodeRF(rf_mode mode) -{ - if (mode == VHFMODE) - { - // switch to VHF Attenna - FX3SetGPIO(VHF_EN); - - // Initialize VCO - - // Initialize Mixer - return Fx3->Control(TUNERINIT, (uint32_t)0); - } - else if (mode == HFMODE) - { - Fx3->Control(TUNERSTDBY); - return FX3UnsetGPIO(VHF_EN); // switch to HF Attenna - } - - return false; -} - - -bool RX999Radio::UpdateattRF(int att) -{ - return false; -} - -uint64_t RX999Radio::TuneLo(uint64_t freq) -{ - if (!(gpios & VHF_EN)) - { - // this is in HF mode - return 0; - } - else - { - int sel; - // set preselector - if (freq <= 120*1000*1000) sel = 0b111; - else if (freq <= 250*1000*1000) sel = 0b101; - else if (freq <= 300*1000*1000) sel = 0b110; - else if (freq <= 380*1000*1000) sel = 0b100; - else if (freq <= 500*1000*1000) sel = 0b000; - else if (freq <= 1000ll*1000*1000) sel = 0b010; - else if (freq <= 2000ll*1000*1000) sel = 0b001; - else sel = 0b011; - - Fx3->Control(TUNERTUNE, freq + IF_FREQ); - - Fx3->SetArgument(PRESELECTOR, sel); - // Set VCXO - return freq - IF_FREQ; - } -} - -int RX999Radio::getRFSteps(const float **steps) -{ - return 0; -} - -int RX999Radio::getIFSteps(const float **steps) -{ - *steps = this->if_steps; - return if_step_size; -} - -bool RX999Radio::UpdateGainIF(int gain_index) -{ - uint8_t gain = MODE | (gain_index + 1); - - DbgPrintf("UpdateGainIF %d \n", gain); - - return Fx3->SetArgument(AD8340_VGA, gain); -} diff --git a/source_modules/sddc_source/src/libsddc/Core/radio/RXLucy.cpp b/source_modules/sddc_source/src/libsddc/Core/radio/RXLucy.cpp deleted file mode 100644 index 3ac2ddf..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/radio/RXLucy.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "RadioHandler.h" - -#define ADC_FREQ (64u*1000*1000) -#define IF_FREQ (ADC_FREQ / 4) - -#define HIGH_MODE 0x80 -#define LOW_MODE 0x00 - -#define MODE HIGH_MODE - -RXLucyRadio::RXLucyRadio(fx3class *fx3) - : RadioHardware(fx3) -{ - // initialize steps - for (uint8_t i = 0; i < if_step_size; i++) { - this->if_steps[if_step_size - i - 1] = -( - ((i & 0x01) != 0) * 0.5f + - ((i & 0x02) != 0) * 1.0f + - ((i & 0x04) != 0) * 2.0f + - ((i & 0x08) != 0) * 4.0f + - ((i & 0x010) != 0) * 8.0f + - ((i & 0x020) != 0) * 16.0f - ); - } - - for (uint8_t i = 0; i < step_size; i++) - { - this->steps[step_size - i - 1] = -1.0f * i; - } -} - -void RXLucyRadio::Initialize(uint32_t adc_rate) -{ - SampleRate = adc_rate; - Fx3->Control(STARTADC, adc_rate); -} - - -rf_mode RXLucyRadio::PrepareLo(uint64_t freq) -{ - if (freq < 35000ll * 1000) return NOMODE; - if (freq > 6000ll * 1000 * 1000) return NOMODE; - - if ( freq >= this->SampleRate / 2) - return VHFMODE; - else - return HFMODE; -} - - -bool RXLucyRadio::UpdateattRF(int att) -{ - if (att > step_size - 1) att = step_size - 1; - if (att < 0) att = 0; - uint8_t d = step_size - att - 1; - - DbgPrintf("UpdateattRF %f \n", this->steps[att]); - return Fx3->SetArgument(VHF_ATTENUATOR, d); -} -bool RXLucyRadio::UpdateGainIF(int att) //HF103 now -{ - if (att > if_step_size - 1) att = if_step_size - 1; - if (att < 0) att = 0; - uint8_t d = if_step_size - att - 1; - - DbgPrintf("UpdateattRF %f \n", this->if_steps[att]); - - return Fx3->SetArgument(DAT31_ATT, d); -} - -uint64_t RXLucyRadio::TuneLo(uint64_t freq) -{ - if (!(gpios & VHF_EN)) - { - // this is in HF mode - return 0; - } - else - { - Fx3->Control(TUNERTUNE, freq + IF_FREQ); - - // Set VCXO - return freq - IF_FREQ; - } - -} -bool RXLucyRadio::UpdatemodeRF(rf_mode mode) -{ - if (mode == VHFMODE) - { - // switch to VHF Attenna - FX3SetGPIO(VHF_EN); - - // Initialize VCO - - // Initialize Mixer - return Fx3->Control(TUNERINIT, (uint32_t)0); - } - else if (mode == HFMODE) - { - Fx3->Control(TUNERSTDBY); - return FX3UnsetGPIO(VHF_EN); // switch to HF Attenna - } - return false; -} - -int RXLucyRadio::getRFSteps(const float **steps) -{ - *steps = this->steps; - return step_size; -} - -int RXLucyRadio::getIFSteps(const float** steps) -{ - *steps = this->if_steps; - return if_step_size; -} - - - diff --git a/source_modules/sddc_source/src/libsddc/Core/radio/RadioHardware.cpp b/source_modules/sddc_source/src/libsddc/Core/radio/RadioHardware.cpp deleted file mode 100644 index d21f36e..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/radio/RadioHardware.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "RadioHandler.h" - -bool RadioHardware::FX3SetGPIO(uint32_t mask) -{ - gpios |= mask; - - return Fx3->Control(GPIOFX3, gpios); -} - -bool RadioHardware::FX3UnsetGPIO(uint32_t mask) -{ - gpios &= ~mask; - - return Fx3->Control(GPIOFX3, gpios); -} - -RadioHardware::~RadioHardware() -{ - if (Fx3) { - FX3SetGPIO(SHDWN); - } -} \ No newline at end of file diff --git a/source_modules/sddc_source/src/libsddc/Core/sddc_config.cpp b/source_modules/sddc_source/src/libsddc/Core/sddc_config.cpp deleted file mode 100644 index 6612d18..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/sddc_config.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "license.txt" -#include "sddc_config.h" - -bool saveADCsamplesflag = false; -uint32_t adcnominalfreq = DEFAULT_ADC_FREQ; -uint32_t MIN_ADC_FREQ = 50000000; // ADC sampling frequency minimum -uint32_t MAX_ADC_FREQ = 140000000; // ADC sampling frequency minimum -uint32_t N2_BANDSWITCH = 80000000; // threshold 5 or 6 SR bandwidths diff --git a/source_modules/sddc_source/src/libsddc/Core/sddc_config.h b/source_modules/sddc_source/src/libsddc/Core/sddc_config.h deleted file mode 100644 index 610d3d4..0000000 --- a/source_modules/sddc_source/src/libsddc/Core/sddc_config.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef _CONFIG_H_ -#define _CONFIG_H_ - -#include "license.txt" - -#include "../Interface.h" -#include // atan => PI -#include -#include -#include - -//#define _DEBUG // defined in VS configuration - -#ifdef __cplusplus -inline void null_func(const char *format, ...) { } -#define DbgEmpty null_func -#else -#define DbgEmpty { } -#endif - -// macro to call callback function with just status extHWstatusT -#define EXTIO_STATUS_CHANGE( CB, STATUS ) \ - do { \ - SendMessage(h_dialog, WM_USER + 1, STATUS, 0); \ - if (CB) { \ - DbgPrintf("<==CALLBACK: %s\n", #STATUS); \ - CB( -1, STATUS, 0, NULL );\ - }\ - }while(0) - -#ifdef VERBOSE_DEBUG - #define EnterFunction() \ - DbgPrintf("==>%s\n", __FUNCDNAME__) - - #define EnterFunction1(v1) \ - DbgPrintf("==>%s(%d)\n", __FUNCDNAME__, (v1)) -#else - #define EnterFunction() - #define EnterFunction1(v1) -#endif - -#ifdef _DEBUG -#define DbgPrintf (printf) -#else -#define DbgPrintf DbgEmpty -#endif - -#define VERSION (1.2) // Dll version number x.xx -#define SWVERSION "1.2.1" -#define SETTINGS_IDENTIFIER "sddc_1.06" -#define SWNAME "ExtIO_sddc.dll" - -#define QUEUE_SIZE 32 -#define WIDEFFTN // test FFTN 8192 - -#define FFTN_R_ADC (8192) // FFTN used for ADC real stream DDC tested at 2048, 8192, 32768, 131072 - -// GAINFACTORS to be adjusted with lab reference source measured with HDSDR Smeter rms mode -#define BBRF103_GAINFACTOR (7.8e-8f) // BBRF103 -#define HF103_GAINFACTOR (1.14e-8f) // HF103 -#define RX888_GAINFACTOR (0.695e-8f) // RX888 -#define RX888mk2_GAINFACTOR (1.08e-8f) // RX888mk2 - -enum rf_mode { NOMODE = 0, HFMODE = 0x1, VHFMODE = 0x2 }; - -#define HF_HIGH (32000000) // 32M -#define MW_HIGH ( 2000000) - -#define EXT_BLOCKLEN 512 * 64 /* 32768 only multiples of 512 */ - -#define RFDDCNAME ("NVIA L768M256") -#define RFDDCVER ("v 1.0") - -// URL definitions -#define URL1B "16bit SDR Receiver" -#define URL1 "http://www.hdsdr.de/" -#define URL_HDSR "http://www.hdsdr.de/" -#define URL_HDSDRA "http://www.hdsdr.de/" - -extern bool saveADCsamplesflag; -extern uint32_t adcnominalfreq; - -const uint32_t transferSize = 131072; -const uint32_t transferSamples = 131072 / sizeof(int16_t); - -const uint32_t DEFAULT_ADC_FREQ = 64000000; // ADC sampling frequency - -const uint32_t DEFAULT_TRANSFERS_PER_SEC = DEFAULT_ADC_FREQ / transferSamples; - -extern uint32_t MIN_ADC_FREQ; // ADC sampling frequency minimum -extern uint32_t MAX_ADC_FREQ; // ADC sampling frequency minimum -extern uint32_t N2_BANDSWITCH; // threshold 5 or 6 SR bandwidths -#endif // _CONFIG_H_ - diff --git a/source_modules/sddc_source/src/libsddc/HWSDRtable.h b/source_modules/sddc_source/src/libsddc/HWSDRtable.h deleted file mode 100644 index 9700aab..0000000 --- a/source_modules/sddc_source/src/libsddc/HWSDRtable.h +++ /dev/null @@ -1,44 +0,0 @@ - -/* -HWSDRtable.h v1.2 -Hardware detection of BBRF103 family SDRs -+--------------+-------+------+------+------+------+------+------+------+------+----------------------------+ -| SDR | MODEL | GPIO | GPIO | GPIO | GPIO | GPIO | GPIO | GPIO | GPIO | USED BY | -| | # | 33 | 36 | 45 | 50 | 51 | 52 | 53 | 54 | | -+--------------+-------+------+------+------+------+------+------+------+------+----------------------------+ -| BBRF103 | 0x01 | - | - | - | pd* | - | - | - | LED | Oscar Steila | -+--------------+-------+------+------+------+------+------+------+------+------+----------------------------+ -| HF103 | 0x02 | - | - | - | - | pd* | - | - | LED | Oscar Steila | -+--------------+-------+------+------+------+------+------+------+------+------+----------------------------+ -| RX888 | 0x03 | - | - | pd | - | - | - | - | - | Justin Peng / Howard Su | -+--------------+-------+------+------+------+------+------+------+------+------+----------------------------+ -| RX888 r2 | 0x04 | - | pd | - | - | - | - | - | - | Justin Peng / Howard Su | -+--------------+-------+------+------+------+------+------+------+------+------+----------------------------+ -| RX999 | 0x05 | pd | - | - | - | - | - | - | - | Justin Peng / Howard Su | -+--------------+-------+------+------+------+------+------+------+------+------+----------------------------+ -| LUCY | 0x06 | - | - | - | - | - | pd+ | pd+ | - | Wiktor Starzak | -+--------------+-------+------+------+------+------+------+------+------+------+----------------------------+ -| --- | - | - | - | - | pd | pd | pd | pd | LED | Oscar Steila | -+--------------+-------+------+------+------+------+------+------+------+------+----------------------------+ -| SDR-HF | - | - | - | - | pu | pd | pd | pd | LED | Pieter Ibelings | -+--------------+-------+------+------+------+------+------+------+------+------+----------------------------+ -| | | - | - | | | | | | | ... | -+--------------+-------+------+------+------+------+------+------+------+------+----------------------------+ - -Where: - - floating no connection - pu 1k resistor pull-up to 3V3 - pd 1k resistor pull-down to GND - pd* 1k resistor pull-down to GND to be added with a patch - pd+ 1k resistor pull-down all pd+ are connected to the same pull-down - LED plus resistor to 3V3 connected to GPIO54 on FX3 SuperSpeed Kit - -The 1k value is low enough to be able to detect the resistor using the GPIO internal programmable pull-up pull-down vs a floating pin. -The value is high enough to not disturb use of GPIOs for other purpose after detection. - - - -*/ - - -// TODO \ No newline at end of file diff --git a/source_modules/sddc_source/src/libsddc/Interface.h b/source_modules/sddc_source/src/libsddc/Interface.h deleted file mode 100644 index 0a323bf..0000000 --- a/source_modules/sddc_source/src/libsddc/Interface.h +++ /dev/null @@ -1,154 +0,0 @@ -#pragma once - -#define FIRMWARE_VER_MAJOR 2 -#define FIRMWARE_VER_MINOR 1 - -// HF103 commands !!! -enum FX3Command { - // Start GPII engine and stream the data from ADC - // WRITE: UINT32 - STARTFX3 = 0xAA, - - // Stop GPII engine - // WRITE: UINT32 - STOPFX3 = 0xAB, - - // Get the information of device - // including model, version - // READ: UINT32 - TESTFX3 = 0xAC, - - // Control GPIOs - // WRITE: UINT32 - GPIOFX3 = 0xAD, - - // Write data to I2c bus - // WRITE: DATA - // INDEX: reg - // VALUE: i2c_addr - I2CWFX3 = 0xAE, - - // Read data from I2c bus - // READ: DATA - // INDEX: reg - // VALUE: i2c_addr - I2CRFX3 = 0xAF, - - // Reset USB chip and get back to bootloader mode - // WRITE: NONE - RESETFX3 = 0xB1, - - // Set Argument, packet Index/Vaule contains the data - // WRITE: (Additional Data) - // INDEX: Argument_index - // VALUE: arguement value - SETARGFX3 = 0xB6, - - // Start ADC with the specific frequency - // Optional, if ADC is running with crystal, this is not needed. - // WRITE: UINT32 -> adc frequency - STARTADC = 0xB2, - - // R82XX family Tuner functions - // Initialize R82XX tuner - // WRITE: NONE - TUNERINIT = 0xB4, - - // Tune to a sepcific frequency - // WRITE: UINT64 - TUNERTUNE = 0xB5, - - // Stop Tuner - // WRITE: NONE - TUNERSTDBY = 0xB8, - - // Read Debug string if any - // READ: - READINFODEBUG = 0xBA, -}; - -#define OUTXIO0 (1U << 0) // ATT_LE -#define OUTXIO1 (1U << 1) // ATT_CLK -#define OUTXIO2 (1U << 2) // ATT_DATA -#define OUTXIO3 (1U << 3) // SEL0 -#define OUTXIO4 (1U << 4) // SEL1 -#define OUTXIO5 (1U << 5) // SHDWN -#define OUTXIO6 (1U << 6) // DITH -#define OUTXIO7 (1U << 7) // RAND - -#define OUTXIO8 (1U << 8) // 256 -#define OUTXIO9 (1U << 9) // 512 -#define OUTXI10 (1U << 10) // 1024 -#define OUTXI11 (1U << 11) // 2048 -#define OUTXI12 (1U << 12) // 4096 -#define OUTXI13 (1U << 13) // 8192 -#define OUTXI14 (1U << 14) // 16384 -#define OUTXI15 (1U << 15) // 32768 -#define OUTXI16 (1U << 16) - -enum GPIOPin { - SHDWN = OUTXIO5, - DITH = OUTXIO6, - RANDO = OUTXIO7, - BIAS_HF = OUTXIO8, - BIAS_VHF = OUTXIO9, - LED_YELLOW = OUTXI10, - LED_RED = OUTXI11, - LED_BLUE = OUTXI12, - ATT_SEL0 = OUTXI13, - ATT_SEL1 = OUTXI14, - - // RX888r2 - VHF_EN = OUTXI15, - PGA_EN = OUTXI16, -}; - -enum RadioModel { - NORADIO = 0x00, - BBRF103 = 0x01, - HF103 = 0x02, - RX888 = 0x03, - RX888r2 = 0x04, - RX999 = 0x05, - RXLUCY = 0x06, - RX888r3 = 0x07, -}; - -enum ArgumentList { - // Set R8xx lna/mixer gain - // value: 0-29 - R82XX_ATTENUATOR = 1, - - // Set R8xx vga gain - // value: 0-15 - R82XX_VGA = 2, - - // Set R8xx sideband - // value: 0/1 - R82XX_SIDEBAND = 3, - - // Set R8xx harmonic - // value: 0/1 - R82XX_HARMONIC = 4, - - // Set DAT-31 Att - // Value: 0-63 - DAT31_ATT = 10, - - // Set AD8340 chip vga - // Value: 0-255 - AD8340_VGA = 11, - - // Preselector - // Value: 0-2 - PRESELECTOR = 12, - - // VHFATT - // Value: 0-15 - VHF_ATTENUATOR = 13, -}; - -#define _DEBUG_USB_ -#define MAXLEN_D_USB (100) - - diff --git a/source_modules/sddc_source/src/libsddc/LICENSE.txt b/source_modules/sddc_source/src/libsddc/LICENSE.txt deleted file mode 100644 index e143754..0000000 --- a/source_modules/sddc_source/src/libsddc/LICENSE.txt +++ /dev/null @@ -1,23 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017-2020 Oscar Steila ik1xpvgmail.com - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE.The MIT License (MIT) -The MIT License (MIT) - diff --git a/source_modules/sddc_source/src/libsddc/libsddc/CMakeLists.txt b/source_modules/sddc_source/src/libsddc/libsddc/CMakeLists.txt deleted file mode 100644 index 452f90e..0000000 --- a/source_modules/sddc_source/src/libsddc/libsddc/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -cmake_minimum_required(VERSION 3.13) - -if (MSVC) - set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) -endif (MSVC) - -include_directories("." "../Core") - -add_library(sddc SHARED - libsddc.cpp -) - -if (MSVC) - target_link_libraries(sddc PUBLIC Setupapi.lib) -else() - target_include_directories(sddc PUBLIC "${LIBUSB_INCLUDE_DIR}") - target_link_directories(sddc PUBLIC "${LIBUSB_LIBRARY_DIRS}") - target_link_libraries(sddc PUBLIC ${LIBUSB_LIBRARIES}) -endif (MSVC) - -target_include_directories(sddc PUBLIC "${LIBFFTW_INCLUDE_DIR}") -target_link_directories(sddc PUBLIC "${LIBFFTW_LIBRARY_DIRS}") -target_link_libraries(sddc PUBLIC ${LIBFFTW_LIBRARIES}) - -target_link_libraries(sddc PRIVATE SDDC_CORE) -set_target_properties(sddc PROPERTIES VERSION ${PROJECT_VERSION}) -set_target_properties(sddc PROPERTIES SOVERSION 0) - -# applications -add_executable(sddc_test sddc_test.c) -target_link_libraries(sddc_test PRIVATE sddc ${ASANLIB}) - -add_executable(sddc_stream_test sddc_stream_test.c wavewrite.c) -target_link_libraries(sddc_stream_test sddc ${ASANLIB}) - -add_executable(sddc_vhf_stream_test sddc_vhf_stream_test.c wavewrite.c) -target_link_libraries(sddc_vhf_stream_test sddc ${ASANLIB}) diff --git a/source_modules/sddc_source/src/libsddc/libsddc/libsddc.cpp b/source_modules/sddc_source/src/libsddc/libsddc/libsddc.cpp deleted file mode 100644 index ba27f0b..0000000 --- a/source_modules/sddc_source/src/libsddc/libsddc/libsddc.cpp +++ /dev/null @@ -1,396 +0,0 @@ -#include "libsddc.h" -#include "sddc_config.h" -#include "r2iq.h" -#include "RadioHandler.h" - -struct sddc -{ - SDDCStatus status; - RadioHandlerClass* handler; - uint8_t led; - int samplerateidx; - double freq; - - sddc_read_async_cb_t callback; - void *callback_context; -}; - -sddc_t *current_running; - -static void Callback(const float* data, uint32_t len) -{ -} - -class rawdata : public r2iqControlClass { - void Init(float gain, ringbuffer* buffers, ringbuffer* obuffers) override - { - idx = 0; - } - - void TurnOn() override - { - this->r2iqOn = true; - idx = 0; - } - -private: - int idx; -}; - -int sddc_get_device_count() -{ - return 1; -} - -int sddc_get_device_info(struct sddc_device_info **sddc_device_infos) -{ - auto ret = new sddc_device_info(); - const char *todo = "TODO"; - ret->manufacturer = todo; - ret->product = todo; - ret->serial_number = todo; - - *sddc_device_infos = ret; - - return 1; -} - -int sddc_free_device_info(struct sddc_device_info *sddc_device_infos) -{ - delete sddc_device_infos; - return 0; -} - -sddc_t *sddc_open(int index, const char* imagefile) -{ - auto ret_val = new sddc_t(); - - fx3class *fx3 = CreateUsbHandler(); - if (fx3 == nullptr) - { - return nullptr; - } - - // open the firmware - unsigned char* res_data; - uint32_t res_size; - - FILE *fp = fopen(imagefile, "rb"); - if (fp == nullptr) - { - return nullptr; - } - - fseek(fp, 0, SEEK_END); - res_size = ftell(fp); - res_data = (unsigned char*)malloc(res_size); - fseek(fp, 0, SEEK_SET); - if (fread(res_data, 1, res_size, fp) != res_size) - return nullptr; - - bool openOK = fx3->Open(res_data, res_size); - if (!openOK) - return nullptr; - - ret_val->handler = new RadioHandlerClass(); - - if (ret_val->handler->Init(fx3, Callback, new rawdata())) - { - ret_val->status = SDDC_STATUS_READY; - ret_val->samplerateidx = 0; - } - - return ret_val; -} - -void sddc_close(sddc_t *that) -{ - if (that->handler) - delete that->handler; - delete that; -} - -enum SDDCStatus sddc_get_status(sddc_t *t) -{ - return t->status; -} - -enum SDDCHWModel sddc_get_hw_model(sddc_t *t) -{ - switch(t->handler->getModel()) - { - case RadioModel::BBRF103: - return HW_BBRF103; - case RadioModel::HF103: - return HW_HF103; - case RadioModel::RX888: - return HW_RX888; - case RadioModel::RX888r2: - return HW_RX888R2; - case RadioModel::RX888r3: - return HW_RX888R3; - case RadioModel::RX999: - return HW_RX999; - default: - return HW_NORADIO; - } -} - -const char *sddc_get_hw_model_name(sddc_t *t) -{ - return t->handler->getName(); -} - -uint16_t sddc_get_firmware(sddc_t *t) -{ - return t->handler->GetFirmware(); -} - -const double *sddc_get_frequency_range(sddc_t *t) -{ - return nullptr; -} - -enum RFMode sddc_get_rf_mode(sddc_t *t) -{ - switch(t->handler->GetmodeRF()) - { - case HFMODE: - return RFMode::HF_MODE; - case VHFMODE: - return RFMode::VHF_MODE; - default: - return RFMode::NO_RF_MODE; - } -} - -int sddc_set_rf_mode(sddc_t *t, enum RFMode rf_mode) -{ - switch (rf_mode) - { - case VHF_MODE: - t->handler->UpdatemodeRF(VHFMODE); - break; - case HF_MODE: - t->handler->UpdatemodeRF(HFMODE); - default: - return -1; - } - - return 0; -} - -/* LED functions */ -int sddc_led_on(sddc_t *t, uint8_t led_pattern) -{ - if (led_pattern & YELLOW_LED) - t->handler->uptLed(0, true); - if (led_pattern & RED_LED) - t->handler->uptLed(1, true); - if (led_pattern & BLUE_LED) - t->handler->uptLed(2, true); - - t->led |= led_pattern; - - return 0; -} - -int sddc_led_off(sddc_t *t, uint8_t led_pattern) -{ - if (led_pattern & YELLOW_LED) - t->handler->uptLed(0, false); - if (led_pattern & RED_LED) - t->handler->uptLed(1, false); - if (led_pattern & BLUE_LED) - t->handler->uptLed(2, false); - - t->led &= ~led_pattern; - - return 0; -} - -int sddc_led_toggle(sddc_t *t, uint8_t led_pattern) -{ - t->led = t->led ^ led_pattern; - if (t->led & YELLOW_LED) - t->handler->uptLed(0, false); - if (t->led & RED_LED) - t->handler->uptLed(1, false); - if (t->led & BLUE_LED) - t->handler->uptLed(2, false); - - return 0; -} - - -/* ADC functions */ -int sddc_get_adc_dither(sddc_t *t) -{ - return t->handler->GetDither(); -} - -int sddc_set_adc_dither(sddc_t *t, int dither) -{ - t->handler->UptDither(dither != 0); - return 0; -} - -int sddc_get_adc_random(sddc_t *t) -{ - return t->handler->GetRand(); -} - -int sddc_set_adc_random(sddc_t *t, int random) -{ - t->handler->UptRand(random != 0); - return 0; -} - -/* HF block functions */ -double sddc_get_hf_attenuation(sddc_t *t) -{ - return 0; -} - -int sddc_set_hf_attenuation(sddc_t *t, double attenuation) -{ - return 0; -} - -int sddc_get_hf_bias(sddc_t *t) -{ - return t->handler->GetBiasT_HF(); -} - -int sddc_set_hf_bias(sddc_t *t, int bias) -{ - t->handler->UpdBiasT_HF(bias != 0); - return 0; -} - - -/* VHF block and VHF/UHF tuner functions */ -double sddc_get_tuner_frequency(sddc_t *t) -{ - return t->freq; -} - -int sddc_set_tuner_frequency(sddc_t *t, double frequency) -{ - t->freq = t->handler->TuneLO((int64_t)frequency); - - return 0; -} - -int sddc_get_tuner_rf_attenuations(sddc_t *t, const double *attenuations[]) -{ - return 0; -} - -double sddc_get_tuner_rf_attenuation(sddc_t *t) -{ - return 0; -} - -int sddc_set_tuner_rf_attenuation(sddc_t *t, double attenuation) -{ - //TODO, convert double to index - t->handler->UpdateattRF(5); - return 0; -} - -int sddc_get_tuner_if_attenuations(sddc_t *t, const double *attenuations[]) -{ - // TODO - return 0; -} - -double sddc_get_tuner_if_attenuation(sddc_t *t) -{ - return 0; -} - -int sddc_set_tuner_if_attenuation(sddc_t *t, double attenuation) -{ - return 0; -} - -int sddc_get_vhf_bias(sddc_t *t) -{ - return t->handler->GetBiasT_VHF(); -} - -int sddc_set_vhf_bias(sddc_t *t, int bias) -{ - t->handler->UpdBiasT_VHF(bias != 0); - return 0; -} - -double sddc_get_sample_rate(sddc_t *t) -{ - return 0; -} - -int sddc_set_sample_rate(sddc_t *t, double sample_rate) -{ - switch((int64_t)sample_rate) - { - case 32000000: - t->samplerateidx = 0; - break; - case 16000000: - t->samplerateidx = 1; - break; - case 8000000: - t->samplerateidx = 2; - break; - case 4000000: - t->samplerateidx = 3; - break; - case 2000000: - t->samplerateidx = 4; - break; - default: - return -1; - } - return 0; -} - -int sddc_set_async_params(sddc_t *t, uint32_t frame_size, - uint32_t num_frames, sddc_read_async_cb_t callback, - void *callback_context) -{ - // TODO: ignore frame_size, num_frames - t->callback = callback; - t->callback_context = callback_context; - return 0; -} - -int sddc_start_streaming(sddc_t *t) -{ - current_running = t; - t->handler->Start(t->samplerateidx); - return 0; -} - -int sddc_handle_events(sddc_t *t) -{ - return 0; -} - -int sddc_stop_streaming(sddc_t *t) -{ - t->handler->Stop(); - current_running = nullptr; - return 0; -} - -int sddc_reset_status(sddc_t *t) -{ - return 0; -} - -int sddc_read_sync(sddc_t *t, uint8_t *data, int length, int *transferred) -{ - return 0; -} diff --git a/source_modules/sddc_source/src/libsddc/libsddc/libsddc.h b/source_modules/sddc_source/src/libsddc/libsddc/libsddc.h deleted file mode 100644 index 3f2454c..0000000 --- a/source_modules/sddc_source/src/libsddc/libsddc/libsddc.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * libsddc - low level functions for wideband SDR receivers like - * BBRF103, RX-666, RX888, HF103, etc - * - * Copyright (C) 2020 by Franco Venturi - * - * 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 . - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -#ifndef __LIBSDDC_H -#define __LIBSDDC_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -typedef struct sddc sddc_t; - -struct sddc_device_info { - const char *manufacturer; - const char *product; - const char *serial_number; -}; - -enum SDDCStatus { - SDDC_STATUS_OFF, - SDDC_STATUS_READY, - SDDC_STATUS_STREAMING, - SDDC_STATUS_FAILED = 0xff -}; - -enum SDDCHWModel { - HW_NORADIO, - HW_BBRF103, - HW_HF103, - HW_RX888, - HW_RX888R2, - HW_RX999, - HW_RX888R3, -}; - -enum RFMode { - NO_RF_MODE, - HF_MODE, - VHF_MODE -}; - -enum LEDColors { - YELLOW_LED = 0x01, - RED_LED = 0x02, - BLUE_LED = 0x04 -}; - -/* basic functions */ -int sddc_get_device_count(); - -int sddc_get_device_info(struct sddc_device_info **sddc_device_infos); - -int sddc_free_device_info(struct sddc_device_info *sddc_device_infos); - -sddc_t *sddc_open(int index, const char* imagefile); - -void sddc_close(sddc_t *t); - -enum SDDCStatus sddc_get_status(sddc_t *t); - -enum SDDCHWModel sddc_get_hw_model(sddc_t *t); - -const char *sddc_get_hw_model_name(sddc_t *t); - -uint16_t sddc_get_firmware(sddc_t *t); - -const double *sddc_get_frequency_range(sddc_t *t); - -enum RFMode sddc_get_rf_mode(sddc_t *t); - -int sddc_set_rf_mode(sddc_t *t, enum RFMode rf_mode); - - -/* LED functions */ -int sddc_led_on(sddc_t *t, uint8_t led_pattern); - -int sddc_led_off(sddc_t *t, uint8_t led_pattern); - -int sddc_led_toggle(sddc_t *t, uint8_t led_pattern); - - -/* ADC functions */ -int sddc_get_adc_dither(sddc_t *t); - -int sddc_set_adc_dither(sddc_t *t, int dither); - -int sddc_get_adc_random(sddc_t *t); - -int sddc_set_adc_random(sddc_t *t, int random); - - -/* HF block functions */ -double sddc_get_hf_attenuation(sddc_t *t); - -int sddc_set_hf_attenuation(sddc_t *t, double attenuation); - -int sddc_get_hf_bias(sddc_t *t); - -int sddc_set_hf_bias(sddc_t *t, int bias); - - -/* VHF block and VHF/UHF tuner functions */ -double sddc_get_tuner_frequency(sddc_t *t); - -int sddc_set_tuner_frequency(sddc_t *t, double frequency); - -int sddc_get_tuner_rf_attenuations(sddc_t *t, const double *attenuations[]); - -double sddc_get_tuner_rf_attenuation(sddc_t *t); - -int sddc_set_tuner_rf_attenuation(sddc_t *t, double attenuation); - -int sddc_get_tuner_if_attenuations(sddc_t *t, const double *attenuations[]); - -double sddc_get_tuner_if_attenuation(sddc_t *t); - -int sddc_set_tuner_if_attenuation(sddc_t *t, double attenuation); - -int sddc_get_vhf_bias(sddc_t *t); - -int sddc_set_vhf_bias(sddc_t *t, int bias); - - -/* streaming functions */ -typedef void (*sddc_read_async_cb_t)(uint32_t data_size, uint8_t *data, - void *context); - -double sddc_get_sample_rate(sddc_t *t); - -int sddc_set_sample_rate(sddc_t *t, double sample_rate); - -int sddc_set_async_params(sddc_t *t, uint32_t frame_size, - uint32_t num_frames, sddc_read_async_cb_t callback, - void *callback_context); - -int sddc_start_streaming(sddc_t *t); - -int sddc_handle_events(sddc_t *t); - -int sddc_stop_streaming(sddc_t *t); - -int sddc_reset_status(sddc_t *t); - -int sddc_read_sync(sddc_t *t, uint8_t *data, int length, int *transferred); - -#ifdef __cplusplus -} -#endif - -#endif /* __LIBSDDC_H */ \ No newline at end of file diff --git a/source_modules/sddc_source/src/libsddc/libsddc/wavehdr.h b/source_modules/sddc_source/src/libsddc/libsddc/wavehdr.h deleted file mode 100644 index 2f96a2a..0000000 --- a/source_modules/sddc_source/src/libsddc/libsddc/wavehdr.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2019 by Hayati Ayguen - * - * 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 2 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 . - */ - -#ifndef __WAVEHDR_H -#define __WAVEHDR_H - -#include -#include -#include - -#pragma pack(push) -#pragma pack(1) - -typedef struct -{ - char ID[4]; - uint32_t size; -} chunk_hdr; - -typedef struct -{ - uint16_t wYear; /* 1601 through 30827 */ - uint16_t wMonth; /* 1..12 */ - uint16_t wDayOfWeek; /* 0 .. 6: 0 == Sunday, .., 6 == Saturday */ - uint16_t wDay; /* 1 .. 31 */ - uint16_t wHour; /* 0 .. 23 */ - uint16_t wMinute; /* 0 .. 59 */ - uint16_t wSecond; /* 0 .. 59 */ - uint16_t wMilliseconds; /* 0 .. 999 */ -} Wind_SystemTime; - - -typedef struct -{ - /* RIFF header */ - chunk_hdr hdr; /* ID == "RIFF" string, size == full filesize - 8 bytes (maybe with some byte missing...) */ - char waveID[4]; /* "WAVE" string */ -} riff_chunk; - -typedef struct -{ - /* FMT header */ - chunk_hdr hdr; /* ID == "fmt " */ - int16_t wFormatTag; - int16_t nChannels; - int32_t nSamplesPerSec; - int32_t nAvgBytesPerSec; - int16_t nBlockAlign; - int16_t nBitsPerSample; -} fmt_chunk; - -typedef struct -{ - /* auxi header - used by SpectraVue / rfspace / HDSDR / ELAD FDM .. */ - chunk_hdr hdr; /* ="auxi" (chunk rfspace) */ - Wind_SystemTime StartTime; - Wind_SystemTime StopTime; - uint32_t centerFreq; /* receiver center frequency */ - uint32_t ADsamplerate; /* A/D sample frequency before downsampling */ - uint32_t IFFrequency; /* IF freq if an external down converter is used */ - uint32_t Bandwidth; /* displayable BW if you want to limit the display to less than Nyquist band */ - int32_t IQOffset; /* DC offset of the I and Q channels in 1/1000's of a count */ - int32_t Unused2; - int32_t Unused3; - int32_t Unused4; - int32_t Unused5; -} auxi_chunk; - -typedef struct -{ - /* DATA header */ - chunk_hdr hdr; /* ="data" */ -} data_chunk; - -typedef struct -{ - riff_chunk r; - fmt_chunk f; - auxi_chunk a; - data_chunk d; -} waveFileHeader; - -#pragma pack(pop) - -#endif /* __WAVEHDR_H */ - -// vim: tabstop=8:softtabstop=8:shiftwidth=8:noexpandtab - diff --git a/source_modules/sddc_source/src/libsddc/libsddc/wavewrite.c b/source_modules/sddc_source/src/libsddc/libsddc/wavewrite.c deleted file mode 100644 index 0b3fb14..0000000 --- a/source_modules/sddc_source/src/libsddc/libsddc/wavewrite.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2019 by Hayati Ayguen - * - * 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 2 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 . - */ - -#include "wavewrite.h" - -#include -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#include -#else -#include -#include -#include -#include -#define _USE_MATH_DEFINES - -#include // portable: uint64_t MSVC: __int64 - -int gettimeofday(struct timeval * tp, struct timezone * tzp) -{ - // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's - // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC) - // until 00:00:00 January 1, 1970 - static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL); - - SYSTEMTIME system_time; - FILETIME file_time; - uint64_t time; - - GetSystemTime( &system_time ); - SystemTimeToFileTime( &system_time, &file_time ); - time = ((uint64_t)file_time.dwLowDateTime ) ; - time += ((uint64_t)file_time.dwHighDateTime) << 32; - - tp->tv_sec = (long) ((time - EPOCH) / 10000000L); - tp->tv_usec = (long) (system_time.wMilliseconds * 1000); - return 0; -} -#endif - -#include - -#include "wavehdr.h" - -static waveFileHeader waveHdr; - -static uint32_t waveDataSize = 0; -int waveHdrStarted = 0; - - -static void waveSetCurrTime(Wind_SystemTime *p) -{ - struct timeval tv; - struct tm t; - - gettimeofday(&tv, NULL); - p->wMilliseconds = tv.tv_usec / 1000; - -#ifdef _WIN32 - t = *gmtime(&tv.tv_sec); -#else - gmtime_r(&tv.tv_sec, &t); -#endif - - p->wYear = t.tm_year + 1900; /* 1601 through 30827 */ - p->wMonth = t.tm_mon + 1; /* 1..12 */ - p->wDayOfWeek = t.tm_wday; /* 0 .. 6: 0 == Sunday, .., 6 == Saturday */ - p->wDay = t.tm_mday; /* 1 .. 31 */ - p->wHour = t.tm_hour; /* 0 .. 23 */ - p->wMinute = t.tm_min; /* 0 .. 59 */ - p->wSecond = t.tm_sec; /* 0 .. 59 */ -} - -static void waveSetStartTimeInt(time_t tim, double fraction, Wind_SystemTime *p) -{ - struct tm t = *gmtime( &tim ); - p->wYear = t.tm_year + 1900; /* 1601 through 30827 */ - p->wMonth = t.tm_mon + 1; /* 1..12 */ - p->wDayOfWeek = t.tm_wday; /* 0 .. 6: 0 == Sunday, .., 6 == Saturday */ - p->wDay = t.tm_mday; /* 1 .. 31 */ - p->wHour = t.tm_hour; /* 0 .. 23 */ - p->wMinute = t.tm_min; /* 0 .. 59 */ - p->wSecond = t.tm_sec; /* 0 .. 59 */ - p->wMilliseconds = (int)( fraction * 1000.0 ); - if (p->wMilliseconds >= 1000) - p->wMilliseconds = 999; -} - -void waveSetStartTime(time_t tim, double fraction) -{ - waveSetStartTimeInt(tim, fraction, &waveHdr.a.StartTime ); - waveHdr.a.StopTime = waveHdr.a.StartTime; /* to fix */ -} - - -void wavePrepareHeader(unsigned samplerate, unsigned freq, int bitsPerSample, int numChannels) -{ - int bytesPerSample = bitsPerSample / 8; - int bytesPerFrame = bytesPerSample * numChannels; - - memcpy( waveHdr.r.hdr.ID, "RIFF", 4 ); - waveHdr.r.hdr.size = sizeof(waveFileHeader) - 8; /* to fix */ - memcpy( waveHdr.r.waveID, "WAVE", 4 ); - - memcpy( waveHdr.f.hdr.ID, "fmt ", 4 ); - waveHdr.f.hdr.size = 16; - waveHdr.f.wFormatTag = 1; /* PCM */ - waveHdr.f.nChannels = numChannels; /* I and Q channels */ - waveHdr.f.nSamplesPerSec = samplerate; - waveHdr.f.nAvgBytesPerSec = samplerate * bytesPerFrame; - waveHdr.f.nBlockAlign = waveHdr.f.nChannels; - waveHdr.f.nBitsPerSample = bitsPerSample; - - memcpy( waveHdr.a.hdr.ID, "auxi", 4 ); - waveHdr.a.hdr.size = 2 * sizeof(Wind_SystemTime) + 9 * sizeof(int32_t); /* = 2 * 16 + 9 * 4 = 68 */ - waveSetCurrTime( &waveHdr.a.StartTime ); - waveHdr.a.StopTime = waveHdr.a.StartTime; /* to fix */ - waveHdr.a.centerFreq = freq; - waveHdr.a.ADsamplerate = samplerate; - waveHdr.a.IFFrequency = 0; - waveHdr.a.Bandwidth = 0; - waveHdr.a.IQOffset = 0; - waveHdr.a.Unused2 = 0; - waveHdr.a.Unused3 = 0; - waveHdr.a.Unused4 = 0; - waveHdr.a.Unused5 = 0; - - memcpy( waveHdr.d.hdr.ID, "data", 4 ); - waveHdr.d.hdr.size = 0; /* to fix later */ - waveDataSize = 0; -} - -void waveWriteHeader(unsigned samplerate, unsigned freq, int bitsPerSample, int numChannels, FILE * f) -{ - if (f != stdout) { - assert( !waveHdrStarted ); - wavePrepareHeader(samplerate, freq, bitsPerSample, numChannels); - fwrite(&waveHdr, sizeof(waveFileHeader), 1, f); - waveHdrStarted = 1; - } -} - -int waveWriteSamples(FILE* f, void * vpData, size_t numSamples, int needCleanData) -{ - size_t nw; - switch (waveHdr.f.nBitsPerSample) - { - case 0: - default: - return 1; - case 8: - /* no endian conversion needed for single bytes */ - nw = fwrite(vpData, sizeof(uint8_t), numSamples, f); - waveDataSize += sizeof(uint8_t) * numSamples; - return (nw == numSamples) ? 0 : 1; - case 16: - /* TODO: endian conversion needed */ - nw = fwrite(vpData, sizeof(int16_t), numSamples, f); - waveDataSize += sizeof(int16_t) * numSamples; - if ( needCleanData ) - { - /* TODO: convert back endianness */ - } - return (nw == numSamples) ? 0 : 1; - } -} - -int waveWriteFrames(FILE* f, void * vpData, size_t numFrames, int needCleanData) -{ - size_t nw; - switch (waveHdr.f.nBitsPerSample) - { - case 0: - default: - return 1; - case 8: - /* no endian conversion needed for single bytes */ - nw = fwrite(vpData, waveHdr.f.nChannels * sizeof(uint8_t), numFrames, f); - waveDataSize += waveHdr.f.nChannels * sizeof(uint8_t) * numFrames; - return (nw == numFrames) ? 0 : 1; - case 16: - /* TODO: endian conversion needed */ - nw = fwrite(vpData, waveHdr.f.nChannels * sizeof(int16_t), numFrames, f); - waveDataSize += waveHdr.f.nChannels * sizeof(int16_t) * numFrames; - if ( needCleanData ) - { - /* TODO: convert back endianness */ - } - return (nw == numFrames) ? 0 : 1; - } -} - - -int waveFinalizeHeader(FILE * f) -{ - if (f != stdout) { - assert( waveHdrStarted ); - waveSetCurrTime( &waveHdr.a.StopTime ); - waveHdr.d.hdr.size = waveDataSize; - waveHdr.r.hdr.size += waveDataSize; - /* fprintf(stderr, "waveFinalizeHeader(): datasize = %d\n", waveHdr.dataSize); */ - waveHdrStarted = 0; - if ( fseek(f, 0, SEEK_SET) ) - return 1; - if ( 1 != fwrite(&waveHdr, sizeof(waveFileHeader), 1, f) ) - return 1; - /* fprintf(stderr, "waveFinalizeHeader(): success writing header\n"); */ - return 0; - } - return 1; -} - -// vim: tabstop=8:softtabstop=8:shiftwidth=8:noexpandtab diff --git a/source_modules/sddc_source/src/libsddc/libsddc/wavewrite.h b/source_modules/sddc_source/src/libsddc/libsddc/wavewrite.h deleted file mode 100644 index 804c894..0000000 --- a/source_modules/sddc_source/src/libsddc/libsddc/wavewrite.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2019 by Hayati Ayguen - * - * 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 2 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 . - */ -#ifndef __WAVEWRITE_H -#define __WAVEWRITE_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern int waveHdrStarted; - -/*! - * helper functions to write and finalize wave headers - * with compatibility to some SDR programs - showing frequency: - * raw sample data still have to be written by caller to FILE*. - * call waveWriteHeader() before writing anything to to file - * and call waveFinalizeHeader() afterwards, - * stdout/stderr can't be used, because seek to begin isn't possible. - * - */ - -void waveWriteHeader(unsigned samplerate, unsigned freq, int bitsPerSample, int numChannels, FILE * f); - -/* waveWriteFrames() writes (numFrames * numChannels) samples - * waveWriteSamples() - * both return 0, when no errors occured - */ -int waveWriteFrames(FILE* f, void * vpData, size_t numFrames, int needCleanData); -int waveWriteSamples(FILE* f, void * vpData, size_t numSamples, int needCleanData); /* returns 0, when no errors occured */ -void waveSetStartTime(time_t t, double fraction); -int waveFinalizeHeader(FILE * f); /* returns 0, when no errors occured */ - -#ifdef __cplusplus -} -#endif - -#endif /*__WAVEWRITE_H*/ diff --git a/source_modules/sddc_source/src/main.cpp b/source_modules/sddc_source/src/main.cpp deleted file mode 100644 index 55f6ae4..0000000 --- a/source_modules/sddc_source/src/main.cpp +++ /dev/null @@ -1,247 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define CONCAT(a, b) ((std::string(a) + b).c_str()) - -SDRPP_MOD_INFO{ - /* Name: */ "sddc_source", - /* Description: */ "SDDC source module for SDR++", - /* Author: */ "Ryzerth;pkuznetsov", - /* Version: */ 0, 1, 0, - /* Max instances */ 1 -}; - -ConfigManager config; - -const char* AGG_MODES_STR = "Off\0Low\0High\0"; - -class AirspyHFSourceModule : public ModuleManager::Instance { -public: - AirspyHFSourceModule(std::string name) { - this->name = name; - - if (core::args["server"].b()) { return; } - - sampleRate = 768000.0; - - handler.ctx = this; - handler.selectHandler = menuSelected; - handler.deselectHandler = menuDeselected; - handler.menuHandler = menuHandler; - handler.startHandler = start; - handler.stopHandler = stop; - handler.tuneHandler = tune; - handler.stream = &stream; - - refresh(); - - selectFirst(); - - sigpath::sourceManager.registerSource("SDDC", &handler); - } - - ~AirspyHFSourceModule() { - stop(this); - sigpath::sourceManager.unregisterSource("SDDC"); - } - - void postInit() {} - - void enable() { - enabled = true; - } - - void disable() { - enabled = false; - } - - bool isEnabled() { - return enabled; - } - - void refresh() { - devListTxt = ""; - - devCount = sddc_get_device_count(); - for (int i = 0; i < devCount; i++) { - // Open device - sddc_t* dev = sddc_open(i, "../sddc_source/res/firmwares/SDDC_FX3.img"); - if (dev == NULL) { continue; } - - // Get device name (check if implemented) - const char* name = sddc_get_hw_model_name(dev); - if (name == NULL) { - sddc_close(dev); - continue; - } - - // Add to list - char tmp[256]; - sprintf(tmp, "%s (%d)", name, i); - devNames.push_back(name); - devListTxt += name; - devListTxt += '\0'; - sddc_close(dev); - } - } - - void selectFirst() { - if (devCount != 0) { - selectById(0); - } - } - - void selectByName(std::string name) { - for (int i = 0; i < devCount; i++) { - if (devNames[i] == name) { - selectById(i); - break; - } - } - } - - void selectById(int id) { - if (id < 0 || id >= devCount) { - selectedDevName = ""; - return; - } - - devId = id; - selectedDevName = devNames[id]; - } - -private: - std::string getBandwdithScaled(double bw) { - char buf[1024]; - if (bw >= 1000000.0) { - sprintf(buf, "%.1lfMHz", bw / 1000000.0); - } - else if (bw >= 1000.0) { - sprintf(buf, "%.1lfKHz", bw / 1000.0); - } - else { - sprintf(buf, "%.1lfHz", bw); - } - return std::string(buf); - } - - static void menuSelected(void* ctx) { - AirspyHFSourceModule* _this = (AirspyHFSourceModule*)ctx; - core::setInputSampleRate(_this->sampleRate); - spdlog::info("AirspyHFSourceModule '{0}': Menu Select!", _this->name); - } - - static void menuDeselected(void* ctx) { - AirspyHFSourceModule* _this = (AirspyHFSourceModule*)ctx; - spdlog::info("AirspyHFSourceModule '{0}': Menu Deselect!", _this->name); - } - - static void start(void* ctx) { - AirspyHFSourceModule* _this = (AirspyHFSourceModule*)ctx; - if (_this->running) { return; } - if (_this->selectedDevName == "") { return; } - - // Start device - - _this->running = true; - spdlog::info("AirspyHFSourceModule '{0}': Start!", _this->name); - } - - static void stop(void* ctx) { - AirspyHFSourceModule* _this = (AirspyHFSourceModule*)ctx; - if (!_this->running) { return; } - _this->running = false; - _this->stream.stopWriter(); - - // Stop device - - _this->stream.clearWriteStop(); - spdlog::info("AirspyHFSourceModule '{0}': Stop!", _this->name); - } - - static void tune(double freq, void* ctx) { - AirspyHFSourceModule* _this = (AirspyHFSourceModule*)ctx; - if (_this->running) { - // Tune device - } - _this->freq = freq; - spdlog::info("AirspyHFSourceModule '{0}': Tune: {1}!", _this->name, freq); - } - - static void menuHandler(void* ctx) { - AirspyHFSourceModule* _this = (AirspyHFSourceModule*)ctx; - float menuWidth = ImGui::GetContentRegionAvail().x; - - if (_this->running) { style::beginDisabled(); } - - ImGui::SetNextItemWidth(menuWidth); - if (ImGui::Combo(CONCAT("##_sddc_dev_sel_", _this->name), &_this->devId, _this->devListTxt.c_str())) { - // Select here - } - - if (ImGui::Combo(CONCAT("##_sddc_sr_sel_", _this->name), &_this->srId, _this->sampleRateListTxt.c_str())) { - _this->sampleRate = _this->sampleRateList[_this->srId]; - core::setInputSampleRate(_this->sampleRate); - // Select SR here - } - - ImGui::SameLine(); - float refreshBtnWdith = menuWidth - ImGui::GetCursorPosX(); - if (ImGui::Button(CONCAT("Refresh##_sddc_refr_", _this->name), ImVec2(refreshBtnWdith, 0))) { - _this->refresh(); - // Reselect and reset samplerate if it changed - } - - if (_this->running) { style::endDisabled(); } - - // All other controls - } - - std::string name; - bool enabled = true; - dsp::stream stream; - double sampleRate; - SourceManager::SourceHandler handler; - bool running = false; - double freq; - int devId = 0; - int srId = 0; - sddc_t* openDev; - - int devCount = 0; - std::vector devNames; - std::string selectedDevName = ""; - std::string devListTxt; - std::vector sampleRateList; - std::string sampleRateListTxt; -}; - -MOD_EXPORT void _INIT_() { - json def = json({}); - def["devices"] = json({}); - def["device"] = ""; - config.setPath(core::args["root"].s() + "/sddc_config.json"); - config.load(def); - config.enableAutoSave(); -} - -MOD_EXPORT ModuleManager::Instance* _CREATE_INSTANCE_(std::string name) { - return new AirspyHFSourceModule(name); -} - -MOD_EXPORT void _DELETE_INSTANCE_(ModuleManager::Instance* instance) { - delete (AirspyHFSourceModule*)instance; -} - -MOD_EXPORT void _END_() { - config.disableAutoSave(); - config.save(); -} \ No newline at end of file