// Simple program to route either the cyrstal clock or PLL clock to the // output GPIO pin. /* License: This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define ABORT(a) exit(a) // Used for debugging #define MARK std::cout << "Currently in file: " << __FILE__ << " line: " << __LINE__ << std::endl // Nominal clock frequencies #define F_XTAL (19200000.0) #define F_PLLD_CLK (500000000.0) // Choose proper base address depending on RPI1/RPI2 setting from makefile. #ifdef RPI2 #define BCM2708_PERI_BASE 0x3f000000 //#pragma message "Raspberry Pi 2/3 detected." #else #define BCM2708_PERI_BASE 0x20000000 //#pragma message "Raspberry Pi 1 detected." #endif #define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */ #define PAGE_SIZE (4*1024) #define BLOCK_SIZE (4*1024) // This must be declared global so that it can be called by the atexit // function. 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 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<divisor_max) { divisor_actual=divisor_max; } if (divisor_actual<2) { divisor_actual=2; } // Actual frequency const double freq_actual=source_freq/divisor_actual; cout << "Actual frequency produced (nominal): " << setprecision(30) << freq_actual << " Hz" << endl; cout << "Actual divisor used: " << setprecision(30) << divisor_actual << endl; // Initial configuration int mem_fd; char *gpio_mem, *gpio_map; volatile unsigned *gpio = NULL; setup_io(mem_fd,gpio_mem,gpio_map,gpio); setup_gpios(gpio); allof7e = (unsigned *)mmap( NULL, 0x002FFFFF, //len PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, BCM2708_PERI_BASE //base ); if ((long int)allof7e==-1) { cerr << "Error: mmap error!" << endl; ABORT(-1); } cout << "Press CTRL-C to stop / exit" << endl; atexit(txoff); signal (SIGINT, handSig); signal (SIGTERM, handSig); signal (SIGHUP, handSig); signal (SIGQUIT, handSig); txon(source,divisor_actual); // Wait forever while (1) { usleep(1000000); } return 0; }