kopia lustrzana https://github.com/F5OEO/WsprryPi
Add hardware TX via GPCLK0 on GPIO4
rodzic
cfe61da8b3
commit
84831d93bb
163
wspr.c
163
wspr.c
|
@ -19,9 +19,159 @@ Encoding process is in 5 steps:
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "wspr.h" // wspr definitions and functions
|
#include "wspr.h" // wspr definitions and functions
|
||||||
|
|
||||||
|
|
||||||
|
#define BCM2708_PERI_BASE 0x20000000
|
||||||
|
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
|
||||||
|
#define PAGE_SIZE (4*1024)
|
||||||
|
#define BLOCK_SIZE (4*1024)
|
||||||
|
|
||||||
|
int mem_fd;
|
||||||
|
char *gpio_mem, *gpio_map;
|
||||||
|
char *spi0_mem, *spi0_map;
|
||||||
|
|
||||||
|
|
||||||
|
// I/O access
|
||||||
|
volatile unsigned *gpio;
|
||||||
|
volatile unsigned *allof7e;
|
||||||
|
|
||||||
|
// 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*)((int)allof7e+base-0x7e000000)
|
||||||
|
#define SETBIT(base, bit) ACCESS(base) |= 1<<bit
|
||||||
|
#define CLRBIT(base, bit) ACCESS(base) &= ~(1<<bit)
|
||||||
|
#define CM_GP0CTL (0x7e101070)
|
||||||
|
#define GPFSEL0 (0x7E200000)
|
||||||
|
#define CM_GP0DIV (0x7e101074)
|
||||||
|
|
||||||
|
|
||||||
|
struct GPCTL {
|
||||||
|
char SRC : 4;
|
||||||
|
char ENAB : 1;
|
||||||
|
char KILL : 1;
|
||||||
|
char : 1;
|
||||||
|
char BUSY : 1;
|
||||||
|
char FLIP : 1;
|
||||||
|
char MASH : 2;
|
||||||
|
unsigned int : 13;
|
||||||
|
char PASSWD : 8;
|
||||||
|
};
|
||||||
|
|
||||||
|
void txon()
|
||||||
|
{
|
||||||
|
|
||||||
|
allof7e = (unsigned *)mmap(
|
||||||
|
NULL,
|
||||||
|
0x01000000, //len
|
||||||
|
PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED,
|
||||||
|
mem_fd,
|
||||||
|
0x20000000 //base
|
||||||
|
);
|
||||||
|
|
||||||
|
if ((int)allof7e==-1) exit(-1);
|
||||||
|
|
||||||
|
SETBIT(GPFSEL0 , 14);
|
||||||
|
CLRBIT(GPFSEL0 , 13);
|
||||||
|
CLRBIT(GPFSEL0 , 12);
|
||||||
|
|
||||||
|
struct GPCTL setupword = {6/*SRC*/, 1, 0, 0, 0, 1,0x5a};
|
||||||
|
ACCESS(CM_GP0CTL) = *((int*)&setupword);
|
||||||
|
}
|
||||||
|
|
||||||
|
void txoff()
|
||||||
|
{
|
||||||
|
struct GPCTL setupword = {6/*SRC*/, 1, 0, 0, 0, 1,0x5a};
|
||||||
|
ACCESS(CM_GP0CTL) = *((int*)&setupword);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setfreq(long freq)
|
||||||
|
{
|
||||||
|
ACCESS(CM_GP0DIV) = (0x5a << 24) + freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set up a memory regions to access GPIO
|
||||||
|
//
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mmap GPIO */
|
||||||
|
|
||||||
|
// Allocate MAP block
|
||||||
|
if ((gpio_mem = malloc(BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) {
|
||||||
|
printf("allocation error \n");
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure pointer is on 4K boundary
|
||||||
|
if ((unsigned long)gpio_mem % PAGE_SIZE)
|
||||||
|
gpio_mem += PAGE_SIZE - ((unsigned long)gpio_mem % PAGE_SIZE);
|
||||||
|
|
||||||
|
// Now map it
|
||||||
|
gpio_map = (unsigned char *)mmap(
|
||||||
|
gpio_mem,
|
||||||
|
BLOCK_SIZE,
|
||||||
|
PROT_READ|PROT_WRITE,
|
||||||
|
MAP_SHARED|MAP_FIXED,
|
||||||
|
mem_fd,
|
||||||
|
GPIO_BASE
|
||||||
|
);
|
||||||
|
|
||||||
|
if ((long)gpio_map < 0) {
|
||||||
|
printf("mmap error %d\n", (int)gpio_map);
|
||||||
|
exit (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always use volatile pointer!
|
||||||
|
gpio = (volatile unsigned *)gpio_map;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup_gpios()
|
||||||
|
{
|
||||||
|
int g;
|
||||||
|
// Switch GPIO 7..11 to output mode
|
||||||
|
|
||||||
|
/************************************************************************\
|
||||||
|
* You are about to change the GPIO settings of your computer. *
|
||||||
|
* Mess this up and it will stop working! *
|
||||||
|
* It might be a good idea to 'sync' before running this program *
|
||||||
|
* so at least you still have your code changes written to the SD-card! *
|
||||||
|
\************************************************************************/
|
||||||
|
|
||||||
|
// Set GPIO pins 7-11 to output
|
||||||
|
for (g=7; g<=11; g++) {
|
||||||
|
INP_GPIO(g); // must use INP_GPIO before we can use OUT_GPIO
|
||||||
|
//OUT_GPIO(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Code_msg (char usr_message[], unsigned long int *N, unsigned long int *M)
|
Code_msg (char usr_message[], unsigned long int *N, unsigned long int *M)
|
||||||
{
|
{
|
||||||
|
@ -278,5 +428,18 @@ int main(int argc, char *argv[])
|
||||||
printf("\n");
|
printf("\n");
|
||||||
centre_freq = atof(argv[4]);
|
centre_freq = atof(argv[4]);
|
||||||
sym_to_tuning_words(centre_freq, wspr_symbols, tuning_words);
|
sym_to_tuning_words(centre_freq, wspr_symbols, tuning_words);
|
||||||
|
|
||||||
|
/* Now we have the list of tuning words, let's transmit them
|
||||||
|
Note that this version doesn't check whether we are in a correct timeslot
|
||||||
|
*/
|
||||||
|
|
||||||
|
setup_io();
|
||||||
|
setup_gpios();
|
||||||
|
txon();
|
||||||
|
for (i = 0; i < 162; i++) {
|
||||||
|
setfreq(tuning_words[i]);
|
||||||
|
usleep(8192/12000);
|
||||||
|
}
|
||||||
|
txoff();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue