├── .gitattributes ├── .gitignore ├── Quad Firmware Flashing ├── KEIL-Flashtools │ ├── ExtDll.iex │ ├── Mini51flashtools.ini │ ├── jxdhack.uvopt │ ├── jxdhack.uvproj │ ├── main.c │ ├── main.crf │ ├── main.d │ └── mini51flashtools.png ├── Readme.md └── images │ ├── Nu-Link-PCB-fs.jpg │ ├── mini51flashtools.png │ ├── ports_on_pcb.jpg │ └── stm32f0-disco-swd-pinout.jpg ├── Quad Hardware ├── Circuit Diagrams │ ├── Copter00.pdf │ ├── Copter00.sch │ ├── Readme.txt │ └── fb-pins.txt ├── Datasheets │ ├── IMU_PS-MPU-6000A-00v3.4.pdf │ ├── IMU_RM-MPU-6000A.pdf │ ├── LDO_LM6206N3.pdf │ ├── MCU_DA00-MINI51_52_54C1.pdf │ ├── Mosfet_G2310.pdf │ └── Tranceiver_BK2423 Datasheet v2.0.pdf ├── Images │ ├── pcb-front.jpg │ ├── pcb-front_annotated.jpg │ ├── pcb-rear.jpg │ ├── pcb-rear_annotated.jpg │ └── ports.jpg ├── PCB_overview.jpg ├── Readme.md ├── pinout.txt └── system_design_overview.png ├── Readme.md ├── Remote Control ├── Datenblatt.doc ├── Firmware für AVR │ ├── Monitor.c │ ├── Readme.txt │ ├── Rfm70-rx-tx-sch.pdf │ ├── VT100.c │ ├── all-fb.h │ ├── rfm70-fb-rx.c │ ├── rfm70-fb-tx.c │ ├── rfm70.c │ ├── rfm70.h │ ├── timer.c │ ├── timer.h │ └── vt100.h ├── Images │ ├── HOC_Fernbedienung_Platine_Ausschnitt.jpeg │ ├── HOC_Fernbedienung_Platine_B-Seite.jpeg │ ├── HOC_Fernbedienung_Platine_total.jpeg │ ├── HOC_Fernbedienung_Sendemodul.jpeg │ └── RC-MCU-UR-HOC.jpg ├── LCD port in remote control │ ├── Readme.txt │ └── running.png ├── Protokoll.pdf └── readme.md └── jxd385.jpg /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /Quad Firmware Flashing/KEIL-Flashtools/ExtDll.iex: -------------------------------------------------------------------------------- 1 | [EXTDLL] 2 | Count=0 3 | -------------------------------------------------------------------------------- /Quad Firmware Flashing/KEIL-Flashtools/Mini51flashtools.ini: -------------------------------------------------------------------------------- 1 | 2 | KILL FUNC * 3 | KILL BUTTON * 4 | DEFINE BUTTON "Mini51 ShowConfig","ConfigRegs()" 5 | DEFINE BUTTON "Mini51 ChipErase" ,"ChipErase()" 6 | DEFINE BUTTON "Mini51 WriteStdConfig" ,"WriteStdConfig()" 7 | DEFINE BUTTON "Mini51 Reset" ,"RESET" 8 | 9 | FUNC void InitandUnlock (void) 10 | { 11 | _WDWORD(0xe000edf0,0x05f0003); 12 | 13 | _WDWORD(0xe0002008,0x000000); 14 | _WDWORD(0xe000200C,0x000000); 15 | _WDWORD(0xe0002010,0x000000); 16 | _WDWORD(0xe0002014,0x000000); 17 | 18 | 19 | _WDWORD(0x50000100,0x59); 20 | _WDWORD(0x50000100,0x16); 21 | _WDWORD(0x50000100,0x88); 22 | } 23 | 24 | FUNC int ReadViaISP(int adr) 25 | { 26 | int out; 27 | 28 | _WDWORD(0x5000c000,0x33); 29 | _WDWORD(0x5000c00c,0x00); // ISP-Command=Read 30 | _WDWORD(0x5000c004,adr); 31 | _WDWORD(0x5000c010,1); 32 | 33 | while (_RDWORD(0x5000c010)) {printf(".");} 34 | 35 | out=_RDWORD(0x5000c008); 36 | 37 | _WDWORD(0x5000c000,0x32); 38 | 39 | return out; 40 | } 41 | 42 | FUNC void WriteViaISP(int adr, int dat) 43 | { 44 | int out; 45 | 46 | _WDWORD(0x5000c000,0x33); 47 | _WDWORD(0x5000c00c,0x21); // ISP-Command=Programe 48 | _WDWORD(0x5000c004,adr); 49 | _WDWORD(0x5000c008,dat); 50 | 51 | _WDWORD(0x5000c010,1); 52 | 53 | while (_RDWORD(0x5000c010)) {printf(".");} 54 | if (_RDWORD(0x5000c000)&0x40) {printf("ISP Error\n");return;} 55 | 56 | _WDWORD(0x5000c000,0x32); 57 | } 58 | 59 | FUNC void PageErase(int adr) 60 | { 61 | int out; 62 | 63 | _WDWORD(0x5000c000,0x33); 64 | _WDWORD(0x5000c00c,0x22); // ISP-Command=Programe 65 | _WDWORD(0x5000c004,adr); 66 | 67 | _WDWORD(0x5000c010,1); 68 | 69 | while (_RDWORD(0x5000c010)) {printf(".");} 70 | if (_RDWORD(0x5000c000)&0x40) {printf("ISP Error\n");return;} 71 | 72 | _WDWORD(0x5000c000,0x32); 73 | } 74 | 75 | FUNC void WriteStdConfig() 76 | { 77 | int conf1; 78 | int conf0; 79 | 80 | conf0=0x00700083; // Boot from APROM, Flash Unlocked 81 | conf1=0; 82 | 83 | PageErase(0x300000); 84 | WriteViaISP(0x300000,conf0); 85 | WriteViaISP(0x300004,conf1); 86 | printf("Done!\n"); 87 | } 88 | 89 | FUNC void ConfigRegs() 90 | { 91 | int conf0,conf1,id; 92 | InitandUnlock(); 93 | printf("\nReading Configuration registers.\n\n"); 94 | conf0=ReadViaISP(0x300000); 95 | conf1=ReadViaISP(0x300004); 96 | id=_RDWORD(0x50000000); 97 | printf("Config0 (0x00300000):0x%X",conf0); 98 | if (!(conf0&2)) printf(" <-Flash is locked!"); 99 | printf("\n"); 100 | printf("Config1 (0x00300004):0x%X\n",conf1); 101 | printf("Device ID :0x%X ",id); 102 | if (id==0x205100) printf("Mini51LAN Found!"); 103 | if (id==0x205103) printf("Mini51ZAN Found!"); 104 | if (id==0x205104) printf("Mini51TAN Found!"); 105 | 106 | if (id==0x205200) printf("Mini52LAN Found!"); 107 | if (id==0x205203) printf("Mini52ZAN Found!"); 108 | if (id==0x205204) printf("Mini52TAN Found!"); 109 | 110 | if (id==0x205400) printf("Mini54LAN Found!"); 111 | if (id==0x205403) printf("Mini54ZAN Found!"); 112 | if (id==0x205404) printf("Mini54TAN Found!"); 113 | 114 | printf("\n\n"); 115 | } 116 | 117 | FUNC void ChipErase() 118 | { 119 | int conf0; 120 | InitandUnlock(); 121 | conf0=ReadViaISP(0x300000); 122 | if (conf0&2) 123 | { 124 | printf("Flash is not locked! Doing nothing.\n"); 125 | return; 126 | } 127 | 128 | printf("Flash is locked. \n"); 129 | 130 | _WDWORD(0x5000c000,0x33); 131 | _WDWORD(0x5000c01c,0x01); // Write one to undocumented register 132 | 133 | if (_RDWORD(0x5000c000)&0x40) {printf("ISP Error\n");return;} 134 | if (_RDWORD(0x5000c010)) {printf("ISP Busy error\n");return;} 135 | 136 | _WDWORD(0x5000c00c,0x26); // Undocumented ISP-Command Chip-Erase 137 | _WDWORD(0x5000c004,0); 138 | printf("Performing chip erase.\n"); 139 | _WDWORD(0x5000c010,1); 140 | 141 | while (_RDWORD(0x5000c010)) {printf(".");} 142 | 143 | if (_RDWORD(0x5000c000)&0x40) {printf("ISP Error\n");return;} 144 | 145 | _WDWORD(0x5000c000,0x32); 146 | 147 | printf("APROM:"); 148 | if (ReadViaISP(0x00000000)==0xffffffff) 149 | { printf("Erased!\n");} else 150 | { printf("Error!\n"); return;} 151 | 152 | printf("LDROM:"); 153 | if (ReadViaISP(0x00100000)==0xffffffff) 154 | { printf("Erased!\n");} else 155 | { printf("Error!\n"); return;} 156 | 157 | printf("Config:"); 158 | if (ReadViaISP(0x0030000)==0xffffffff) 159 | { printf("Erased!\n");} else 160 | { printf("Error!\n"); return;} 161 | 162 | _WDWORD(0x5000c01c,0x01); // Write zero to undocumented register 163 | } 164 | 165 | 166 | -------------------------------------------------------------------------------- /Quad Firmware Flashing/KEIL-Flashtools/jxdhack.uvopt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1.0 5 | 6 |
### uVision Project, (C) Keil Software
7 | 8 | 9 | *.c 10 | *.s*; *.src; *.a* 11 | *.obj 12 | *.lib 13 | *.txt; *.h; *.inc 14 | *.plm 15 | *.cpp 16 | 17 | 18 | 19 | 0 20 | 0 21 | 22 | 23 | 24 | Target 1 25 | 0x4 26 | ARM-ADS 27 | 28 | 12000000 29 | 30 | 1 31 | 1 32 | 1 33 | 0 34 | 35 | 36 | 1 37 | 65535 38 | 0 39 | 0 40 | 0 41 | 42 | 43 | 79 44 | 66 45 | 8 46 | .\ 47 | 48 | 49 | 1 50 | 1 51 | 1 52 | 0 53 | 1 54 | 1 55 | 0 56 | 1 57 | 0 58 | 0 59 | 0 60 | 0 61 | 62 | 63 | 1 64 | 1 65 | 1 66 | 1 67 | 1 68 | 1 69 | 1 70 | 0 71 | 0 72 | 73 | 74 | 1 75 | 0 76 | 1 77 | 78 | 255 79 | 80 | 81 | 0 82 | Reference Manual 83 | DATASHTS\Nuvoton\M051Series\M051_Series_Technical_Reference_Manual_EN_V2.0.pdf 84 | 85 | 86 | 1 87 | Technical Reference Manual 88 | datashts\arm\cortex_m0\r0p0\DDI0432C_CORTEX_M0_R0P0_TRM.PDF 89 | 90 | 91 | 2 92 | Generic User Guide 93 | datashts\arm\cortex_m0\r0p0\DUI0497A_CORTEX_M0_R0P0_GENERIC_UG.PDF 94 | 95 | 96 | 97 | SARMCM3.DLL 98 | 99 | DARMCM1.DLL 100 | -pCM0 101 | SARMCM3.DLL 102 | 103 | TARMCM1.DLL 104 | -pCM0 105 | 106 | 107 | 0 108 | 1 109 | 0 110 | 1 111 | 1 112 | 1 113 | 1 114 | 1 115 | 1 116 | 0 117 | 0 118 | 1 119 | 1 120 | 1 121 | 0 122 | 1 123 | 1 124 | 0 125 | 0 126 | 12 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | STLink\ST-LINKIII-KEIL_SWO.dll 138 | 139 | 140 | 141 | 0 142 | Nu_Link 143 | -S1 -B115200 -O0 144 | 145 | 146 | 0 147 | DLGUARM 148 | (105=-1,-1,-1,-1,0) 149 | 150 | 151 | 0 152 | DLGTARM 153 | (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0) 154 | 155 | 156 | 0 157 | ARMDBGFLAGS 158 | 159 | 160 | 161 | 0 162 | ST-LINKIII-KEIL_SWO 163 | -U-O8384 -O8384 -S0 -C0 -N00("ARM CoreSight SW-DP") -D00(0BB11477) -L00(0) -TO62 -TC10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO0 -FD20000000 -FC800 -FN2 -FF0NU_M054_AP_16 -FS00 -FL04000 -FF1Mini51_CFG -FS1300000 -FL18 164 | 165 | 166 | 0 167 | UL2CM3 168 | -O206 -S0 -C0 -FO7 -FD20000000 -FC800 -FN1 -FF0NU_M054_AP_16 -FS00 -FL04000) 169 | 170 | 171 | 172 | 173 | 0 174 | 0 175 | 0 176 | 1 177 |
42
178 | 0 179 | 0 180 | 0 181 | 0 182 | 0 183 | 1 184 | 185 | 186 | 0x0000002A 187 |
188 |
189 | 190 | 191 | 1 192 | 0 193 | 0x20000000 194 | 195 | 196 | 197 | 198 | 0 199 | Mini51 ShowConfig 200 | ConfigRegs() 201 | 202 | 203 | 1 204 | Mini51 ChipErase 205 | ChipErase() 206 | 207 | 208 | 2 209 | Mini51 WriteStdConfig 210 | WriteStdConfig() 211 | 212 | 213 | 3 214 | Mini51 Reset 215 | RESET 216 | 217 | 218 | 219 | 0 220 | 221 | 222 | 0 223 | 1 224 | 1 225 | 0 226 | 0 227 | 0 228 | 0 229 | 1 230 | 0 231 | 0 232 | 0 233 | 0 234 | 0 235 | 0 236 | 0 237 | 0 238 | 0 239 | 0 240 | 0 241 | 0 242 | 0 243 | 0 244 | 0 245 | 0 246 | 247 | 248 | 249 |
250 |
251 | 252 | 253 | Source Group 1 254 | 0 255 | 0 256 | 0 257 | 0 258 | 259 | 260 |
261 | -------------------------------------------------------------------------------- /Quad Firmware Flashing/KEIL-Flashtools/jxdhack.uvproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1.1 5 | 6 |
### uVision Project, (C) Keil Software
7 | 8 | 9 | 10 | Target 1 11 | 0x4 12 | ARM-ADS 13 | 14 | 15 | M054ZAN 16 | Nuvoton 17 | IRAM(0x20000000-0x20000FFF) IROM(0-0x03FFF) CLOCK(12000000) CPUTYPE("Cortex-M0") 18 | 19 | "STARTUP\Nuvoton\M051Series\startup_M051Series.s" ("Nuvoton M051 Series Startup Code") 20 | UL2CM3(-O206 -S0 -C0 -FO7 -FD20000000 -FC800 -FN1 -FF0NU_M054_AP_16 -FS00 -FL04000) 21 | 5588 22 | M051Series.h 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | SFD\Nuvoton\M051Series\M051AN.SFR 33 | 0 34 | 0 35 | 36 | 37 | 38 | Nuvoton\M051Series\ 39 | Nuvoton\M051Series\ 40 | 41 | 0 42 | 0 43 | 0 44 | 0 45 | 1 46 | 47 | .\ 48 | jxdhack 49 | 1 50 | 0 51 | 0 52 | 1 53 | 1 54 | .\ 55 | 1 56 | 0 57 | 0 58 | 59 | 0 60 | 0 61 | 62 | 63 | 0 64 | 0 65 | 0 66 | 0 67 | 68 | 69 | 0 70 | 0 71 | 72 | 73 | 0 74 | 0 75 | 76 | 77 | 0 78 | 0 79 | 80 | 81 | 0 82 | 0 83 | 84 | 0 85 | 86 | 87 | 88 | 0 89 | 0 90 | 0 91 | 0 92 | 0 93 | 1 94 | 0 95 | 0 96 | 0 97 | 0 98 | 3 99 | 100 | 101 | 1 102 | 103 | 104 | SARMCM3.DLL 105 | 106 | DARMCM1.DLL 107 | -pCM0 108 | SARMCM3.DLL 109 | 110 | TARMCM1.DLL 111 | -pCM0 112 | 113 | 114 | 115 | 1 116 | 0 117 | 0 118 | 0 119 | 16 120 | 121 | 122 | 0 123 | 0 124 | 1 125 | 1 126 | 1 127 | 1 128 | 1 129 | 1 130 | 0 131 | 132 | 133 | 1 134 | 0 135 | 0 136 | 1 137 | 1 138 | 1 139 | 0 140 | 1 141 | 1 142 | 143 | 0 144 | 12 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | STLink\ST-LINKIII-KEIL_SWO.dll 159 | 160 | 161 | 162 | 163 | 1 164 | 0 165 | 0 166 | 0 167 | 1 168 | 4096 169 | 170 | 1 171 | BIN\UL2CM3.DLL 172 | "" () 173 | 174 | 175 | 176 | 177 | 0 178 | 179 | 180 | 181 | 0 182 | 1 183 | 1 184 | 1 185 | 1 186 | 1 187 | 1 188 | 1 189 | 0 190 | 1 191 | 1 192 | 0 193 | 1 194 | 1 195 | 0 196 | 0 197 | 1 198 | 1 199 | 1 200 | 1 201 | 1 202 | 1 203 | 1 204 | 1 205 | 1 206 | 0 207 | 0 208 | "Cortex-M0" 209 | 210 | 0 211 | 0 212 | 0 213 | 1 214 | 1 215 | 0 216 | 0 217 | 0 218 | 0 219 | 0 220 | 8 221 | 0 222 | 0 223 | 0 224 | 3 225 | 3 226 | 0 227 | 0 228 | 0 229 | 0 230 | 0 231 | 0 232 | 0 233 | 0 234 | 0 235 | 0 236 | 1 237 | 0 238 | 0 239 | 0 240 | 0 241 | 1 242 | 0 243 | 244 | 245 | 0 246 | 0x0 247 | 0x0 248 | 249 | 250 | 0 251 | 0x0 252 | 0x0 253 | 254 | 255 | 0 256 | 0x0 257 | 0x0 258 | 259 | 260 | 0 261 | 0x0 262 | 0x0 263 | 264 | 265 | 0 266 | 0x0 267 | 0x0 268 | 269 | 270 | 0 271 | 0x0 272 | 0x0 273 | 274 | 275 | 0 276 | 0x20000000 277 | 0x1000 278 | 279 | 280 | 1 281 | 0x0 282 | 0x4000 283 | 284 | 285 | 0 286 | 0x0 287 | 0x0 288 | 289 | 290 | 1 291 | 0x0 292 | 0x0 293 | 294 | 295 | 1 296 | 0x0 297 | 0x0 298 | 299 | 300 | 1 301 | 0x0 302 | 0x0 303 | 304 | 305 | 1 306 | 0x0 307 | 0x4000 308 | 309 | 310 | 1 311 | 0x0 312 | 0x0 313 | 314 | 315 | 0 316 | 0x0 317 | 0x0 318 | 319 | 320 | 0 321 | 0x0 322 | 0x0 323 | 324 | 325 | 0 326 | 0x0 327 | 0x0 328 | 329 | 330 | 0 331 | 0x20000000 332 | 0x1000 333 | 334 | 335 | 0 336 | 0x0 337 | 0x0 338 | 339 | 340 | 341 | 342 | 343 | 1 344 | 1 345 | 0 346 | 0 347 | 0 348 | 0 349 | 0 350 | 0 351 | 0 352 | 0 353 | 0 354 | 0 355 | 0 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 1 365 | 0 366 | 0 367 | 0 368 | 0 369 | 0 370 | 0 371 | 0 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 0 381 | 0 382 | 0 383 | 0 384 | 1 385 | 0 386 | 0x00000000 387 | 0x20000000 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | Source Group 1 400 | 401 | 402 | 403 | 404 | 405 |
406 | -------------------------------------------------------------------------------- /Quad Firmware Flashing/KEIL-Flashtools/main.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | void SystemInit(void) { 4 | 5 | } 6 | 7 | int main(void) { 8 | 9 | while(1); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /Quad Firmware Flashing/KEIL-Flashtools/main.crf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Firmware Flashing/KEIL-Flashtools/main.crf -------------------------------------------------------------------------------- /Quad Firmware Flashing/KEIL-Flashtools/main.d: -------------------------------------------------------------------------------- 1 | .\main.o: main.c 2 | -------------------------------------------------------------------------------- /Quad Firmware Flashing/KEIL-Flashtools/mini51flashtools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Firmware Flashing/KEIL-Flashtools/mini51flashtools.png -------------------------------------------------------------------------------- /Quad Firmware Flashing/Readme.md: -------------------------------------------------------------------------------- 1 | ## Hack-O-Copter Firmware flashing ## 2 | 3 | The main controller of the JD385 and many other small quadrocopters is a Nuvoton Mini54ZAN, a Cortex-M0 based microcontroller with 16kb of user flash and 2kb of SRAM. 4 | 5 | The controller can be accessed through the serial wire debug (SWD) port, which is accessible on the board. Unfortunately it turned out, that the code protection was activated. Therefore it was not possible to read out the existing firmware or to reprogram the device. The only way to deactivate the protection is to perform a chip erase. 6 | 7 | Unfortunately, Nuvoton decided not to publish information about how to perform a chip erase. Officially you need to buy one of their custom SWD adapters, "Nu-Link", to unlock their devices. True to the spirit, the required sequence was reverse engineered from an original programmer - [details linked here](https://github.com/hackocopter/SWD-Hacking). As described below, it is now possible to unlock and reflash the JD385 flight controller with any SWD adapter that is supported by Keil µVision. 8 | 9 | ### Requirements ### 10 | 11 | Since the controller only has 16kb of flash, it is fully supported by the free evaluation version of Keil µVision/MDK-ARM. You can find it here: 12 | 13 | https://www.keil.com/demo/eval/arm.htm 14 | 15 | To support the Nuvoton controllers, you also have to install legacy device support: 16 | 17 | http://www.keil.com/mdk5/legacy 18 | 19 | In addition to the software, you also need a SWD adapter that is supported by Keil and the required drivers. The most compatible option is to use Nuvotons original "Nu-Link" which support setting of the fuses natively. The lowest cost option is probably to use a STM discovery kit, which comes with ST-Link. It is possible to flash new firmware into a discovery board to be more compatible to openOCD, but the native ST-Link works as well. 20 | 21 | ### Connecting to a debugger ### 22 | 23 | Only three wires are required: **SWDCLK**,**SWDDATA** and **GND**. You can find them on the flight controller board as marked here: 24 | 25 | ![Port locatation](images/ports_on_pcb.jpg) 26 | 27 | If you use a STM discovery board, you have to disconnect the ST-Link jumpers. The image below shows the STM32F0 board, the pinout is similar on the other boards and should be explained in the manual. 28 | 29 | ![Port locatation](images/stm32f0-disco-swd-pinout.jpg) 30 | 31 | ### Unlocking the controller ### 32 | 33 | **Warning:** This will erase the original firmware! So far there is no way to recover it. 34 | 35 | You can skip this step if you is a Nu-Link, as this will simply ask to perform a chip erase. If you use a different SWD adapter, read on. 36 | 37 | First, you need to open the [KEIL-Flashtools](KEIL-Flashtools/) in Keil. This is an empty project which allows to enter the debug mode without flashing a new firmware. Please make sure you SWD adapter is correctly selected in the preferences. 38 | 39 | Then you need to perform the following steps, as illustrated in the picture below: 40 | 41 | 1. Start debug mode 42 | 2. Enter "INCLUDE Mini51flashtools.ini" into the command line. 43 | 3. A clickable menu will pop up. 44 | 45 | ![Flashtools](images/mini51flashtools.png) 46 | 47 | - **Mini51 ShowConfig:** Display the current config register content. Click here first to verify that everything works as intended. 48 | - **Mini51 ChipErase:** unlock and erase the controller, if it was locked. 49 | - **Mini51 WriteStdConfig:** write the standard configuration to the config registers. You should do this after chip erase. 50 | 51 | ### Next steps ### 52 | 53 | You can try one of the blinky examples from [here](https://github.com/hackocopter/Examples). 54 | 55 | -------------------------------------------------------------------------------- /Quad Firmware Flashing/images/Nu-Link-PCB-fs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Firmware Flashing/images/Nu-Link-PCB-fs.jpg -------------------------------------------------------------------------------- /Quad Firmware Flashing/images/mini51flashtools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Firmware Flashing/images/mini51flashtools.png -------------------------------------------------------------------------------- /Quad Firmware Flashing/images/ports_on_pcb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Firmware Flashing/images/ports_on_pcb.jpg -------------------------------------------------------------------------------- /Quad Firmware Flashing/images/stm32f0-disco-swd-pinout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Firmware Flashing/images/stm32f0-disco-swd-pinout.jpg -------------------------------------------------------------------------------- /Quad Hardware/Circuit Diagrams/Copter00.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/Circuit Diagrams/Copter00.pdf -------------------------------------------------------------------------------- /Quad Hardware/Circuit Diagrams/Copter00.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/Circuit Diagrams/Copter00.sch -------------------------------------------------------------------------------- /Quad Hardware/Circuit Diagrams/Readme.txt: -------------------------------------------------------------------------------- 1 | JXD 385 Quadrocopter circuit diagrams 2 | CAD: Eagle 4.16 3 | 4 | As reconstructed from board photographs. Some footprints may be off. Almost all 5 | component values are missing. 6 | 7 | Sheet 1/5: CPU 8 | Sheet 2/5: Motor control, Power 9 | Sheet 3/5: Radio 10 | Sheet 4/5: IMU 11 | Sheet 5/5: Remote control 12 | 13 | 14 | Schaltbilder für den JXD Quattrocopter JD-385. 15 | 16 | CAD: Eagle 4.16 17 | 18 | Blatt 1: CPU weitgehend fertig 19 | Blatt 2: Motor, Stromversorgung fertig 20 | Blatt 3: Funk nur rudimentär, damit Eagle keine Fehler meldet 21 | Blatt 4: Sensoren nur rudimentär, damit Eagle keine Fehler meldet 22 | Blatt 5: Sender der Fernbedienung fertig, eventuell fehlen einige Stützkondensatoren 23 | 24 | 25 | Anmerkungen: 26 | - Die Footprints sind nicht getestet und stimmen mit hoher Wahrscheinlichkeit nicht mit dem Original überein. 27 | - Bauteil Werte fehlen fast durchgängig. 28 | 29 | Version 0.2: 30 | Fehlende Bauteile des Senders nachgetragen, Bauteilwerte ergänzt. 31 | 32 | Stand: 21-APR-2014, Georg 33 | -------------------------------------------------------------------------------- /Quad Hardware/Circuit Diagrams/fb-pins.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/Circuit Diagrams/fb-pins.txt -------------------------------------------------------------------------------- /Quad Hardware/Datasheets/IMU_PS-MPU-6000A-00v3.4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/Datasheets/IMU_PS-MPU-6000A-00v3.4.pdf -------------------------------------------------------------------------------- /Quad Hardware/Datasheets/IMU_RM-MPU-6000A.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/Datasheets/IMU_RM-MPU-6000A.pdf -------------------------------------------------------------------------------- /Quad Hardware/Datasheets/LDO_LM6206N3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/Datasheets/LDO_LM6206N3.pdf -------------------------------------------------------------------------------- /Quad Hardware/Datasheets/MCU_DA00-MINI51_52_54C1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/Datasheets/MCU_DA00-MINI51_52_54C1.pdf -------------------------------------------------------------------------------- /Quad Hardware/Datasheets/Mosfet_G2310.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/Datasheets/Mosfet_G2310.pdf -------------------------------------------------------------------------------- /Quad Hardware/Datasheets/Tranceiver_BK2423 Datasheet v2.0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/Datasheets/Tranceiver_BK2423 Datasheet v2.0.pdf -------------------------------------------------------------------------------- /Quad Hardware/Images/pcb-front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/Images/pcb-front.jpg -------------------------------------------------------------------------------- /Quad Hardware/Images/pcb-front_annotated.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/Images/pcb-front_annotated.jpg -------------------------------------------------------------------------------- /Quad Hardware/Images/pcb-rear.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/Images/pcb-rear.jpg -------------------------------------------------------------------------------- /Quad Hardware/Images/pcb-rear_annotated.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/Images/pcb-rear_annotated.jpg -------------------------------------------------------------------------------- /Quad Hardware/Images/ports.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/Images/ports.jpg -------------------------------------------------------------------------------- /Quad Hardware/PCB_overview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/PCB_overview.jpg -------------------------------------------------------------------------------- /Quad Hardware/Readme.md: -------------------------------------------------------------------------------- 1 | ## JXD385 flight controller ## 2 | 3 | ![system](system_design_overview.png) 4 | 5 | ### PCB ### 6 | 7 | ![PCB](PCB_overview.jpg) 8 | 9 | ### Controller Pin Out ### 10 | 11 | Pin GPIO Secondary External connection 12 | 1 P1.5 AIN5 Sense for Motor 4, but not populated on PCB 13 | 2 reset SWD Port reset 14 | 3 P3.0 AIN6 NC 15 | 4 P5.4 NC 16 | 5 P3.1 AIN7 Sense for Motor 1, but not populated on PCB 17 | 6 P3.2 INT0 MPU6050, pin 12 (interrupt) 18 | 7 P3.4 SDA MPU6050, pin 24 (SDA) 19 | 8 P3.5 SCL MPU6050, pin 23 (SCL) 20 | 9 P3.6 T1X Connected to test pad 21 | 10 P5.1 NC 22 | 11 P5.0 NC 23 | 12 VSS GND 24 | 13 P5.2 Connected to unpopulated circuit part to control rear LEDS 25 | 14 P2.2 PWM0 NC 26 | 15 P2.3 PWM1 NC 27 | 16 P2.4 PWM2 Motor 1 PWM 28 | 17 P2.5 PWM3 Motor 2 PWM 29 | 18 P2.6 PWM4 Motor 3 PWM 30 | 19 P4.6 ICE_CLK (SWD) SWD Port CLK 31 | 20 P4.7 ICE_DAT (SWD) SWD Port Dat 32 | 21 P0.7 SPICLK BK2423 SPI CLK 33 | 22 P0.6 MISO BK2423 SPI MISO 34 | 23 P0.5 MOSI BK2423 SPI MOSI 35 | 24 P0.4 PWM5 Motor 4 PWM 36 | 25 P0.1 BK2434 SPI CSN 37 | 26 P0.0 Controls LEDs (Low active) 38 | 27 P5.3 NC 39 | 28 VDD 3.3V 40 | 29 P1.0 AIN1 Sense for Motor 2, but not populated on PCB 41 | 30 P1.2 RX UART PORT RX 42 | 31 P1.3 TX UART PORT TX 43 | 32 P1.4 AIN4 Sense for Motor 3, but not populated on PCB 44 | -------------------------------------------------------------------------------- /Quad Hardware/pinout.txt: -------------------------------------------------------------------------------- 1 | Pin GPIO Secondary External connection 2 | 1 P1.5 AIN5 Sense for Motor 4, but not populated on PCB 3 | 2 reset SWD Port reset 4 | 3 P3.0 AIN6 NC 5 | 4 P5.4 NC 6 | 5 P3.1 AIN7 Sense for Motor 1, but not populated on PCB 7 | 6 P3.2 INT0 MPU6050, pin 12 (interrupt) 8 | 7 P3.4 SDA MPU6050, pin 24 (SDA) 9 | 8 P3.5 SCL MPU6050, pin 23 (SCL) 10 | 9 P3.6 T1X Connected to test pad 11 | 10 P5.1 NC 12 | 11 P5.0 NC 13 | 12 VSS GND 14 | 13 P5.2 Connected to unpopulated circuit part to control rear LEDS 15 | 14 P2.2 PWM0 NC 16 | 15 P2.3 PWM1 NC 17 | 16 P2.4 PWM2 Motor 1 PWM 18 | 17 P2.5 PWM3 Motor 2 PWM 19 | 18 P2.6 PWM4 Motor 3 PWM 20 | 19 P4.6 ICE_CLK (SWD) SWD Port CLK 21 | 20 P4.7 ICE_DAT (SWD) SWD Port Dat 22 | 21 P0.7 SPICLK BK2423 SPI CLK 23 | 22 P0.6 MISO BK2423 SPI MISO 24 | 23 P0.5 MOSI BK2423 SPI MOSI 25 | 24 P0.4 PWM5 Motor 4 PWM 26 | 25 P0.1 BK2434 SPI CSN 27 | 26 P0.0 Controls LEDs (Low active) 28 | 27 P5.3 NC 29 | 28 VDD 3.3V 30 | 29 P1.0 AIN1 Sense for Motor 2, but not populated on PCB 31 | 30 P1.2 RX UART PORT RX 32 | 31 P1.3 TX UART PORT TX 33 | 32 P1.4 AIN4 Sense for Motor 3, but not populated on PCB 34 | -------------------------------------------------------------------------------- /Quad Hardware/system_design_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Quad Hardware/system_design_overview.png -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | ## Hack-O-Copter Documentation ## 2 | 3 | The JXD185/385 is a cheap quadrocopter that retails for less than 30 EUR including remote control on many websites. You can find it by searching for "6 axis mini UFO". It is a low-cost clone of the popular Hubsan X4. The same hardware and firmware is also used by the JXD388 and the F180. 4 | 5 | It was found that the flight controller is build around several standard components: An Invensense MPU6050 IMU, an Cortex-M0 controller and a nRF24l01 compatible tranceiver. This is a very similar hardware configuration to many "hobbyist" -grade quadrocoptors, which are several times more expensive. The microcontroller debug and serial ports are easily accessible on the pcb. If that isn't an invitation to hacking, what else is? 6 | 7 | This repository holds the documentation of the reverse engineering work so far. This information is the result of a community effort in a BBS thread on mikrocontroller.net: [Thread (german)](http://www.mikrocontroller.net/topic/309185) 8 | 9 | ### Status ### 10 | 11 | Completed: 12 | 13 | - All relevant components have been identified and documented. 14 | - Circuit diagrams of the flight controller and the remote control have been reconstructed. 15 | - The chip erase sequence to unlock the write protected flight controller has been reverse engineered. It is now possible to flash new firmware with any SWD adapter. 16 | - The remote control protocol was identified (V202) and verified. 17 | - **NEW**: Open source firmware available here: https://github.com/hackocopter/bradwii-jd385 (Port of Bradwii) 18 | 19 | Open: 20 | 21 | - The original firmware could not be read out due to write protection. 22 | - Reprogramming of the remote control. 23 | 24 | 25 | ---------- 26 | 27 | 28 | ![Product photo](jxd385.jpg) 29 | -------------------------------------------------------------------------------- /Remote Control/Datenblatt.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Remote Control/Datenblatt.doc -------------------------------------------------------------------------------- /Remote Control/Firmware für AVR/Monitor.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "all-fb.h" 9 | #include "../uart.h" 10 | #include "rfm70.h" 11 | #include "vt100.h" 12 | #include "timer.h" 13 | 14 | 15 | #define UART_BAUD_RATE 9600 16 | 17 | 18 | const uint8_t PROGMEM hop_tbl[4][16] = { 19 | { 0x27, 0x1B, 0x39, 0x28, 0x24, 0x22, 0x2E, 0x36, 20 | 0x19, 0x21, 0x29, 0x14, 0x1E, 0x12, 0x2D, 0x18 }, // 00 21 | { 0x2E, 0x33, 0x25, 0x38, 0x19, 0x12, 0x18, 0x16, 22 | 0x2A, 0x1C, 0x1F, 0x37, 0x2F, 0x23, 0x34, 0x10 }, // 01 23 | { 0x11, 0x1A, 0x35, 0x24, 0x28, 0x18, 0x25, 0x2A, 24 | 0x32, 0x2C, 0x14, 0x27, 0x36, 0x34, 0x1C, 0x17 }, // 02 25 | { 0x22, 0x27, 0x17, 0x39, 0x34, 0x28, 0x2B, 0x1D, 26 | 0x18, 0x2A, 0x21, 0x38, 0x10, 0x26, 0x20, 0x1F } // 03 27 | }; 28 | 29 | uint8_t rx_channel[16]; 30 | uint8_t act_channel; 31 | uint8_t our_txid[3]; 32 | PAYLOAD pload; 33 | uint8_t ticms; 34 | uint8_t tic1s; 35 | uint8_t timeout; 36 | uint8_t status; 37 | 38 | 39 | const char PROGMEM status_str[2][5] = { 40 | {"bind"}, 41 | {"run "} 42 | }; 43 | 44 | 45 | //-------------------------------------- 46 | const char PROGMEM maske[] = { 47 | "JD-385 Monitor\n\n" 48 | "Tx-ID: 00 00 00\n\n" 49 | " Poti Trimm\n" 50 | "Gas : 000\n" 51 | "Seitenruder : 000 - 000\n" 52 | "Hoehenruder : 000 - 000\n" 53 | "Querruder : 000 - 000\n\n" 54 | "Flags : 00\n" 55 | "Status : " 56 | }; 57 | 58 | 59 | //-------------------------------------- 60 | char hex_str[] = "0123456789ABCDEF"; 61 | char to_hex(uint8_t nibble) { 62 | return(hex_str[nibble & 0x0f]); 63 | } 64 | 65 | 66 | //-------------------------------------- 67 | void disp_byte(uint8_t x) { 68 | uart_putc(to_hex(x >> 4)); 69 | uart_putc(to_hex(x)); 70 | } 71 | 72 | 73 | //-------------------------------------- 74 | void disp_dec(int8_t x) { 75 | if (x & 0x80) { 76 | uart_putc('-'); 77 | x = x & 0x7f; 78 | } 79 | else { 80 | uart_putc(' '); 81 | } 82 | uart_putc('0' + (x / 100)); 83 | x = x % 100; 84 | uart_putc('0' + (x / 10)); 85 | uart_putc('0' + (x % 10)); 86 | } 87 | 88 | 89 | //-------------------------------------- 90 | void disp_trimm(int8_t x) { 91 | if (x < 0) { 92 | uart_putc('-'); 93 | x = abs(x); 94 | } 95 | else { 96 | uart_putc(' '); 97 | } 98 | uart_putc('0' + (x / 100)); 99 | x = x % 100; 100 | uart_putc('0' + (x / 10)); 101 | uart_putc('0' + (x % 10)); 102 | } 103 | 104 | 105 | //-------------------------------------- 106 | void disp_abs(uint8_t x) { 107 | uart_putc('0' + (x / 100)); 108 | x = x % 100; 109 | uart_putc('0' + (x / 10)); 110 | uart_putc('0' + (x % 10)); 111 | } 112 | 113 | 114 | //-------------------------------------- 115 | void update_data(void) { 116 | 117 | term_cursor(6, 16); 118 | disp_abs(pload.throttle); 119 | 120 | term_cursor(7, 15); 121 | disp_dec(pload.rudder); 122 | uart_puts_P(" "); 123 | disp_trimm(pload.trimm_yaw -0x40); 124 | 125 | term_cursor(8, 15); 126 | disp_dec(pload.elevator); 127 | uart_puts_P(" "); 128 | disp_trimm(pload.trimm_pitch -0x40); 129 | 130 | term_cursor(9, 15); 131 | disp_dec(pload.aileron); 132 | uart_puts_P(" "); 133 | disp_trimm(pload.trimm_roll -0x40); 134 | 135 | term_cursor(11, 17); 136 | disp_byte(pload.flags); 137 | 138 | term_cursor(12, 16); 139 | uart_puts_p(status_str[status]); 140 | } 141 | 142 | 143 | //-------------------------------------- 144 | int main(void) { 145 | 146 | 147 | 148 | DDRA |= 0x03; 149 | DDRD |= 0x0c; 150 | uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU)); 151 | _delay_ms(100); 152 | sei(); 153 | term_clear(); 154 | term_cursor(0, 0); 155 | uart_puts_P("\n\nFernsteuerung Rx Test RFM70\n"); 156 | 157 | uart_puts_P("RFM70 wird initialisiert..."); 158 | if (RFM70_init()) { 159 | uart_puts_P("fehlgeschlagen, Abbruch\n"); 160 | while(1); 161 | } 162 | uart_puts_P("fertig\n"); 163 | 164 | setModeRX(); 165 | setChannel(8); 166 | _delay_ms(1000); 167 | term_clear(); 168 | term_cursor(0, 0); 169 | uart_puts_p(maske); 170 | status = BIND; 171 | tic1s = 0; 172 | timer_init(); 173 | sei(); 174 | while(1) { 175 | if ((volatile uint8_t) tic1s) { 176 | update_data(); 177 | tic1s = 0; 178 | if (status == BIND) PORTD ^= 0x04; 179 | } 180 | 181 | if (receivePayload((uint8_t *) &pload)) { 182 | PORTA ^= 0x01; 183 | } 184 | _delay_us(1000); 185 | 186 | if ((status == BIND) && (pload.flags == 0xc0)) { 187 | memcpy(our_txid, pload.tx_id, 3); 188 | term_cursor(3, 8); 189 | disp_byte(our_txid[0]); 190 | uart_putc(' '); 191 | disp_byte(our_txid[1]); 192 | uart_putc(' '); 193 | disp_byte(our_txid[2]); 194 | status = RUN; 195 | } 196 | } 197 | } 198 | 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /Remote Control/Firmware für AVR/Readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Remote Control/Firmware für AVR/Readme.txt -------------------------------------------------------------------------------- /Remote Control/Firmware für AVR/Rfm70-rx-tx-sch.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Remote Control/Firmware für AVR/Rfm70-rx-tx-sch.pdf -------------------------------------------------------------------------------- /Remote Control/Firmware für AVR/VT100.c: -------------------------------------------------------------------------------- 1 | // VT100 Escape Sequenzen (nur ein kleiner Teil) 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "../uart.h" 9 | 10 | #define t_putc uart_putc 11 | 12 | void send_esc(uint8_t c) { 13 | t_putc(0x1b); 14 | t_putc(c); 15 | } 16 | 17 | 18 | void send_dec(uint8_t n) { 19 | t_putc('0' + (n/10)); 20 | t_putc('0' + (n%10)); 21 | } 22 | 23 | 24 | void term_clear(void) { 25 | send_esc('['); 26 | t_putc('2'); 27 | t_putc('J'); 28 | } 29 | 30 | 31 | void term_cursor(uint8_t row, uint8_t column) { 32 | send_esc('['); 33 | send_dec(row); 34 | t_putc(';'); 35 | send_dec(column); 36 | t_putc('H'); 37 | } 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Remote Control/Firmware für AVR/all-fb.h: -------------------------------------------------------------------------------- 1 | #ifndef ALLFB_H 2 | #define ALLFB_H 3 | 4 | typedef struct payload { 5 | uint8_t throttle; 6 | uint8_t rudder; 7 | uint8_t elevator; 8 | uint8_t aileron; 9 | uint8_t trimm_yaw; 10 | uint8_t trimm_pitch; 11 | uint8_t trimm_roll; 12 | uint8_t tx_id[3]; 13 | uint8_t empty[4]; 14 | uint8_t flags; // 0xc0 = bind, 0x04 = flip, Rest nicht genutzt 15 | uint8_t chksum; 16 | } PAYLOAD; 17 | 18 | #define BIND 0 19 | #define RUN 1 20 | 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /Remote Control/Firmware für AVR/rfm70-fb-rx.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "all-fb.h" 10 | #include "../../uart.h" 11 | #include "../rfm70.h" 12 | 13 | 14 | #define UART_BAUD_RATE 9600 15 | 16 | uint16_t ticks; 17 | volatile uint8_t ticms; 18 | PAYLOAD pl; 19 | uint8_t hopping; 20 | uint8_t act_channel; 21 | uint8_t kanal[16]; 22 | uint8_t cha_fine; 23 | uint8_t status; 24 | 25 | 26 | //-------------------------------------- 27 | const uint8_t PROGMEM hop_tbl[4][16] = { 28 | { 0x27, 0x1B, 0x39, 0x28, 0x24, 0x22, 0x2E, 0x36, 29 | 0x19, 0x21, 0x29, 0x14, 0x1E, 0x12, 0x2D, 0x18 }, // 00 30 | { 0x2E, 0x33, 0x25, 0x38, 0x19, 0x12, 0x18, 0x16, 31 | 0x2A, 0x1C, 0x1F, 0x37, 0x2F, 0x23, 0x34, 0x10 }, // 01 32 | { 0x11, 0x1A, 0x35, 0x24, 0x28, 0x18, 0x25, 0x2A, 33 | 0x32, 0x2C, 0x14, 0x27, 0x36, 0x34, 0x1C, 0x17 }, // 02 34 | { 0x22, 0x27, 0x17, 0x39, 0x34, 0x28, 0x2B, 0x1D, 35 | 0x18, 0x2A, 0x21, 0x38, 0x10, 0x26, 0x20, 0x1F } // 03 36 | }; 37 | 38 | 39 | //-------------------------------------- 40 | void timer_init(void) { 41 | TCCR1B |= (1<= 1000) { 56 | ticks = 0; 57 | PORTA ^= 0x80; 58 | } 59 | 60 | ticms++; 61 | } 62 | 63 | 64 | //-------------------------------------- 65 | char hex_str[] = "0123456789ABCDEF"; 66 | char to_hex(uint8_t nibble) { 67 | return(hex_str[nibble & 0x0f]); 68 | } 69 | 70 | 71 | //-------------------------------------- 72 | void disp_byte(uint8_t x) { 73 | uart_putc(to_hex(x >> 4)); 74 | uart_putc(to_hex(x)); 75 | } 76 | 77 | 78 | //-------------------------------------- 79 | void disp_dec(int8_t x) { 80 | if (x & 0x80) { 81 | uart_putc('-'); 82 | x = x & 0x7f; 83 | } 84 | else { 85 | uart_putc(' '); 86 | } 87 | uart_putc('0' + (x / 100)); 88 | x = x % 100; 89 | uart_putc('0' + (x / 10)); 90 | uart_putc('0' + (x % 10)); 91 | } 92 | 93 | 94 | //-------------------------------------- 95 | void disp_abs(uint8_t x) { 96 | uart_putc('0' + (x / 100)); 97 | x = x % 100; 98 | uart_putc('0' + (x / 10)); 99 | uart_putc('0' + (x % 10)); 100 | } 101 | 102 | 103 | //-------------------------------------- 104 | uint8_t sum_pl() { 105 | 106 | uint8_t i, sum; 107 | uint8_t *ppl; 108 | 109 | ppl = (uint8_t *)&pl; 110 | sum = 0; 111 | for (i = 0; i < 14; i++) { 112 | sum += *ppl; 113 | ppl++; 114 | } 115 | return(sum & 0xff); 116 | } 117 | 118 | 119 | //-------------------------------------- 120 | void help(void) { 121 | uart_puts_P("\nC = ++Hop-Kanal c = --Hop-Kanal" 122 | "\nF = ++Kanal f = --Kanal" 123 | "\nP = fester Kanal p = huepfen" 124 | "\n\n"); 125 | } 126 | 127 | 128 | //-------------------------------------- 129 | int main(void) { 130 | 131 | uint8_t sum, hop_base, hop_inc; 132 | uint8_t i, tmp; 133 | uint16_t j; 134 | uint8_t rx_ok; 135 | 136 | DDRA = 0xff; 137 | PORTA &= 0xf0; 138 | 139 | uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU)); 140 | timer_init(); 141 | _delay_ms(100); 142 | sei(); 143 | uart_puts_P("\033[2J\033[0;0H\n\n" 144 | "Fernsteuer Empfaenger (JD-385) Simulator\n\n" 145 | "RFM70 wird initialisiert..."); 146 | if (RFM70_init()) { 147 | uart_puts_P("fehlgeschlagen, Abbruch\n"); 148 | while(1); 149 | } 150 | setModeRX(); 151 | uart_puts_P("fertig\n"); 152 | 153 | status = BIND; 154 | help(); 155 | while(1) { 156 | j = uart_getc(); 157 | if ((j & 0xff00) == 0) { 158 | switch(j & 0xff) { 159 | case 'P': 160 | hopping = 0; 161 | break; 162 | case 'p': 163 | hopping = 1; 164 | break; 165 | case 'C': 166 | act_channel = (act_channel + 1) & 0x0f; 167 | setChannel(kanal[act_channel]); 168 | cha_fine = kanal[act_channel]; 169 | break; 170 | case 'c': 171 | act_channel = (act_channel + 15) & 0x0f; 172 | setChannel(kanal[act_channel]); 173 | cha_fine = kanal[act_channel]; 174 | break; 175 | case 'F': 176 | cha_fine = (cha_fine + 1) & 0x7f; 177 | setChannel(cha_fine); 178 | break; 179 | case 'f': 180 | cha_fine = (cha_fine + 127) & 0x7f; 181 | setChannel(cha_fine); 182 | break; 183 | default: help(); 184 | } 185 | if (hopping) { 186 | uart_puts_P("\nhopping "); 187 | } 188 | else { 189 | uart_puts_P("\nKanal "); 190 | disp_abs(cha_fine); 191 | } 192 | } 193 | PORTA ^= 0x02; 194 | i = receivePayload((uint8_t *)&pl); 195 | if (i != 0) { 196 | PORTA ^= 0x04; 197 | if ((status == BIND) && (pl.flags == 0xc0)) { 198 | status = RUN; 199 | uart_puts_P("\nSender gefunden. ID = "); 200 | disp_byte(pl.tx_id[0]); 201 | uart_putc('-'); 202 | disp_byte(pl.tx_id[1]); 203 | uart_putc('-'); 204 | disp_byte(pl.tx_id[2]); 205 | sum = pl.tx_id[0] + pl.tx_id[1] + pl.tx_id[2]; 206 | hop_base = sum & 0x03; 207 | hop_inc = (sum & 0x1c) >> 2; 208 | uart_puts_P("\nKanaele: "); 209 | for (i = 0; i < 16; i++) { 210 | tmp = pgm_read_byte(&hop_tbl[hop_base][i]) + hop_inc; 211 | if ((tmp & 0x0f) == 0) tmp -=3; 212 | kanal[i] = tmp; 213 | disp_abs(tmp); 214 | uart_putc(' '); 215 | } 216 | uart_putc('\n'); 217 | act_channel = 0; 218 | setChannel(kanal[act_channel]); 219 | cha_fine = kanal[act_channel]; 220 | ticms = 0; 221 | rx_ok = 0; 222 | } 223 | if (status == RUN) { 224 | act_channel = (act_channel + 1) & 0x0f; 225 | setChannel(kanal[act_channel]); 226 | cha_fine = kanal[act_channel]; 227 | ticms = 0; 228 | rx_ok++; 229 | if (rx_ok == 0) rx_ok = 255; 230 | } 231 | } 232 | if (ticms == 127) { 233 | ticms = 0; 234 | disp_byte(rx_ok); 235 | rx_ok = 0; 236 | uart_putc('T'); 237 | } 238 | } 239 | return(0); 240 | } 241 | 242 | 243 | -------------------------------------------------------------------------------- /Remote Control/Firmware für AVR/rfm70-fb-tx.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "all-fb.h" 10 | #include "../../uart.h" 11 | #include "../rfm70.h" 12 | 13 | 14 | #define UART_BAUD_RATE 9600 15 | 16 | uint16_t ticks; 17 | volatile uint8_t start_cnt; 18 | volatile uint8_t tick_slow; 19 | volatile uint8_t tick_fast; 20 | uint8_t ticms; 21 | PAYLOAD pl; 22 | uint8_t hopping; 23 | uint8_t act_channel; 24 | uint8_t kanal[16]; 25 | uint8_t cha_fine; 26 | uint8_t stop; 27 | volatile uint8_t do_tx; 28 | volatile uint8_t do_hop; 29 | 30 | 31 | //-------------------------------------- 32 | const uint8_t PROGMEM hop_tbl[4][16] = { 33 | { 0x27, 0x1B, 0x39, 0x28, 0x24, 0x22, 0x2E, 0x36, 34 | 0x19, 0x21, 0x29, 0x14, 0x1E, 0x12, 0x2D, 0x18 }, // 00 35 | { 0x2E, 0x33, 0x25, 0x38, 0x19, 0x12, 0x18, 0x16, 36 | 0x2A, 0x1C, 0x1F, 0x37, 0x2F, 0x23, 0x34, 0x10 }, // 01 37 | { 0x11, 0x1A, 0x35, 0x24, 0x28, 0x18, 0x25, 0x2A, 38 | 0x32, 0x2C, 0x14, 0x27, 0x36, 0x34, 0x1C, 0x17 }, // 02 39 | { 0x22, 0x27, 0x17, 0x39, 0x34, 0x28, 0x2B, 0x1D, 40 | 0x18, 0x2A, 0x21, 0x38, 0x10, 0x26, 0x20, 0x1F } // 03 41 | }; 42 | 43 | 44 | //-------------------------------------- 45 | void timer_init(void) { 46 | TCCR1B |= (1<> 4)); 92 | uart_putc(to_hex(x)); 93 | } 94 | 95 | 96 | //-------------------------------------- 97 | void disp_dec(int8_t x) { 98 | if (x & 0x80) { 99 | uart_putc('-'); 100 | x = x & 0x7f; 101 | } 102 | else { 103 | uart_putc(' '); 104 | } 105 | uart_putc('0' + (x / 100)); 106 | x = x % 100; 107 | uart_putc('0' + (x / 10)); 108 | uart_putc('0' + (x % 10)); 109 | } 110 | 111 | 112 | //-------------------------------------- 113 | void disp_abs(uint8_t x) { 114 | uart_putc('0' + (x / 100)); 115 | x = x % 100; 116 | uart_putc('0' + (x / 10)); 117 | uart_putc('0' + (x % 10)); 118 | } 119 | 120 | 121 | //-------------------------------------- 122 | uint8_t sum_pl() { 123 | 124 | uint8_t i, sum; 125 | uint8_t *ppl; 126 | 127 | sum = 0; 128 | ppl = (uint8_t *) &pl; 129 | for (i = 0; i < 15; i++) { 130 | sum += *ppl; 131 | ppl++; 132 | } 133 | return(sum & 0xff); 134 | } 135 | 136 | 137 | //-------------------------------------- 138 | void help(void) { 139 | uart_puts_P("\nG = ++Gas g = --Gas" 140 | "\nH = ++Hoehe h = --Hoehe" 141 | "\nS = ++Seite s = --Seite" 142 | "\nQ = ++Quer q = --Quer" 143 | "\nC = ++Hop-Kanal c = --Hop-Kanal" 144 | "\nF = ++Kanal f = --Kanal" 145 | "\nP = fester Kanal p = huepfen" 146 | "\nB = bind b = Flug" 147 | "\nX = Stop x = weiter" 148 | "\n\n"); 149 | } 150 | 151 | 152 | //-------------------------------------- 153 | void inc_p(uint8_t *p) { 154 | if (!(*p & 0x80)) { 155 | (*p)++; 156 | if (*p == 0x80) *p = 0x7f; 157 | } 158 | else { 159 | (*p)--; 160 | if (*p == 0x80) *p = 0; 161 | } 162 | } 163 | 164 | 165 | //-------------------------------------- 166 | void dec_p(uint8_t *p) { 167 | if (!(*p & 0x80)) { 168 | (*p)--; 169 | if (*p == 0xff) *p = 0x81; 170 | } 171 | else { 172 | (*p)++; 173 | if (*p == 0x00) *p = 0xff; 174 | } 175 | } 176 | 177 | 178 | //-------------------------------------- 179 | int main(void) { 180 | 181 | uint32_t txid; 182 | uint8_t sum, hop_base, hop_inc; 183 | uint8_t i, tmp; 184 | uint16_t j; 185 | uint8_t *ppl; 186 | 187 | DDRD |= 0xf8; 188 | PORTD &= 0x07; 189 | DDRB |= 0x01; 190 | 191 | uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU)); 192 | timer_init(); 193 | _delay_ms(100); 194 | sei(); 195 | uart_puts_P("\033[2J\033[0;0H\n\n" 196 | "Fernsteuer Sender (JD-385) Simulator\n\n" 197 | "Seriennummer: "); 198 | /* 199 | txid = 0; 200 | for (i = 0; i < 8; i++) { 201 | do { 202 | j = uart_getc(); 203 | } while (( (j & 0xff00) != 0) 204 | || ((j & 0xff) < '0') 205 | || ((j & 0xff) > '9') 206 | ); 207 | uart_putc(j & 0xff); 208 | txid = txid * 10; 209 | txid = txid + (j & 0x0f); 210 | } 211 | */ 212 | txid = 0x123456; 213 | uart_puts_P("\nTx-Id: "); 214 | disp_byte((txid & 0xff0000) >> 16); 215 | uart_putc('-'); 216 | disp_byte((txid & 0xff00) >> 8); 217 | uart_putc('-'); 218 | disp_byte(txid & 0xff); 219 | uart_puts_P("\nSendekanaele: "); 220 | pl.tx_id[2] = txid & 0xff; 221 | pl.tx_id[1] = (txid & 0xff00) >> 8; 222 | pl.tx_id[0] = (txid & 0xff0000) >> 16; 223 | sum = pl.tx_id[0] + pl.tx_id[1] + pl.tx_id[2]; 224 | hop_base = sum & 0x03; 225 | hop_inc = (sum & 0x1c) >> 2; 226 | for (i = 0; i < 16; i++) { 227 | tmp = pgm_read_byte(&hop_tbl[hop_base][i]) + hop_inc; 228 | if ((tmp & 0x0f) == 0) tmp -=3; 229 | kanal[i] = tmp; 230 | disp_abs(tmp); 231 | uart_putc(' '); 232 | } 233 | uart_putc('\n'); 234 | act_channel = 0; 235 | hopping = 0; 236 | pl.throttle = 0; 237 | pl.rudder = 0; 238 | pl.elevator = 0; 239 | pl.aileron = 0; 240 | pl.trimm_yaw = 64; 241 | pl.trimm_pitch = 64; 242 | pl.trimm_roll = 64; 243 | for (i = 0; i < 4; i++) { 244 | pl.empty[i] = 0; 245 | } 246 | pl.flags = 0xc0; 247 | pl.chksum = sum_pl(); 248 | 249 | uart_puts_P("\nRFM70 wird initialisiert..."); 250 | if (RFM70_init()) { 251 | uart_puts_P("fehlgeschlagen, Abbruch\n"); 252 | while(1) { 253 | PORTB |= 0x01; 254 | _delay_ms(200); 255 | PORTB &= 0xfe; 256 | _delay_ms(200); 257 | } 258 | } 259 | uart_puts_P("fertig\n"); 260 | 261 | setModeTX(); 262 | setChannel(kanal[act_channel]); 263 | cha_fine = kanal[act_channel]; 264 | help(); 265 | stop = 0; 266 | hopping = 1; 267 | start_cnt = 120; 268 | while(1) { 269 | j = uart_getc(); 270 | if ((j & 0xff00) == 0) { 271 | switch(j & 0xff) { 272 | case 'G': 273 | pl.throttle++; 274 | if (pl.throttle == 0) pl.throttle = 255; 275 | break; 276 | case 'g': 277 | pl.throttle--; 278 | if (pl.throttle == 255) pl.throttle = 0; 279 | break; 280 | case 'H': 281 | inc_p(&pl.elevator); 282 | break; 283 | case 'h': 284 | dec_p(&pl.elevator); 285 | break; 286 | case 'S': 287 | inc_p(&pl.rudder); 288 | break; 289 | case 's': 290 | dec_p(&pl.rudder); 291 | break; 292 | case 'Q': 293 | inc_p(&pl.aileron); 294 | break; 295 | case 'q': 296 | dec_p(&pl.aileron); 297 | break; 298 | case 'B': 299 | pl.flags = 0xc0; 300 | break; 301 | case 'b': 302 | pl.flags = 0x00; 303 | break; 304 | case 'P': 305 | hopping = 0; 306 | break; 307 | case 'p': 308 | hopping = 1; 309 | break; 310 | case 'C': 311 | act_channel = (act_channel + 1) & 0x0f; 312 | setChannel(kanal[act_channel]); 313 | cha_fine = kanal[act_channel]; 314 | break; 315 | case 'c': 316 | act_channel = (act_channel + 15) & 0x0f; 317 | setChannel(kanal[act_channel]); 318 | cha_fine = kanal[act_channel]; 319 | break; 320 | case 'F': 321 | cha_fine = (cha_fine + 1) & 0x7f; 322 | setChannel(cha_fine); 323 | break; 324 | case 'f': 325 | cha_fine = (cha_fine + 127) & 0x7f; 326 | setChannel(cha_fine); 327 | break; 328 | case 'X': 329 | stop = 1; 330 | break; 331 | case 'x': 332 | stop = 0; 333 | break; 334 | default: help(); 335 | } 336 | 337 | pl.chksum = sum_pl(); 338 | if (hopping) { 339 | uart_puts_P("\nhopping "); 340 | } 341 | else { 342 | uart_puts_P("\nKanal "); 343 | disp_abs(cha_fine); 344 | } 345 | uart_puts_P(" : "); 346 | ppl = (uint8_t *) &pl; 347 | for (i = 0; i < 16; i++) { 348 | disp_byte(*ppl); 349 | ppl++; 350 | uart_putc(' '); 351 | } 352 | } 353 | if (tick_slow) { 354 | tick_slow = 0; 355 | PORTB ^= 0x01; 356 | } 357 | // if (start_cnt == 0) pl.flags = 0; 358 | 359 | // if (!stop) { 360 | if (do_tx) { 361 | PORTD ^= 0x10; 362 | do_tx = 0; 363 | flushTxFIFO(); 364 | if (!sendPayload((uint8_t *) &pl, 16, 0)) { 365 | for (i = 0; i < 10; i++) { 366 | PORTB ^= 0x01; 367 | _delay_ms(200); 368 | PORTB &= 0xfe; 369 | _delay_ms(200); 370 | } 371 | } 372 | } 373 | if (do_hop && hopping) { 374 | do_hop = 0; 375 | PORTD ^= 0x20; 376 | act_channel = (act_channel + 1) & 0x0f; 377 | setChannel(kanal[act_channel]); 378 | cha_fine = kanal[act_channel]; 379 | } 380 | // } 381 | } 382 | return(0); 383 | } 384 | 385 | -------------------------------------------------------------------------------- /Remote Control/Firmware für AVR/rfm70.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Remote Control/Firmware für AVR/rfm70.c -------------------------------------------------------------------------------- /Remote Control/Firmware für AVR/rfm70.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Remote Control/Firmware für AVR/rfm70.h -------------------------------------------------------------------------------- /Remote Control/Firmware für AVR/timer.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "all-fb.h" 4 | #include "../uart.h" 5 | #include "vt100.h" 6 | #include "rfm70.h" 7 | #include "rfm70-fb.h" 8 | 9 | // Interrupt alle 1ms 10 | 11 | uint16_t ticks; 12 | PAYLOAD pl; 13 | 14 | 15 | //-------------------------------------- 16 | void timer_init(void) { 17 | TCCR1B |= (1<= 1000) { 32 | tic1s = 1; 33 | ticks = 0; 34 | } 35 | 36 | ticms++; 37 | } 38 | -------------------------------------------------------------------------------- /Remote Control/Firmware für AVR/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMER_H 2 | #define TIMER_H 3 | 4 | void timer_init(void); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /Remote Control/Firmware für AVR/vt100.h: -------------------------------------------------------------------------------- 1 | void term_clear(void); 2 | void term_cursor(uint8_t, uint8_t); 3 | -------------------------------------------------------------------------------- /Remote Control/Images/HOC_Fernbedienung_Platine_Ausschnitt.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Remote Control/Images/HOC_Fernbedienung_Platine_Ausschnitt.jpeg -------------------------------------------------------------------------------- /Remote Control/Images/HOC_Fernbedienung_Platine_B-Seite.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Remote Control/Images/HOC_Fernbedienung_Platine_B-Seite.jpeg -------------------------------------------------------------------------------- /Remote Control/Images/HOC_Fernbedienung_Platine_total.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Remote Control/Images/HOC_Fernbedienung_Platine_total.jpeg -------------------------------------------------------------------------------- /Remote Control/Images/HOC_Fernbedienung_Sendemodul.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Remote Control/Images/HOC_Fernbedienung_Sendemodul.jpeg -------------------------------------------------------------------------------- /Remote Control/Images/RC-MCU-UR-HOC.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Remote Control/Images/RC-MCU-UR-HOC.jpg -------------------------------------------------------------------------------- /Remote Control/LCD port in remote control/Readme.txt: -------------------------------------------------------------------------------- 1 | Auf der LCD Schnittstelle werden mit 250Hz Wiederholrate abwechselnd 3 Datensätze ausgegeben. 2 | Die Daten sind auf der fallenden Flanke von CLK gültig. Der Takt ist nicht gleichförmig. 3 | 4 | Die Taktfrequenz liegt bei etwa 85kHz. 5 | 6 | Ein Beispiel für einen Datensatz zeigt RUNNING.PNG. 7 | 8 | Ein Zusammenhang zwischen Aktionen an der FB und den Bits und Bytes ist nicht zu erkennen. 9 | 10 | Für eine weitegehende Analyse müsste ein Sender mit LCD vorhanden sein. 11 | 12 | 13 | -------------------------------------------------------------------------------- /Remote Control/LCD port in remote control/running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Remote Control/LCD port in remote control/running.png -------------------------------------------------------------------------------- /Remote Control/Protokoll.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/Remote Control/Protokoll.pdf -------------------------------------------------------------------------------- /Remote Control/readme.md: -------------------------------------------------------------------------------- 1 | This folder contains Information about the remote control. 2 | 3 | The remote control is based on a N79E814AS20 microcontroller and BK2423 RD Module with LNA. The circuit has been reverse engineered, but so far no attempt was made to modify the firmware. 4 | 5 | There only seems to be a chinese datasheet available. 6 | 7 | http://www.nuvoton.com/NuvotonMOSS/Community/ProductInfo.aspx?tp_GUID=c60884e1-c6a9-45da-8268-6be8b32e9cf2 8 | 9 | Den Anfang eines Datenblattes auf Deutsch findet man unter "datenblatt.doc" als Word Dokument. 10 | 11 | 12 | RC-Protocol 13 | =========== 14 | 15 | Eine Protokollbeschreibung in Deutsch ist in Protokoll.pdf zu finden. Einzelheiten zur Implementierung findet man im Verzeichnis "Firmware für AVR". 16 | 17 | The stock JXD-385 uses an RC protocol known as "V202". It has been reverse engineered and reimplemented in the Deviation firmware for Devo controls: 18 | 19 | http://www.deviationtx.com/forum/protocol-development/1647-v202-protocol 20 | 21 | Arduino testcode: 22 | https://bitbucket.org/rivig/v202/src 23 | 24 | Sourcecode of firmware: 25 | https://bitbucket.org/PhracturedBlue/deviation/src/c960b8ea4e77/src/protocol/?at=default 26 | 27 | The JXD385 remote control sends a stream of 16 byte packets to the quadcopter. There is no reverse channel and no acknowledgement is used. 28 | 29 | ``` 30 | Format: 31 | 32 | Byte Function Range 33 | 0 Throttle 0-255, note: Trim will be added by remote control 34 | 1 Yaw bit 7 indicates direction, max value in [6:0] depends on speed button settings 35 | 2 Pitch bit 7 indicates direction, max value in [6:0] depends on speed button settings 36 | 3 roll bit 7 indicates direction, max value in [6:0] depends on speed button settings 37 | 4 trim yaw 2-126, 64 is neutral 38 | 5 trim pitch 2-126, 64 is neutral 39 | 6 trim roll 2-126, 64 is neutral 40 | 7 txid1 Unique ID, 0x1fe475 in my RC 41 | 8 txid2 Unique ID, 0x1fe475 in my RC 42 | 9 txid3 Unique ID, 0x1fe475 in my RC 43 | 10 unused 44 | 11 unused 45 | 12 unused 46 | 13 unused 47 | 14 Flags 0x04 is "flip button", 0xc0 is "binding" 48 | 15 Checksum 49 | 50 | Example of packets: 51 | 52 | > 74 99 00 00 40 40 3E 1F E4 75 00 00 00 00 00 43 53 | > 80 99 00 00 40 40 3E 1F E4 75 00 00 00 00 00 4F 54 | > FF 00 00 00 40 40 3E 1F E4 75 00 00 00 00 00 35 55 | > FF 00 00 00 40 40 3E 1F E4 75 00 00 00 00 00 35 56 | > FF 14 00 00 40 40 3E 1F E4 75 00 00 00 00 00 49 57 | > FF 15 00 00 40 40 3E 1F E4 75 00 00 00 00 00 4A 58 | ``` 59 | -------------------------------------------------------------------------------- /jxd385.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hackocopter/JD385_Documentation/f39e3b3be2f83a5204b55d62476acb0d038cf095/jxd385.jpg --------------------------------------------------------------------------------