From c9de7b36c9d963313a9ae1bdc1451928c611ebc9 Mon Sep 17 00:00:00 2001 From: Ole Bauck Date: Sat, 21 Mar 2026 23:33:28 +0100 Subject: [PATCH] ch32 uf2: Added bootloader as a feature. Everything works except entering bootloader from code (uart task) after a power cycle. --- ch32v203/.cargo/config.toml | 5 ++- ch32v203/Cargo.toml | 2 + ch32v203/bootloader.elf | Bin 0 -> 49852 bytes ch32v203/build.rs | 60 ++++++++++++++++++++++--- ch32v203/memory-with-bootloader-128k.x | 11 +++++ ch32v203/memory-with-bootloader-32k.x | 11 +++++ ch32v203/memory-with-bootloader-64k.x | 11 +++++ ch32v203/src/bin/usb_dap.rs | 8 ++++ ch32v203/src/bin/usb_dap_ppk2_uart.rs | 8 ++++ ch32v203/src/bin/usb_ppk2.rs | 9 +++- ch32v203/src/bin/usb_uart.rs | 8 ++++ ch32v203/src/lib.rs | 25 +++++++++++ ch32v203/src/usb_uart_task.rs | 8 ++++ ch32v203/uf2_flash.sh | 7 +++ 14 files changed, 164 insertions(+), 9 deletions(-) create mode 100644 ch32v203/bootloader.elf create mode 100644 ch32v203/memory-with-bootloader-128k.x create mode 100644 ch32v203/memory-with-bootloader-32k.x create mode 100644 ch32v203/memory-with-bootloader-64k.x create mode 100755 ch32v203/uf2_flash.sh diff --git a/ch32v203/.cargo/config.toml b/ch32v203/.cargo/config.toml index cf0435f..c9fcca3 100644 --- a/ch32v203/.cargo/config.toml +++ b/ch32v203/.cargo/config.toml @@ -2,8 +2,9 @@ target = "riscv32imc-unknown-none-elf" [target."riscv32imc-unknown-none-elf"] -# runner = "wlink -v flash --enable-sdi-print --watch-serial --erase" -runner = "wchisp flash" +# runner = "wlink flash" +# runner = "wchisp flash" +runner = "./uf2_flash.sh" # runner = "probe-rs run --chip ch32v203" # runner = "arm-none-eabi-size" diff --git a/ch32v203/Cargo.toml b/ch32v203/Cargo.toml index 7076398..7efa4ed 100644 --- a/ch32v203/Cargo.toml +++ b/ch32v203/Cargo.toml @@ -16,6 +16,8 @@ ch32v203k6t6 = ["ch32-hal/ch32v203k6t6"] ch32v203k8t6 = ["ch32-hal/ch32v203k8t6"] ch32v203rbt6 = ["ch32-hal/ch32v203rbt6"] +bootloader = [] + default = ["ch32v203g6u6"] [dependencies] diff --git a/ch32v203/bootloader.elf b/ch32v203/bootloader.elf new file mode 100644 index 0000000000000000000000000000000000000000..10a7b01b1c8c67c4ae96979d645c92de2e494798 GIT binary patch literal 49852 zcmeIbd3;sX)jqz@y}9>>K?npwK!!k2!3tzfuxc}h)Ieee!0{SxLP#5uGzo~-0Ynr> zsG&%$3Rj?b6MPSrOW0FH5lUTIn-I=?4SN$+MHu&Mh{E>mesx#JyV%tNe z!|c7JYIc6uq`q{0)$j9{n8LwDz3+yS20yiBsVVHe^2)6@Od7T@IUF7pyZ-6GXrN~% z$F6xg;l?}i_n9}h{4`>ESA~WT{%vn)d2sMky`i=EzpCg^X!l=2htktRCVdjNwP9mh zewvn9|Mxtn(_x1?(u7v7s7Suj8r-{nl(}bp za97y$u0O#%xITST*jg3YJ@UYz-m5J0yXPCWO#5wbBq<>_XkWNDl9muVhWm_!*!X>k zt6Gx7PX>FhioDUgzQI@(u>;S9lUG}VlY=JEyCKCqz9IORMAMskg4wzuebcj6D6%RX zOKwRR_Sai0VjK3EX)UN@aB^hcPY=Gq+L9wCVb}A=Jh7_flJefG-uqzj7S>=`!=En% zH94FS=)LNyJ(W-Fe(Raf!9mFyynDco&wEo&FptxB6N)_j#42c8gW=DpKLxITx2UBz zeAVG~+b$WkYumaVuk09BA(}po-D7qfD%#Q?_2*kgijTeFdAaMhB}Y!k*|lx;j-nOM z?nvJpG3ob2%ylo)^W2JE&;R_fEu#X3yQ;UKe;d~9dNKb3Q#hiecTYHJ1T?SOnw}Oh z`4xe}(5(^Mc9m=iTZjLZvSiJc@FD}PZ5u!_R>PVN+prJh!{XSIeQWl;aZbtY z<)8ex_q`L$IoqV3lFVy&kKcJ{L-m#vtFU)f`SRqJ3bWzG4Mq7Wdk1#jP-dI83H*71a*sx1W#p7D& z=dKsGz+=RJdHPyw`-YO_mJ=Wktr6+>SmV<-W4jOAUECsxR;g9ldo}v;8f!%F71ooz z*II$#&Z6zTqas%F1(Cw1Rvxo$+BaV>JchP||5(%e-YE0>lc+B-ef?Y8S;M$ZlJU#4 z59~CdZ7X+L+k4-;3P;i>+Z9&`PQTIG-n=E$a><(S9Z0?@VijGrdtT(wW7j6%bb>kl zrqq&&%@Rq;PDEHHL4`}(`n#>oI zZwgym7XG+3yCq`vUir-Q*vOp;p=*+Nt}?fmkKWpgK97yv8CW+j{m$FRr{DY1*mY;8 z-}MVb`6Z4FX-}2+hD;!N{qg3s^-0C6!b#hPMRxz_kwdFmPFu&g_J$)EHIgHv0>55^ z$R;Etz4X|UH8B%8F?jbNv-0leO{ly$QnV6s2e*cwx;)nQszEOX22{kl516Yf((m|( zxxV75O}*i?q}aHfft7b(i=#3rF}C(S;G*%tpIYO$Mpl)bdwp_G!rnh+CO3^Rzs_6r zSg0a)+k2BLPb2l|C(w$T*s(iJ@b1%bj377eeQSLB9Rtjt$ypQ|wsSZ+z)7(oI}@-^ ziw)&IDI;d>45RK0Xoo|s7gi(>81U)JxdTl4eQ%9N`-3C4t(-g6)Z_n3Gh)Zexvi#t z$GD2vcMk;U`HG74dp{YE+`i|N@ju@ZYORF+e;s%Vh&c_sui=SMYb&jOws^}#wDzwi z)biFSX8NDkytDdjsKMeZX*mz_b;)j?w z9T=Rx`IGT0UVOc99P5w#W6d!wWfAthReIsWeUG$g7 z;gxqiHQ|@5-ZQb!9x>Th?JrzWj!{1t`*=^_*7Df@?it9qrr&$}`2YFk^%c8s-oO18 zUuH%!f4%0GCr|zL${i~v^u8Ctk^jl|aapJS;+Ly;n&&q3{wbw!<*r0?O=#;6(>IN@ zt`0BW(!2V-!@Z$VrgvAWS+yd2^{>oZ<+1%?>zAuiijr>{Y4Q&pp0KLjnw31{hD&>I z81hN-8Y{Sa@UQm&GMsAlzL8=+-MI3_p{Dnl{fAdwb4~b{uf9?E*fsmtuY3_RUdj~n z`TF!t`>jyoKepT+nOJd0q%nowXTQ6{ochGdyMJq4Qi1jdV>iARKvrO^;CL`Ex0hqZ zhCSvL89PqMiCwYBoKf)8M>bSETamtr*?#-@;!tpN#5(i(Kb*d+x;MNjFmYw()N6Nb zOTRN>((l4%&r^-dm%o^PAIh5|f#2c?`G@&<@BLpKQ`+$8Ep;#bE!5l_Dhwotp8n|L zz14^QcT1@G2eAC~KYstjlXWY~_7zNAes#s}&}W-NrDr@8YW@Xl-Sy`uwEm|LezIk4 z-S6sFZoVoI+`J?3R7>*81BZK4R-0e$Uucr&W4|YC4O3or-YDzsQ1;S==J#t}S`*tJv9hn+X=0Z>YrNbI*%^(POb#UsduYX;6=grqxb=zj zdtMsb8(toWjoE2dl%2K;N5WWmzi(LS(+?gw7LF|at59|3acnj|)*Cr+7`?G?|L|KY zc278P57r*nUHCipbw>17uD<>rOMP|lvS{yBqka}kJ}`LY-A|1V-o0Xc@VMs^w?-x| z{PUXD8&DpHV`5xvKsc#)ZiTrfoV@gad3k-PB74*hv$hzs@YXH+4z#PeH@$GW0C zbnTMEMJ*eigKufct0GC5-wW$Yf>R=9YnTyUx2?YX>TC8L`axu3WcP@Dhqgo}nz7HZ zhI1-bUAyn_?O4e~630Ftyt8N=#*Pv13~@&E6=ho^=U)Hu-i}Y6YN@@dH#~5_zeXjM z42yiSX7{ao4i&XrGHUlt@2wtC+Oc=z>K~LpRTfLwX=EOPC$~j@a}!3x1gqi)k=;YL ztWUuu@qu_Q-sgenrRL`~QhJ-2C3> z!Jih5UwOBMBlehzbFc5c;IpB-*SxnY`GW03bN>d3)$b)@eq8_F!Tb{jm@Nm)o9Mxd zxlURh#PJqci~o0(pm*NDv4yccf*F)67H8$Op=8OAH*90xa2C3KB`hUyU3X5&CqF)C z+c_n_K;LW$n6%3;w>EX`?f7(91!mh%dmFAWw_c5P@(ud}n03dk3VpnH&5n+}hcEwl z?~7YG&%*zYf6&5JCi-<$`s4#!w?saEJpVoOCj0r69o8nhr$@bm;{)1%?AW{JL)uzV z7J{|=w+8RF#)Ts3o8KB6yt`=JC8N^sd28%%e_>4V0As4KJ(zg(?L3>m$S2ojWA5>T zcA*L2U&*ZOths3ouT-nIjyZD*4We9(LTMaxwEY? z);wj>qMn}4?vrQCXldfL0X_cim zec7^Q(;U{{PFZW$yTAnSS8EG@EiOD*=mi02xtaQxpFjSwFOcO$^_h8yiCLZym;edK zgeOAJAb?*+W>$7iZeD)D%%b9w(z5dL!4fmeWScBA*QA*S#5fE4Vw@Fsm>$>~6D%@a zCT1ER^N_au7xbT8T^A{pLg{GY?Xkqw^^> z4*w11e**&%t;khijUu0&1^JxO3nWcO(GhrE+Q(_%U+Iv`zu$-Xmu4N{X#YCHp@&J|xo8xH98W`M+(ootHWNx}}MIgb3!ksfLy zk5YP8+5D=8debpfIKd=GaGxWXZX)jjCsoclqoK0)%xG;{T}}0zx-!!xBEb)b*lj!k zgQi5}R1+BmoK#$0T_3G0E2*!pHLHaiyw4G?cZADKq?E$W>}oa&E4av!yws6gY9j3_ ziFr1PS=MY4UU2U*wg>;^h(=B1M-;842c?y@=4ZkRuB9Z0`9C_6mKnMYIIO)_S5jwQ zI*!bQbI}d|aHN7}=wBVFvYL!&H6r%%ab$}kNtJWVAB7^C*%%=t78A_SbYNR7Q#4;W zj%=3%%|9sx)mKL6mzUK>OB!mURmDZ-&%>C5VUJNXOsvG|Y}x zRh$1$N%htBLaih1b)}Wm&8sh}AmM-F2(v29UzAW(T8f?(oj2kska^Rll+;(wEsHX5 zD=W-fwx#;oDs{T9zNo&;yxlK3I^XQ>%ixg`tvk!SBa8&L^t-rGP2zT$#z(U!3d?n~ z%)7(R23zE?u2;Eq$dzYBE6~r{X!EyWD=EeP`?VuA)C~PE;8C?0ozT;z(XyIa6S2tm zXeD#%YfYk+1x1foSqI{PKEzT63*#R}AwnQMf&XHf?$PY4+?@_+Ctf(|vUR^u8s6JX!R8v$^S%0SK zv_vj=1(IAPT-F7)#p_`4_{EK_?Z$f48v6sd?@VmgEeEim3v?{$>0Hv&gDEE3)Z862 zZ&@Qq=QJ5u+#QQz0_tft?^;9HSv8;z;;JsNqzP{+opJfxrcG8{3vNn+!EK1jqiM$H5D>G4CNUh zfw+N0Tewq&Zw6=BaacNhiq50eC4q_m1)J7d(0&1?wG!ZQf^LTr19+a4dWTi!u<~sX z{0YD=$OP{Pc!%IAfc*d_nbjqtnXK-@z(lDkgkeXj62PhiuqpwpN&u@GPGMF>AXQBu zU{&8BU{$9A;FmZG!TlTiY?;}h5&bqefdv=#G)Fr-y3LQ2IM*R|N86eg_L!TMd?Cn# zI4g=mx7iptk)3iY$cghoUQNrb=FY%$hWQDQ&43rsv_$}Kl84n#Yhzoqy+bOyJ20K< zZ?m$-?pSMUlzw!Z%}W0W^l=|SeHPSV_C7WHInA0Oo#^-$lcuCAL6WT7jue2~V z-3$U|UJ-y9eh4kAvJcw~V@_bwzYf|mM98WSP91?hlIGSxT<4oc$0QUW@$8o-#*Te0KdaRO@70c6ODaN_c0I$>J!4Ta~__^q!6$O)E0Kql^IBGH5@1$Ki89 zFpo#&5RlNQc69hyfN!!aSHb3HC(w zH>x_7zQTnm&@BhJ5h0MdXR95|#EMZUx0;rQpA0*` zM3N(XKXQqO+^XO>3nP}K{5g=8lo!C1ZzY8(zm$L}FD$0~N>Z5e1d{D*33$leLcnal z4?vIb;Yf5=_xs?)PN%xZz?JF*u)60+VRbtRSe>v~-8-bPIs&Qg69QKEF9KFK6zw!a zmLUgqBHoS&B%o_#%>7ev47+7KWCr~ez#gOjsblo%Adh|rUB);)1`l~uW|+~h!EX*1 zJC&5U%oH4#KPKHWL*535)r?L>f>7)4uGa7=Ao&Iv4Z&IrU(AHZ1Eag)ltlbm_RLDS z&J2~A9DmK!5IjV{5D0}K5MhRZKtk{o0YmV60*2rX05jx4R5gTkNmt*7*&P*{gVr%0 zIu(BeIjL9xV=sWQ7r=@Iu;PDGm=zO9#ffOVRLtR0Dn1^-3}IDLu^G=Z-tk;gPgvae z-R3Blg0b!k%mbElp~Sj{A(}$ZtOu-gc1|{ojBM`e>ga-8E-7b%lExJ$hek7@`@;5~ zMa|u<7d31Co69ZdI*fHo1A1em92Ov-K<#eY)4BL^E1#4NpwM|U0>W4Y#CkfqqMbcm z<_c>x^&bPzA$MOC&CFZS+S6@T>FV?qGGj}+q8$qtb~pDp+;z(R8@X84b}Z~R>#bvW z_>JV)fl8D#lB61t%z*J|5l4^=deLfrY7Hl^MRyScq7iYqfsTpBb*G5U9Qw0Ad~?_16VE9;gQU}+>T4uLw8t-K5sjcjXf zM|l>b@*|W7Q2uz-yIp;{*h(hrm-H!(L6(Y7T+B0pCJkng`F~8KX|hTwddvc#8X_}> z;h}rDbQi@Lf;r!EuBTbI(2y)PNn(~ZS|K?ao=07hlmeKPyGUVDzDvNQ6c&?GSWHR+ zNy<+Ncr0`aAsfWFic@W^ZeaDB<(X-r$2Im>b`Lt3|R4JodWL|4wXUFn9VxFUeAEGLDo z2%swh=!(eD6#{YPdIGxgBLceeGXS3}>?4F_p5y{2Mn@?S;NDG11Fn7gH9V1 z#Dq48Y|KiPCXjk5I^>v;zgi5sv&<#dWzZR#E9R2CnkEiqRjaLufdCYTjk7Y7S;72? z)|sJsgILe-S(Yj%_hBM5jvZ+pMvb_78Gw{yY)=NwoH(R1xd6=^2o>HzjabFgnKUK(b}yG;o-8hMGYW6ByJ9etRd3 z_FGJ2z%I8&GiDQEZHU{4STDqt*~s)^)^Ul+=!s(!8%7PYl15z!;^bs2IAqYElLyf& zdU+hY9HK?me*ARnTcgpQLClR4MpsJMofe(IP}ibU=MQqaVG3ePbvKiyN-G@#ns}nL z$F-LxwSL1-Ohfq1K&(VUxN6B?qzzN@b=U$K8zbC5i!(}VLF84Ql;VsKFbO+ef&v_i z-FSt^V|N-y-32Dn)5iuEkJkLiVAxnhbMqtZ*d_4%Y<`40UPfSr-1CpEAanODwlMx0 zP-8Ymh%m7~!60Kp=C+zu1z@{TwCp541c#g#>r6VH2B^H%9&fEQ`4L z5$^V23uJDLaL@BTXmH1~%|On^2=^nffy`Yh$+;UN+@FNaag?|a8^q2*bg#h%I2p73 ziJbAF!Tn%{YJP-^!Lis-t%>j=&aK!YmzjZw50BXxc@%};`3ZYaIOrpo2uoub-e_b9 zVmg-LjYg&*jwfRSoQ1emVFP5n8Q3gbyk>U~q276-mqfkuMDHZ(oo6DrbJt8)axr$b z3YTMdox+>3yG!Ad==>L$2j@jz!|r{BV_<2L&)Ufpjz(y0jzZU3G(u~iD>V%D44Q~W zxXZ&9yex5JqyS*P($B)~E`|4D_bY|mJ&sMJ>C-Ny)2BTO=@X;F7|;n`uR}du*j*^l zMA)Y1h|i1AlYvw`PqIEmA+sKLaFAMnU7CQ+0286EiSD=;rv>u_w0nS*I2BZFp0arH`3sIo;JoOl^df)bg}3Vo@#{n#&=W-h(Jiv>2 zfS)G^_#z(Q=S8?{#}>TI+880=f$!*;$PF<56dgEAMzRkSeu~{xjx=Yu$`Bil-JfFvbj$-fb^&SdS!{rAE6$T~_*12_ z6=97zs~RiNMC!pkixTrO>0rMU+dww1uypbSBpk~ZVM}po-^YcW!(%3X-^`kf=970P zwy{cH!L*#{$~sb%xC`58mFmM^!8nrr0Jc%C2pv!Z6fmwU*4a|)r4Y6nBiyYeM9!_l zemn8GUJ%ZeAbccL*S8YF=aMV4>gYX;^ zS!f@HOyfnsZ<3A!xXqz2#@}v%SCfu0p$Gd-*b*;sQk|vE*uu-rrP3qIP>_|$Tobt% zcr7-L53gcR^Bfbn{{UO?lFp40f)Az8fu=0Q@qHyW~)^Y-5B#CVhC(j>dc- z&5dx!i%AI=Ex&YQgaW+OhjE>|!I+g3E(QaRL+%=?oF_uBPzaWmfwY|DbA`N_WQ=RP zBKd-ic?FWSNYn`o8PN!L1F;1!yBPNOgK-cW3~@(h;4-WSY@xtq7h_R@LRc0G5$@=n zDhKQmtL9b0QfvuWt89!Aak<0%a5&-!Bb>--j)~zGm~3u=$>tWAB?qB{6{#3=u$LvI z(4w7eyi~~5l~mvsSbA@G{g`Z1mQ_UInDkqFuphfV`B$Ar`y06n=o+C@$j8 zif{p!CeTEl1Nl`-oE_or&)9sut^nefnnJM>Sk;-<6zGWDXt!`%JIGt zG@rXBY=O%XBi!@yTf$GQvtW=?7hpppxwAQEgTpICPhf*ScTZvyod^-tc%ZvNXZwZD z-slNo1n7doCTz&`x3SwJ&__N;$RCi5abzj>R}h~Y;qD=9q3@eqoD5Lepkgh0k_eNC zN*(7#xT97uF->)(!t){@+3Gx4S&4|BD^|(k5yPu^ldZ$=2nP2hmAHJ?AauRM%1->Aao4N@;?pn;vb#lo^9ry@l3&_W;VyS$234gqcO*C-I+D7jDAg#VvdV{^OZ4A#j5cy#iwHE$Wij#4e^Dw736Xu-v1xbhSUxJW0k8ulg za+`zAggNgFVHDV0wl>V>vbABJS!+jpiO_rqJ&rBB-IZnsv46sa2>mtK!aNmXNKM$~ z@yuxsc|05HBgE4mp7MwuPk2n2Im>(v^FJnRnEx?j!~Bma8|Ht^*)acO(uVmTvo_5C zq$zmD4tmBiQQRO^S`v+>WqO6VWwmvc)pJ11%E-*m%&78M4fW;tYe&2|X}A?L&cv+h zy85zG&@x09x4TLmSzc*&<(%qTR^gFqit0;dRh7*xt8x`RS0?F=y^}<|sJ?o3WeM&l ztSXvcR%%yb6YI*(h?dmVr{(%3i%NJ0Vwqi=r(RZ6SC*FDN0N5aa{NTxwpQ0LyUY$! zbxnQc?8>unmlpqX+U-&uLV4w!%K9?gds#m#T0N)gOt(=~t1icFfAt_~JvOPTdQL^Z zG@DT%PT9hBv#M)pK_h4r%d4t!V^<%urPU3^RrEAYUu?Rp%)B_;Y?)`LWL8maw78N4 zHBnqyQBhV`A1$h?te7*qOj=@FsID!=U5Hhc_4TN-Y))xq5i^N5=t~94hQ7zk$ZgS%~1#=fGu?7 zoz|48Lyz0XU7wb~mjXxEe@{5I!0TJP69BOK)am2oZ{Bg97aam4jCEsRr zua8$>BH5pRM~KtUa(}#>8XblgroJ4{lfIn(YIbBKGI2E?;gc)k)qQjs&x@nW^ykkJ z(r7RS4JX(A?)u0_XjROgA1x}bjM}qnS|+A>9sOmb;n0DZds+TMCCm7(?% z7vd-4GOhIG=n_I${qm{JUzG~#h}YMMZ!pB_0WMCN<_wN1IxQ`8stWnNQ_Bk%;sqWU zQRWFt)H9UgjJo|+C*!rliMLcI!NS;&`Q4cp>liDCWKW2!&>>~(WF|4_j~2(s(-~8P z(MMXE(TC`_Cdl3`f8(!)JD3mI>%Il)<>?dLWk?@eZh5xanCoWF$GcW4X5l# zIuX+K9V&7MdC!J-=)?E^%z*6J@g={^ZN64H+2#fjJTFCDsyYCkW76w9W%)wkm~=wn zB`}11w)+?d(=l$RAVchg#A&#%Z{nio$sVmMc}l zD0tdxc1;x?EZ39p@~Zl1+1#S4=cT{N>GFE2Bi%~gO@Q;I6$RdpVt zYHd+zCD#ic1y39D(K(*UX6Y10IVI>>Cd-_{%jVZWXv(zAtX!SA9Y$t`%gfI9u`s}^ zPG*)4RH6W?tB~!{;dSL~v{!4MDJ^m2qiNaGb273Da9Wy|mtByXRZx&Svmi4wKO-lz zAUmfZCpR;1W>#+VH?j-LT}526m~Hpn|3O>VESb|Y^K)}%=49t)6l7&(73Ak;42 z$j{Ep&CUlQ3(v6^G*9zaTUJw7iG=|o1?8Dp88fpAX68bz0Ab5G^4B~q-*dUNOr4hL zG80YC%$iw{lZR98oB}j9AI4Da%-n)(7@e7!mzmu>EhpF0pH)9ikeLTFS;GgGro=$dZXK1y7^VTiC3POac@a?@wZ zv>fDt_Oe}vJ4!)MM?jb1szJ#<2I7XPY#kxhsiSgq0>N-lFcaC9Gcy<2hAc#gGYWF^ zb749!FRLH}$9GoqH&~M{e8j3R3;%BhH2borXXj;QB1>|zGcz$LVL;2v!oPfsOZm8> zm!F%Jmw~|~zH%??GN&WSW@gQtnUj-U0Oygr*&G}4^JnH{A#G-6!3t6&$LD%nvgJ+B z$^QJS|Mc3H8;d z#W)L^QD1#(j8pcf)K{DyZ?zYaW?wNDveFQY2~qw%q!&`EwN;Y=_ZyvT|x!) zxCv89ahc^#nI6y065ph0bB~-hJ%+31Oq|M!&n|oF^t8Bo`KohfxqUXK+P?hyznahl z`|9&#yaQf_edQT4-auT6ef7C9-bnvBhMqrKj@hh!a}2zr0`O7?u2PGh%_W4Z5yg3XM}xvxCS_O+sE z_aDrZeGPb-_m!v1z9!;w??0F```YP0{TQpG<)6drHv!2!S_Wok@zP{J!yFlX$2k%9 zPoe&S&SAPq6hG2wMea1}oFO2I9FD8#8|%o6Pd;z3bM*eB(Jnh{nRA*%{kYuw%0p%! zBmeP;*GJ#Wystjy^)V5bdH=zv*T+o%iN`=4E%6*)zllfY(Go8&Cob`vGX&%VIemvd zk@ja^+|cK6-3;n8^l4pg?)is4hvlmJhdwgnv(Fp)9L4`^=*!D-(~kz?((kJeeSNI_ z=R;o~16~4t^`WniiMRy(PlmoecKXji#_DJp=-n}UDm#Kz1_yfosxeG_H&+ua5tRlRHsqV}< zC311FsJ1LxG^aFLH?OEBnqyzap_u)bdc20K3U7WYIXzllTjt#U;^Rv_|Avn%tGJ^6 z9S}Yo&eHqEy2Cbzc;H5xU6g-XXO-K-V|;?lS)Eq~Swe20Gzuq}Pp#W3Y!+G>Z8 z{zb!B9WK@ioxgOLK&Q=NmEUu*)~QlyT4@iBJNA}%1-n|$;xfqT)dXW*=whwcxyoPy z7ug)v`+XN{y((qbdnv1O>|N#+?0P+mms=3TDGe@*;i+`5pfxLlak;`_vFcS`LF-mI zyYAH%>vL>g?JL=}dseTbA>SVjjdgt=iu&Obp))tc3DKi9eJJXdPtEpit$5?38|w#s zNw$|hA=Y`LSA)}^y?sf3XT7dn7cWM4f7qAg_g6J-hu8bObLze62wI%WUddL_&$syebLzeI2wI%aUd^|8)i^1%u`kK*vzJVp;>GCm z?R`mppHVEgL|FrV)Bi_q82@dVpbSI74A zztks}Y^;0wP#hm!5!UuI*SM2J_x7RqeDo6N=W#;x^1eP4pPQ;?`+2|Tl~dybeMx># zy*hv4*5KsMgMBDISG~OXWt0Dq-$G! zC3VXdwOx8z>US+a<1gB-_-y}{*7zqFnQxx+mDCNJMK_*znRMfKzLL6Oi`s7dUg~u% zzu+(0Zuo4!Y{4g47-^ijhZG}K;)5N?f@dj7}7BC2ExytafAMrWvDY>&;Lt@m8)3aO=!*|WGi$XI)A#GB^q6&`QIF@aCWzz6}E zPaWtAkuFkyCkqEBq&{(u_eI*lE5unGmf;+)o7f+tvaSoO1T+FdfMvL;$yg|`Ar2iKhy<)a04X;X0PMcRqD z7d9&gf6M)ePq?;7@A~kGW_Xf6wfM4XJa)my9`GLIvf8;g=k{cMM(?u9i)L5iNsvlB zv$8C2=FA27b9&5J&st?XjvD4vR+dg#HZ^U^iBpz#wBb#kZOv)++tW{+IwfOSW;uTO zWd&*9z}xVrPKBF)wTc?*tE2L|Y&@Sa8%^dLooDg!hq^Rg82Z3sWPDOQ^F(WXlq2*I zg*+VutdA_d-ny(t?%6MHs5(6@V?hQ^dp`El@pw#qZFLn{IF0;7SbU>1u9(#o;mH%U zR+K*VIAB*f3V-*=bBb62USy2qXT@Trs6>b`eZbhQ@HHZ9anO{k*1Zsy}wc5J+x{}lXU0reztOzi26*ZOB zMbVP-iZ2gdCT4zE>VwCB=98S3 zwIA<2#10RA;+hyyV&JG>_c($vyS6S`-_g;A=X_e*F)@}z=Vs2#oUyDEF9n~j%CzhmZLJGtfG{IoW`^=-w6@3Emf%%>0XQ=#A@0i~Ccf0& zgRhhH(Dw92cmt}Gh)gKJhhBrP2CUF{yO4@c-`eCQmW#tyXb8w#Asto;LJy4z4Y1iB z%|qdlp=7Y1gUaa8OrV#6tk7s6K0-b=L{IqCEh1~9;Gf~sIJ=;hC=l#YpX51R_33qx zZJ!8LmPmbyr+Hl4r*|NzK79zJKJiic3E~qU09K!fg0I_gVnHnlxkG&-w&S#)P$dXG zq&~&dJg)5%ABb0IeeN8pIA^!L{?~^O|wE{Z3N%a z0Vj*#C>y1OrT`r;D$JWHE|)KDFoA?1)R=E90y0hVM4A=~NlXb%2P_sM>*AXppok_g zyIF$Xv4B;C>LVZN)#S6M$MGh&7ZA;N_E{5h%^q5?am1oUbLQXQ9NG z7O>{Yp;VN>;ovkQnytV^r zyq*IZBend_<^I9tzUp#!x!l)XuD-7%AvjTDvj=qc;uwhnODXtNXejW3XfiS%0U}!qyB+6E=x_uL`^i+P%dh{2^yLVM=HcV1_HsSFnV~ z2>)b4jfg8D->N)LX5z_SXRlwBHaX`C( zQpDfafUM9o(EcKb{=NxhM@gV1gV#Ht+WxS4ELviW2sLnk+apB!^S;ae5D0osEI*=j zs*E7}0rl|yLW!In1nT&62vkd^qcGkNW69!Wupo}S{MwA|r9hnxQc2Zb8$)Oxmw>5~ zkmG^0&PilzF4%AktP-Y(N1ht7o8qoAU;Tky7&TK+do3}REU=Nw+zIQ zlJgelX~)9Zl3!6sdbv7jTnko5>$Cqy1I8-P;8(#_OTNr8IE z-9qXZNpZe@OvhZJ;GZtl3Rpk`c~J7LV|G{wH2_4q){CckTzmbw8G^djyBA2;dVGgj z_))1|pibtGkgBc_P8PlpHF@|h-f*x-<0}R2pl3;+AkqR=`W4TbK&8GZHm*s~C7+b^ zh`c$CS`5~!egep*}d=r%2f`fqC79vEF0~X(BW%C7U zyAwdwMkNZG3dzBgyjikB;I~5=pz5*l8@HacskOz>%Q>pl3-`z71K+??6orRRFyJWQ9()k?Oqc=@6>6 z5LNP3@--<4H4uuv1w-#&iMq0}fEaXFaKjB0<5(qW>iGt5!2;jUe5;_1Lq_7TbgdWlXFrMad z?Ew(4oU;eOFpzx$&bN&PA4I3{bdzr@TjL^l$n~DQ<1Bc?#g-iIQqpsCc~Q8G41Bp9 zg385%Ks|3u1y#>-_$qQ;nT!V-DQAk4sFNx>gdRe*?9$^w)YZy#O6p)CP~FN>eGVaf znRxiB&x0$+g_9xKroXoWaB&GC!~R5iXH91b&1gdRd? zGaJtWQC(MbJZR?$jokBHl_o(spe+JQ5rf|WvTY00CboN2!u#de=lkJ;f5qg;5m8*6h zk7x;FAkXC=*AmWF=A!hBmT;Achwcj~jg@83%Rs?yb&jtw45y3Bgj%s8<`j|64I-#I ze3d&oo~uGaOR|qhC55fC-kZW^5Z?B52vvtjb%d=tdt9COJsm>TAyOS-tImh6&PSdO zq3RHgmNp7o^XD^4swIIsCLQ#sgv$S%#1!ewLqcRc4c-SiSCS$D$nGb;C^8(p4?Ro~ zej;LwAigVK(eacxPSRPRR(leuTA4tdK&FFgg(_i5z5^f^ulN}NTavHG*9#p)NF`pd zC?wRz3bZ6!zpYx#L4iuG@u+-lzuF?QZ7m=iBY_jBT5X<|Kr6%px(8HEkBbB`9WQoi z%LVaRx*Q1p(-VQJeWk0j+SR$v)w#jb5vV#hx;pDzoei$e&7O`x?etAbG_Xv?a%C9USy3`k_`VWz+S^~BA9syN*?^l9&>5-phuqB@a94{jgkv$MR zN2mjVKphNURxOS-gfnE+c?~G|T^$pMZ3}M`ss(|1MDHP0$0&iS_MuYQ7Xr0^_j*); z8aaMZ!EQNWaMvX|MGIZ0=+9J<6E~qw!isopmq<^dq5G@0HIdPo-x@idQXFBpbHMbDU0fYh5* zF=N3XUk@7&{tSNc0;rU9CgFEJ?C1;B{^L7mG05`5vOqmjF#^4VjAdK?K+`LjH}K<&G4gE~@S z2{n&}sLSlL$XBXBrJk?U<6uglPXA4y+E>X1ae>{Yl3Xwg)Ryvft*}acLS5(E#BbU} zz2@Hqc4~+;e$|3g9}Y{dA1~4(PEwg2EFns4+j2s+EzlC}D?F+|J$A1FHF%CL@YYhI zT#hcn;2Jxtgsxe2qZ(mW5o+ELX;#J4Jg%KpH$zafY7>xV)g5AnS#>8+IQS^CibuMX zG*+8Mn6XsEnfYFq_5juNh<^}Jk8-{|m+ST^GDES1*qjQz-vC;nJfOz~k+xM3Bm5i% zQ$j_6@(Nv9wzH2|f`wUtF9W8AN`PJk(mr~PY>l`;U7YX}BQ{l_M*K}s^$Oe`SX=_siVbjf%Y7(RQmFf7~u6wB2++kKNTWRSw0iQ1R+xY_5-Qh=dRo#SB{@NL9haL zUWK&?1$xF3TFyE~09v7|*;iu)HUp&zT0`O_f%IXDAo`F61iM@Z^Q$W3CF6@K&=jU2M z9Ioa9=>n3capwq~p767~jDi(vN2yKd=L0QOI&0^+!`D{p`hp0Nq4kRaQw3cLloH~} z)8%B_GrdZZdZkAdXh~>RgPI!pHu%>8rO3F%Z^hX90CA%-o8&5d=v{iX5gnN z1*<)bC~%Scg{o3QpkDGYcr~`RG9ZYO2|%cXk^)sf(W44f>R^v5P^n2CRiIKwcvOMv zK?|=9|D_RSrM}0kz9c98}MMsEQ|5+f8k)At` zlA0ll04IqgU#p%ji9m#Uc$D-IYI+FN*>0&vB~*SqfV+tQ`ZwU4LFLgsRL;*fp)^|1oj}87{JslFy}k!%tax=F&QNl#;} zC71eViB+yBYk_pmoQ+bw&^gcZ3ksk!2{gg@O+WsDoN3FpeE3c4e`iX1e7dt z-*IVeLZckNmjrKU(S{CH$2Ahih@DQL5pp4jA55}!1nLTG8L8@E~)U6&>pjvp=qY6~&a~@ToQvcvl1!`Wr z0xGisUCpcZEGpwwit9MN%O$?1(oS1ggbXk8^HWtgiQuXj>|h}sF?NgVw9|)1;5iC&W_k$jlP}7@BFqU+x{+uE@?|tDC z52cd zTbD1GXpR$3l(nA_wGorV1_z8ORMMlI&_h_DpKkN@+6~#3&`uJ>lZ^~lB@0M3a$K5x zAw?|`dPtY0q-oeiFeOBbr63|;LHh`05pCih8Os6n+S4qcRH1#F>=gOi8KGK}@3A1} zdQFNYSm1~?SM+$M*bWr@HCC=?q0obZF0c9FHam$ab+HyB>Nras@)VG*@3FYg7^6V`_WQSVWgww;0_LyaIlBShBl91wjtRt^=G zV5BZQ47+=YY6J5GRiJT^hf*gG$)~9-u7h zp-P1Mc_@D_(mcGs02(Q$i~K;(XyF=sL`P5Q`C&TyKo_Vvl0fPR2@0Vetn#@ZwDlXZ z(qIX7@zjK0h_eq8!r*dyVi&qj?EEquL_&}z^pH;M@idQXPwf2SoKEbMfOKM?OpC$K zF|kjCQ7P#ZEniRKP#gR^F2?W*8Y#gWahB>7;5QSPA0A@oA&$fBA~?LLkt5Y`Y*jP{ zs6c4so(!Z{+)e>XksEUOtvfW3b_D7LyJFEHk>4-E-447=BT)GZRf|-Cdg-;zqY6}N zmq#UpT>E9LComeT-qJf(Gzchx&YZMd>%vh2;y4yUP|hP0YYtirOnW* zR3f5hd-sVRGxGsKrvg2wYEFH>L2;r)K|U%KY}Ctn+d&SWB6NXzdFffP!Zwk%nPlc=LLKcB6L-(b|KV2Vp4f;LYXPZA>5GULTh z>hU&X+H>MZ3O~okMH1$)On%lZqL6#!`{^Amm! zpJn|8%&h>tZ=O#wIDD4%7cln$RH2(s!rtMttUqm!+*B)sfcbCi*CNd4V?PWU+p)h7 zVLr_+{{j2Lb2ML)5TC!G4B?BpBuk3+f8XD<`w zFMRSPC?E8d8&F<16yI({J@hw*a)wX89p$}f&jmK0x9~f^BxK8FC|?0SGmZM|P`(KE zhTG-aQ7-h=_W;U_*E2}n;gEkAWi(uVw6_E0H0Y1F_5X@>!@a&6ekl)z_iy^v`CLZ$X(O3;lT*<73qSCNDG5=JuZEuBi9Sl|yOl>}+d|;aTI3cDxP>k7{`$(_^N) zxhLA(nGwZPVA0lgw+Pd1ZFVU$o~gx-B|WCOGc(%V+};#j)Y#QT(@jylYpS!Oy}Q|T zU)bKWsJXlKqUPv=wvO0$&Em%IHb)nC$D*d4$ z5MEo2%ke;Van(G6U~`;49|tt4fRGI1QaDcLWn20eH4A_aK7PVnRtwFPF)$^|7~k$&`{-^(lWdb zu70+OO56<}e7aidQ?(g9fg{&eI*TeHC%C#sjseAJ5B@f{>+AQFKBqLT&?RbTgxD@oppjV z#(dnmZkCxW@W>tCy%W7)j58iKAdnTWHufZ1*%S=&8eI?#6hv&h| zD=QoW&|+mIYQrToZcKb3&FdR+uewtDfWf@`!o@v}3$X9$()}U_Ep3i*KA+yxysXDe zZ))smG}9M!cbn<*Wa9M3o}RAO1xxTEF*6;nJzI?90aDEimb63{b~P?;b_%WS3p*U# zxL`q7^HQgTJZ)?3?t#9lHFh<&x6qsxyV_gg*ozxuU9P3J)^@iBIE+L1EB}s#B!)I` z#ef0Hn@2e}=`Y^K(`tQ$e7;Ahstl9zK}{;QNus-wbRVd;XnVj>>dm zCqLSwuJd#3aU3Vkuo)kx8Ix^e?#Sa-ZSS#@-{gsySDga(PCL#4ro8ie2y(BEbV?p? z5lDWyYx41TF(+s~-clc?l@m_J7hy5pIzPt-*E|j;FSpW|`Hql}_d_2h`+CUnu@~p( z*!U?34koXt%9y8TI#M3*!9H?fIFgGefSsRXQQqf{sfXMj5Zqy) nPsYYLBZXw;$sBNglaXBV@Qh7x>ZP7v?jRibt)qm!BlrIUKedS` literal 0 HcmV?d00001 diff --git a/ch32v203/build.rs b/ch32v203/build.rs index 3f57399..035d3f1 100644 --- a/ch32v203/build.rs +++ b/ch32v203/build.rs @@ -1,11 +1,59 @@ +//! This build script copies the `memory.x` file from the crate root into +//! a directory where the linker can always find it at build time. +//! For many projects this is optional, as the linker always searches the +//! project root directory -- wherever `Cargo.toml` is. However, if you +//! are using a workspace or have a more complicated build setup, this +//! build script becomes required. Additionally, by requesting that +//! Cargo re-run the build script whenever `memory.x` is changed, +//! updating `memory.x` ensures a rebuild of the application with the +//! new memory settings. + +#[cfg(feature = "bootloader")] +fn linker_data() -> &'static [u8] { + #[cfg(any( + feature = "ch32v203c6t6", + feature = "ch32v203f6p6", + feature = "ch32v203g6u6", + feature = "ch32v203k6t6" + ))] + return include_bytes!("memory-with-bootloader-32k.x"); + #[cfg(any( + feature = "ch32v203c8t6", + feature = "ch32v203c8u6", + feature = "ch32v203f8p6", + feature = "ch32v203f8u6", + feature = "ch32v203g8r6", + feature = "ch32v203k8t6" + ))] + return include_bytes!("memory-with-bootloader-64k.x"); + #[cfg(feature = "ch32v203rbt6")] + return include_bytes!("memory-with-bootloader-128k.x"); +} + fn main() { + #[cfg(feature = "bootloader")] + { + use std::env; + use std::fs::File; + use std::io::Write; + use std::path::PathBuf; + // If we use a bootloader, then we want to alter flash origin to 0x1000 + // We do this by giving the linker a different memory.x file + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(linker_data()) + .unwrap(); + println!("cargo::rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo::rerun-if-changed=memory.x"); + } + // println!("cargo:rustc-link-arg-bins=--nmagic"); println!("cargo:rustc-link-arg-bins=-Tlink.x"); // println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); - - // let out_dir = std::env::var("OUT_DIR").unwrap(); - // let out_dir = std::path::PathBuf::from(out_dir); - // std::fs::write(out_dir.join("memory.x"), include_bytes!("memory.x")).unwrap(); - // println!("cargo:rustc-link-search={}", out_dir.display()); - // println!("cargo:rerun-if-changed=memory.x"); } diff --git a/ch32v203/memory-with-bootloader-128k.x b/ch32v203/memory-with-bootloader-128k.x new file mode 100644 index 0000000..fbaa06a --- /dev/null +++ b/ch32v203/memory-with-bootloader-128k.x @@ -0,0 +1,11 @@ +MEMORY +{ + FLASH : ORIGIN = 0x00001000, LENGTH = 124K + RAM : ORIGIN = 0x20000000, LENGTH = 64K +} +REGION_ALIAS("REGION_TEXT", FLASH); +REGION_ALIAS("REGION_RODATA", FLASH); +REGION_ALIAS("REGION_DATA", RAM); +REGION_ALIAS("REGION_BSS", RAM); +REGION_ALIAS("REGION_HEAP", RAM); +REGION_ALIAS("REGION_STACK", RAM); \ No newline at end of file diff --git a/ch32v203/memory-with-bootloader-32k.x b/ch32v203/memory-with-bootloader-32k.x new file mode 100644 index 0000000..336cc4c --- /dev/null +++ b/ch32v203/memory-with-bootloader-32k.x @@ -0,0 +1,11 @@ +MEMORY +{ + FLASH : ORIGIN = 0x00001000, LENGTH = 28K + RAM : ORIGIN = 0x20000000, LENGTH = 10K +} +REGION_ALIAS("REGION_TEXT", FLASH); +REGION_ALIAS("REGION_RODATA", FLASH); +REGION_ALIAS("REGION_DATA", RAM); +REGION_ALIAS("REGION_BSS", RAM); +REGION_ALIAS("REGION_HEAP", RAM); +REGION_ALIAS("REGION_STACK", RAM); \ No newline at end of file diff --git a/ch32v203/memory-with-bootloader-64k.x b/ch32v203/memory-with-bootloader-64k.x new file mode 100644 index 0000000..6741502 --- /dev/null +++ b/ch32v203/memory-with-bootloader-64k.x @@ -0,0 +1,11 @@ +MEMORY +{ + FLASH : ORIGIN = 0x00001000, LENGTH = 60K + RAM : ORIGIN = 0x20000000, LENGTH = 20K +} +REGION_ALIAS("REGION_TEXT", FLASH); +REGION_ALIAS("REGION_RODATA", FLASH); +REGION_ALIAS("REGION_DATA", RAM); +REGION_ALIAS("REGION_BSS", RAM); +REGION_ALIAS("REGION_HEAP", RAM); +REGION_ALIAS("REGION_STACK", RAM); \ No newline at end of file diff --git a/ch32v203/src/bin/usb_dap.rs b/ch32v203/src/bin/usb_dap.rs index 2955244..b361f8f 100644 --- a/ch32v203/src/bin/usb_dap.rs +++ b/ch32v203/src/bin/usb_dap.rs @@ -35,6 +35,14 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { #[embassy_executor::main(entry = "qingke_rt::entry")] async fn main(spawner: Spawner) { + #[cfg(feature = "bootloader")] + unsafe { + qingke::register::mtvec::write( + 0x00001000, + qingke::register::mtvec::TrapMode::VectoredAddress, + ); + } + let p = hal::init(hal::Config { rcc: hal::rcc::Config::SYSCLK_FREQ_144MHZ_HSI, ..Default::default() diff --git a/ch32v203/src/bin/usb_dap_ppk2_uart.rs b/ch32v203/src/bin/usb_dap_ppk2_uart.rs index f84eabb..b50dc31 100644 --- a/ch32v203/src/bin/usb_dap_ppk2_uart.rs +++ b/ch32v203/src/bin/usb_dap_ppk2_uart.rs @@ -43,6 +43,14 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { #[embassy_executor::main(entry = "qingke_rt::entry")] async fn main(spawner: Spawner) { + #[cfg(feature = "bootloader")] + unsafe { + qingke::register::mtvec::write( + 0x00001000, + qingke::register::mtvec::TrapMode::VectoredAddress, + ); + } + let mut config = hal::Config::default(); config.rcc = hal::rcc::Config::SYSCLK_FREQ_144MHZ_HSI; config.rcc.apb2_pre = ch32_hal::rcc::APBPrescaler::DIV2; diff --git a/ch32v203/src/bin/usb_ppk2.rs b/ch32v203/src/bin/usb_ppk2.rs index 5838544..9028110 100644 --- a/ch32v203/src/bin/usb_ppk2.rs +++ b/ch32v203/src/bin/usb_ppk2.rs @@ -40,7 +40,14 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { #[embassy_executor::main(entry = "qingke_rt::entry")] async fn main(spawner: Spawner) { - hal::debug::SDIPrint::enable(); + #[cfg(feature = "bootloader")] + unsafe { + qingke::register::mtvec::write( + 0x00001000, + qingke::register::mtvec::TrapMode::VectoredAddress, + ); + } + let mut config = hal::Config::default(); config.rcc = hal::rcc::Config::SYSCLK_FREQ_144MHZ_HSI; config.rcc.apb2_pre = ch32_hal::rcc::APBPrescaler::DIV2; diff --git a/ch32v203/src/bin/usb_uart.rs b/ch32v203/src/bin/usb_uart.rs index 8fd28d0..19ce3f2 100644 --- a/ch32v203/src/bin/usb_uart.rs +++ b/ch32v203/src/bin/usb_uart.rs @@ -45,6 +45,14 @@ fn panic(_info: &core::panic::PanicInfo) -> ! { // println will not work without probe. #[embassy_executor::main(entry = "qingke_rt::entry")] async fn main(spawner: Spawner) { + #[cfg(feature = "bootloader")] + unsafe { + qingke::register::mtvec::write( + 0x00001000, + qingke::register::mtvec::TrapMode::VectoredAddress, + ); + } + let p = hal::init(hal::Config { rcc: hal::rcc::Config::SYSCLK_FREQ_144MHZ_HSI, ..Default::default() diff --git a/ch32v203/src/lib.rs b/ch32v203/src/lib.rs index 7a80be2..eddd2e6 100644 --- a/ch32v203/src/lib.rs +++ b/ch32v203/src/lib.rs @@ -12,6 +12,31 @@ macro_rules! my_println { }; } +#[cfg(feature = "bootloader")] +pub unsafe fn enable_backup_registers() { + ch32_hal::pac::RCC.apb1pcenr().modify(|w| { + w.set_pwren(true); + w.set_bkpen(true); + }); + const R32_PWR_CTLR: usize = 0x40007000; + unsafe { + // BDP: Backup domain write enable + *(R32_PWR_CTLR as *mut u32) |= 1 << 8; + } +} + +#[cfg(feature = "bootloader")] +pub unsafe fn enter_bootloader() { + const R16_BKP_DATAR10: usize = 0x40006C28; + unsafe { + // Set R16_BKP_DATAR10 to 0x624c ('bL') to enter bootloader on next boot + *(R16_BKP_DATAR10 as *mut u16) = 0x624c; + } + + // Reset chip to enter bootloader + ch32_hal::pac::PFIC.sctlr().write(|w| w.set_sysreset(true)); +} + pub fn bytes_to_hex<'a>(bytes: &[u8], out: &'a mut [u8]) -> Result<&'a str, ()> { // Need exactly 2 chars per byte if out.len() < bytes.len() * 2 { diff --git a/ch32v203/src/usb_uart_task.rs b/ch32v203/src/usb_uart_task.rs index f9eb0a7..44821ad 100644 --- a/ch32v203/src/usb_uart_task.rs +++ b/ch32v203/src/usb_uart_task.rs @@ -21,6 +21,10 @@ pub async fn usb_tx_uart_rx_task( mut uart_config: UartConfig, ) -> ! { let mut buf = [0; 64]; + #[cfg(feature = "bootloader")] + unsafe { + crate::enable_backup_registers(); + } loop { usb_tx.wait_connection().await; @@ -34,6 +38,10 @@ pub async fn usb_tx_uart_rx_task( { Either::First(_) => { let baud = usb_tx.line_coding().data_rate(); + #[cfg(feature = "bootloader")] + if baud == 1337 { + unsafe { crate::enter_bootloader() } + } println!("Setting baud to: {}", baud); uart_config.baudrate = baud; if let Err(err) = uart_rx.set_config(&uart_config) { diff --git a/ch32v203/uf2_flash.sh b/ch32v203/uf2_flash.sh new file mode 100755 index 0000000..27ec521 --- /dev/null +++ b/ch32v203/uf2_flash.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# Convert ELF to binary +riscv64-unknown-elf-objcopy -O binary $1 target/output.bin +# Convert binary to UF2 using the WCH Family ID +uf2conv -f 0x699b62ec -b 0x08001000 -o target/flash.uf2 target/output.bin +# Copy to the board (assuming it's mounted) +cp target/flash.uf2 /media/$USER/CH32V\ UF2/ \ No newline at end of file