Skip to content

Commit

Permalink
Added option to use GPIO21 instead of GPIO4
Browse files Browse the repository at this point in the history
  • Loading branch information
markondej committed Mar 30, 2020
1 parent 97bf94d commit f4c1d03
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 3 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,21 @@ Where:

Other options:
* -d dma_channel - Specifies the DMA channel to be used (0 by default), type 255 to disable DMA transfer, CPU will be used instead
* -b bandwidth - Specifies the bandwidth in kHz, 200 by default
* -b bandwidth - Specifies the bandwidth in kHz, 100 by default
* -r - Loops the playback

After transmission has begun, simply tune an FM receiver to chosen frequency, You should hear the playback.
### Raspberry Pi 4
On Raspberry Pi 4 power saving options probably interfers somehow with this software making transmitting not possible on standard FM broadcasting frequencies. However it is possible to transmit on lower frequencies i.eg. 66MHz. It is recommended to change either ARM core scaling governor settings to "performance" or to change ARM minium and maximum core frequencies to one constant value (see: https://www.raspberrypi.org/forums/viewtopic.php?t=152692 ).
On Raspberry Pi 4 other built-in hardware probably interfers somehow with this software making transmitting not possible on all standard FM broadcasting frequencies. In this case it is recommended to:
1. Compile executable with option to use GPIO21 instead of GPIO4 (PIN 40 on GPIO header):
```
make GPIO21=1
```
2. Change either ARM core frequency scaling governor settings to "performance" or to change ARM minium and maximum core frequencies to one constant value (see: https://www.raspberrypi.org/forums/viewtopic.php?t=152692 ).
```
echo "performance"| sudo tee /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
```
3. Using lower FM broadcasting frequencies (below 93 MHz) when transmitting.
### Supported audio formats
You can transmitt uncompressed WAV (.wav) files directly or read audio data from stdin, eg.:
```
Expand Down
6 changes: 5 additions & 1 deletion makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
EXECUTABLE = fm_transmitter
VERSION = 0.9.4
FLAGS = -Wall -O3 -std=c++11
TRANSMITTER = -fno-strict-aliasing -I/opt/vc/include
ifeq ($(GPIO21), 1)
TRANSMITTER += -DGPIO21
endif

all: main.o mailbox.o sample.o wave_reader.o transmitter.o
g++ -L/opt/vc/lib -lm -lpthread -lbcm_host -o $(EXECUTABLE) main.o mailbox.o sample.o wave_reader.o transmitter.o
Expand All @@ -15,7 +19,7 @@ wave_reader.o: wave_reader.cpp wave_reader.hpp
g++ $(FLAGS) -c wave_reader.cpp

transmitter.o: transmitter.cpp transmitter.hpp
g++ $(FLAGS) -fno-strict-aliasing -I/opt/vc/include -c transmitter.cpp
g++ $(FLAGS) $(TRANSMITTER) -c transmitter.cpp

main.o: main.cpp
g++ $(FLAGS) -DVERSION=\"$(VERSION)\" -DEXECUTABLE=\"$(EXECUTABLE)\" -c main.cpp
Expand Down
11 changes: 11 additions & 0 deletions transmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#define DMA0_BASE_OFFSET 0x00007000
#define DMA15_BASE_OFFSET 0x00e05000
#define CLK0_BASE_OFFSET 0x00101070
#define CLK1_BASE_OFFSET 0x00101078
#define PWMCLK_BASE_OFFSET 0x001010a0
#define GPIO_BASE_OFFSET 0x00200000
#define PWM_BASE_OFFSET 0x0020c000
Expand Down Expand Up @@ -236,12 +237,22 @@ class ClockDevice : public Device
class ClockOutput : public ClockDevice
{
public:
#ifndef GPIO21
ClockOutput(unsigned divisor) : ClockDevice(CLK0_BASE_OFFSET, divisor) {
output = reinterpret_cast<uint32_t *>(peripherals->GetVirtualAddress(GPIO_BASE_OFFSET));
*output = (*output & 0xffff8fff) | (0x04 << 12);
#else
ClockOutput(unsigned divisor) : ClockDevice(CLK1_BASE_OFFSET, divisor) {
output = reinterpret_cast<uint32_t *>(peripherals->GetVirtualAddress(GPIO_BASE_OFFSET + 0x08));
*output = (*output & 0xffffffc7) | (0x02 << 3);
#endif
}
virtual ~ClockOutput() {
#ifndef GPIO21
*output = (*output & 0xffff8fff) | (0x01 << 12);
#else
*output = (*output & 0xffffffc7) | (0x02 << 3);
#endif
}
inline void SetDivisor(unsigned divisor) {
clock->div = (0x5a << 24) | (0xffffff & divisor);
Expand Down

0 comments on commit f4c1d03

Please sign in to comment.