// 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;
}