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 <stdlib.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
|
||||
|
||||
|
||||
#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
|
||||
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");
|
||||
centre_freq = atof(argv[4]);
|
||||
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;
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue