diff --git a/README b/README index 45a4a1c..afadad7 100644 --- a/README +++ b/README @@ -4,7 +4,7 @@ Makes a very simple WSPR beacon from your RasberryPi by connecting GPIO port to Antenna (and LPF), operates on LF, MF, HF and VHF bands from 0 to 250 MHz. -It is now compatible with both the original Raspberry Pi and the Raspberry Pi 2. +Compatible with the original Raspberry Pi and the Raspberry Pi 2/3. ****** Installation / update: @@ -36,7 +36,8 @@ Usage: (WSPR --help output): -p --ppm ppm Known PPM correction to 19.2MHz RPi nominal crystal frequency. -s --self-calibration - Call ntp_adjtime() before every transmission to obtain the PPM error of the xtal. + Call ntp_adjtime() before every transmission to obtain the PPM error + of the xtal. -r --repeat Repeatedly, and in order, transmit on all the specified freqs. -x --terminate @@ -59,7 +60,7 @@ Usage: (WSPR --help output): -15 indicates the WSPR-15 region of band . Transmission gaps can be created by specifying a TX frequency of 0 - + Note that 'callsign', 'locator', and 'tx_power_dBm' are simply used to fill in the appropriate fields of the WSPR message. Normally, tx_power_dBm should be 10, representing the signal power coming out of the Pi. Set this value @@ -171,7 +172,7 @@ Example usage: sudo ./wspr --self-calibration N9NNN EM10 33 20m Transmit a WSPR transmission slightly off-center on 30m every 10 minutes for - a total of 7 transmissions, and using a fixed PPM correction value. sudo + a total of 7 transmissions, and using a fixed PPM correction value. sudo ./wspr --repeat --terminate 7 --ppm 43.17 N9NNN EM10 33 10140210 0 0 0 0 Transmit repeatedly on 40m, use NTP based frequency offset calibration, @@ -213,6 +214,8 @@ Credits: Michael Tatarinov for adding a patch to get PPM info directly from the kernel. + Retzler AndrĂ¡s (HA7ILM) added support for the RPi2/3. + [1] PiFM code from http://www.icrobotics.co.uk/wiki/index.php/Turning_the_Raspberry_Pi_Into_an_FM_Transmitter [2] Original WSPR Pi transmitter code by Dan: diff --git a/wspr.cpp b/wspr.cpp index 64d9dfa..3ffc169 100644 --- a/wspr.cpp +++ b/wspr.cpp @@ -18,7 +18,8 @@ License: */ -//ha7ilm: added RPi2 support based on a patch to PiFmRds by Cristophe Jacquet and Richard Hirst: http://git.io/vn7O9 +// ha7ilm: added RPi2 support based on a patch to PiFmRds by Cristophe +// Jacquet and Richard Hirst: http://git.io/vn7O9 #include #include @@ -89,21 +90,20 @@ volatile unsigned *allof7e = NULL; // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y) #define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) -#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)) +//#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)) -#define GPIO_SET *(gpio+7) // sets bits 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 GPIO_SET *(gpio+7) // sets bits 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 ACCESS(base) *(volatile int*)((long int)allof7e+base-0x7e000000) #define SETBIT(base, bit) ACCESS(base) |= 1<=mbox.pool_size) return 1; + if (mbox.pool_cnt>=mbox.pool_size) { + cerr << "Error: unable to allocated more pages!" << endl; + ABORT(-1); + } unsigned offset = mbox.pool_cnt*4096; *vAddr = (void*)(((unsigned)mbox.virt_addr) + offset); *pAddr = (void*)(((unsigned)mbox.bus_addr) + offset); //printf("getRealMemoryPageFromPool bus_addr=%x virt_addr=%x\n", (unsigned)*pAddr,(unsigned)*vAddr); mbox.pool_cnt++; - return 0; } void deallocMemPool() @@ -338,7 +301,7 @@ void txSym( } void unSetupDMA(){ - printf("exiting\n"); + //cout << "Exiting!" << endl; struct DMAregs* DMA0 = (struct DMAregs*)&(ACCESS(DMA_PHYS_BASE)); DMA0->CS =1<<31; // reset dma controller txoff(); @@ -506,16 +469,16 @@ void setup_io( ) { /* open /dev/mem */ if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { - printf("can't open /dev/mem \n"); - exit (-1); + cerr << "Error: can't open /dev/mem" << endl; + ABORT (-1); } /* mmap GPIO */ // Allocate MAP block if ((gpio_mem = (char *)malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) { - printf("allocation error \n"); - exit (-1); + cerr << "Error: allocation error" << endl; + ABORT (-1); } // Make sure pointer is on 4K boundary @@ -533,14 +496,13 @@ void setup_io( ); if ((long)gpio_map < 0) { - printf("mmap error %ld\n", (long int)gpio_map); - exit (-1); + cerr << "mmap error" << (long int)gpio_map << endl; + ABORT (-1); } // Always use volatile pointer! gpio = (volatile unsigned *)gpio_map; - } void setup_gpios( @@ -1028,13 +990,18 @@ void timeval_print(struct timeval *tv) { printf("%s.%03ld", buffer, (tv->tv_usec+500)/1000); } -int open_mbox() +void open_mbox() { unlink(DEVICE_FILE_NAME); - if (mknod(DEVICE_FILE_NAME, S_IFCHR|0600, makedev(100, 0)) < 0) { printf("Failed to create mailbox device.\n"); return 1; } + if (mknod(DEVICE_FILE_NAME, S_IFCHR|0600, makedev(100, 0)) < 0) { + cerr << "Failed to create mailbox device." << endl; + ABORT(-1); + } mbox.handle = mbox_open(); - if (mbox.handle < 0) { printf("Failed to open mailbox.\n"); return 1; } - return 0; + if (mbox.handle < 0) { + cerr << "Failed to open mailbox." << endl; + ABORT(-1); + } } int main(const int argc, char * const argv[]) { @@ -1091,7 +1058,7 @@ int main(const int argc, char * const argv[]) { cerr << "Error: mmap error!" << endl; ABORT(-1); } - if (open_mbox()) return 1; + open_mbox(); txon(); struct PageInfo constPage; struct PageInfo instrPage; @@ -1155,7 +1122,7 @@ int main(const int argc, char * const argv[]) { printf("\n"); */ - printf("Ready to transmit (setup complete)...\n"); + cout << "Ready to transmit (setup complete)..." << endl; int band=0; int n_tx=0; for(;;) { @@ -1184,7 +1151,7 @@ int main(const int argc, char * const argv[]) { if (no_delay) { cout << " Transmitting immediately (not waiting for WSPR window)" << endl; } else { - printf(" Waiting for next WSPR transmission window...\n"); + cout << " Waiting for next WSPR transmission window..." << endl; wait_every((wspr15) ? 15 : 2); }