kopia lustrzana https://github.com/F5OEO/rpitx
Shuffle to remove spurious and begining of calibration
rodzic
bfa3447731
commit
aa67743458
|
@ -0,0 +1,140 @@
|
|||
//
|
||||
// Simple FSQ beacon for Arduino, with the Etherkit Si5351A Breakout
|
||||
// Board, by Jason Milldrum NT7S.
|
||||
//
|
||||
// Original code based on Feld Hell beacon for Arduino by Mark
|
||||
// Vandewettering K6HX, adapted for the Si5351A by Robert
|
||||
// Liesenfeld AK6L <ak6l@ak6l.org>. Timer setup
|
||||
// code by Thomas Knutsen LA3PNA.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||
// permit persons to whom the Software is furnished to do so, subject
|
||||
// to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define TONE_SPACING 8789 // ~8.7890625 Hz
|
||||
#define BAUD_2 7812 // CTC value for 2 baud
|
||||
#define BAUD_3 5208 // CTC value for 3 baud
|
||||
#define BAUD_4_5 3472 // CTC value for 4.5 baud
|
||||
#define BAUD_6 2604 // CTC value for 6 baud
|
||||
|
||||
#define LED_PIN 13
|
||||
|
||||
#define bool char
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
// Global variables
|
||||
|
||||
unsigned long freq = 0;//7105350; // Base freq is 1350 Hz higher than dial freq in USB
|
||||
uint8_t cur_tone = 0;
|
||||
static uint8_t crc8_table[256];
|
||||
char callsign[10] = "F5OEO";
|
||||
char tx_buffer[40];
|
||||
uint8_t callsign_crc;
|
||||
int FileText;
|
||||
int FileFreqTiming;
|
||||
// Global variables used in ISRs
|
||||
volatile bool proceed = false;
|
||||
|
||||
|
||||
void WriteTone(double Frequency,uint32_t Timing)
|
||||
{
|
||||
typedef struct {
|
||||
double Frequency;
|
||||
uint32_t WaitForThisSample;
|
||||
} samplerf_t;
|
||||
samplerf_t RfSample;
|
||||
|
||||
RfSample.Frequency=Frequency;
|
||||
RfSample.WaitForThisSample=Timing; //en 100 de nanosecond
|
||||
//printf("Freq =%f Timing=%d\n",RfSample.Frequency,RfSample.WaitForThisSample);
|
||||
if (write(FileFreqTiming, &RfSample,sizeof(samplerf_t)) != sizeof(samplerf_t)) {
|
||||
fprintf(stderr, "Unable to write sample\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *sText;
|
||||
if (argc > 2)
|
||||
{
|
||||
sText=(char *)argv[1];
|
||||
//FileText = open(argv[1], O_RDONLY);
|
||||
|
||||
char *sFileFreqTiming=(char *)argv[2];
|
||||
FileFreqTiming = open(argv[2], O_WRONLY|O_CREAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("usage : pidrone StringToTransmit file.ft\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
//100KHZ
|
||||
int Freq_span = 100000;
|
||||
int NbStep = 2000;
|
||||
int i;
|
||||
for(i=1;i<NbStep;i++)
|
||||
{
|
||||
WriteTone(Freq_span*i/NbStep-Freq_span/2,1000e6/NbStep);
|
||||
}
|
||||
WriteTone(00000,250e6);
|
||||
for (i=0;i<strlen(sText);i++)
|
||||
{
|
||||
int bit;
|
||||
WriteTone(25000,1250e3);//Start bit
|
||||
for(bit=0;bit<8;bit++)
|
||||
{
|
||||
if((sText[i]&(1<<(7-bit)))>0)
|
||||
{
|
||||
WriteTone(25000,1250e3);
|
||||
printf("1");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteTone(-25000,1250e3);
|
||||
printf("0");
|
||||
}
|
||||
|
||||
}
|
||||
WriteTone(25000,1250e3);//Stop bit
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
WriteTone(00000,250e6);
|
||||
close(FileFreqTiming);
|
||||
}
|
||||
|
Plik binarny nie jest wyświetlany.
|
@ -0,0 +1,761 @@
|
|||
// OPERA_Decode_Test.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
// Purpose : to study coding and decoding of OPERA which was developed by EA5HVK.
|
||||
//
|
||||
// Usage : "OPERA_Decode_Test [? | d | s | w]
|
||||
// where : s= help, d = debug, s = AA1AA and w = 7L1RLL
|
||||
//
|
||||
// Version : 1.0.3, 11/27/2015 change print_char() to print_str()
|
||||
// Version : 1.0.2, 11/27/2015 bug fix at unpack(), and add 7L1RLL as a 2nd sample.
|
||||
// Version : 1.0.1, 11/27/2015 Add a function of print_char()
|
||||
// Version : 1.0.0, 11/25/2015 Initial Release, but under construction on error correction.
|
||||
//
|
||||
// Copyright : 7L1RLL(Rick Wakatori) 2015 under Terms of The GNU General
|
||||
// Public License.
|
||||
//
|
||||
// Environments : Microsoft Visual C++ 2010 Express under Windows 10.
|
||||
// Compiler version : 10.0.40219.1 SPIRel
|
||||
//
|
||||
// Acknowledgements :
|
||||
// a)EA5HVK(Jose) for work on OPERA
|
||||
// b)F4GCB(Patrick) for PIC program on CRC16 which is a copy into this program.
|
||||
// c)PE1NNZ(Guido), for Article titled Opera Protocol Specification.
|
||||
|
||||
//#include "stdafx.h"
|
||||
#include "stdio.h"
|
||||
#include "math.h"
|
||||
#include "string.h"
|
||||
|
||||
short int call_AA1AA[239] =
|
||||
{ // callsign = "AA1AA"
|
||||
1,0,1,1, 0,1,0,0, 1,0,1,1, 0,0,1,0, // 0xB4, 0xB2
|
||||
1,1,0,0, 1,1,0,1, 0,0,1,1, 0,0,1,0, // 0xCD, 0x32
|
||||
1,0,1,0, 1,1,0,0, 1,0,1,1, 0,0,1,1, // 0xAC, 0xB3
|
||||
0,1,0,0, 1,0,1,0, 1,1,0,0, 1,1,0,0, // 0x4A, 0xCC
|
||||
1,1,0,0, 1,1,0,1, 0,0,1,1, 0,0,1,0, // 0xCD, 0x32
|
||||
1,0,1,0, 1,0,1,1, 0,0,1,1, 0,1,0,1, // 0xA9, 0x35
|
||||
0,1,0,0, 1,1,0,0, 1,1,0,1, 0,1,0,0, // 0x4C, 0xD4
|
||||
1,0,1,1, 0,1,0,0, 1,0,1,0, 1,1,0,1, // 0xB4, 0xAD
|
||||
0,0,1,1, 0,1,0,0, 1,1,0,1, 0,1,0,0, // 0x34, 0xD4
|
||||
1,1,0,0, 1,0,1,0, 1,0,1,1, 0,0,1,1, // 0xCA, 0xB3
|
||||
0,0,1,0, 1,0,1,0, 1,1,0,1, 0,1,0,0, // 0x2A, 0xD4
|
||||
1,0,1,0, 1,1,0,1, 0,1,0,1, 0,1,0,1, // 0xAD, 0x55
|
||||
0,1,0,0, 1,0,1,0, 1,1,0,1, 0,0,1,1, // 0x4A, 0xD3
|
||||
0,0,1,1, 0,1,0,1, 0,0,1,0, 1,1,0,0, // 0x35, 0x2C
|
||||
1,1,0,1, 0,1,0,0, 1,1,0,0, 1,0,1 // 0xD4, 0xCA
|
||||
};
|
||||
|
||||
short int call_F5OEO[239] = {1,0,1,1, 0,1,0,1, 0,0,1,0, 1,1,0,1, 0,1,0,1, 0,1,0,1, 0,1,0,0, 1,1,0,1, 0,1,0,0, 1,1,0,0,
|
||||
1,1,0,0, 1,1,0,0, 1,0,1,0, 1,1,0,1, 0,1,0,1, 0,0,1,0, 1,0,1,0, 1,1,0,1, 0,0,1,1, 0,1,0,0,
|
||||
1,0,1,0, 1,0,1,1, 0,1,0,1, 0,1,0,1, 0,0,1,0, 1,0,1,0, 1,1,0,1, 0,0,1,1, 0,0,1,1, 0,0,1,0,
|
||||
1,1,0,0, 1,1,0,1, 0,0,1,0, 1,1,0,1, 0,1,0,1, 0,1,0,0, 1,0,1,1, 0,1,0,0, 1,0,1,1, 0,0,1,1,
|
||||
0,1,0,1, 0,0,1,1, 0,1,0,1 ,0,1,0,0, 1,0,1,0, 1,0,1,0, 1,1,0,1, 0,1,0,0, 1,1,0,1, 0,1,0,1,
|
||||
0,0,1,0, 1,0,1,1, 0,0,1,0, 1,1,0,1 ,0,0,1,1, 0,1,0,1, 0,0,1,1, 0,1,0,0, 1,1,0,0, 1,0,1
|
||||
};
|
||||
|
||||
|
||||
|
||||
short int call_7L1RLL[239] =
|
||||
{
|
||||
1,0,1,0, 1,1,0,1, 0,0,1,0, 1,1,0,1, // 0xAD, 0x2D
|
||||
0,0,1,0, 1,0,1,0, 1,1,0,0, 1,0,1,0, // 0x2A, 0xCA
|
||||
1,0,1,0, 1,0,1,0, 1,0,1,1, 0,1,0,0, // 0xAA, 0xB4
|
||||
1,0,1,1, 0,0,1,0, 1,0,1,0, 1,0,1,1, // 0xB2, 0xAB
|
||||
0,0,1,1, 0,1,0,1, 0,0,1,0, 1,0,1,0, // 0x35, 0x2A
|
||||
1,0,1,0, 1,0,1,1, 0,1,0,1, 0,0,1,1, // 0xAB, 0x53
|
||||
0,0,1,1, 0,0,1,0, 1,1,0,0, 1,1,0,0, // 0x32, 0xCC
|
||||
1,1,0,1, 0,0,1,0, 1,0,1,0, 1,0,1,1, // 0xD2, 0xAB
|
||||
0,0,1,1, 0,0,1,0, 1,1,0,0, 1,0,1,1, // 0x32, 0xCB
|
||||
0,1,0,0, 1,1,0,0, 1,1,0,1, 0,1,0,1, // 0x4C, 0xD5
|
||||
0,1,0,1, 0,0,1,1, 0,1,0,1, 0,0,1,1, // 0x53, 0x53
|
||||
0,0,1,0, 1,1,0,0, 1,1,0,0, 1,1,0,1, // 0x2C, 0xCD
|
||||
0,1,0,0, 1,1,0,1, 0,1,0,0, 1,0,1,1, // 0x4D, 0x4B
|
||||
0,1,0,0, 1,1,0,0, 1,0,1,1, 0,1,0,0, // 0x4C, 0xB4
|
||||
1,0,1,0, 1,0,1,0, 1,0,1,0, 1,1,0 // 0xAA, 0xAC
|
||||
};
|
||||
|
||||
short int interleave_target[119] =
|
||||
{ //after interleave
|
||||
1,0,0,1, 1,0,1,1, 0,1,0,0, 1,0,1,1, //0x9B, 0x4B
|
||||
1,1,0,1, 1,0,1,0, 0,1,1,1, 0,1,0,1, //0xDA, 0x75
|
||||
0,1,0,0, 1,0,1,1, 1,1,1,0, 1,0,0,0, //0x4B, 0xE8
|
||||
0,1,0,1, 0,0,0,1, 1,0,0,1, 1,1,0,0, //0x51, 0x9C
|
||||
1,0,0,1, 0,0,0,1, 0,1,1,1, 1,0,1,0, //0x91, 0x7A
|
||||
1,1,1,1, 0,0,0,1, 1,1,0,0, 0,0,0,0, //0xF1, 0xC0
|
||||
0,1,1,1, 0,0,1,0, 1,0,0,0, 1,1,0,1, //0x72, 0x8D
|
||||
0,0,0,1, 0,1,1 //0x16
|
||||
};
|
||||
|
||||
short int before_interleave_target[119] =
|
||||
{ // before interleave
|
||||
1,1,0,1, 0,0,1,0, 0,0,0,0, 0,0,0,1, // 0xD2, 0x01
|
||||
1,0,0,1, 1,1,1,0, 0,1,1,0, 1,0,1,1, // 0x9E, 0x6B
|
||||
0,1,0,0, 1,1,1,1, 0,0,1,0, 1,0,1,0, // 0x4F, 0x2A
|
||||
1,1,0,1, 0,1,0,1, 0,1,1,1, 1,0,0,1, // 0xD5, 0x79
|
||||
1,0,1,0, 0,1,0,1, 1,1,1,0, 0,0,0,0, // 0xA5, 0xE0
|
||||
0,0,0,0, 1,1,0,0, 1,1,0,0, 0,0,1,1, // 0x0C, 0xC3
|
||||
1,1,1,1, 0,0,1,1, 0,1,0,1, 0,1,0,1, // 0xF3, 0x55
|
||||
1,1,0,1, 0,0,1 // 0xD2
|
||||
};
|
||||
|
||||
short int walsh_matrix[8][7] = {
|
||||
{0,0,0,0,0,0,0},{1,0,1,0,1,0,1},{0,1,1,0,0,1,1},{1,1,0,0,1,1,0},
|
||||
{0,0,0,1,1,1,1},{1,0,1,1,0,1,0},{0,1,1,1,1,0,0},{1,1,0,1,0,0,1}
|
||||
};
|
||||
|
||||
short int pseudo_sequence[51] =
|
||||
{
|
||||
1,1,1,0, 0,0,0,1, 0,1,0,1, 0,1,1,1, // 0xE1, 0x57
|
||||
1,1,1,0, 0,1,1,0, 1,1,0,1, 0,0,0,0, // 0xE6, 0xD0
|
||||
0,0,0,1, 1,0,0,1, 0,0,0,1, 0,1,0,1, // 0x19, 0x15
|
||||
0,1,1 // 0x60
|
||||
};
|
||||
|
||||
char before_scramble_target[52] =
|
||||
"000000000110110001101111000011110001111000001100100";
|
||||
|
||||
short int before_WH_target[52] =
|
||||
{
|
||||
1,1,1,0, 0,0,0,1, 0,0,1,1, 1,0,1,1, // 0xE1, 0x3B
|
||||
1,0,0,0, 1,0,0,1, 1,1,0,1, 1,1,1,1, // 0x89, 0xDF
|
||||
0,0,0,0, 0,1,1,1, 0,0,0,1, 1,0,0,1, // 0x07, 0x19
|
||||
1,1,1 // 0xE0
|
||||
};
|
||||
|
||||
char packed_target[29] ="0000011011000110111100001111"; //0x0606F0F
|
||||
|
||||
char call_target[7] = "AA1AA ";
|
||||
|
||||
// **** Grobal variables ****
|
||||
short int symbol[239]; // to be decode
|
||||
short int interleaved[119];
|
||||
short int before_interleave[119];
|
||||
short int error_position[239]; // does not use in V1.0.0
|
||||
short int before_WH[51];
|
||||
char before_scramble[51];
|
||||
char packed[28];
|
||||
char call[7];
|
||||
short int DEBUG = 0;
|
||||
|
||||
// **** functions ****
|
||||
void decode_opera(short int symbol[239]);
|
||||
void manchester_decode(short int symbol[239], short int interleaved[119]);
|
||||
void de_interleave(short int interleaved[119], short int before_interleave[119]);
|
||||
void de_walsh_matrix(short int before_interleave[119], short int before_WH[51]);
|
||||
void de_scramble(short int befor_WH[51], char before_scramble[51]);
|
||||
void de_crc(char before_scramble[51], char packed[28]);
|
||||
void generate_crc(char datas[28], char crc[17], int length);
|
||||
void unpack(char packed[28], char call[7]);
|
||||
char de_normalizer(int bc, int byte_num);
|
||||
void print_help();
|
||||
void print_short_int(const char* caption, short int* code, int length);
|
||||
void print_str(const char* caption, char* code);
|
||||
void strcpy_w(char * s1, char * s2, int length);
|
||||
void strcat_w(char * s1, char * s2, int lenS1, int lenS2);
|
||||
|
||||
//**********************************
|
||||
int main(int argc, char* argv[])
|
||||
//**********************************
|
||||
{
|
||||
char s1 = 0x00;
|
||||
int i;
|
||||
|
||||
printf("argc=%d\n", argc);
|
||||
switch(argc)
|
||||
{
|
||||
case 1 : // Help required
|
||||
{
|
||||
printf("%s\n","More argument is required !");
|
||||
print_help();
|
||||
return 0;
|
||||
}
|
||||
case 2 : // 2 arguments
|
||||
{
|
||||
s1 = (char) argv[1][0];
|
||||
|
||||
if ((s1 == '?') && (argv[1][1] == 0x00))
|
||||
{
|
||||
printf("%s\n", "Help selected");
|
||||
print_help();
|
||||
return 0;
|
||||
}
|
||||
else if ((s1 == 'd' || s1 == 's' || s1 == 'w') && (argv[1][1] == 0x00))
|
||||
{
|
||||
if (s1 =='d')
|
||||
{
|
||||
printf("%s\n", "Debug selected.");
|
||||
DEBUG = 1;
|
||||
for (i = 0; i < 239; i++)
|
||||
symbol[i] = call_AA1AA[i];
|
||||
decode_opera(symbol);
|
||||
DEBUG = 0;
|
||||
return 0;
|
||||
}
|
||||
else if (s1 == 's')
|
||||
{
|
||||
printf("%s\n", "Sample selected.");
|
||||
for (i = 0; i < 239; i++)
|
||||
symbol[i] = call_F5OEO[i];
|
||||
decode_opera(symbol);
|
||||
DEBUG = 0;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s\n", "Sample 7L1RLL selected.");
|
||||
DEBUG = 0;
|
||||
for (i = 0; i < 239; i++)
|
||||
symbol[i] = call_7L1RLL[i];
|
||||
decode_opera(symbol);
|
||||
DEBUG = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
default : // 3 arguments
|
||||
{
|
||||
printf("%s\n", "Too many arguments.");
|
||||
print_help();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} // end of _tmain()
|
||||
|
||||
//**************************************************
|
||||
void decode_opera(short int * symbol)
|
||||
//**************************************************
|
||||
{
|
||||
print_short_int("symbol given =", symbol, 239);
|
||||
manchester_decode(symbol, interleaved);
|
||||
print_short_int("de_manchester code =", interleaved, 119);
|
||||
if (DEBUG)
|
||||
print_short_int("de_manchester_target =", interleave_target, 119);
|
||||
de_interleave(interleaved, before_interleave);
|
||||
print_short_int("de_interleave =", before_interleave, 119);
|
||||
if (DEBUG)
|
||||
print_short_int("de_interleave_target =", before_interleave_target, 119);
|
||||
de_walsh_matrix(before_interleave, before_WH);
|
||||
print_short_int("de_Walsh-Hamadard =", before_WH, 51);
|
||||
if (DEBUG)
|
||||
print_short_int("de_WH_target =", before_WH_target, 51);
|
||||
de_scramble(before_WH, before_scramble);
|
||||
print_str("de_scramble = ", before_scramble);
|
||||
if (DEBUG)
|
||||
print_str("de_scramble_target = ", before_scramble_target);
|
||||
de_crc(before_scramble, packed);
|
||||
print_str("de_CRC = ", packed);
|
||||
if (DEBUG)
|
||||
print_str("de_CRC_target = ", packed_target);
|
||||
unpack(packed, call);
|
||||
printf("unpached call = %s\n", call);
|
||||
if (DEBUG)
|
||||
printf("call_target = %s\n", call_target);
|
||||
} // end of decode_opera()
|
||||
|
||||
//***********************************************************************
|
||||
void manchester_decode(short int* symbol, short int* symbol_interleaving)
|
||||
//***********************************************************************
|
||||
{
|
||||
int i = 0;
|
||||
int idx = 0; // delete start 2 bit
|
||||
|
||||
while (idx < 238)
|
||||
{
|
||||
if ((symbol[idx + 1] == 1) && (symbol[idx + 2] == 0))
|
||||
{
|
||||
symbol_interleaving[i] = (short) 0;
|
||||
}
|
||||
else if ((symbol[idx + 1] == 0) && (symbol[idx + 2] == 1))
|
||||
{
|
||||
symbol_interleaving[i] = (short) 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
error_position[idx] = (short) 1;
|
||||
}
|
||||
i++; idx += 2;
|
||||
}
|
||||
} // end of manchester_decode()
|
||||
|
||||
//************************************************************************
|
||||
void de_interleave(short int* interleaved, short int* before_interleave)
|
||||
//************************************************************************
|
||||
{
|
||||
int i =0, idx = 0, j = 0;
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
for (j = i; j < 119; j += 7)
|
||||
{
|
||||
before_interleave[j] = interleaved[idx];
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
} // end of de_interleave
|
||||
|
||||
//*********************************************************************
|
||||
void de_walsh_matrix(short int* vector_to_tx, short int* symbol_coding)
|
||||
//*********************************************************************
|
||||
{ // 119 bit to 51 bit
|
||||
int idx = 0, i, j, k, data = 0;
|
||||
short int temp[7];
|
||||
|
||||
for (i = 0; i < 119; i += 7)
|
||||
{
|
||||
for(j = 0; j < 7; j++) temp[j] = vector_to_tx[i + j];
|
||||
temp[7]=0x00;
|
||||
|
||||
// search the value for match
|
||||
data = 0;
|
||||
for (k = 0; k < 7; k++)
|
||||
{
|
||||
if (k < 6)
|
||||
{
|
||||
data = data + (int) pow((double)(temp[k]*2), (6 - k));
|
||||
}
|
||||
else if (k == 6)
|
||||
{
|
||||
if (temp[6] == 1) data = data + 1;
|
||||
}
|
||||
}
|
||||
if (data == 0) // 0000000 = 0
|
||||
{
|
||||
symbol_coding[idx + 0] = 0;
|
||||
symbol_coding[idx + 1] = 0;
|
||||
symbol_coding[idx + 2] = 0;
|
||||
}
|
||||
else if (data == 85) // 1010101 = 2^6 + 2^4 + 2^2 + 1 = 85
|
||||
{
|
||||
symbol_coding[idx + 0] = 0;
|
||||
symbol_coding[idx + 1] = 0;
|
||||
symbol_coding[idx + 2] = 1;
|
||||
}
|
||||
else if (data == 51) // 0110011 = 2^5 + 2^4 + 2 + 1 = 51
|
||||
{
|
||||
symbol_coding[idx + 0] = 0;
|
||||
symbol_coding[idx + 1] = 1;
|
||||
symbol_coding[idx + 2] = 0;
|
||||
}
|
||||
else if (data == 102) // 1100110 = 2^6 + 2^5 + 2^2 + 2 = 102
|
||||
{
|
||||
symbol_coding[idx + 0] = 0;
|
||||
symbol_coding[idx + 1] = 1;
|
||||
symbol_coding[idx + 2] = 1;
|
||||
}
|
||||
else if (data == 15) // 0001111 = 2^3 + 2^2 + 2 + 1 = 15
|
||||
{
|
||||
symbol_coding[idx + 0] = 1;
|
||||
symbol_coding[idx + 1] = 0;
|
||||
symbol_coding[idx + 2] = 0;
|
||||
}
|
||||
else if (data == 90) // 1011010 = 2^6 + 2^4 + 2^3 + 2 = 90
|
||||
{
|
||||
symbol_coding[idx + 0] = 1;
|
||||
symbol_coding[idx + 1] = 0;
|
||||
symbol_coding[idx + 2] = 1;
|
||||
}
|
||||
else if (data == 60) //0111100 = 2^5 + 2^4 + 2^3 + 2^2 = 60
|
||||
{
|
||||
symbol_coding[idx + 0] = 1;
|
||||
symbol_coding[idx + 1] = 1;
|
||||
symbol_coding[idx + 2] = 0;
|
||||
}
|
||||
else if (data == 105) // 1101001 = 2^6 + 2^5 + 2^3 + 1 = 105
|
||||
{
|
||||
symbol_coding[idx + 0] = 1;
|
||||
symbol_coding[idx + 1] = 1;
|
||||
symbol_coding[idx + 2] = 1;
|
||||
}
|
||||
else printf("xxxx");
|
||||
|
||||
idx +=3;
|
||||
|
||||
}
|
||||
} // enf of de-WH
|
||||
|
||||
//************************************************************
|
||||
void de_scramble(short int * vector_to_tx, char * vector)
|
||||
//************************************************************
|
||||
{ // | 51 bit | to | 51 bit |
|
||||
short int vector_temp[51];
|
||||
int i;
|
||||
|
||||
// convert binary to ASCII
|
||||
for (i = 0; i < 51; i++)
|
||||
{
|
||||
vector_temp[i] = vector_to_tx[i] ^ pseudo_sequence[i];
|
||||
vector[i] = (char) vector_temp[i] + 0x30;
|
||||
}
|
||||
} //end of de_scramble()
|
||||
|
||||
//*************************************************
|
||||
void de_crc(char * vector, char * packed)
|
||||
//*************************************************
|
||||
{ // 51 bits to 28bits
|
||||
|
||||
char crc1[17], crc1a[17], crc2[4], crc2a[4];
|
||||
int i, crc_ok;
|
||||
char temp[52] = {0};
|
||||
|
||||
// extract packed from received data
|
||||
for (i = 0; i < 28; i++) //4..31 for packed
|
||||
packed[i] = temp[i] = vector[i + 4];
|
||||
packed[28] = temp[28] = 0x00;
|
||||
|
||||
if (DEBUG)
|
||||
print_str("temp in de_crc = ", temp);
|
||||
if (DEBUG)
|
||||
print_str("packed in de_crc = ", packed);
|
||||
|
||||
// extract crc1 from received data
|
||||
for (i = 0; i < 16; i++) //32..47 for crc1
|
||||
crc1[i] = vector[i + 32];
|
||||
crc1[16] = 0x00;
|
||||
|
||||
if (DEBUG)
|
||||
print_str("crc1 exracted from received data = ", crc1);
|
||||
|
||||
//crc2 extracted from received data
|
||||
for (i = 0; i < 3; i++) //48..50 for crc2
|
||||
crc2[i] = vector[i + 48];
|
||||
crc2[3] = 0x00;
|
||||
|
||||
if (DEBUG)
|
||||
print_str("crc2 extracted from received data = ", crc2);
|
||||
|
||||
generate_crc(temp, crc1a, 16);
|
||||
if (DEBUG)
|
||||
print_str("temp before crc add = ", temp);
|
||||
if (DEBUG)
|
||||
print_str("crc1a calcurated = ", crc1a);
|
||||
strcat_w(temp, crc1a, 28, 16); // 28 + 16 = 44
|
||||
|
||||
generate_crc(temp, crc2a, 3);
|
||||
strcat_w(temp, crc2a, 44, 3); // 44 + 3 = 47
|
||||
|
||||
// verify crc1 and crc2
|
||||
crc_ok = 1;
|
||||
for (i = 0; i < 16; i++)
|
||||
if (crc1[i] != crc1a[i]) crc_ok = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
if (crc2[i] != crc2a[i]) crc_ok = 0;
|
||||
if (crc_ok)
|
||||
printf("CRC : OK\n");
|
||||
else
|
||||
{
|
||||
printf("CRC : No good\n");
|
||||
print_str("crc1a calcurated = ", crc1a);
|
||||
print_str("crc1_received = ", crc1);
|
||||
print_str("crc2a calcurated = ", crc2a);
|
||||
print_str("crc2a_received = ", crc2);
|
||||
}
|
||||
|
||||
} //end of de_crc()
|
||||
|
||||
//************************************************************************
|
||||
void generate_crc(char * datas, char * crc, int length)
|
||||
//************************************************************************
|
||||
{ // 32 + 16(length) = 48 or 48 + 3(length) = 51
|
||||
// CRC16-IBM : Polynominal = X16+X15+X2+1 = 1000 0000 0000 0101
|
||||
// This function is a copy of JUMA TX136/500 control program
|
||||
// whitch was written by F4GCB (Patrick). Thanks Patrick.
|
||||
|
||||
int i, j, k, len;
|
||||
char buffer[52];
|
||||
short int wcrc[17] = {0}, byte1 = 0, byte2 = 0;
|
||||
|
||||
len = strlen(datas);
|
||||
for (i = 0; i < len; i++)
|
||||
buffer[i] = datas[i];
|
||||
buffer[len] = 0x00;
|
||||
if (DEBUG)
|
||||
print_str("input datas in generate_crc =", buffer);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if (j > 0) buffer[i] = buffer[i] >> 1;
|
||||
byte1 = buffer[i] & 0x01;
|
||||
byte2 = byte1 ^ wcrc[0]; // XOR with X16
|
||||
wcrc[0] = byte2 ^ wcrc[1]; // XOR with X15
|
||||
for (k = 1; k < 13; k++)
|
||||
wcrc[k] = wcrc[k + 1];
|
||||
wcrc[13] = byte2 ^ wcrc[14]; // XOR with X2
|
||||
wcrc[14] = wcrc[15]; //
|
||||
wcrc[15] = byte2; //
|
||||
}
|
||||
}
|
||||
|
||||
// if msb byte crc = 0 then value at 27
|
||||
byte2 = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
byte2 = byte2 + (int)(wcrc[i] * pow (2.0, i));
|
||||
if (byte2 == 0) byte2 = 27; // 0x1B = 0b0001 1011
|
||||
|
||||
// if lsb byte crc = 0 then value at 43
|
||||
byte1 = 0;
|
||||
for (i = 8; i < 16; i++)
|
||||
byte1 = byte1 + (int)(wcrc[i] * pow(2.0, i - 8));
|
||||
if (byte1 == 0) byte1 = 43; // 0x2B = 0b0010 1011
|
||||
|
||||
if (DEBUG)
|
||||
printf("byte1 before replace =%2x, byte2 =%2x\n", byte1, byte2);
|
||||
|
||||
// merge crc into a bit string
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if (i > 0) byte2 = byte2 >> 1;
|
||||
wcrc[7 - i] = byte2 & 0x01; // (binary)
|
||||
if (i > 0) byte1 = byte1 >> 1;
|
||||
wcrc[15 - i] = byte1 & 0x01; // (binary)
|
||||
}
|
||||
if (length > 16) length = 16;
|
||||
for (i = 16 - length; i < 16; i++)
|
||||
crc[i - (16 - length)] = wcrc[i] + 0x30;
|
||||
crc[length]= 0x00;
|
||||
if (DEBUG)
|
||||
print_str("crc =", crc);
|
||||
} // end of generate_crc()
|
||||
|
||||
//*************************************
|
||||
void unpack(char * packed, char * call)
|
||||
//*************************************
|
||||
{ // 28 bits to 48 bits
|
||||
int i;
|
||||
int temp;
|
||||
unsigned long code_sum = 0, remains = 0;
|
||||
|
||||
if (DEBUG)
|
||||
print_str("packed in unpack = ", packed);
|
||||
|
||||
// separate a string to coded callsign
|
||||
|
||||
for (i = 0; i < 28; i++)
|
||||
code_sum = code_sum + (unsigned long)(packed[27 - i] - '0') * pow(2.0, i);
|
||||
|
||||
// de_normalizer of callsign
|
||||
remains = 36*10*27*27*27;
|
||||
if (DEBUG)
|
||||
{
|
||||
printf(" 0 : code_sum = %9Lu\n", code_sum);
|
||||
printf(" 0 : remains = %9Lu\n", remains);
|
||||
}
|
||||
|
||||
if (code_sum > remains)
|
||||
{
|
||||
temp = code_sum / remains;
|
||||
code_sum %= remains;
|
||||
}
|
||||
else temp = 0;
|
||||
if (DEBUG)
|
||||
printf(" 0 : temp = %9Lu\n", temp);
|
||||
call[0] = de_normalizer(temp, 0);
|
||||
|
||||
remains = 10*27*27*27;
|
||||
if (DEBUG)
|
||||
{
|
||||
printf(" 1 : code_sum = %9Lu\n", code_sum);
|
||||
printf(" 1 : remains = %9Lu\n", remains);
|
||||
}
|
||||
if (code_sum >= remains)
|
||||
{
|
||||
temp = code_sum / remains;
|
||||
code_sum %= remains;
|
||||
}
|
||||
else temp = 0;
|
||||
if (DEBUG)
|
||||
printf(" 1 : temp = %9Lu\n", temp);
|
||||
call[1] = de_normalizer(temp, 1);
|
||||
|
||||
remains = 27*27*27;
|
||||
if (DEBUG)
|
||||
{
|
||||
printf(" 2 : code_sum = %9Lu\n", code_sum);
|
||||
printf(" 2 : remains = %9Lu\n", remains);
|
||||
}
|
||||
if (code_sum >= remains)
|
||||
{
|
||||
temp = code_sum / remains;
|
||||
code_sum %= remains;
|
||||
}
|
||||
else temp = 0;
|
||||
if (DEBUG)
|
||||
printf(" 2 : temp = %9Lu\n", temp);
|
||||
call[2] = de_normalizer(temp, 2);
|
||||
|
||||
remains = 27*27;
|
||||
if (DEBUG)
|
||||
{
|
||||
printf(" 3 : code_sum = %9Lu\n", code_sum);
|
||||
printf(" 3 : remains = %9Lu\n", remains);
|
||||
}
|
||||
if (code_sum >= remains)
|
||||
{
|
||||
temp = code_sum / remains;
|
||||
code_sum %= remains;
|
||||
}
|
||||
else temp = 0;
|
||||
if (DEBUG)
|
||||
printf(" 3 : temp = %9Lu\n", temp);
|
||||
call[3] = de_normalizer(temp, 3);
|
||||
|
||||
remains = 27;
|
||||
if (DEBUG)
|
||||
{
|
||||
printf(" 4 : code_sum = %9Lu\n", code_sum);
|
||||
printf(" 4 : remains = %9Lu\n", remains);
|
||||
}
|
||||
if (code_sum >= remains)
|
||||
{
|
||||
temp = code_sum / remains;
|
||||
code_sum %= remains;
|
||||
}
|
||||
else temp = 0;
|
||||
if (DEBUG)
|
||||
printf(" 4 : temp = %9Lu\n", temp);
|
||||
call[4] = de_normalizer(temp, 4);
|
||||
|
||||
remains = 1;
|
||||
if (DEBUG)
|
||||
{
|
||||
printf(" 5 : code_sum = %9Lu\n", code_sum);
|
||||
printf(" 5 : remains = %9Lu\n", remains);
|
||||
}
|
||||
if (code_sum >= remains)
|
||||
{
|
||||
temp = code_sum;
|
||||
//code_sum %= remains;
|
||||
}
|
||||
else temp = 0;
|
||||
if (DEBUG)
|
||||
printf(" 5 : temp = %9Lu\n", temp);
|
||||
call[5] = de_normalizer(temp, 5);
|
||||
|
||||
call[6] = 0x00;
|
||||
} // end of unpack
|
||||
|
||||
//********************************
|
||||
char de_normalizer(int bc, int n)
|
||||
//********************************
|
||||
{
|
||||
char cc = 0;
|
||||
|
||||
if (DEBUG)
|
||||
printf(" %u : input of de_normalizer, bc = %9Lu\n", n, bc);
|
||||
switch (n)
|
||||
{
|
||||
case 0 :
|
||||
{
|
||||
if (bc == 0) cc = ' ';
|
||||
else if (bc >= 1 && bc <= 26) cc = bc - 1 +'A';
|
||||
else if (bc >= 27 && bc <= 37) cc = bc - 27 + '0';
|
||||
break;
|
||||
}
|
||||
case 1 :
|
||||
{
|
||||
if (bc >= 0 && bc <= 25) cc = bc + 'A';
|
||||
else if (bc >= 26 && bc <= 36) cc = bc - 26 + '0';
|
||||
break;
|
||||
}
|
||||
case 2 :
|
||||
{
|
||||
if (bc >= 0 && bc <= 9) cc = bc + '0';
|
||||
break;
|
||||
}
|
||||
case 3: case 4: case 5:
|
||||
{
|
||||
if (bc == 0) cc = ' ';
|
||||
else if (bc >= 1 && bc <= 26) cc = bc - 1 + 'A';
|
||||
break;
|
||||
}
|
||||
default : break;
|
||||
}
|
||||
if (DEBUG)
|
||||
printf(" %u : output of de_normalizer, cc = %c\n", n, cc);
|
||||
return (cc);
|
||||
} // end of de _normlizer
|
||||
|
||||
//********************************************************************
|
||||
void print_short_int(const char *caption, short int *code, int length)
|
||||
//********************************************************************
|
||||
{ // This is a service function for debugging
|
||||
int i = 0;
|
||||
|
||||
printf("%s\n", caption);
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
printf("%u", code[i]);
|
||||
if (((i + 1) % 4) == 0) printf(" ");
|
||||
if (((i + 1) % 40) == 0) printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
} // end fo print_short_int
|
||||
|
||||
//********************************************************************
|
||||
void print_short_char(const char * caption, char * code, int length)
|
||||
//********************************************************************
|
||||
{ // This is a service function for debugging
|
||||
int i = 0;
|
||||
|
||||
printf("%s\n", caption);
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
printf("%c", code[i]);
|
||||
if (((i + 1) % 4) == 0) printf(" ");
|
||||
if (((i + 1) % 40) == 0) printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
} // end fo print_short_char
|
||||
|
||||
//********************************************************************
|
||||
void print_str(const char * caption, char * code)
|
||||
//********************************************************************
|
||||
{ // This is a service function for debugging
|
||||
int i = 0;
|
||||
|
||||
printf("%s\n", caption);
|
||||
for (i = 0; i < strlen(code); i++)
|
||||
{
|
||||
printf("%c", code[i]);
|
||||
if (((i + 1) % 4) == 0) printf(" ");
|
||||
if (((i + 1) % 40) == 0) printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
} // end fo print_char
|
||||
//*******************************************************
|
||||
void strcpy_w(char * s1, char * s2, int length)
|
||||
//*******************************************************
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
s1[i] = s2[i];
|
||||
s1[length] = 0x00;
|
||||
} // end of strcpy_w
|
||||
|
||||
//****************************************************************
|
||||
void strcat_w(char * s1, char * s2, int lenS1, int lenS2)
|
||||
//****************************************************************
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lenS2; i++)
|
||||
s1[i + lenS1] = s2[i];
|
||||
s1[lenS1 + lenS2]= 0x00;
|
||||
|
||||
} // end of strcat_w()
|
||||
|
||||
//***************
|
||||
void print_help()
|
||||
//***************
|
||||
{
|
||||
printf("%s\n","Usage : OPERA_Decode_Test [ ? | d | s | w]");
|
||||
printf("%s\n"," Help : OPERA_Decode_Test ?");
|
||||
printf("%s\n"," Debug : OPERA_Decode_Test d");
|
||||
printf("%s\n"," AA1AA : OPERA_Decode_Test s");
|
||||
printf("%s\n"," 7L1RLL : OPERA_Decode_Test w");
|
||||
printf("%s\n"," Sample callsign is \"AA1AA\". ");
|
||||
} // end of help
|
||||
|
||||
//************** End of Program **************************************
|
Plik binarny nie jest wyświetlany.
|
@ -0,0 +1,80 @@
|
|||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
char* itoa(unsigned long val, int n, char* buf, int radix)
|
||||
{
|
||||
char c[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
int i = 0;
|
||||
while (n-i) {
|
||||
unsigned long d = (unsigned long)pow(radix, n-i-1);
|
||||
buf[i++] = c[val/d];
|
||||
val = val%d;
|
||||
}
|
||||
buf[i] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
int crc16op(char* msg, int n)
|
||||
{
|
||||
int i,j,crc=0; // crc-16 (0x8005 poly, flip in and out, 2 zero bytes in tail) of msg[0..n-1]
|
||||
for(i=0;i!=n+2;i++){
|
||||
|
||||
for(j=0;j!=8;j++)
|
||||
crc = crc&1 ? (crc>>1) ^ 0xa001 : crc>>1;
|
||||
}
|
||||
// replace, swap and store crc in msg[32..48]
|
||||
crc = crc&0xff00 ? ( crc&0x00ff ? crc : 0x001b|(crc&0xff00) ) : 0x2b00|(crc&0x00ff);
|
||||
crc = ((crc&0x00ff)<<8); // amp="amp" crc="crc" xff00="xff00">>8);
|
||||
return crc;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]){
|
||||
if(argc != 2){
|
||||
printf("usage: opera [callsign]\n");
|
||||
return 0;
|
||||
}
|
||||
const char* call = argv[1];
|
||||
char msg[239];
|
||||
int i,j;
|
||||
|
||||
char c[]=" "; //align last prefix digit at c[2] and fill gaps with blanks
|
||||
int aligned = isdigit(call[2]);
|
||||
strncpy(aligned ? c : &c[1], call, aligned ? 6 : 5);
|
||||
//strupr(c); To implement : for now warning, should be in CAPITAL
|
||||
|
||||
unsigned long n1=(c[0]>='0'&&c[0]<='9'?c[0]-'0'+27:c[0]==' '?0:c[0]-'A'+1); // packing call e.g. " K1JT ", "AA1AA " into n1
|
||||
n1=36*n1+(c[1]>='0'&&c[1]<='9'?c[1]-'0'+26:c[1]-'A');
|
||||
n1=10*n1+c[2]-'0';
|
||||
n1=27*n1+(c[3]==' '?0:c[3]-'A'+1);
|
||||
n1=27*n1+(c[4]==' '?0:c[4]-'A'+1);
|
||||
n1=27*n1+(c[5]==' '?0:c[5]-'A'+1);
|
||||
itoa(n1, 28, &msg[4], 2); //msg[4..32] = binary representation n1 in ASCII
|
||||
itoa(crc16op(&msg[4], 28), 16, &msg[32], 2); //store bin-crc of msg[4..31] in msg[32..47]
|
||||
itoa(crc16op(&msg[4], 28+16) & 0x07, 3, &msg[48], 2); //store bin-crc of msg[4..47] in msg[48..51]
|
||||
msg[0]=msg[1]=msg[2]=msg[3]='0'; //unused bits msg[0-3]
|
||||
|
||||
const char* prn_vec = "111000010101011111100110110100000001100100010101011";
|
||||
for(i=0; i!=51; i++) //scramble
|
||||
msg[i] = ((msg[i]-'0') ^ (prn_vec[i]-'0')) +'0';
|
||||
|
||||
const char* wh[] = {"0000000", "1010101", "0110011", "1100110", "0001111", "1011010", "0111100", "1101001"};
|
||||
for(i=(51/3)-1; i>=0; i--){ // Walsh-Hadamard encoding to msg[0..118]
|
||||
char b = (msg[i*3+0]-'0')*4+(msg[i*3+1]-'0')*2+(msg[i*3+2]-'0')*1;
|
||||
for(j=0; j!=7;j++)
|
||||
msg[i*7+j] = wh[b][j];
|
||||
}
|
||||
|
||||
for(i=0; i!=7; i++) // interleave 7x17 to msg[121..240]
|
||||
for(j=0; j!=17; j++)
|
||||
msg[121+j+17*i] = msg[i+7*j];
|
||||
|
||||
for(i=0; i!=119; i++){ // Manchester encoding to msg[2..120]
|
||||
msg[2*i+1+2] = msg[121+i];
|
||||
msg[2*i+0+2] = (msg[2*i+1+2] == '0') + '0';
|
||||
}
|
||||
msg[0] = msg[1] ='1'; // head
|
||||
msg[239] = '\0'; // tail
|
||||
|
||||
printf("message=%s symbols=%s\n", c, msg);
|
||||
}
|
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
|
@ -0,0 +1,531 @@
|
|||
//******************************************************************************
|
||||
// OPERA_Coding_Test.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
// Purpose : Algorithm testing by a laptop computer before implementation
|
||||
// into PIC micro processor.
|
||||
//
|
||||
// Usage: "OPERA_Coding_Test [? | d | s] ["callsign"]";
|
||||
// where : s = help, d = debug and s = sample";
|
||||
//
|
||||
// Version 1.0.4, 2015/11/29: Modified print format
|
||||
// Version 1.0.3, 2015/11/13: Delete an additional start bit for decoder
|
||||
// Version 1.0.2, 2015/11/11: Add Visual C++ directives
|
||||
// Version 1.0.1, 2015/11/10: Changed help message
|
||||
// Version 1.0.0, 2015/11/07: Initial Release
|
||||
//
|
||||
// Copyright(C) 2015 F4GCB
|
||||
// Partial copyright (C)2015 7L1RLL
|
||||
//
|
||||
// Environment : Microsoft Visual C++ 2010 Express under Windows 10.
|
||||
// Compiler version 10.0.40219.1 SP1Rel
|
||||
//
|
||||
// Acknowledgement :
|
||||
// 1)Portion of this OPERA is derived from the work of EA5HVK.
|
||||
// 2)All functions of this program are a copy of JUMA-TX500/136
|
||||
// Transmitter Controller which written by F4GCB.
|
||||
//******************************************************************************
|
||||
|
||||
//#include "stdafx.h"
|
||||
//#include <locale.h>
|
||||
//#include <tchar.h>
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include "stdint.h"
|
||||
#include "math.h"
|
||||
|
||||
//#define __VCpp__ TRUE
|
||||
|
||||
// Grobal Variables
|
||||
|
||||
int FileFreqTiming;
|
||||
// Test program using SNDFILE
|
||||
// see http://www.mega-nerd.com/libsndfile/api.html for API
|
||||
|
||||
void WriteTone(double Frequency,uint32_t Timing)
|
||||
{
|
||||
typedef struct {
|
||||
double Frequency;
|
||||
uint32_t WaitForThisSample;
|
||||
} samplerf_t;
|
||||
samplerf_t RfSample;
|
||||
|
||||
RfSample.Frequency=Frequency;
|
||||
RfSample.WaitForThisSample=Timing; //en 100 de nanosecond
|
||||
//printf("Freq =%f Timing=%d\n",RfSample.Frequency,RfSample.WaitForThisSample);
|
||||
if (write(FileFreqTiming,&RfSample,sizeof(samplerf_t)) != sizeof(samplerf_t)) {
|
||||
fprintf(stderr, "Unable to write sample\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static const short int pseudo_sequence[51] = {
|
||||
1,1,1,0,0,0,0,1,0,1, 0,1,0,1,1,1,1,1,1,0, 0,1,1,0,1,1,0,1,0,0, 0,0,0,0,0,1,1,0,0,1,
|
||||
0,0,0,1,0,1,0,1,0,1, 1
|
||||
};
|
||||
static short int walsh_matrix[8][7] = {
|
||||
{0,0,0,0,0,0,0},{1,0,1,0,1,0,1},{0,1,1,0,0,1,1},{1,1,0,0,1,1,0},
|
||||
{0,0,0,1,1,1,1},{1,0,1,1,0,1,0},{0,1,1,1,1,0,0},{1,1,0,1,0,0,1}
|
||||
};
|
||||
static short int symbol[239];
|
||||
char call[7], call_coded[45], vector[52];
|
||||
short int vector_to_tx[51];
|
||||
short int symbol_interleaving[119], symbol_coding[119];
|
||||
short int DEBUG = 0;
|
||||
const char sampleCall[7] = "AA1AA";
|
||||
|
||||
// Declaration of functions
|
||||
|
||||
void genn_opera(void);
|
||||
void generate_call(char call[7], char call_coded[45]);
|
||||
void add_crc16(char call_coded[45], char vector[52]);
|
||||
void scramble(char vector[52], short int symbol_coding[119]);
|
||||
void Walsh_Hammered_code(short int symbol_coding[119], short int vector_to_tx[51]);
|
||||
void interleave(short int vector_to_tx[51], short int symbol_interleaving[119]);
|
||||
void ManchesterEncode(short int symbol_interleaving[119], short int symbol[239]);
|
||||
char chr_norm_opera(char bc);
|
||||
void print_help(void);
|
||||
void print_short_int(const char caption[], short int code[239], int length);
|
||||
void print_str(const char caption[250], char code[52]);
|
||||
void strcpy_w(char s1[52], char s2[52], int length);
|
||||
void strcat_w(char s1[52], char s2[52], int lenS1, int lenS2);
|
||||
void encodepitx(short int *code, int length,float Nop);
|
||||
|
||||
#ifdef __VCpp__
|
||||
//**********************************
|
||||
// main forVisual C++
|
||||
int _tmain(int argc, _TCHAR* argv[])
|
||||
//**********************************
|
||||
{
|
||||
_tsetlocale(LC_ALL, _T("")); //Change Unicode to OS-Default locale
|
||||
#else
|
||||
int main(int argc, char* argv[])
|
||||
//**********************************
|
||||
{
|
||||
#endif
|
||||
int i = 0;
|
||||
char s1 = 0x00, s2[7] = "";
|
||||
|
||||
|
||||
switch (argc)
|
||||
{
|
||||
case 1 : // Help required
|
||||
case 2 : // Help required
|
||||
{
|
||||
printf("Usage : %s CALLSIGN file.rfa \n", argv[0]);
|
||||
//print_help();
|
||||
return 0;
|
||||
}
|
||||
case 3: // 2 arguments
|
||||
{
|
||||
s1 = (char)argv[1][0];
|
||||
if ((s1 == 's') && (argv[1][1] == 0x00)) // sample callsign
|
||||
{
|
||||
printf("%s\n","A sample callsign is used.");
|
||||
DEBUG = 0; i = 0;
|
||||
while (sampleCall[i] != 0 && i < 7)
|
||||
{
|
||||
call[i] = sampleCall[i]; call[++i] = 0x00;
|
||||
}
|
||||
genn_opera();
|
||||
return 0;
|
||||
}
|
||||
else if ((s1 =='?') && (argv[1][1] == 0x00))
|
||||
{
|
||||
printf("%s\n","Help requested");
|
||||
print_help();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// range check
|
||||
if (!((argv[1][0] >= '0' && argv[1][0] <= '9') || (argv[1][0] >= 'A' && argv[1][0] <= 'Z') ||
|
||||
(argv[1][0] >= 'a' && argv[1][0] <= 'z')))
|
||||
{
|
||||
printf("%s\n","Callsign must be began with an alphan/numeric character");
|
||||
print_help();
|
||||
return 0;
|
||||
}
|
||||
DEBUG = 0; i = 0;
|
||||
while (argv[1][i] != 0 && i < 7)
|
||||
{
|
||||
call[i] = argv[1][i]; call[++i] = 0x00;
|
||||
}
|
||||
|
||||
FileFreqTiming = open( argv[2], O_WRONLY|O_CREAT, 0644);
|
||||
genn_opera();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
printf("%s\n", "Too many arguments.");
|
||||
print_help();
|
||||
break;
|
||||
}
|
||||
} // end of switch argc
|
||||
return 0;
|
||||
} // end of _tmain
|
||||
|
||||
//*******************
|
||||
void genn_opera(void)
|
||||
//*******************
|
||||
{
|
||||
printf("\nCallsign = %s\n", call);
|
||||
|
||||
generate_call(call, call_coded);
|
||||
if (DEBUG)
|
||||
print_str("call_coded =", call_coded);
|
||||
|
||||
add_crc16(call_coded, vector);
|
||||
|
||||
if (DEBUG)
|
||||
print_str("crc16 vector =", vector);
|
||||
|
||||
scramble(vector, vector_to_tx);
|
||||
if (DEBUG)
|
||||
print_short_int("vector_to_tx =", vector_to_tx, 44);
|
||||
|
||||
Walsh_Hammered_code(vector_to_tx, symbol_coding);
|
||||
if (DEBUG)
|
||||
print_short_int("symbol_coding =", symbol_coding, 119);
|
||||
|
||||
interleave(symbol_coding, symbol_interleaving);
|
||||
if (DEBUG)
|
||||
print_short_int("symbol_interleaving =", symbol_interleaving, 119);
|
||||
|
||||
ManchesterEncode(symbol_interleaving, symbol);
|
||||
print_short_int("symbol =", symbol, 239);
|
||||
encodepitx(symbol,239,1);
|
||||
|
||||
} // genn_opera
|
||||
|
||||
//****************************************************
|
||||
// Normalize characters space S..Z 0..9 in order 0..36
|
||||
char chr_norm_opera(char bc)
|
||||
//****************************************************
|
||||
{
|
||||
char cc = 0;
|
||||
|
||||
if (bc >= '0' && bc <= '9') cc = bc - '0' + 27;
|
||||
if (bc >= 'A' && bc <= 'Z') cc = bc - 'A' + 1;
|
||||
if (bc >= 'a' && bc <= 'z') cc = bc - 'a' + 1;
|
||||
if (bc == ' ') cc = 0;
|
||||
|
||||
return (cc);
|
||||
} // enf of chr_norm_opera
|
||||
|
||||
//**********************************************
|
||||
void generate_call(char *call, char *call_coded)
|
||||
//**********************************************
|
||||
{
|
||||
int i;
|
||||
unsigned long code_sum;
|
||||
|
||||
//the thired character must always be a number
|
||||
if (chr_norm_opera(call[2]) < 27)
|
||||
{
|
||||
for (i=5; i> 0; i--) call[i] = call[i-1];
|
||||
call[0]=' ';
|
||||
}
|
||||
|
||||
// the call must always have 6 characters
|
||||
for (i=strlen(call); i < 6; i++)
|
||||
call[i] = ' ';
|
||||
call[6] = 0x00;
|
||||
|
||||
if (DEBUG) printf("NormalizedCall=%s\n", call);
|
||||
code_sum = chr_norm_opera(call[0]);
|
||||
code_sum = code_sum * 36 + chr_norm_opera(call[1]) - 1;
|
||||
code_sum = code_sum * 10 + chr_norm_opera(call[2]) - 27;
|
||||
code_sum = code_sum * 27 + chr_norm_opera(call[3]);
|
||||
code_sum = code_sum * 27 + chr_norm_opera(call[4]);
|
||||
code_sum = code_sum * 27 + chr_norm_opera(call[5]);
|
||||
|
||||
if (DEBUG) printf("code_sum=%Lu\n", code_sum);
|
||||
|
||||
// merge coded callsign ino a string
|
||||
call_coded[28] = 0x00;
|
||||
call_coded[27] = (short int) ((code_sum & 0x01) + 0x30);
|
||||
for (i = 26; i >= 0; i--)
|
||||
{
|
||||
code_sum = code_sum >> 1;
|
||||
call_coded[i] = (short int)((code_sum & 0x01) + 0x30);
|
||||
}
|
||||
} // end of pack_callsign
|
||||
|
||||
//***************************************************
|
||||
void generate_crc(char *datas, char *crc, int length)
|
||||
//***************************************************
|
||||
{
|
||||
unsigned int i, j, k;
|
||||
char buffer[52]; //strlen(datas)];
|
||||
short int wcrc[16] = {0}, byte1 = 0, byte2 = 0;
|
||||
|
||||
#ifdef __VCpp__
|
||||
strcpy_s(buffer, 52, datas);// strcpy(buffer, datas);
|
||||
#else
|
||||
strcpy(buffer, datas);// strcpy(buffer, datas);
|
||||
#endif
|
||||
if (DEBUG)
|
||||
print_str("buffer_crc = ", buffer);
|
||||
|
||||
for (i = 0; i < strlen(datas); i++)
|
||||
{
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if (j > 0) buffer[i] = buffer[i] >> 1;
|
||||
byte1 = buffer[i] & 0x01;
|
||||
byte2 = byte1 ^ wcrc[0];
|
||||
wcrc[0] = byte2 ^ wcrc[1];
|
||||
for (k = 1; k < 13; k++)
|
||||
wcrc[k] = wcrc[k+1];
|
||||
wcrc[13] = byte2 ^ wcrc[14];
|
||||
wcrc[14] = wcrc[15];
|
||||
wcrc[15] = byte2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if msb byte crc = 0 then value at 27
|
||||
byte2 = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
#ifdef __VCpp__ // add for Visual C++ by 7L1RLL 11/07/2015
|
||||
byte2 = byte2 + (short) wcrc[i] * pow((double)2.0, (int)i);
|
||||
#else
|
||||
byte2 = byte2 + wcrc[i] * pow(2, i);
|
||||
#endif
|
||||
if (byte2 == 0) byte2 =27;
|
||||
|
||||
// if lsb byte crc = 0 then value at 43
|
||||
byte1 = 0;
|
||||
for (i = 8; i < 16; i++)
|
||||
#ifdef __VCpp__
|
||||
byte1 = byte1 + (short) (wcrc[i] * (double)pow(2.0, (int)i - 8)); // add cast by 7L1RLL
|
||||
#else
|
||||
byte1 = byte1 + (wcrc[i] * pow(2, i - 8));
|
||||
#endif
|
||||
if (byte1 == 0) byte1 = 43;
|
||||
if (DEBUG) printf("byte1 = %x, byte2 = %x\n", byte1, byte2);
|
||||
|
||||
// merge crc into a string
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if (i > 0) byte2 = byte2 >> 1;
|
||||
wcrc[7 - i] = byte2 & 0x01;
|
||||
|
||||
if ( i > 0) byte1 = byte1 >> 1;
|
||||
wcrc[15 - i] = byte1 & 0x01;
|
||||
}
|
||||
if (length > 16) length = 16;
|
||||
for (i = 16 - length; i < 16; i++)
|
||||
crc[i - (16 - length)] = wcrc[i] + 0x30;
|
||||
crc[length] = 0x00;
|
||||
} // end of genarate_crc
|
||||
|
||||
//*********************************************
|
||||
void add_crc16(char * call_coded, char *vector)
|
||||
//*********************************************
|
||||
{ // input: |28 bits|, output : |51 bits|
|
||||
char crc1[17] = "", crc2[4] = "";
|
||||
|
||||
#ifdef __VCpp__ // for wide character compiler
|
||||
char temp[52] = "";
|
||||
|
||||
_tsetlocale(LC_ALL, _T("")); //Change Unicode to OS-Default locale
|
||||
|
||||
if (DEBUG)
|
||||
print_str("call_coded in add CRC16 =", call_coded);
|
||||
strcpy_w(temp, call_coded, 28); // 28 bit
|
||||
if (DEBUG)
|
||||
print_str("temp in add CRC16=", temp);
|
||||
generate_crc(call_coded, crc1, 16);
|
||||
if (DEBUG)
|
||||
print_str("crc1 =", crc1);
|
||||
strcat_w(temp, crc1, 28, 16); // 28 + 16 = 44
|
||||
generate_crc( temp, crc2, 3);
|
||||
if (DEBUG)
|
||||
print_str("crc2 =", crc2);
|
||||
#else // PIC C compiler using ASCII
|
||||
// char crc1[17] = "", crc2[4] = "";
|
||||
generate_crc(call_coded, crc1, 16);
|
||||
if (DEBUG) printf("crc1 =%s\n", crc1);
|
||||
generate_crc(strcat(call_coded, crc1), crc2, 3);
|
||||
if (DEBUG) printf("crc2 =%s\n", crc2);
|
||||
#endif
|
||||
// |4 bits sync| + |28 bits call| + |19 bit crc|
|
||||
#ifdef __VCpp__
|
||||
strcpy_w(vector, "0000", 4); // 4
|
||||
strcat_w(vector, temp, 4, 44); // 4 + 44 = 48
|
||||
strcat_w(vector, crc2, 48, 3); // 48 + 3 = 51
|
||||
#else // not VC++ ex : PIC
|
||||
strcpy(vector, "0000"); // 4
|
||||
strcat(vector, call_coded); // 4 + 44 = 48
|
||||
strcat(vector, crc2); // 48 + 3 = 51
|
||||
#endif
|
||||
} // end of add_crc16
|
||||
|
||||
//**************************************************
|
||||
void scramble(char *vector, short int *vector_to_tx)
|
||||
//**************************************************
|
||||
{ // encoding |51 bits|
|
||||
int i=0;
|
||||
|
||||
for (i = 0; i < 51; i++)
|
||||
{
|
||||
vector_to_tx[i] = vector[i] & 0x01;
|
||||
// convert ASCII to binary
|
||||
vector_to_tx[i] = vector_to_tx[i] ^ pseudo_sequence[i];
|
||||
}
|
||||
} // end of scrambling
|
||||
|
||||
//*************************************************************************
|
||||
void Walsh_Hammered_code(short int *vector_to_tx, short int *symbol_coding)
|
||||
//*************************************************************************
|
||||
{ // order 8 walsh matrix codification : |119 bits|
|
||||
int data = 0, idx = 0, i = 0, j = 0;
|
||||
|
||||
for (i = 0; i < 51; i += 3)
|
||||
{
|
||||
data = 0;
|
||||
for (j = 0; j < 3; j++)
|
||||
data = data + (vector_to_tx[i + j] << (2 - j));
|
||||
for (j = 0; j < 7; j++)
|
||||
{
|
||||
symbol_coding[idx] = walsh_matrix[data][j];
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
} //end of Walsh_Hammered_code
|
||||
|
||||
//***********************************************************************
|
||||
void interleave(short int *symbol_coding, short int *symbol_interleaving)
|
||||
//***********************************************************************
|
||||
{ // interleaving : |119 bits|
|
||||
int idx = 0, i = 0, j = 0;
|
||||
|
||||
idx = 0;
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
for (j = i; j < 119; j += 7)
|
||||
{
|
||||
symbol_interleaving[idx]= symbol_coding[j];
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
} // end of interleave
|
||||
|
||||
//**********************************************************************
|
||||
void ManchesterEncode(short int *symbol_interleaving, short int *symbol)
|
||||
//**********************************************************************
|
||||
{ // manchester codification : |11| + |238 bits| - |1 bit| modified by 7L1RLL 11/07/2015
|
||||
int idx = 0;
|
||||
int i = 0, j = 0;
|
||||
|
||||
symbol[0] = 1;
|
||||
for (i = 0; i < 119; i++)
|
||||
{
|
||||
if (symbol_interleaving[i] == 0)
|
||||
{
|
||||
symbol[idx + 1] = 1;
|
||||
symbol[idx + 2] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
symbol[idx + 1] = 0;
|
||||
symbol[idx + 2] = 1;
|
||||
}
|
||||
idx += 2;
|
||||
}
|
||||
} // end of Manchester_encode
|
||||
|
||||
//***************
|
||||
void print_help()
|
||||
//***************
|
||||
{
|
||||
printf("%s\n","Usage : OPERA_Coding_Test [? | s | [d \"callsign\"]]");
|
||||
printf("%s\n"," Normal : OPERA_Coding_Test \"callsign\"");
|
||||
printf("%s\n"," Help : OPERA_Coding_Test ?");
|
||||
printf("%s\n"," Sample : OPERA_Coding_Test s");
|
||||
printf("%s\n"," Debug : OPERA_Coding_Test d \"callsign\"");
|
||||
printf("%s\n"," Callsign format shall be like \"AA1AAA\". ");
|
||||
printf("%s\n"," Third character mast be a numeric character(0..9).");
|
||||
} // end of help
|
||||
|
||||
//********************************************************************
|
||||
void print_short_int(const char *caption, short int *code, int length)
|
||||
//********************************************************************
|
||||
{ // This is service function for debugging
|
||||
int i = 0;
|
||||
|
||||
printf("%s\n", caption);
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
printf("%d", code[i]);
|
||||
if (((i+1) % 4) == 0) printf(" ");
|
||||
if (((i+1) % 40) == 0) printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
} // end fo print_short_int
|
||||
|
||||
|
||||
void encodepitx(short int *code, int length,float Nop)
|
||||
{
|
||||
int i = 0;
|
||||
int j=0;
|
||||
/*and each of the
|
||||
239 symbols are transmitted by keying the transmitter as CW on and off with a symbol
|
||||
rate of 0.256*n s/symbol, where n is the integer of operation mode OPn that corresponds
|
||||
with the Opera frequency recommendation: */
|
||||
//WriteTone(1*32767,1e6*(256*Nop));
|
||||
WriteTone(1*32767,1e6*(256*Nop));
|
||||
for (i = 0; i < length-1; i++)
|
||||
{
|
||||
//for(j=0;j<1000;j++)
|
||||
WriteTone(code[i]*32767,1e6*(256*Nop));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//********************************************************************
|
||||
void print_str(const char * caption, char * code)
|
||||
//********************************************************************
|
||||
{ // This is a service function for debugging
|
||||
int i = 0;
|
||||
|
||||
printf("%s\n", caption);
|
||||
for (i = 0; i < strlen(code); i++)
|
||||
{
|
||||
printf("%c", code[i]);
|
||||
if (((i + 1) % 4) == 0) printf(" ");
|
||||
if (((i + 1) % 40) == 0) printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
} // end fo print_str
|
||||
//*******************************************************
|
||||
void strcpy_w(char * s1, char * s2, int length)
|
||||
//*******************************************************
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
s1[i] = s2[i];
|
||||
s1[length] = 0x00;
|
||||
} // end of strcpy_w
|
||||
|
||||
//****************************************************************
|
||||
void strcat_w(char * s1, char * s2, int lenS1, int lenS2)
|
||||
//****************************************************************
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < lenS2; i++)
|
||||
s1[i + lenS1] = s2[i];
|
||||
s1[lenS1 + lenS2]= 0x00;
|
||||
|
||||
} // end of strcat_w()
|
||||
//************** End of Program ********************************
|
Plik binarny nie jest wyświetlany.
|
@ -0,0 +1,121 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <sndfile.h>
|
||||
|
||||
#define ln(x) (log(x)/log(2.718281828459045235f))
|
||||
#define BUFFER_LEN 1024*8
|
||||
|
||||
int FileFreqTiming;
|
||||
// Test program using SNDFILE
|
||||
// see http://www.mega-nerd.com/libsndfile/api.html for API
|
||||
|
||||
void WriteTone(double Frequency,uint32_t Timing)
|
||||
{
|
||||
typedef struct {
|
||||
double Frequency;
|
||||
uint32_t WaitForThisSample;
|
||||
} samplerf_t;
|
||||
samplerf_t RfSample;
|
||||
|
||||
RfSample.Frequency=Frequency;
|
||||
RfSample.WaitForThisSample=Timing; //en 100 de nanosecond
|
||||
//printf("Freq =%f Timing=%d\n",RfSample.Frequency,RfSample.WaitForThisSample);
|
||||
if (write(FileFreqTiming,&RfSample,sizeof(samplerf_t)) != sizeof(samplerf_t)) {
|
||||
fprintf(stderr, "Unable to write sample\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
float data [2*BUFFER_LEN] ;
|
||||
float data_filtered[2*BUFFER_LEN] ; // we generate complex I/Q samples
|
||||
SNDFILE *infile, *outfile ;
|
||||
SF_INFO sfinfo ;
|
||||
|
||||
int readcount, nb_samples ;
|
||||
char *infilename ;
|
||||
char *outfilename ;
|
||||
int k ;
|
||||
float x ;
|
||||
|
||||
if( argc < 2 ) {
|
||||
printf("Usage : %s in.wav [out.wav]\n", argv[0]);
|
||||
return(1);
|
||||
}
|
||||
infilename = argv[1];
|
||||
if( argc == 3 ) {
|
||||
outfilename = argv[2];
|
||||
} else {
|
||||
outfilename = (char *)malloc( 128 );
|
||||
sprintf( outfilename, "%s", "out.ft");
|
||||
}
|
||||
if (! (infile = sf_open (infilename, SFM_READ, &sfinfo)))
|
||||
{ /* Open failed so print an error message. */
|
||||
printf ("Not able to open input file %s.\n", infilename);
|
||||
/* Print the error message from libsndfile. */
|
||||
puts (sf_strerror (NULL));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( sfinfo.samplerate != 48000 ) {
|
||||
printf("Input rate must be 48K.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
FileFreqTiming = open(outfilename, O_WRONLY|O_CREAT, 0644);
|
||||
|
||||
/** **/
|
||||
printf ("Reading file : %s\n", infilename );
|
||||
printf ("Sample Rate : %d\n", sfinfo.samplerate);
|
||||
printf ("Channels : %d\n", sfinfo.channels);
|
||||
printf ("----------------------------------------\n");
|
||||
printf ("Writing file : %s\n", outfilename );
|
||||
|
||||
/* While there are.frames in the input file, read them, process
|
||||
** them and write them to the output file.
|
||||
*/
|
||||
|
||||
while ((readcount = sf_readf_float(infile, data, BUFFER_LEN)))
|
||||
{
|
||||
nb_samples = readcount / sfinfo.channels;
|
||||
for( k=0 ; k < nb_samples ; k++ ) {
|
||||
x = data[k*sfinfo.channels];
|
||||
if( sfinfo.channels == 2 ) {
|
||||
// stereo file, avg left + right
|
||||
x += data[k*sfinfo.channels+1];
|
||||
x /= 2;
|
||||
}
|
||||
//printf("%f \n",x);
|
||||
float FactAmplitude=2.0; // To be analyzed more deeply !
|
||||
/*
|
||||
double A = 87.7f; // compression parameter
|
||||
double ampf=x/32767.0;
|
||||
ampf = (fabs(ampf) < 1.0f/A) ? A*fabs(ampf)/(1.0f+ln(A)) : (1.0f+ln(A*fabs(ampf)))/(1.0f+ln(A)); //compand
|
||||
x= (int)(round(ampf * 32767.0f));
|
||||
*/
|
||||
WriteTone(x*32767*FactAmplitude,1e9/48000.0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Close input and output files. */
|
||||
sf_close (infile) ;
|
||||
close(FileFreqTiming);
|
||||
|
||||
return 0;
|
||||
}
|
119
src/RpiTx.c
119
src/RpiTx.c
|
@ -89,6 +89,10 @@ int FREQ_MINI_TIMING=157;
|
|||
int PWMF_MARGIN = 1120; //A Margin for now at 1us with PCM ->OK
|
||||
int globalppmpll=0;
|
||||
|
||||
|
||||
int CalibrationTab[PWM_STEP_MAXI];
|
||||
uint32_t *Shuffle[PWM_STEP_MAXI];
|
||||
|
||||
typedef unsigned char uchar; // 8 bit
|
||||
typedef unsigned short uint16; // 16 bit
|
||||
typedef unsigned int uint; // 32 bits
|
||||
|
@ -108,6 +112,7 @@ int Randomize=0;
|
|||
|
||||
uint32_t GlobalTabPwmFrequency[50];
|
||||
|
||||
|
||||
//End F5OEO
|
||||
|
||||
char EndOfApp=0;
|
||||
|
@ -441,7 +446,7 @@ inline void FrequencyAmplitudeToRegister(double TuneFrequency,uint32_t Amplitude
|
|||
|
||||
static uint32_t CompteurDebug=0;
|
||||
#define DEBUG_RATE 20000
|
||||
int PwmNumberStep;
|
||||
int PwmNumberStep=0;
|
||||
CompteurDebug++;
|
||||
static uint32_t TabPwmAmplitude[18]={0x00000000,
|
||||
0x80000000,0xA0000000,0xA8000000,0xAA000000,
|
||||
|
@ -472,9 +477,19 @@ inline void FrequencyAmplitudeToRegister(double TuneFrequency,uint32_t Amplitude
|
|||
if(SampleRate!=0)
|
||||
WaitNanoSecond = (1e9/SampleRate);
|
||||
}
|
||||
|
||||
PwmNumberStep=WaitNanoSecond/FREQ_MINI_TIMING;
|
||||
if(PwmNumberStep>PWM_STEP_MAXI) PwmNumberStep=PWM_STEP_MAXI;
|
||||
|
||||
int i;
|
||||
for(i=1;i<PWM_STEP_MAXI;i++)
|
||||
{
|
||||
if(CalibrationTab[i]>=WaitNanoSecond)
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
PwmNumberStep=i;
|
||||
//PwmNumberStep=WaitNanoSecond/FREQ_MINI_TIMING;
|
||||
//if(PwmNumberStep>PWM_STEP_MAXI) PwmNumberStep=PWM_STEP_MAXI;
|
||||
|
||||
|
||||
// ********************************** PWM FREQUENCY PROCESSING *****************************
|
||||
|
@ -517,22 +532,22 @@ inline void FrequencyAmplitudeToRegister(double TuneFrequency,uint32_t Amplitude
|
|||
|
||||
//if((CompteurDebug%200)==0) printf("PwmNumberStep =%d TuneFrequency %f : FreqTuning %f FreqStep %f PwmFreqStep %f fPWMFrequency %f PWMFrequency %d f1 %f f2 %f %x %x\n",PwmNumberStep,TuneFrequency,FreqTuning,FreqStep,FreqStep/PwmNumberStep,fPWMFrequency,PWMFrequency,f1,f2,RegisterF1,RegisterF2);
|
||||
|
||||
int i;
|
||||
|
||||
|
||||
static int NbF1,NbF2,NbF1F2;
|
||||
NbF1=0;
|
||||
NbF2=0;
|
||||
NbF1F2=0;
|
||||
|
||||
int BeginShuffle=rand()%PwmNumberStep;
|
||||
|
||||
int AdaptPWMFrequency;
|
||||
if((PwmNumberStep-PWMFrequency-(PWMF_MARGIN+FREQ_DELAY_TIME)/FREQ_MINI_TIMING)>PwmNumberStep/2)
|
||||
if((PwmNumberStep-PWMFrequency)/*-(PWMF_MARGIN+FREQ_DELAY_TIME)/FREQ_MINI_TIMING)*/>PwmNumberStep/2)
|
||||
{
|
||||
RegisterF1=0x5A000000 | (FreqDividerf1<<12) | (FreqFractionnalf1);
|
||||
RegisterF2=0x5A000000 | (FreqDividerf2<<12) | (FreqFractionnalf2);
|
||||
AdaptPWMFrequency=PWMFrequency;
|
||||
NbF1=0;
|
||||
NbF2=(PWMF_MARGIN+FREQ_DELAY_TIME)/FREQ_MINI_TIMING;
|
||||
NbF2=0;//PWMFrequency;//(PWMF_MARGIN+FREQ_DELAY_TIME)/FREQ_MINI_TIMING;
|
||||
|
||||
}
|
||||
else // SWAP F1 AND F2
|
||||
|
@ -542,7 +557,7 @@ inline void FrequencyAmplitudeToRegister(double TuneFrequency,uint32_t Amplitude
|
|||
RegisterF1=0x5A000000 | (FreqDividerf2<<12) | (FreqFractionnalf2);
|
||||
AdaptPWMFrequency=PwmNumberStep-PWMFrequency;
|
||||
NbF1=0;
|
||||
NbF2=(PWMF_MARGIN+FREQ_DELAY_TIME)/FREQ_MINI_TIMING;
|
||||
NbF2=0;//PWMFrequency;//(PWMF_MARGIN+FREQ_DELAY_TIME)/FREQ_MINI_TIMING;
|
||||
}
|
||||
|
||||
i=0;
|
||||
|
@ -561,13 +576,15 @@ inline void FrequencyAmplitudeToRegister(double TuneFrequency,uint32_t Amplitude
|
|||
{
|
||||
if(NbF1<AdaptPWMFrequency)
|
||||
{
|
||||
ctl->sample[NoSample].FrequencyTab[i++]=RegisterF1;
|
||||
ctl->sample[NoSample].FrequencyTab[Shuffle[PwmNumberStep][(i+BeginShuffle)%PwmNumberStep]/*rand()%(PwmNumberStep)*/]=RegisterF1;
|
||||
i++;
|
||||
NbF1++;
|
||||
NbF1F2++;
|
||||
}
|
||||
if(NbF2<PwmNumberStep-AdaptPWMFrequency-1)
|
||||
{
|
||||
ctl->sample[NoSample].FrequencyTab[i++]=RegisterF2;
|
||||
ctl->sample[NoSample].FrequencyTab[Shuffle[PwmNumberStep][(i+BeginShuffle)%PwmNumberStep]/*rand()%(PwmNumberStep)*/]=RegisterF2;
|
||||
i++;
|
||||
NbF2++;
|
||||
NbF1F2++;
|
||||
}
|
||||
|
@ -644,7 +661,7 @@ int GetDMADelay(int Step)
|
|||
dma_cb_t *cbp = ctl->cb;
|
||||
cur_cb = (uint32_t)virtbase; // DMA AT 1st CBS
|
||||
dma_reg[DMA_CONBLK_AD+DMA_CHANNEL*0x40]=mem_virt_to_phys((void*)cur_cb);
|
||||
usleep(100);
|
||||
//usleep(100);
|
||||
int samplecnt;
|
||||
for (samplecnt = 0; samplecnt < NUM_SAMPLES ; samplecnt++)
|
||||
{
|
||||
|
@ -655,10 +672,10 @@ int GetDMADelay(int Step)
|
|||
}
|
||||
|
||||
dma_reg[DMA_CS+DMA_CHANNEL*0x40] = DMA_CS_PRIORITY(7) | DMA_CS_PANIC_PRIORITY(7) | DMA_CS_DISDEBUG |DMA_CS_ACTIVE; // START DMA : go, mid priority, wait for outstanding writes :7 Seems Max Priority
|
||||
usleep(5000); //Wait to be sure DMA is running stable
|
||||
//usleep(500); //Wait to be sure DMA is running stable
|
||||
int i;
|
||||
int SumDelay=0;
|
||||
for(i=0;i<10;i++)
|
||||
for(i=0;i<4;i++)
|
||||
{
|
||||
|
||||
|
||||
|
@ -690,7 +707,7 @@ int GetDMADelay(int Step)
|
|||
time_difference = gettime_now.tv_nsec - start_time;
|
||||
if(time_difference<0) time_difference+=1E9;
|
||||
|
||||
//printf("Delay = %d\n",time_difference/free_slots);
|
||||
//printf("Delay = %d (time_diff %ld freesolt %d \n",time_difference/free_slots,time_difference,free_slots);
|
||||
|
||||
SumDelay+=time_difference/free_slots;
|
||||
}
|
||||
|
@ -702,7 +719,7 @@ int GetDMADelay(int Step)
|
|||
dma_reg[DMA_CS+DMA_CHANNEL*0x40] |= DMA_CS_RESET; //BCM2708_DMA_ABORT|BCM2708_DMA_RESET;
|
||||
udelay(100);
|
||||
|
||||
return SumDelay/10;
|
||||
return SumDelay/4;
|
||||
}
|
||||
|
||||
int CalibrateSystem(int *ppm,int *BaseDelayDMA,int *StepDelayDMA)
|
||||
|
@ -715,33 +732,71 @@ int CalibrateSystem(int *ppm,int *BaseDelayDMA,int *StepDelayDMA)
|
|||
ntx.modes = 0; /* only read */
|
||||
status = ntp_adjtime(&ntx);
|
||||
double clockppm;
|
||||
|
||||
int hFileCsv;
|
||||
hFileCsv=open("calib.csv",O_CREAT | O_WRONLY);
|
||||
|
||||
if (status != TIME_OK)
|
||||
{
|
||||
printf("Error: NTP\n");
|
||||
return 0;
|
||||
//return 0;
|
||||
}
|
||||
clockppm = (double)ntx.freq/(double)(1 << 16);
|
||||
if(abs(clockppm)<200)
|
||||
*ppm=clockppm;
|
||||
//printf("Clock PPM = %f\n",ppm);
|
||||
int i;
|
||||
int BaseDelay=0;
|
||||
BaseDelay=GetDMADelay(0);
|
||||
int BaseDelay=1;
|
||||
/*BaseDelay=GetDMADelay(0);
|
||||
|
||||
*BaseDelayDMA=BaseDelay;
|
||||
*StepDelayDMA=(GetDMADelay(PWM_STEP_MAXI/2)-(*BaseDelayDMA))/(PWM_STEP_MAXI/2);
|
||||
//for(i=1;i<200;i+=10)
|
||||
//printf("Step %d =%d\n",i,(GetDMADelay(i)-BaseDelay)/i);
|
||||
*StepDelayDMA=(GetDMADelay(PWM_STEP_MAXI/2)-(*BaseDelayDMA))/(PWM_STEP_MAXI/2);*/
|
||||
char csvline[255];
|
||||
for(i=0;i<200;i+=1)
|
||||
{
|
||||
int Delay=GetDMADelay(i);
|
||||
printf("Step %d :%d \n",i,Delay);//,(GetDMADelay(i)-BaseDelay)/i);
|
||||
sprintf(csvline,"%d:%d\n",i,Delay);
|
||||
CalibrationTab[i]=Delay;
|
||||
write(hFileCsv,csvline,strlen(csvline));
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void InitShuffle()
|
||||
{
|
||||
int i,j;
|
||||
for(i=1;i<PWM_STEP_MAXI;i++)
|
||||
{
|
||||
Shuffle[i]=(uint32_t *)malloc(i*sizeof(uint32_t));
|
||||
|
||||
for(j=0;j<i;j++)
|
||||
{
|
||||
Shuffle[i][j]=j;
|
||||
}
|
||||
//shuffle_int(Shuffle[i],i);
|
||||
}
|
||||
|
||||
|
||||
for(i=1;i<PWM_STEP_MAXI;i++)
|
||||
{
|
||||
printf("%d :",i);
|
||||
for(j=0;j<i;j++)
|
||||
{
|
||||
printf("%d ",Shuffle[i][j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int pitx_init(int SampleRate, double TuningFrequency, int* skipSignals,int SetDma)
|
||||
{
|
||||
InitGpio();
|
||||
InitDma(terminate, skipSignals);
|
||||
if(SetDma) DMA_CHANNEL=SetDma;
|
||||
SetupGpioClock(SampleRate,TuningFrequency);
|
||||
InitShuffle();
|
||||
//int FREQ_MINI_TIMING=157;
|
||||
//int PWMF_MARGIN = 1120; //A Margin for now at 1us with PCM ->OK
|
||||
|
||||
|
@ -1270,7 +1325,8 @@ int pitx_run(
|
|||
{
|
||||
// SHOULD NOT EXEED 200 STEP*500ns; SAMPLERATE SHOULD BE MAX TO HAVE PRECISION FOR PCM
|
||||
// BUT FIFO OF PCM IS 16 : SAMPLERATE MAYBE NOT EXCESS 16*80000 ! CAREFULL BUGS HERE
|
||||
#define MAX_DELAY_WAIT (PWM_STEP_MAXI/2*FREQ_MINI_TIMING-PWMF_MARGIN)
|
||||
//#define MAX_DELAY_WAIT (PWM_STEP_MAXI/2*FREQ_MINI_TIMING-PWMF_MARGIN)
|
||||
int MAX_DELAY_WAIT = CalibrationTab[199];
|
||||
static int CompteSample=0;
|
||||
static uint32_t TimeRemaining=0;
|
||||
static samplerf_t SampleRf;
|
||||
|
@ -1341,15 +1397,26 @@ int pitx_run(
|
|||
|
||||
int i;
|
||||
//printf("Begin free %d\n",free_slots);
|
||||
static int Up=1;
|
||||
for(i=0;i<DmaSampleBurstSize;i++)
|
||||
{
|
||||
//To be fine tuned !!!!
|
||||
static int OutputPower=32767;
|
||||
CompteSample++;
|
||||
if(Up==1)
|
||||
{
|
||||
|
||||
CompteSample++;
|
||||
if(CompteSample==500000) Up=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
CompteSample--;
|
||||
if(CompteSample==0) Up=1;
|
||||
}
|
||||
debug=1;//(debug+1)%2;
|
||||
//OutputPower=(CompteSample/10)%32768;
|
||||
|
||||
FrequencyAmplitudeToRegister(GlobalTuningFrequency/HarmonicNumber/*+(CompteSample*0.1)*/,OutputPower,last_sample++,25000,0,NoUsePwmFrequency,debug);
|
||||
FrequencyAmplitudeToRegister(GlobalTuningFrequency/HarmonicNumber+(CompteSample*0.05),OutputPower,last_sample++,30000,0,NoUsePwmFrequency,debug);
|
||||
free_slots--;
|
||||
//printf("%f \n",GlobalTuningFrequency+(((CompteSample/10)*1)%50000));
|
||||
if (last_sample == NUM_SAMPLES) last_sample = 0;
|
||||
|
|
Ładowanie…
Reference in New Issue