Permalink
Fetching contributors…
Cannot retrieve contributors at this time
175 lines (146 sloc) 3.9 KB
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <math.h>
#include <time.h>
#include <sys/mman.h>
#include <libconfig.h>
int main(int argc, char *argv[])
{
FILE *fp;
int fd, offset, length, i, j;
time_t t;
struct tm *gmt;
volatile void *cfg, *sts;
volatile uint64_t *fifo[8];
volatile uint8_t *rst, *sel;
volatile uint16_t *cntr;
int32_t type = 2;
uint64_t buffer[8][45000];
config_t config;
config_setting_t *setting, *element;
char date[12];
char name[32];
char zeros[15] = "000000_0000.c2";
double dialfreq;
double corr;
double freq[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
int number;
uint8_t chan = 0;
if(argc != 2)
{
fprintf(stderr, "Usage: write-c2-files config_file.cfg\n");
return EXIT_FAILURE;
}
config_init(&config);
if(!config_read_file(&config, argv[1]))
{
fprintf(stderr, "Error on line %d in configuration file.\n", config_error_line(&config));
return EXIT_FAILURE;
}
if(!config_lookup_float(&config, "corr", &corr))
{
fprintf(stderr, "No 'corr' setting in configuration file.\n");
return EXIT_FAILURE;
}
if(corr < -100.0 || corr > 100.0)
{
fprintf(stderr, "Wrong 'corr' setting in configuration file.\n");
return EXIT_FAILURE;
}
setting = config_lookup(&config, "bands");
if(setting == NULL)
{
fprintf(stderr, "No 'bands' setting in configuration file.\n");
return EXIT_FAILURE;
}
length = config_setting_length(setting);
if(length > 8)
{
fprintf(stderr, "More than 8 bands in configuration file.\n");
return EXIT_FAILURE;
}
if(length < 1)
{
fprintf(stderr, "Less than 1 band in configuration file.\n");
return EXIT_FAILURE;
}
for(i = 0; i < length; ++i)
{
element = config_setting_get_elem(setting, i);
if(!config_setting_lookup_float(element, "freq", &freq[i]))
{
fprintf(stderr, "No 'freq' setting in element %d.\n", i);
return EXIT_FAILURE;
}
if(!config_setting_lookup_int(element, "chan", &number))
{
fprintf(stderr, "No 'chan' setting in element %d.\n", i);
return EXIT_FAILURE;
}
if(number < 1 || number > 2)
{
fprintf(stderr, "Wrong 'chan' setting in element %d.\n", i);
return EXIT_FAILURE;
}
chan |= (number - 1) << i;
}
t = time(NULL);
if((gmt = gmtime(&t)) == NULL)
{
fprintf(stderr, "Cannot convert time.\n");
return EXIT_FAILURE;
}
if((fd = open("/dev/mem", O_RDWR)) < 0)
{
fprintf(stderr, "Cannot open /dev/mem.\n");
return EXIT_FAILURE;
}
sts = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x40000000);
cfg = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x40001000);
for(i = 0; i < 8; ++i)
{
fifo[i] = mmap(NULL, 8*sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x40002000 + i * 0x1000);
*(uint32_t *)(cfg + 8 + i * 4) = (uint32_t)floor((1.0 + 1.0e-6 * corr) * freq[i] / 125.0 * (1<<30) + 0.5);
}
rst = (uint8_t *)(cfg + 0);
sel = (uint8_t *)(cfg + 4);
cntr = (uint16_t *)(sts + 12);
*sel = chan;
*rst |= 1;
*rst &= ~1;
offset = 0;
memset(buffer, 0, 45000 * 8 * 8);
while(offset < 42000)
{
while(*cntr < 500) usleep(300000);
for(i = 0; i < 250; ++i)
{
for(j = 0; j < 8; ++j)
{
buffer[j][offset + i] = *fifo[j];
}
}
offset += 250;
}
for(i = 0; i < length; ++i)
{
dialfreq = freq[i] - 0.0015;
strftime(date, 12, "%y%m%d_%H%M", gmt);
sprintf(name, "wspr_%d_%d_%s.c2", i, (uint32_t)(dialfreq * 1.0e6), date);
if((fp = fopen(name, "wb")) == NULL)
{
fprintf(stderr, "Cannot open output file %s.\n", name);
return EXIT_FAILURE;
}
fwrite(zeros, 1, 14, fp);
fwrite(&type, 1, 4, fp);
fwrite(&dialfreq, 1, 8, fp);
fwrite(buffer[i], 1, 360000, fp);
fclose(fp);
}
return EXIT_SUCCESS;
}