-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
pifunk.c
3318 lines (2906 loc) · 119 KB
/
pifunk.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
Program: PiFunk (C)
Copyright: 2018 - 2020
Author: WodoWiesel
version: 0.1.7.6e
----Licence----------------------------------------------------------------------------------------------
GPL v3.0
-> see LICENSE.MD !!
-----Disclaimers------------------------------------------------------------------------------------------
- Rewritten for own purposes!
- Private Project! It's Early Access & Work in Progress (WIP)!
- **NO guarantees/liabilities or warranties** for any damages/injuries !!
- Usage at **your own risk** !! I'm not a professional!
- Check laws of your country first! Some Frequencies (MHz) & Powerlevels (W / Watt) are prohibited or need at least a HAM-License!
Transmissions in EU only 0.4 mW ERP "effective radiated power" allowed.
- Pi operates with square-waves (²/^2)!!
-> "dirty" transmissions (TX) simultaneously on permitted frequencies possible!
Use Low-/High-Band-Pass-Filters !!
with dry (not electrolytic) capacitors (C=10-100 pF (Farad)) with solenoid (ring),
toroid (ferrite material) chokes with inductance (B=10-50 uH (Henry) like the FT37-43, depends on the Freq.)
or resistors (R=~10 kOhm), diodes to prevent backflow if needed
- You should always ground your antenna to prevent further damage!!
- at least use dummyloads with 50 Ohm @ max. 4 Watt (S=0 level) and compare signals with swr/pwr-meter when no antenna is attached!
- Do not shortout or do overstress it with more than 3.3 V, it may cause damages!
more infos about GPIO electronics https://de.scribd.com/doc/101830961/GPIO-Pads-Control2
- Access on ARM-System and running Linux, normaly on Raspberry Pi (my Pi 1 Model B+ Rev. 1.2 2014)
and used python 3.7.4+ on original Raspbian OS
!!!!!!! program needs more testing on real pi !!!!!!!
--------------------------------------------------------------------------------------------------------
1) Pi-FM version - frequency modulation direction left/right ← , →
2) Pi-AM version - amplitude modulation direction up/down ↑ , ↓
--> 700 MHz system clock of the Pi 1 -> please use heatsink + fan
Setups & dependencies:
OS: Raspbian Buster - Kernel 4.19.97+ (01.04.2020) full incl. desktop & recommended software based on debian
don't forget to update:
sudo apt-get update && upgrade
SHA-256: ac557f27eb8697912263a1de812dfc99fa8d69bd6acc73a0b7756a1083ba0176
-> get 3 different versions here: https://www.raspberrypi.org/downloads/raspbian/
-> or direct link: https://downloads.raspberrypi.org/raspbian_full_latest/
gcc >=9.2.0 compiler or g++>=5.4.1 for 11/14/17
gdb >=7.11.1 debugger
->get project:
git clone https://www.github.com/wodowiesel/PiFunk/
->instructions:
=> You need admin/root permissions!!
You will need "alsa" sound library for this:
sudo apt-get install libsndfile1-dev
install kernal and I2C:
sudo apt-get install libraspberrypi-dev raspberrypi-kernel-headers i2c-tools
The I2C pins include a fixed 1.8 kOhm pull-up resistor to 3.3 V
This means they are not suitable for use as general purpose IO where a pull-up is not required
Check I2C BUS:
sudo i2cdetect -y 1
cd PiFunk // goto path
generate Libs:
sudo gcc pifunk.c -v -g3 -ggdb3 -pg -std=gnu99 -Iinclude -Llib -L/opt/vc/lib -D_USE_MATH_DEFINES -D_GNU_C_SOURCE -lgnu -lm -lpthread -lbcm_host -lbcm2835 -lsndfile -O3 -o src/pifunk.s
sudo gcc pifunk.c -v -g3 -ggdb3 -pg -std=gnu99 -Iinclude -Llib -L/opt/vc/lib -D_USE_MATH_DEFINES -D_GNU_C_SOURCE -lgnu -lm -lpthread -lbcm_host -lbcm2835 -lsndfile -O3 -o lib/pifunk.i
sudo gcc pifunk.c -v -g3 -ggdb3 -pg -std=gnu99 -Iinclude -Llib -L/opt/vc/lib -D_USE_MATH_DEFINES -D_GNU_C_SOURCE -lgnu -lm -lpthread -lbcm_host -lbcm2835 -lsndfile -O3 -o lib/pifunk.o
sudo gcc pifunk.o -v -g3 -ggdb3 -pg -std=gnu99 -Iinclude -Llib -L/opt/vc/lib -D_USE_MATH_DEFINES -D_GNU_C_SOURCE -lgnu -lm -lpthread -lbcm_host -lbcm2835 -lsndfile -O3 -o lib/libpifunk.a
sudo gcc pifunk.o -v -g3 -ggdb3 -pg -std=gnu99 -Iinclude -Llib -L/opt/vc/lib -D_USE_MATH_DEFINES -D_GNU_C_SOURCE -lgnu -lm -lpthread -lbcm_host -lbcm2835 -lsndfile -O3 -o lib/libpifunk.lib
sudo gcc pifunk.o -v -g3 -ggdb3 -pg -std=gnu99 -Iinclude -Llib -L/opt/vc/lib -D_USE_MATH_DEFINES -D_GNU_C_SOURCE -lgnu -lm -lpthread -lbcm_host -lbcm2835 -lsndfile -fPIC -O3 -shared -o lib/libpifunk.so
sudo gcc pifunk.o -v -g3 -ggdb3 -pg -std=gnu99 -Iinclude -Llib -L/opt/vc/lib -D_USE_MATH_DEFINES -D_GNU_C_SOURCE -lgnu -lm -lpthread -lbcm_host -lbcm2835 -lsndfile -fPIC -O3 -shared -o lib/libpifunk.dll
program: sudo gcc pifunk.c -v -g3 -ggdb3 -pg -Q -std=gnu99 -Iinclude -Llib -L/opt/vc/lib -D_USE_MATH_DEFINES -D_GNU_SOURCE -lgnu -lm -lpthread -lbcm_host -lbcm2835 -lsndfile -llibpifunk -O3 -o bin/pifunk
Usage/run:
default: sudo ./pifunk -n sound.wav -f 446.006250 -s 22050 -m fm -p 7 -c callsign -g 4 -d 14 -b 12.50 -t 1 -x on
https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Preprocessor-Options.html
https://renenyffenegger.ch/notes/development/languages/C-C-plus-plus/GCC/options/index
or do make (compile flags and arm-specifics in makefile included)
-lbcm_host // firmware v1.20190718 located in /opt/vc/include/
-lbcm2835
-lpthread
-lm flag for math lib (obligatory),
-g3 for debugger level, -c for not linking to library
-llibpifunk // own lib from this project
-D_POSIX_C_SOURCE=200809L // already in gnu_source included
-std=c99 is the same as -std=iso9899:1999
or -std=gnu99 supports c99 + additional gnu extensions
or -std=c17 (11/14 also possible)
-E tells to stop after preprocessing stage
-v verbose
-a keyword performs basic-block counting annotations for gdb & gprof
This option is supported for HP/UX compatibility.
The keyword argument must be one of the strings ‘archive’, ‘shared’, or ‘default’.
-aarchive is functionally equivalent to ‘-Bstatic’, and the other two keywords are functionally equivalent to ‘-Bdynamic’.
This option may be used any number of times.
-Q Print function names. Show statistics about compilation passes.
-> real gpio hardware can't be simulated by VM! must be executed and compiled on pi wtith linux!
As virtual machine best possible with Qemu
possible freq-shift of ~0.005 MHz -> ~5 kHz !!
todo:
memory-stuff
pointer & address corrections
make compatible arguments/funcs for py/shell scripts
*/
// std C includes
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h> // for c99
#include <stdarg.h>
#include <stdint.h>
#include <stddef.h>
#include <stdalign.h>
#include <stdnoreturn.h>
#include <stdatomic.h>
#include <unistd.h>
// functionality includes
#include <iso646.h> // c95 back-compatible -std=iso9899:199409
#include <argp.h>
#include <string.h>
#include <getopt.h>
#include <time.h>
#include <utime.h>
#include <sched.h>
#include <float.h>
#include <locale.h>
#include <errno.h>
#include <ctype.h>
#include <wchar.h>
#include <wctype.h>
#include <fcntl.h>
#include <malloc.h>
#include <dirent.h>
#include <signal.h>
#include <assert.h>
#include <setjmp.h>
#include <limits.h>
#include <termios.h>
#include <pthread.h>
#include <inttypes.h>
#include <math.h>
#include <tgmath.h>
#include <complex.h>
#include <features.h>
#include <fenv.h>
#include <grp.h>
#include <pwd.h>
#include <poll.h>
#include <argp.h>
#include <uchar.h>
#include <gnumake.h>
//#include <metrics.h>
//#include <missing.h>
// for c++99/11/14/17/20
/*
#include <iostream> //
#include <iomanip> //
#include <iosfwd> //
#include <ios> //
#include <istream> //
#include <stdalign> //
#include <stdnoreturn> //
#include <stdatomic> //
#include <cstdlib> // General purpose utilities: program control, dynamic memory allocation, random numbers, sort and search
#include <cstdio> //
#include <cstdarg> // Handling of variable length argument lists
#include <cstdint> // (since C++11) fixed-size types and limits of other types
#include <cstddef> // definitions & NULL
#include <csignal> // Functions and macro constants for signal management
#include <cstring> //strings
#include <cmath> // Common mathematics functions
#include <ctime> // C-style time/date utilites
#include <climits> // limits of integral types
#include <cfloat> // limits of float types
#include <uchar> //
#include <threads> //
#include <algorithm> //
#include <vector> //
#include <fstream> //
#include <sstream> //
#include <ostream> //
#include <streambuf> //
#include <strstream> // depr c98
#include <syncstream> // c++20
#include <locale> // Localization utilities
#include <clocale> // C localization utilities
#include <codecvt> //
#include <regex> //
#include <atomic> //
#include <complex> // Complex number type
#include <valarray> // Class for representing and manipulating arrays of values
#include <random> // (since C++11) Random number generators and distributions
#include <numeric> // Numeric operations on values in containers
#include <ratio> // (since C++11) Compile-time rational arithmetic
#include <cfenv> // (since C++11) Floating-point environment access functions
#include <bit> // (since C++20) Bit manipulation functions
#include <concepts> // (since C++20) Fundamental library concepts
#include <coroutine> // (since C++20) Coroutine support library
#include <csetjmp> // Macro (and function) that saves (and jumps) to an execution context
#include <typeinfo> // Runtime type information utilities
#include <typeindex> // (since C++11) std::type_index
#include <type_traits> // (since C++11) Compile-time type information
#include <bitset> // std::bitset class template
#include <functional> // Function objects, Function invocations, Bind operations and Reference wrappers
#include <utility> // Various utility components
#include <chrono> // (since C++11) C++ time utilites
#include <initializer_list> // (since C++11) std::initializer_list class template
#include <tuple> // (since C++11) std::tuple class template
#include <any> // (since C++17) std::any class
#include <optional> // (since C++17) std::optional class template
#include <variant> // (since C++17) std::variant class template
#include <compare> // (since C++20) Three-way comparison operator support
#include <version> // (since C++20) supplies implementation-dependent library information
#include <source_location> // (since C++20) supplies means to obtain source code location
#include <new> // Low-level memory management utilities
#include <memory> //Higher level memory management utilities
#include <scoped_allocator> // (since C++11) Nested allocator class
#include <memory_resource> // (since C++17) Polymorphic allocators and memory resources
#include <cinttypes> // (since C++11) formatting macros , intmax_t and uintmax_t math and conversions
#include <limits> // standardized way to query properties of arithmetic types
#include <exception> // Exception handling utilities
#include <stdexcept> // Standard exception objects
#include <cassert> // Conditionally compiled macro that compares its argument to zero
#include <system_error> // (since C++11) defines std::error_code, a platform-dependent error code
#include <cerrno> // Macro containing the last error number
#include <cctype> // Functions to determine the type contained in character data
#include <cwctype> // Functions to determine the type contained in wide character data
#include <cstring> // various narrow character string handling functions
#include <cwchar> // various wide and multibyte string handling functions
#include <cuchar> // (since C++11) C-style Unicode character conversion functions
#include <string> // std::basic_string class template
#include <string_view> // (since C++17) std::basic_string_view class template
#include <charconv> //(since C++17) std::to_chars and std::from_chars
#include <format> // (since C++20) Formatting library including std::format
#include <array> // (since C++11) std::array container
#include <vector> // std::vector container
#include <deque> // std::deque container
#include <list> // std::list container
#include <forward_list> // (since C++11) std::forward_list container
#include <set> // std::set and std::multiset associative containers
#include <map> // std::map and std::multimap associative containers
#include <unordered_set> // (since C++11) std::unordered_set and std::unordered_multiset unordered associative containers
#include <unordered_map> // (since C++11) std::unordered_map and std::unordered_multimap unordered associative containers
#include <stack> // std::stack container adaptor
#include <queue> // std::queue and std::priority_queue container adaptors
#include <span> // (since C++20) std::span view
#include <iterator> //
#include <ranges> // (since C++20) Range access, primitives, requirements, utilities and adaptors
#include <execution> // (since C++17) Predefined execution policies for parallel versions of the algorithms
#include <filesystem> // (since C++17) std::path class and supporting functions
#include <forward_list> // (since C++11) std::forward_list container
#include <concepts> // (since C++20) Fundamental library concepts
#include <coroutine> // (since C++20) Coroutine support library
using namespace std; //
*/
// on posix linux
#include <sys/cdefs.h>
#include <sys/time.h>
#include <sys/timex.h>
#include <sys/times.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/select.h>
#include <sys/file.h>
#include <sys/sysmacros.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <sys/poll.h>
// linux kernel driver headers: path /usr/src/linux-headers-4.19.97+/include/
// used for bcm from header to std include /usr/include/linux/
#include <linux/list.h>
#include <linux/poison.h>
#include <linux/kernel.h>
#include <linux/const.h>
#include <linux/preempt.h>
#include <linux/linkage.h>
#include <linux/compiler_types.h>
#include <linux/stringify.h>
#include <asm/linkage.h>
#include <linux/thread_info.h>
#include <linux/bug.h>
#include <build_bug.h>
#include <linux/restart_block.h>
#include <linux/time64.h>
#include <linux/bitops.h>
#include <linux/bits.h>
#include <linux/irqflags.h>
#include <asm-generic/bitops/__ffs.h>
#include <asm-generic/cmpxchg-local.h>
#include <linux/atomic.h>
#include <linux/export.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/reboot.h>
#include <linux/kd.h>
#include <linux/compiler.h>
#include <linux/cpu.h>
#include <linux/node.h>
#include <linux/device.h>
#include <linux/ioport.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/kernfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/osq_lock.h>
#include <linux/debug_locks.h>
#include <linux/idr.h>
#include <linux/radix-tree.h>
#include <linux/rcupdate.h>
#include <linux/cpumask.h>
#include <linux/threads.h>
#include <linux/bitmap.h>
#include <linux/gfp.h>
#include <linux/mmdebug.h>
#include <linux/mmzone.h>
#include <linux/cache.h>
#include <linux/numa.h>
#include <linux/init.h>
#include <linux/seqlock.h>
#include <linux/nodemask.h>
#include <linux/pageblock-flags.h>
#include <linux/page-flags-layout.h>
#include <generated/bounds.h>
#include <asm-generic/memory_model.h>
#include <linux/pfn.h>
#include <asm-generic/getorder.h>
#include <linux/memory_hotplug.h>
#include <linux/notifier.h>
#include <linux/rwsem.h>
#include <linux/srcu.h>
#include <linux/workqueue.h>
#include <linux/timer.h>
#include <linux/ktime.h>
#include <linux/jiffies.h>
#include <linux/timekeeping.h>
#include <linux/timekeeping32.h>
#include <linux/debugobjects.h>
#include <linux/rcu_segcblist.h>
#include <linux/topology.h>
#include <linux/smp.h>
#include <linux/llist.h>
#include <linux/percpu.h>
#include <linux/printk.h>
#include <linux/kern_levels.h>
#include <linux/srcu.h>
#include <linux/percpu-defs.h>
#include <linux/rbtree.h>
#include <linux/uidgid.h>
#include <linux/highuid.h>
#include <linux/kobject_ns.h>
#include <linux/kref.h>
#include <linux/refcount.h>
#include <linux/klist.h>
#include <linux/pm.h>
#include <linux/completion.h>
#include <linux/ratelimit.h>
#include <linux/overflow.h>
#include <linux/pm_wakeup.h>
#include <linux/cpuhotplug.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h>
#include <linux/property.h>
#include <linux/fwnode.h>
#include <linux/rcutiny.h>
#include <asm-generic/pci_iomap.h>
#include <linux/logic_pio.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/cpu_cooling.h>
#include <linux/math64.h>
#include <linux/slab.h>
#include <linux/kasan.h>
#include <linux/bcd.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/hardirq.h>
#include <linux/ftrace_irq.h>
#include <linux/vtime.h>
#include <linux/context_tracking_state.h>
#include <linux/static_key.h>
#include <linux/jump_label.h>
#include <linux/irq_cpustat.h>
#include <linux/irq.h>
#include <linux/irqhandler.h>
#include <linux/irqdesc.h>
#include <linux/hrtimer.h>
#include <linux/timerqueue.h>
#include <linux/pm_opp.h>
#include <linux/ctype.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/dma-mapping.h>
#include <linux/sizes.h>
#include <linux/dma-debug.h>
#include <linux/dma-direction.h>
#include <linux/scatterlist.h>
#include <linux/mm.h>
#include <linux/mem_encrypt.h>
#include <linux/hdmi.h>
#include <linux/ww_mutex.h>
#include <linux/mailbox_client.h>
#include <linux/pm_domain.h>
#include <linux/textsearch.h>
#include <linux/autoconf.h> // path include/generated
// old (till kernel 2.6): config.h
#include <linux/sched/signal.h>
#include <linux/regulator/consumer.h>
#include <linux/kgdb.h>
// I2C & SPI support need
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/spi/spidev.h>
// FW
//#include <soc/bcm2835/raspberrypi-firmware.h>
#include <drm/drm_fb_cma_helper.h>
//#include <drm/drm_fb_helper.h>
// RTC support
#include <linux/rtc.h>
//#include <linux/rtc/ds1307.h>
#include <linux/rtc/ds3231.h>
#include "rtc/ds3231.h" // my rtc
// ip host socket
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
//#include <net/sctp.h>
#include <net/if.h>
#include <netdb.h>
#include <ifaddrs.h>
// windows (10) if needed for maybe rpi3/4 aarch64
/*
#include <windows.h>
#include <win.h>
#include <windef.h>
#include <winnt.h>
#include <winbase.h>
#include <conio.h> // dos-header
*/
// broadcom arm processor for mapping phys. addresses
#include <bcm_host.h>
#include "opt/vc/include/bcm_host.h" // firmware stuff
#include "opt/vc/include/interface/vcos/vcos.h" // Video Core OS Abstraction Layer
//#include "bcm2709/src/bcm2709.h" // pi 1 & 2 A/A+ & B/B+ processor family
//#include "bcm2711/src/bcm2711.h" // pi 3 & 4 A/B coprocessor
// activate for your specific system
#include <bcm2835.h> // -lbcm2835
#include "bcm2835/src/bcm2835.h" // pi 0/1 v1.3
//#include "bcm2836/src/bcm2836.h" // pi 2
//#include "bcm2837/src/bcm2837.h" // pi 3
//#include "bcm2838/src/bcm2838.h" // pi 4
//#include "bcm2838B0/src/bcm2838B0.h" // pi 4 B
// RPi.GPIO lib, 0.7.0 used with pi4 support
//#include "RPI.GPIO/source/i2c.h"
#include "RPI.GPIO/source/c_gpio.h"
#include "RPI.GPIO/source/event_gpio.h"
//#include "RPI.GPIO/source/py_pwm.h"
#include "RPI.GPIO/source/soft_pwm.h"
//#include "RPI.GPIO/source/constants.h"
#include "RPI.GPIO/source/common.h"
#include "RPI.GPIO/source/cpuinfo.h"
// see http://www.mega-nerd.com/libsndfile/api.html for API needed for am -> ALSA sound
// download from mainpage http://www.alsa-project.org/main/index.php/Main_Page
//#include <sndfile.h>
//#include "include/sndfile.h" // has problems!!! with @typedef sf_count somehow -> set as int
// extra library https://github.com/libusb/libusb
// for usb soundcards for mic and alsa usage
#include "libusb/libusb/libusb.h"
//#include "libusb/libusb.h"
//#include "libusb/libusb/libusbi.h"
//#include "libusb/libusb/hotplug.h"
#include "libusb/libusb/version.h"
#include "libusb/libusb/version_nano.h"
//#include "libusb/libusb/os/linux_usbfs.h"
#include "libusb/libusb/os/poll_posix.h"
#include "libusb/libusb/os/threads_posix.h"
// custom header for pifunk (definitions)
#include "include/pifunk.h"
//------------------------------------------------------------------------------
// preproccessor definitions/macros
#ifndef PIFUNK_C
#define PIFUNK_C
#endif
#ifdef __UNIX__
#warning Program runs under UNIX!
#pragma GCC dependency "pifunk.h"
#endif
#ifdef __LINUX__
#warning Program runs under LINUX!
#pragma GCC dependency "pifunk.h"
#endif
#ifdef __ARM__
#warning Program runs under ARM-Architecture!
#pragma ARM
// same as -CODE32
#else
#warning System NOT ARM!!
#endif
#ifdef __ARM64__
#warning Program runs under ARM64-Architecture!
#pragma ARM64
#endif
#ifdef __GNUC__ // gcc
#warning Using GNU C with ANSI ISO C99 as GNU99!
//#pragma GCC system_header
#pragma GCC visibility pop
#define EXPORT __attribute__((visibility("default")))
#define EXPORT_HIDDEN __attribute__((visibility("hidden")))
#define IMPORT
#endif
#ifdef _GNU_SOURCE
#warning Using GNU Source Extention Macro!
//#define basename __basename_gnu
#endif
#ifdef __STDC_VERSION__
#warning Using GNU C with C99 standard version!
//#define _STDC_VERSION (199901L) // -std=c99
#endif
#ifdef _POSIX
#warning Using POSIX standard!
#define _POSIX_C_SOURCE (200809L) // or 199309L
#endif
#ifndef _USE_MATH_DEFINES
#warning Not recognized math definitions!
#define _USE_MATH_DEFINES (1) // for math lib
#endif
#ifdef __CPLUSPLUS
#warning Using GNU C++ with ANSI ISO C++ 99/11/17/20!
extern "C"
{
printf ("\n__CPLUSPLUS\n");
}
#endif
#ifndef NULL
#warning NULL not defined, setting it to 0!
#endif
#define NULL (0) // normally in stddef
//------------------------------------------------------------------------------
// definitions & Macros
#define VERSION "0.1.7.6" // my version
#define VERSION_MAJOR (0) //
#define VERSION_MINOR (1) //
#define VERSION_BUILD (7) //
#define VERSION_PATCH (6) //
#define VERSION_STATUS "experimental" // WIP work in progress
// simple operators
#define IN (0) //
#define OUT (1) //
#define FALSE (0) //
#define TRUE (1) //
// predefine if needed when not using bcm header
//#define HIGH (0x1) // 1
//#define LOW (0x0) // 0
//#define sleep [1000] // for waiting between functions & tasks
#define usleep [1000] //
// mathematical stuff
#define EULER (2.718281828459045235360287471352f) // log e(EULER) = 0.4342944819
//#define log(EULER) (0.4342944819) // already defines
#define lg(EULER) (1.44269504089)
#define ln(x) (log(x)/log(EULER))
#define PI (3.14159265358979323846) // radial constant
#define PHASE (2*PI) // 6.28318530718
#define PERIOD (1/PHASE) // 0.15915494309
#define HALF_PERIOD (1/PI) // 0.31830988618
#define AMPLITUDE (1) // for sampling I/Q must be constant
// buffers
#define BLOCK_SIZE (4*1024) // 4096
#define BUFFER_LEN (8*1024) // 8192
#define BUFFERINSTRUCTIONS (65536) // [1024]
// I-O access via GPIO
volatile unsigned (*gpio); //
volatile unsigned (*allof7e); //
// GPIO setup macros: Always use INP_GPIO (x) before using OUT_GPIO (x) or SET_GPIO_ALT (x, y)
#define ALLOF7EB (*allof7e-SUB_BASE)
#define GPIO_SET *(gpio+7) // setsbits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0
#define GPIO_GET *(gpio+13) // sets bits which are 1 ignores bits which are 0
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) // % means here Modulo-operation for remainder
#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3)) //
#define SET_GPIO_ALT(g, a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
//----------------------------------------------------------------------------------
// specific pi adresses & definitions
// alternative old/different versions
#ifdef RASPBERRY || RPI// and RPI == 1
#define PERIPH_VIRT_BASE (0x20000000) // dec:536870912
#define PERIPH_PHYS_BASE (0x7E000000) // dec:536870912
#define BCM2835_VIRT_BASE (0x20000000) // dec:536870912
#define DRAM_PHYS_BASE (0x40000000) // dec: 1073741824
#define GPIO_BASE_OFFSET (0x00200000) // dec: 2097152
#define MEM_FLAG (0x0C) // alternative
#define CURBLOCK (0x04) // dec: 4
#define CLOCK_BASE (19.2E6) //
#define DMA_CHANNEL (14) //
#define PLLD_FREQ (500000000) //
#endif
// pi 0 zero & w
#ifdef RASPI0 //== 0
#define PERIPH_VIRT_BASE (0x20000000) // base=GPIO_offset dec: 2 virtual base
#define PERIPH_PHYS_BASE (0x7E000000) // dec: 2113929216
#define BCM2835_VIRT_BASE (0x20000000) // dec:536870912
#define DRAM_PHYS_BASE (0x40000000) // dec: 1073741824
#define GPIO_BASE_OFFSET (0x00200000) // dec: 2097152
#define MEM_FLAG (0x0C) // alternative
#define CURBLOCK (0x0C) // dec: 12
#define CLOCK_BASE (19.2E6) // = 19200000
#define DMA_CHANNEL (14) //
#define PLLD_FREQ (500000000) //
#endif
// pi 1 - BCM2835 -> my version
#ifdef RASPI1 // == 1
#define PERIPH_VIRT_BASE (0x20000000) // base=GPIO_offset dec: 2 virtual base
#define PERIPH_PHYS_BASE (0x7E000000) // dec: 2113929216
#define BCM2835_VIRT_BASE (0x20000000) // dec:536870912
#define DRAM_PHYS_BASE (0x40000000) // dec: 1073741824
#define GPIO_BASE_OFFSET (0x00200000) // dec: 2097152
#define MEM_FLAG (0x0C) // alternative
#define CURBLOCK (0x0C) // dec: 12
#define CLOCK_BASE (19.2E6) //
#define PAGE_SIZE (1024) // 4096
#define DMA_CHANNEL (14) //
#define PLLD_FREQ (500000000) //
#endif
// pi 2 - BCM2836/7
#ifdef RASPI2 //== 2
#define PERIPH_VIRT_BASE (0x3F000000) // dec: 1056964608
#define PERIPH_PHYS_BASE (0x7E000000) // dec: 2113929216
#define BCM2836_PERI_BASE (0x3F000000) // register physical address dec: 1056964608 alternative name
#define BCM2837_PERI_BASE (0x3F000000) // later version 2.1
#define DRAM_PHYS_BASE (0xC0000000) // dec: 3221225472
#define GPIO_BASE_OFFSET (0x00200000) // dec: 2097152
#define MEM_FLAG (0x04) // dec: 4
#define CURBLOCK (0x04) // dec: 4 memflag
#define CLOCK_BASE (19.2E6) //
#define PAGE_SIZE (1024) // 4096
#define DMA_CHANNEL (14) //
#define PLLD_FREQ (500000000.) //
#endif
// pi3 - BCM2837/B0
#ifdef RASPI3 //== 3
#define PERIPH_VIRT_BASE (0x20000000) // dec: 536870912
#define PERIPH_PHYS_BASE (0x7E000000) // dec: 2113929216
#define BCM2837_PERI_BASE (0x3F000000) // register physical address dec: 1056964608 alternative name
#define BCM2837B0_PERI_BASE (0x3F000000) // 3B+ and 3A+
#define DRAM_PHYS_BASE (0xC0000000) // dec: 3221225472
#define GPIO_BASE_OFFSET (0x00200000) // dec: 2097152
#define MEM_FLAG (0x04) // dec: 4
#define CURBLOCK (0x04) // dec: 4 memflag
#define CLOCK_BASE (19.2E6) //
#define PAGE_SIZE (1024) // 4096
#define DMA_CHANNEL (14) //
#define PLLD_FREQ (500000000) //
#endif
// pi 4 - BCM2838
#ifdef RASPI4 //== 4
#define PERIPH_VIRT_BASE (0xFE000000) // dec: 4261412864
#define PERIPH_PHYS_BASE (0x7E000000) // dec: 2113929216
#define BCM2838_PERI_BASE (0x3F000000) // dec: 1056964608
#define BCM2711_PERI_BASE (0x3F000000) // co-processor !!!
#define DRAM_PHYS_BASE (0xC0000000) // dec: 3221225472
#define GPIO_BASE_OFFSET (0x7E215000) // GPIO register base address
#define MEM_FLAG (0x04) // dec: 4
#define CURBLOCK (0x04) // dec: 4 memflag
#define CLOCK_BASE (19.2E6) // = 19200000
#define PAGE_SIZE (4096) //
#define XTAL_CLOCK (54.0E6) // = 54000000
#define DMA_CHANNEL (14) // 4A
#define DMA_CHANNELB (7) // BCM2711 (Pi 4 B only) chan=7
#define PLLD_FREQ (750000000) // has higher freq than pi 0-3
#define BUFFER_TIME (1000000) //
#define PWM_WRITES_PER_SAMPLE (10) //
#define PWM_CHANNEL_RANGE (32) //
#endif
// standard & general definitions
// for seting/checking gpiooin variable later
#define PIN_7 (4) // pin 4
#define GPIO_4 (PIN_7)
#define PIN_40 (40) // pin 40
#define GPIO_21 (PIN_40)
#define GPIO_LEN (0x100) // dec: 256
#define LENGTH (0x01000000) // dec: 1
#define SUB_BASE (0x7E000000) // dec: 2113929216 phys base
#define CLKBASE (0x7E101000) // dec: 2114981888
#define PWMBASE (0x7E20C000) // controller dec: 2116075520
#define MODULATE (0x4D72) // dec: 19826
#define FIFO (0x18) // dec: 24
#define CARRIER (0x5A) // dec: 90
#define DMABASE (0x7E007000) // dec: 2113957888
#define DMAREF (0x7F) // dec: 127 dma base reference
#define DMAC (0x0707) // dec: 1799
#define PWMCLK_CNTL0 (0x5A000016) // dec: 1509949462
#define PWMCLK_DIV0 (0x5A002800) // dec: 1509959680
#define PWMCLK_BASE_OFFSET (0x001010A0) // dec: 1052832
// the normal fm-script didn't specified that, but useful!
#define DMA0_BASE_OFFSET (0x00007000) // dec: 28672 -> dma7=0x700, dma14 = 0xE00
#define DMA15_BASE_OFFSET (0x00E05000) // dec: 14700544 -> 0x00
#define TIMER_BASE_OFFSET (0x00003000) // dec: 12288
#define PWM_BASE_OFFSET (0x0020C000) // dec: 2146304
#define PWM_LEN (0x28) // dec: 40
#define CLK_BASE_OFFSET (0x00101000) // dec: 1052672
#define CLK0_BASE_OFFSET (0x00101070) // dec: 1052784
#define CLK1_BASE_OFFSET (0x00101078) // dec: 1052792
#define CLK_LEN (0x1300) // dec: 4864
#define PCM_BASE_OFFSET (0x00203000) // dec: 2109440
#define PCM_LEN (0x24) // dec: 36
//-----------
#define DMA_VIRT_BASE (PERIPH_VIRT_BASE + DMA0_BASE_OFFSET) //
#define GPIO_BASE (BCM2835_PERI_BASE + PERIPH_VIRT_BASE) // hex: 0x5F000000 dec: 1593835520
#define GPIO_BASE1 (BCM2836_PERI_BASE + PERIPH_VIRT_BASE) // hex: 0x5F000000 dec: 1593835520
#define GPIO_BASE2 (BCM2837_PERI_BASE + PERIPH_VIRT_BASE) // hex: 0x5F000000 dec: 1593835520
#define GPIO_BASE3 (BCM2837B0_PERI_BASE + PERIPH_VIRT_BASE) // hex: 0x5F000000 dec: 1593835520
#define GPIO_BASE4 (BCM2838_PERI_BASE + PERIPH_VIRT_BASE) // hex: 0x5F000000 dec: 1593835520
#define PWM_VIRT_BASE (PERIPH_VIRT_BASE + PWM_BASE_OFFSET) //
#define PWM_PHYS_BASE (PERIPH_PHYS_BASE + PWM_BASE_OFFSET) //
#define CLK_VIRT_BASE (PERIPH_VIRT_BASE + CLK_BASE_OFFSET) //
#define GPIO_VIRT_BASE (PERIPH_VIRT_BASE + GPIO_BASE_OFFSET) //
#define GPIO_PHYS_BASE (PERIPH_PHYS_BASE + GPIO_BASE_OFFSET) //
#define PAD_VIRT_BASE (PERIPH_VIRT_BASE + PAD_BASE_OFFSET) //
#define PCM_VIRT_BASE (PERIPH_VIRT_BASE + PCM_BASE_OFFSET) //
#define PCM_PHYS_BASE (PERIPH_PHYS_BASE + PCM_BASE_OFFSET) //
// GPIO
// https://elinux.org/RPi_BCM2835_GPIOs
// https://books.google.de/books?id=gks1CgAAQBAJ&pg=PA407&lpg=PA407&dq=GPCLK2+address&source=bl&ots=OQkStH20YL&sig=ACfU3U2tp104Z3TTsrmU67Ai4L54JhF1uA&hl=de&sa=X&ved=2ahUKEwjw-uKyhZDnAhUCU1AKHcuRDMgQ6AEwAXoECBQQAQ#v=onepage&q=GPCLK2%20address
#define GPFSEL0 (0x00/4) // p.90, dec: 0
#define GPFSEL1 (0x04/4) // 1
#define GPFSEL2 (0x08/4) // 2
#define GPFSEL3 (0x7E200000) // p.90 dec: 2116026368
#define CM_GP0CTL (0x7E101070) // p.107 dec: 2114982000
#define CM_GP0DIV (0x7E101074) // p.108 dec: 2114982004
#define CM_GP1CTL (0x7E101078) //
#define CM_GP1DIV (0x7E10107C) //
#define CM_GP2CTL (0x7E101080) //
#define CM_GP2DIV (0x7E101084) //
#define CM_UART_CTL (0x7E1010F0)
#define CM_UART_DIV (0x7E1010F4)
#define GPPUD (0x94/4) // 37
#define GPPUDCLK0 (0x98/4) // 38
#define GPPUDCLK1 (0x9C/4) // 39
// PADS
// Ref: https://www.scribd.com/doc/101830961/GPIO-Pads-Control2
// Drive Strength (power 7 standard): 0 = 2 mA, 7 = 16 mA.
#define PAD_BASE_OFFSET (0x00100000) // dec: 1048576
#define PAD_LEN (0x40/4) // 0x10 = dec: 16, 0x64 = dec: 100
#define PADGPIO (0x5A000018) // dec: 1509949464
#define GPIO_PAD_0_27 (0x2C/4) // 11
#define GPIO_PAD_28_45 (0x30/4) // 12
#define GPIO_PAD_46_52 (0x34/4) // 13
#define GPCLK_CNTL (0x70/4) // 112 / 4 = 28 -> 0x5A = decimal: 90
#define GPCLK_DIV (0x74/4) // 29
#define CORECLK_CNTL (0x08/4) // 2
#define CORECLK_DIV (0x0C/4) // 3
#define EMMCCLK_CNTL (0x1C0/4) // 112
#define EMMCCLK_DIV (0x1C4/4) // 113
#define CM_PLLA (0x104/4) // 65
#define CM_PLLB (0x170/4) // 92
#define CM_PLLC (0x108/4) // 66
#define CM_PLLD (0x10C/4) // 67
#define CM_PLLH (0x110/4) // 68
#define CM_LOCK (0x114/4) // 69
#define CM_LOCK_FLOCKA (1<<8) //
#define CM_LOCK_FLOCKB (1<<9) //
#define CM_LOCK_FLOCKC (1<<10) //
#define CM_LOCK_FLOCKD (1<<11) //
#define CM_LOCK_FLOCKH (1<<12) //
/*
https://pinout.xyz/pinout/gpclk
SOURCES:
0 0 Hz Ground
1 19.2 MHz oscillator
2 0 Hz testdebug0
3 0 Hz testdebug1
4 0 Hz PLLA // Auxiliary PLL -> for camera
5 1000 MHz PLLC (changes with overclock settings)
6 500 MHz PLLD
7 216 MHz HDMI auxiliary // not needed here in the program
8-15 0 Hz Ground
clock-divider in the form of (SOURCE/(DIV_I + DIV_F/4096))
https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2835/BCM2835-ARM-Peripherals.pdf
Note: that the BCM2835 ARM Peripherals document contains an error
and states that the denominator of the divider is 1024 instead of 4096.
Uses 3 GPIO pins */
#define A2W_PLLA_ANA0 (0x1010/4) // 10287
#define A2W_PLLB_ANA0 (0x10F0/4) // 1084
#define A2W_PLLC_ANA0 (0x1030/4) // 1036
#define A2W_PLLD_ANA0 (0x1050/4) // 1044
#define A2W_PLLH_ANA0 (0x1070/4) // 1052
#define A2W_PLL_KA_SHIFT (7) //
#define A2W_PLL_KI_SHIFT (19) //
#define A2W_PLL_KP_SHIFT (15) //
#define PLLA_CTRL (0x1100/4) // 1088
#define PLLA_FRAC (0x1200/4) // 1152
#define PLLA_DSI0 (0x1300/4) // 1216
#define PLLA_CORE (0x1400/4) // 1280
#define PLLA_PER (0x1500/4) // 1344
#define PLLA_CCP2 (0x1600/4) // 1408
#define PLLB_CTRL (0x11E0/4) // 1144
#define PLLB_FRAC (0x12E0/4) // 1208
#define PLLB_ARM (0x13E0/4) // 1272
#define PLLB_SP0 (0x14E0/4) // 1336
#define PLLB_SP1 (0x15E0/4) // 1400
#define PLLB_SP2 (0x16E0/4) // 1464
#define PLLC_CTRL (0x1120/4) // 1196
#define PLLC_FRAC (0x1220/4) // 1160
#define PLLC_CORE0 (0x1620/4) // 1416
#define PLLC_CORE2 (0x1320/4) // 1224
#define PLLC_CORE1 (0x1420/4) // 1288
#define PLLC_PER (0x1520/4) // 1352
#define PLLD_CTRL (0x1140/4) // 1104
#define PLLD_FRAC (0x1240/4) // 1168
#define PLLD_DSI0 (0x1340/4) // 1232
#define PLLD_DSI1 (0x1640/4) // 1424
#define PLLD_CORE (0x1440/4) // 1296
#define PLLD_PER (0x1540/4) // 1360
#define PLLH_CTRL (0x1160/4) // 1112
#define PLLH_FRAC (0x1260/4) // 1176
#define PLLH_AUX (0x1360/4) // 1240
#define PLLH_RCAL (0x1460/4) // 1304
#define PLLH_PIX (0x1560/4) // 1368
#define PLLH_STS (0x1660/4) // 1432
// PWM
#define PWM_CTL (0x00/4) // 0
#define PWM_FIFO (0x18/4) // 6
#define PWM_DMAC (0x08/4) // 2
#define PWM_RNG1 (0x10/4) // 4
#define PWM_RNG2 (0x20/4) // 8
#define PWMDMAC_ENAB (1<<31) // shift bit to left
#define PWMDMAC_THRSHLD ((15<<8)|(15<<0)) // this means it requests as soon as there is one free slot in the FIFO
// we want this as burst DMA would mess up our timing
// The deviation specifies the bandwidth of the signal: ~20.0 for WBFM (broadcasts) and ~3.5 for NBFM (walkie-talkie)
#define DEVIATION (12.50) // in kHz, a-pmr width normal analog
#define DEVIATION2 (6.25) // d-pmr width digital
#define DEVIATION3 (10.00) // CB width
#define DEVIATION4 (20.00) // dmr width
#define DEVIATION5 (25.00) // dmr mixed
#define PWMCLK_CNTL (40) // offset 0A0
#define PWMCLK_DIV (41) // 0A4
#define PWMCTL_CLRF (1<<6) //
#define PWMCTL_PWEN1 (1<<0) //
#define PWMCTL_PWEN2 (1<<8) //
#define PWMCTL_MODE1 (1<<1) //
#define PWMCTL_MODE2 (1<<9) //
#define PWMCTL_RPTL1 (1<<2) //
#define PWMCTL_RPTL2 (1<<10) //
#define PWMCTL_POLA1 (1<<4) //
#define PWMCTL_USEF1 (1<<5) //
#define PWMCTL_USEF2 (1<<13) //
#define PWMCTL_MSEN1 (1<<7) //