From 533f9ee33221981dedc5d55ec6becb9921121d35 Mon Sep 17 00:00:00 2001 From: Marco Bartolucci Date: Tue, 16 May 2017 11:39:44 +0200 Subject: [PATCH] Hardware (CPLD-based) synchronisation ======================================= This commit allows to synchronise multiple HackRFs with a synchronisation error **below 1 sampling period** > WARNING: Use this at your own risk. If you don't know what you are doing you may damage your HackRF. > The author takes no responsability for potential damages Usage example: synchronise two HackRFs ====================================== 1. Chose the master HackRF which will send the synchronisation pulse (HackRF0). HackRF1 will represent the slave hackrf. 2. Retreive the serial number of both HackRFs using `hackrf_info` 3. Use a wire to connect `SYNC_CMD` of HackRF0 to `SYNC_IN` of HackRF0 and HackRF1 4. Run `hackrf_transfer` with the argument `-H 1` to enable hardware synchronisation: ``` $ hackrf_tranfer ... -r rec1.bin -d HackRF1_serial -H 1 | hackrf_transfer ... -r rec0.bin -d HackRF0_serial -H 1 ``` rec0.bin and rec1.bin will have a time offset below 1 sampling period. The 1PPS output of GNSS receivers can be used to synchronise HackRFs even if they are far from each other. >DON'T APPLY INCOMPATIBLE VOLTAGE LEVELS TO THE CPLD PINS Signal | Header |Pin | Description -------|--------|----|------------ `SYNC_IN` | P28 | 16 | Synchronisation pulse input `SYNC_CMD` | P28 | 15 | Synchronisation pulse output Note: ===== I had to remove CPLD-based decimation to use a GPIO for enabling hardware. More info: ========== [M. Bartolucci, J. A. Del Peral-Rosado, R. Estatuet-Castillo, J. A. Garcia-Molina, M. Crisci and G. E. Corazza, "Synchronisation of low-cost open source SDRs for navigation applications," 2016 8th ESA Workshop on Satellite Navigation Technologies and European Workshop on GNSS Signals and Signal Processing (NAVITEC), Noordwijk, 2016, pp. 1-7.](http://ieeexplore.ieee.org/document/7849328/) [Alternative link](http://spcomnav.uab.es/docs/conferences/Bartolucci_NAVITEC_2016.pdf) --- firmware/common/hackrf_core.c | 31 ++++++----------- firmware/common/hackrf_core.h | 6 +--- firmware/common/sgpio.c | 21 ++---------- firmware/common/sgpio.h | 2 +- firmware/cpld/sgpio_if/README.md | 12 ------- firmware/cpld/sgpio_if/default.xsvf | Bin 37629 -> 37629 bytes firmware/cpld/sgpio_if/default_sync.xsvf | Bin 37629 -> 0 bytes firmware/cpld/sgpio_if/top.jed | 40 +++++++++++----------- firmware/cpld/sgpio_if/top.ucf | 3 +- firmware/cpld/sgpio_if/top.vhd | 13 ++++--- firmware/hackrf_usb/usb_api_transceiver.c | 5 ++- host/hackrf-tools/src/hackrf_transfer.c | 2 +- 12 files changed, 48 insertions(+), 87 deletions(-) mode change 100644 => 100755 firmware/cpld/sgpio_if/default.xsvf delete mode 100755 firmware/cpld/sgpio_if/default_sync.xsvf diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index ac231860..32663946 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -132,11 +132,12 @@ static struct gpio_t gpio_cpld_tms = GPIO(3, 1); static struct gpio_t gpio_cpld_tdi = GPIO(3, 4); #endif -static struct gpio_t gpio_rx_decimation[3] = { - GPIO(5, 12), - GPIO(5, 13), - GPIO(5, 14), -}; +//static struct gpio_t gpio_rx_decimation[3] = { +// GPIO(5, 12), +// GPIO(5, 13), +// GPIO(5, 14), +//}; +static struct gpio_t gpio_hw_sync_enable = GPIO(5,12); static struct gpio_t gpio_rx_q_invert = GPIO(0, 13); i2c_bus_t i2c0 = { @@ -242,11 +243,7 @@ w25q80bv_driver_t spi_flash = { sgpio_config_t sgpio_config = { .gpio_rx_q_invert = &gpio_rx_q_invert, - .gpio_rx_decimation = { - &gpio_rx_decimation[0], - &gpio_rx_decimation[1], - &gpio_rx_decimation[2], - }, + .gpio_hw_sync_enable = &gpio_hw_sync_enable, .slice_mode_multislice = true, }; @@ -824,11 +821,6 @@ void pin_setup(void) { scu_pinmux(SCU_PINMUX_GPIO3_10, SCU_GPIO_PDN | SCU_CONF_FUNCTION0); scu_pinmux(SCU_PINMUX_GPIO3_11, SCU_GPIO_PDN | SCU_CONF_FUNCTION0); - //gpio_input(&gpio_sync_in_a); - //gpio_input(&gpio_sync_in_b); - - //gpio_output(&gpio_sync_out_a); - //gpio_output(&gpio_sync_out_b); #endif #ifdef RAD1O @@ -841,11 +833,6 @@ void pin_setup(void) { scu_pinmux(SCU_PINMUX_GPIO3_10, SCU_GPIO_PDN | SCU_CONF_FUNCTION0); scu_pinmux(SCU_PINMUX_GPIO3_11, SCU_GPIO_PDN | SCU_CONF_FUNCTION0); - //gpio_input(&gpio_sync_in_a); - //gpio_input(&gpio_sync_in_b); - - //gpio_output(&gpio_sync_out_a); - //gpio_output(&gpio_sync_out_b); #endif /* enable input on SCL and SDA pins */ @@ -902,3 +889,7 @@ void led_off(const led_t led) { void led_toggle(const led_t led) { gpio_toggle(&gpio_led[led]); } + +void hw_sync_enable(const hw_sync_mode_t hw_sync_mode){ + gpio_write(&gpio_hw_sync_enable, hw_sync_mode==1); +} diff --git a/firmware/common/hackrf_core.h b/firmware/common/hackrf_core.h index fbace49f..36c03759 100644 --- a/firmware/common/hackrf_core.h +++ b/firmware/common/hackrf_core.h @@ -293,11 +293,7 @@ void led_on(const led_t led); void led_off(const led_t led); void led_toggle(const led_t led); -void hw_sync_syn(); -void hw_sync_stop(); -void hw_sync_ack(); -bool hw_sync_ready(); -void hw_sync_copy_state(); +void hw_sync_enable(const hw_sync_mode_t hw_sync_mode); #ifdef __cplusplus diff --git a/firmware/common/sgpio.c b/firmware/common/sgpio.c index 6180ad53..c128a74e 100644 --- a/firmware/common/sgpio.c +++ b/firmware/common/sgpio.c @@ -49,13 +49,11 @@ void sgpio_configure_pin_functions(sgpio_config_t* const config) { scu_pinmux(SCU_PINMUX_SGPIO14, SCU_GPIO_FAST | SCU_CONF_FUNCTION4); /* GPIO5[13] */ scu_pinmux(SCU_PINMUX_SGPIO15, SCU_GPIO_FAST | SCU_CONF_FUNCTION4); /* GPIO5[14] */ - sgpio_cpld_stream_rx_set_decimation(config, 1); sgpio_cpld_stream_rx_set_q_invert(config, 0); + hw_sync_enable(0); gpio_output(config->gpio_rx_q_invert); - gpio_output(config->gpio_rx_decimation[0]); - gpio_output(config->gpio_rx_decimation[1]); - gpio_output(config->gpio_rx_decimation[2]); + gpio_output(config->gpio_hw_sync_enable); } void sgpio_set_slice_mode( @@ -258,21 +256,6 @@ bool sgpio_cpld_stream_is_enabled(sgpio_config_t* const config) { return (SGPIO_GPIO_OUTREG & (1L << 10)) == 0; /* SGPIO10 */ } -bool sgpio_cpld_stream_rx_set_decimation(sgpio_config_t* const config, const uint_fast8_t n) { - /* CPLD interface is three bits, SGPIO[15:13]: - * 111: decimate by 1 (skip_n=0, skip no samples) - * 110: decimate by 2 (skip_n=1, skip every other sample) - * 101: decimate by 3 (skip_n=2, skip two of three samples) - * ... - * 000: decimate by 8 (skip_n=7, skip seven of eight samples) - */ - const uint_fast8_t skip_n = n - 1; - gpio_write(config->gpio_rx_decimation[0], (skip_n & 1) == 0); - gpio_write(config->gpio_rx_decimation[1], (skip_n & 2) == 0); - gpio_write(config->gpio_rx_decimation[2], (skip_n & 4) == 0); - - return (skip_n < 8); -} #ifdef RAD1O /* The rad1o hardware has a bug which makes it diff --git a/firmware/common/sgpio.h b/firmware/common/sgpio.h index 46681afe..720c227b 100644 --- a/firmware/common/sgpio.h +++ b/firmware/common/sgpio.h @@ -36,7 +36,7 @@ typedef enum { typedef struct sgpio_config_t { gpio_t gpio_rx_q_invert; - gpio_t gpio_rx_decimation[3]; + gpio_t gpio_hw_sync_enable; bool slice_mode_multislice; } sgpio_config_t; diff --git a/firmware/cpld/sgpio_if/README.md b/firmware/cpld/sgpio_if/README.md index 6fabc642..018cfc9d 100644 --- a/firmware/cpld/sgpio_if/README.md +++ b/firmware/cpld/sgpio_if/README.md @@ -4,18 +4,6 @@ RF codec. CPLD-based triggered capture ============================ -Code related to the paper: - -[M. Bartolucci, J. A. del Peral-Rosado, R. Estatuet-Castillo, J. A. Garcia-Molina, M. Crisci, G. E. Corazza, "Synchronisation of low-cost open source SDRs for navigation applications", Proc. 8th ESA Workshop on Satellite Navigation User Equipment Technologies (NAVITEC), Dec 16 2016](http://spcomnav.uab.es/docs/conferences/Bartolucci_NAVITEC_2016.pdf) - -Please read the paper for hardware correction and additional details. - -* If you don't want to build use `default_sync.xsvf` to flash the CPLD -* This is still a very rough implementation. Synchronization can't be disabled! - -Requirements -============ - To build this VHDL project and produce an SVF file for flashing the CPLD: * Xilinx WebPACK 13.4 for Windows or Linux. diff --git a/firmware/cpld/sgpio_if/default.xsvf b/firmware/cpld/sgpio_if/default.xsvf old mode 100644 new mode 100755 index 1b78dbcffbe8e7ac10505df8f7ced610fe1d4d69..a08989e562193c80ee8568d0da6d1b896cf2570f GIT binary patch delta 2471 zcmeH`{ZCs}7{@)gE!Z+z+VVE&3%z5&I{U_8+O4d-XvfP~g&8G8(}J5iV_=ghbBVO* z;`nWYZ>Mi5oa=thWM5k7Ig{khc24vf(cWL1J=Ryo_lXw7Jl#_;QVm! z^LC!+InOztl`&>zjG34uSSYvRGsRZiC)xOrDbC>g`}<#yV3@Gj-;rr3&ry@;a*R(e z)UkOu!PMaJ7M+s!uj-PqDk1ivuh6-LMUld(TB2Lfs%Qm*CAg}HC}WbL8K;!*qB~H6 zCRJ4U+qgN^s|06*7Vbo*fx*xAVtk;k!cTTHmed{+!XRrwqsA{()T-hO#?|c=@2bfvz;JSEHqlD=;_oBi26NQZ`M(}jlBIp zki_25O49qAj@G$%xQGBVOl1S2IK_#;~ zj=y^?&=k7KAELXXFe(&U6y>GDO4-`DIZCDln-#Y=pTtSlgrTBpybv&RzZC5u4F6(s z0%$Om5p_y~sSKkU2YxplP+XDkWmMy2LSiyzHFd}M(L5$sIB%JeByPw$L|}CkjVP5E zcN>w@2|#ivZRO2hQ`9IMPmGIkxL)I>3m+-C?xu+<_~*Lny1Z(NQ~mN0li$Cfo*G z_jQSP8g4S;U`@9~i3KG=Jr-;3YNfeKBqZk1*2Kc>?~=e7#zmj1C`HLSX2j_?)b{Gv z(So)bBW~1&_3JRfU^|P$b=_%FXp{HrLKt^wg`1LlI9-1bI-f>C0iiqChUaBSX!s`$ z@f0Z5paC}@KZJ>GYK6cFF1cCsJVDc0@LW?qNZ{WjEOcx6-gpWa;o8vJ*p-BazP?+H z-7+}grq?8JT*zqdmJy*Lqs_Fq1P{$H)gpU2|Go?&zi;X|-nxj2CtbL({}6I~#h|am z6ZA5aq*vNT1cLas5j1!Vc&~jSMGn=!JrI`i2sg^LJaukORxa=9ch;&uJo78F_PuZ5 SBa^j(&jvpKk5A9=Y4RWQ;BDUk literal 37629 zcmeI5e~4Yh6~|}ZjoFt*vhp@`tv{Nj7M1uDQ>^%FOJlWkB`L;VB%u)vtu&%iixG`p zALW;`oabhL^3fZTJ1gk`!?rCBVxotR|Z{+9yDT4pN^k}s+OCHq<$e$S71h*w3 znO1YD%C}R!{5U)6jRvLYUlB44=?qO>8+B+Lq75E?(pXR{`5?0Uznrn zyT{1;I2X}<#g?~g*RHon`pVVQD!nZir|o~tKGWwkeOEjB7KQ0Ent#PT-7n`BZZC9w z?{oa?_(RS0)>7Jw{M^y^bea}bzLDe)aj3iH(wM6$1iTb|QEh>n7 zBz@&Xsr@E3<93q17dZN!RB2z&>|fJfNd6V8O8KBzI-28Sel<(o!d-S1_a z-p{`?I3DhZ@%v_oj~Krvg7Rqgn{)g-R5RQ6c2oN+`A8|>|8}e1`K0#uuq*HI-wTM; z@n~I{zDk``#Q0rj_^k1x2&dE(ZM>8pXn7x{t`zHhiqxLPhtqegwC=`3VtanU^@l65 z_aw!?@*i5>PD{o&#rcMsB-(GR+`qa#)B3BipuVJd6K99y(fVh3ZnOHzmtVA;;X9=H zL%h_izT%UH_5Gw-edYSoKBL*!Xz{z@J^NnIF|j>A@tH@4eTn8@`B=05mGcejJKwCn z;$OC{yvGTt|J&89zVf;QUa0&c&A;NBpnpmFic5m}lAe#`#Rq0`-OLd@Z;|F3a)(@1 zkoRABLZ|ijJA(ZcNndevR;m3K;k@&BNt|EFBi+m9EpeXtE=gax<-HkOoW~zDeea(= z>BuvaQfnj5C#Uw#SU2lKXfHH51UEfD=d(pSDetFGR+Z(lAF_(<(pyldjuYB0!0 z(pNmI+j|B z&GygYxn}hh`~S1Ub}t?i_1!=1^e3)F+VhcIGppPlxhRp=p2e-1e@_)<*k?3-#Y5V^ zJ5yVLb4=9t0oT87d!)VJkjM9Go|5Nj>hu0_)1FV22&CyNUU&6%%tw45E8j5smTffu z$}6VJgz29V^}XEaYjyb8|B==g#PwPGm`}CTY(sgZ{#i~otFL^gS^tW+-FO%(KHSs% zD^$b!svsZ9zj9kp9?8EVZFoG|cxd;~^4T8Wx6}09)NuUHG_3EZ4Y%i48`k&LX7!cl zHLUN7X7v^0h1TaiA-z9nR$jiAUw3t1uZj;A#*Zz}(h^3bNk`Bt*8LQN<^82=vDqw} zcVyzVK;hz&3cr(t*VPAk2szZRn32K@^MG^@FOuj6*Y*Kvf)`0U&ey*+f?MrNc^ z$7Oj@(3Z}tinQXJMjVH!Re+=)->N*v^~8#&>mZdnuAiL+NViu-s@J>|<2Y;XU1&@C zL??Iw(qDOzOvD9p!~p3Ryhuqn%?yx!UJc1LxH+%VFJ+GN-8{V3dlHZ~^CB6?1(MwW z=_X#JK*Z^;5@(f*n2}1mO6@&Q#4YAU3XXA}S>?^VNOc_dM`olKhoQB=-s89nd68P7 zw&Zc#)x1b`9QPZa$Y2{K&PEwPM|G4$ct3Rach{74&?Um9(l&NWxPn?h(pKyh!-jBID7#A z9WRmyCkjLJ{xdI963#USq?OD_upZ|$a?hKSYk84cvxNj!PsZu_V5P@-kwiFY8j#lW zA|>IxYd|`O7fFOuw*jfciFOtw*W$D(#uJYHsNJ%&!AKFrj87Uj%^2StUStsE|GGkon z=5gF=UZmix(lgP$j~A)Vtnvb0q&g9|sv1(=^|&NlApsHh2s2W+$O4eo@gnJn3)N`= zQpF_3x{m8dTxqEXAf3x=B@=Nw(~_Ra^Ej}fD$+=;B|?Ze_YJRS1^kJsNHv!TO^$HM z5}|Lw;yPv|^RBYI>;>A=CDo98t)a?#95~JuodWUo;P=~ zKC@t@Sf9C2#Kro|LPP1F#QMxiGl5v2Sz#t%#<*CY=?SvJrSNkcF22V4%z_EciKnnO z)@Op1JhRGJp9xm-od_xIA4nOnO3az4?PhV>oc+U z#)ymcnb?*v;$nR!S_vznV|^xC2_r7nXQGub;$nR!{DC3Q3V5u~#I}SH7wa?8N*Hmm zJ`?9lm{%F=GqEjU#Krndv=T;Ktj|O%VZ_DyOtcb4T&&MTD`CXN`b@MEMqI4VL@Qy$ y#rjON5=LCC&-4^O4l2JItaNO(_k1T*>9WU(j_Alm=D%*WmHvy7LS}zWQhW<+7Aw5~ diff --git a/firmware/cpld/sgpio_if/default_sync.xsvf b/firmware/cpld/sgpio_if/default_sync.xsvf deleted file mode 100755 index 85ea588db2bf539181450b7547e2f5f0d8c41eb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37629 zcmeI5U5Fe-5XZZBVs6ifCwsy3JBNyj->9glKJroe~Zhhuu~w(eK; z@9OE9?%EwvqiU(@sE%&6bz3Plu1CzvW|2Ko!^Mw3ckX$$)i(CGZu6&6`;Om6Rp-#o zNT=1wItO(Yk1bwo-?6ka)M|7wdpNvWQLaHLS8NX7DQ?30kp# zFsgb{J^8RIQjv2X9$nd$z!i-Vtk=vLbkCSS*~r`8jX=cXNd zW}=?Q`}x#o#9v}>ugQ7-ZvMOKo-s3TR{1t=-1sreU%i6(>sq%hroStQzi5x;uUbv? zJy3t|CjJsV%-;NZPJhuq5`X8qRXwct%UOD;?Zh6&FXQm3cZk1ekLT|@K|YqhdYssE z<2PY(*R%XRf%v=6bSo|w`N8s6ojZ`vn*N>V@7cs&1#bS3<*)vL_zU)!`TIeLk2hYa zJwbcC`0X9!Z@!5;Ug<{%^8K;NYFXA2oY&A`}3=W&mHgg+Wzu1M_>I4u}A2vJzjqv9jvdl#~ZIko8?nS zgzWLgXMJ?D{^~bEd^|nWYax3)f7N#l`}m)xA4bSt|>#xj!q9H|*(Ip1x{wYv0y%afI>X%{L}{`gRLb zy%*YJ>8ro!>sy$c_VBUvRi8WdO!olwRWEKcUzVPhKhYk~-xqdNt$B`l`syWH_qj&$ z;wGl@;`L{>#LeHi1N2voxO!B;<`0?v9ul<2>(4K5%Rj6_9jL!AHLI`sYV(FF9v<`b z)n9F)13WRw8?W?rJ3{t&`Frh*d5;jeO`gB%p>28BH9%TSe;=Uw(*DSMzM*$-bsjJg zINN0UySrI`)w|SRO33v0{e|lhwN$ow{_3;b@d|D7^i^jz>#w?m_76(P^mn3JfAyyg z`};|={wfpl*R18tC$$Ok^%mhmHuta3=ygGRtmi|j+wA>f0s4uuNrfDpSKapwc_{vd~4R;!diap>b_kS zpI;c?wY0Y_VMrI-5$uX}xy4{0{SIZ(%;oQD7VS~0Fglo$pQQ3Mj9wwZ(kH39a9%++24%_hg+)v$=<%zxsS`$vS(wE1`1d1&H|*H z>LSH;?`)uOrr6*GNRP=P1v73EuW{$eB4y!iW)P(l>miXLsn@JCE>Yp!iEeMF8X&Ea zMG6Y%=}VW(A_X$e-pApra*;4nAmi*35D2$e7AYv4XL53-EK-bc_Xs0J2zQb!QjBot z%Ob@H_qZ@pgm5>@BE<-IxGYkPaK{NFMF@ANEK-bc&&VRh2)A4qDMGk2Ws!oyQ@`aRrfg4>|~Ujw}+HocOk} z1Jd!bNH*g_JK+K8E?FeCqwGWf`O|ZayG#}-3-8B=D7A!<+-sa~OFtlG!bncWdF1m5 zw?Y<)WE?ViCc1aaB4y#)1Q6~7S)`bZJGUNE?0Q@lu8@EzJt~Y8F0ufmm9j{!aGeGq z)!f7wE1b=^P^kwX9W5Irn{i#t{K^^63i$1Hk%pp{2qEL>(COKp_f%b^$R)yX%?b#2 zu`p7EaHrKns;J*Ttg{{m!u8)hf8Y`Bep#f-?Er--+n#IOq%e{@IYBH>#x0RWY6WMN zxaVX<7Aas*8|<4Aw= zJOE1dnKa{4eP+>X!ndOtOlVSlCds$r!;~OOsXjB+XF@-zlX0FBh*X~mk@Q^SQhlZq zrBt6e9}c+2rTR>#qm+%%tTNSS7I8}TnRV_^AmeC%^URl0eI^Z(Z&sP=Gcih7SexoI zAxfTEWvb7FD0#-ERG*1a!i-DxnGhvU#-;j9h>|DcQhg>y2{SI$XJV9a2S%#T#3*5z zU#icN9cl z#%o-v&x8)=xkE|ynHVL^xKy8sQNoN%^_dtYoK>d!O!$H!&kA^|&&0lj8JFraF-n+m zsXh~x})d%{y#o9Z*&5ZRVzR+;KEF-oaE(`H;mwOFdp#J+^91F1d}qlDME zRG*1a!dYdi&%`L" LOC = "P61" | IOSTANDARD = LVCMOS33 | SLEW = SLOW ; NET "HOST_DATA<7>" LOC = "P77" | IOSTANDARD = LVCMOS33 | SLEW = SLOW ; NET "HOST_DIRECTION" LOC = "P71" | IOSTANDARD = LVCMOS33 ; NET "HOST_DISABLE" LOC = "P76" | IOSTANDARD = LVCMOS33 ; -NET "HOST_Q_INVERT" LOC = "P70" | IOSTANDARD = LVCMOS33 ; +NET "HOST_Q_INVERT" LOC = "P70" | IOSTANDARD = LVCMOS33 ; +NET "HOST_SYNC_EN" LOC = "P90" | IOSTANDARD = LVCMOS33 ; NET "HOST_SYNC" LOC = "P55" | IOSTANDARD = LVCMOS33; NET "HOST_SYNC_CMD" LOC = "P56" | IOSTANDARD = LVCMOS33 | SLEW = SLOW ; diff --git a/firmware/cpld/sgpio_if/top.vhd b/firmware/cpld/sgpio_if/top.vhd index a7f71fb3..f65dadbd 100755 --- a/firmware/cpld/sgpio_if/top.vhd +++ b/firmware/cpld/sgpio_if/top.vhd @@ -29,7 +29,8 @@ use UNISIM.vcomponents.all; entity top is Port( HOST_DATA : inout std_logic_vector(7 downto 0); - HOST_CAPTURE : out std_logic; + HOST_CAPTURE : out std_logic; + HOST_SYNC_EN : in std_logic; HOST_SYNC_CMD : out std_logic; HOST_SYNC : in std_logic; HOST_DISABLE : in std_logic; @@ -56,7 +57,8 @@ architecture Behavioral of top is signal transfer_direction_i : transfer_direction; signal host_data_enable_i : std_logic; - signal host_data_capture_o : std_logic; + signal host_data_capture_o : std_logic; + signal host_sync_enable : std_logic := '0'; signal host_sync_o : std_logic := '0'; signal host_sync_i : std_logic := '0'; signal host_sync_latched : std_logic := '0'; @@ -94,7 +96,8 @@ begin else (others => 'Z'); data_from_host_i <= HOST_DATA; - HOST_CAPTURE <= host_data_capture_o; + HOST_CAPTURE <= host_data_capture_o; + host_sync_enable <= HOST_SYNC_EN; host_sync_i <= HOST_SYNC; HOST_SYNC_CMD <= host_sync_o; @@ -153,11 +156,11 @@ begin if rising_edge(host_clk_i) then if transfer_direction_i = to_dac then if codec_clk_i = '1' then - host_data_capture_o <= host_data_enable_i and host_sync_latched; + host_data_capture_o <= host_data_enable_i and (host_sync_latched or not host_sync_enable); end if; else if codec_clk_i = '0' then - host_data_capture_o <= host_data_enable_i and host_sync_latched; + host_data_capture_o <= host_data_enable_i and (host_sync_latched or not host_sync_enable); end if; end if; end if; diff --git a/firmware/hackrf_usb/usb_api_transceiver.c b/firmware/hackrf_usb/usb_api_transceiver.c index f86defad..c2e17518 100644 --- a/firmware/hackrf_usb/usb_api_transceiver.c +++ b/firmware/hackrf_usb/usb_api_transceiver.c @@ -275,9 +275,8 @@ void set_transceiver_mode(const transceiver_mode_t new_transceiver_mode) { if( _transceiver_mode != TRANSCEIVER_MODE_OFF ) { si5351c_activate_best_clock_source(&clock_gen); - if( _hw_sync_mode != HW_SYNC_MODE_OFF) { - hw_sync_enable(); - } + hw_sync_enable(_hw_sync_mode); + baseband_streaming_enable(&sgpio_config); } } diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c index d263d83e..d0956265 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -964,7 +964,7 @@ int main(int argc, char** argv) { } if(hw_sync) { - fprintf(stderr, "call hackrf_set_hw_sync_mode(%d)\n", hw_sync); + fprintf(stderr, "call hackrf_set_hw_sync_mode(%d)\n", hw_sync_enable); result = hackrf_set_hw_sync_mode(device, hw_sync_enable ? HW_SYNC_MODE_ON : HW_SYNC_MODE_OFF); if( result != HACKRF_SUCCESS ) { fprintf(stderr, "hackrf_set_hw_sync_mode() failed: %s (%d)\n", hackrf_error_name(result), result);