diff --git a/README.md b/README.md index bba57f6..e62f176 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This program generates an FM modulation, with RDS (Radio Data System) data gener It is based on the FM transmitter created by [Oliver Mattos and Oskar Weigl](http://www.icrobotics.co.uk/wiki/index.php/Turning_the_Raspberry_Pi_Into_an_FM_Transmitter), and later adapted to using DMA by [Richard Hirst](https://github.com/richardghirst). Christophe Jacquet adapted it and added the RDS data generator and modulator. The transmitter uses the Raspberry Pi's PWM generator to produce VHF signals. -It is compatible with both the Raspberry Pi 1 (the original one) and the Raspberry Pi 2, 3 and 3+. +It is compatible with both the Raspberry Pi 1 (the original one) and the Raspberry Pi 2, 3 and 4. ![](doc/vfd_display.jpg) diff --git a/src/Makefile b/src/Makefile index 6cebd28..7e35ed7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,24 +1,32 @@ CC = gcc -STD_CFLAGS = -Wall -std=gnu99 -c -g -O3 +STD_CFLAGS = -Wall -std=gnu99 -c -g # Enable ARM-specific options only on ARM, and compilation of the app only on ARM UNAME := $(shell uname -m) -# Determine the hardware platform. Below, pi1 stands for the RaspberryPi 1 (the original one), -# and pi2 stands for both the RaspberryPi 2 and 3. +# Determine Raspberry Pi version (if 2 or greater) +RPI_VERSION := $(shell cat /proc/device-tree/model | grep -a -o "Raspberry\sPi\s[0-9]" | grep -o "[0-9]") + +# Determine the hardware platform and set proper compilation flags ifeq ($(UNAME), armv6l) - CFLAGS = $(STD_CFLAGS) -march=armv6 -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -ffast-math -DRASPI=1 - TARGET = pi1 -else ifeq ($(UNAME), armv7l) - CFLAGS = $(STD_CFLAGS) -march=armv7-a -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -ffast-math -DRASPI=2 - TARGET = pi2 -else ifeq ($(UNAME), aarch64) - CFLAGS = $(STD_CFLAGS) -march=armv8-a -O2 -pipe -fstack-protector-strong -fno-plt -ffast-math -DRASPI=2 - TARGET = pi2 + ARCH_CFLAGS = -march=armv6 -O3 -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -ffast-math + TARGET = 1 +else ifeq ($(shell expr $(RPI_VERSION) \> 1), 1) + ifeq ($(UNAME), armv7l) + ARCH_CFLAGS = -march=armv7-a -O3 -mtune=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp -ffast-math + else ifeq ($(UNAME), aarch64) + ARCH_CFLAGS = -march=armv8-a -O2 -pipe -fstack-protector-strong -fno-plt -ffast-math + endif + ifeq ($(shell expr $(RPI_VERSION) \>= 4), 1) + TARGET = 4 + else + TARGET = 2 + endif else - CFLAGS = $(STD_CFLAGS) + ARCH_CFLAGS = -O3 TARGET = other endif +CFLAGS = $(STD_CFLAGS) $(ARCH_CFLAGS) -DRASPI=$(TARGET) ifneq ($(TARGET), other) diff --git a/src/pi_fm_rds.c b/src/pi_fm_rds.c index b8e91b8..7423869 100644 --- a/src/pi_fm_rds.c +++ b/src/pi_fm_rds.c @@ -116,11 +116,19 @@ #define PERIPH_PHYS_BASE 0x7e000000 #define DRAM_PHYS_BASE 0x40000000 #define MEM_FLAG 0x0c +#define PLLFREQ 500000000. #elif (RASPI)==2 #define PERIPH_VIRT_BASE 0x3f000000 #define PERIPH_PHYS_BASE 0x7e000000 #define DRAM_PHYS_BASE 0xc0000000 #define MEM_FLAG 0x04 +#define PLLFREQ 500000000. +#elif (RASPI)==4 +#define PERIPH_VIRT_BASE 0xfe000000 +#define PERIPH_PHYS_BASE 0x7e000000 +#define DRAM_PHYS_BASE 0xc0000000 +#define MEM_FLAG 0x04 +#define PLLFREQ 750000000. #else #error Unknown Raspberry Pi version (variable RASPI) #endif @@ -185,8 +193,6 @@ #define GPFSEL0 (0x00/4) -#define PLLFREQ 500000000. // PLLD is running at 500MHz - // The deviation specifies how wide the signal is. Use 25.0 for WBFM // (broadcast radio) and about 3.5 for NBFM (walkie-talkie style radio) #define DEVIATION 25.0 @@ -392,7 +398,7 @@ int tx(uint32_t carrier_freq, char *audio_file, uint16_t pi, char *ps, char *rt, // register. // // Set the range to 2 bits. PLLD is at 500 MHz, therefore to get 228 kHz - // we need a divisor of 500000 / 2 / 228 = 1096.491228 + // we need a divisor of 500000000 / 2000 / 228 = 1096.491228 // // This is 1096 + 2012*2^-12 theoretically // @@ -403,7 +409,7 @@ int tx(uint32_t carrier_freq, char *audio_file, uint16_t pi, char *ps, char *rt, // // So we use the 'ppm' parameter to compensate for the oscillator error - float divider = (500000./(2*228*(1.+ppm/1.e6))); + float divider = (PLLFREQ/(2000*228*(1.+ppm/1.e6))); uint32_t idivider = (uint32_t) divider; uint32_t fdivider = (uint32_t) ((divider - idivider)*pow(2, 12));