kopia lustrzana https://github.com/lucckb/libpsk
Initial revision
commit
0fd4ad894e
|
@ -0,0 +1,36 @@
|
||||||
|
# Automatic makefile for GNUARM (C/C++)
|
||||||
|
|
||||||
|
#Target binary file name
|
||||||
|
TARGET = psk31test
|
||||||
|
|
||||||
|
#Optimalization [0,1,2,3,s]
|
||||||
|
# 0 - none optimalization, s - size optimalization 3 - most optimized
|
||||||
|
OPT ?= 2
|
||||||
|
|
||||||
|
|
||||||
|
#Common flags
|
||||||
|
COMMON_FLAGS = -pipe -Wall -pedantic -Wextra -Wno-vla -I.
|
||||||
|
COMMON_FLAGS += -D__STDC_CONSTANT_MACROS -I./libpsk/include
|
||||||
|
|
||||||
|
#C compiler options
|
||||||
|
CFLAGS += $(COMMON_FLAGS)
|
||||||
|
CFLAGS += -std=gnu99
|
||||||
|
|
||||||
|
#C++ compiler options
|
||||||
|
CXXFLAGS += $(COMMON_FLAGS) -std=c++11
|
||||||
|
|
||||||
|
#LDflags libraries etc.
|
||||||
|
LDFLAGS += -lavformat -lavcodec -lz -lavutil
|
||||||
|
|
||||||
|
#Per file listing
|
||||||
|
LISTING = n
|
||||||
|
|
||||||
|
#Debug version
|
||||||
|
DEBUG ?= y
|
||||||
|
|
||||||
|
#Source C++ files
|
||||||
|
CPPSRC += $(wildcard *.cpp) $(wildcard libpsk/src/*.cpp)
|
||||||
|
|
||||||
|
include unix.mk
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
/*
|
||||||
|
* decoder.h
|
||||||
|
*
|
||||||
|
* Created on: 24-03-2013
|
||||||
|
* Author: lucck
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
#ifndef LIBPSK_DECODER_HPP_
|
||||||
|
#define LIBPSK_DECODER_HPP_
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
#include <cstddef>
|
||||||
|
#include <array>
|
||||||
|
#include <complex>
|
||||||
|
#include "imd_calculator.hpp"
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
namespace ham {
|
||||||
|
namespace psk {
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
//Sample type variable
|
||||||
|
typedef short sample_type;
|
||||||
|
//Vector data
|
||||||
|
typedef std::array<std::pair<long, long>, 8> signal_vector_type;
|
||||||
|
//Sync vector data
|
||||||
|
typedef std::array<long, 16> sync_array_type;
|
||||||
|
//Squelch tresh type
|
||||||
|
typedef int sqelch_value_type;
|
||||||
|
//Sample rate type
|
||||||
|
typedef short samplerate_type;
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
class decoder {
|
||||||
|
//Make object noncopyable
|
||||||
|
decoder(const decoder&) = delete;
|
||||||
|
decoder& operator=(const decoder&) = delete;
|
||||||
|
static constexpr auto DEC4_LPFIR_LENGTH = 35;
|
||||||
|
static constexpr auto BITFIR_LENGTH = 65;
|
||||||
|
//Survivor states in decoder
|
||||||
|
struct survivor_states
|
||||||
|
{
|
||||||
|
survivor_states( double _path_distance = double(), long _bit_estimates = long() )
|
||||||
|
: path_distance(_path_distance), bit_estimates(_bit_estimates ) {}
|
||||||
|
double path_distance; // sum of all metrics for a given survivor path
|
||||||
|
long bit_estimates; // the bit pattern estimate associated with given survivor path
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
enum class mode
|
||||||
|
{
|
||||||
|
bpsk, //BPSK
|
||||||
|
qpsku, //QPSK USB
|
||||||
|
qpskl //QPSK LSB
|
||||||
|
};
|
||||||
|
enum class baudrate
|
||||||
|
{
|
||||||
|
b31,
|
||||||
|
b63,
|
||||||
|
b125
|
||||||
|
};
|
||||||
|
enum class squelch_mode
|
||||||
|
{
|
||||||
|
slow,
|
||||||
|
fast
|
||||||
|
};
|
||||||
|
//Construct the decoder object
|
||||||
|
explicit decoder( samplerate_type sample_rate );
|
||||||
|
//Process input sample buffer
|
||||||
|
void operator()( sample_type* samples, std::size_t sample_size );
|
||||||
|
//Get signal vector
|
||||||
|
signal_vector_type get_signal_vector( ) const;
|
||||||
|
//Get sync array type
|
||||||
|
sync_array_type get_sync_data() const;
|
||||||
|
//Reset decoder
|
||||||
|
void reset();
|
||||||
|
//Set receive frequency
|
||||||
|
void set_frequency( int freq );
|
||||||
|
//Set detector mode
|
||||||
|
void set_mode( mode mode, baudrate rate );
|
||||||
|
//Set AFC limit
|
||||||
|
void set_afc_limit( int limit );
|
||||||
|
//Get current frequency
|
||||||
|
int get_frequency() const;
|
||||||
|
//Get signal level
|
||||||
|
int get_signal_level() const;
|
||||||
|
//Set squelch tresh
|
||||||
|
void set_squelch_tresh( sqelch_value_type tresh, squelch_mode mode );
|
||||||
|
void calc_quality( double angle );
|
||||||
|
private:
|
||||||
|
bool viterbi_decode( double newangle );
|
||||||
|
void calc_bit_filter( std::complex<double> samp );
|
||||||
|
void calc_agc( std::complex<double> samp );
|
||||||
|
void calc_freq_error( std::complex<double> IQ );
|
||||||
|
void calc_ffreq_error( std::complex<double> IQ );
|
||||||
|
void decode_symb( std::complex<double> newsamp );
|
||||||
|
bool symb_sync(std::complex<double> sample);
|
||||||
|
bool is_qpsk() const
|
||||||
|
{
|
||||||
|
return m_rx_mode != mode::bpsk;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
baudrate m_baudrate;
|
||||||
|
double m_vco_phz;
|
||||||
|
int m_afc_timer;
|
||||||
|
bool m_afc_capture_on;
|
||||||
|
int m_rx_frequency;
|
||||||
|
double m_nco_phzinc;
|
||||||
|
double m_afc_limit;
|
||||||
|
double m_afc_max;
|
||||||
|
double m_afc_min;
|
||||||
|
std::array<std::complex<double>, DEC4_LPFIR_LENGTH> m_que1;
|
||||||
|
std::array<std::complex<double>, DEC4_LPFIR_LENGTH> m_que2;
|
||||||
|
std::array<std::complex<double>, BITFIR_LENGTH> m_que3;
|
||||||
|
int m_fir1_state;
|
||||||
|
int m_fir2_state;
|
||||||
|
int m_fir3_state;
|
||||||
|
std::array<survivor_states, 16> m_survivor_states;
|
||||||
|
std::array<long , 16> m_iq_phase_array;
|
||||||
|
std::array<double, 21> m_sync_ave;
|
||||||
|
int m_sql_level;
|
||||||
|
int m_clk_err_counter;
|
||||||
|
int m_clk_err_timer;
|
||||||
|
int m_clk_err;
|
||||||
|
double m_dev_ave;
|
||||||
|
double m_freq_error;
|
||||||
|
int m_sample_cnt;
|
||||||
|
std::complex<double> m_freq_signal;
|
||||||
|
bool m_fast_afc_mode;
|
||||||
|
std::complex<double> m_bit_signal;
|
||||||
|
bool m_imd_valid;
|
||||||
|
_internal::imd_calculator m_calc_imd;
|
||||||
|
double m_sample_freq;
|
||||||
|
double m_agc_ave;
|
||||||
|
bool m_afc_on;
|
||||||
|
double m_fperr_ave {};
|
||||||
|
double m_fferr_ave {};
|
||||||
|
std::complex<double> m_z1;
|
||||||
|
std::complex<double> m_z2;
|
||||||
|
double m_I0 {}; // 4 stage I/Q delay line variables
|
||||||
|
double m_I1 {};
|
||||||
|
double m_Q0 {};
|
||||||
|
double m_Q1 {};
|
||||||
|
int m_iq_phz_index {};
|
||||||
|
mode m_rx_mode { mode::bpsk };
|
||||||
|
bool m_last_bit_zero {};
|
||||||
|
uint16_t m_bit_acc {};
|
||||||
|
std::array<uint8_t, 2048> m_VaricodeDecTbl;
|
||||||
|
bool m_sq_open {};
|
||||||
|
int m_squelch_speed { 75 };
|
||||||
|
double m_q_freq_error {};
|
||||||
|
int m_on_count {};
|
||||||
|
int m_off_count {};
|
||||||
|
int m_pcnt {};
|
||||||
|
int m_ncnt {};
|
||||||
|
int m_sq_thresh { 50 };
|
||||||
|
double m_nlp_k;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
} /* namespace psk */
|
||||||
|
} /* namespace ham */
|
||||||
|
#endif /* DECODER_H_ */
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* imd_calculator.hpp
|
||||||
|
*
|
||||||
|
* Created on: 24-03-2013
|
||||||
|
* Author: lucck
|
||||||
|
*/
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
#ifndef LIBPSK_IMD_CALCULATOR_HPP_
|
||||||
|
#define LIBPSK_IMD_CALCULATOR_HPP_
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
#include <complex>
|
||||||
|
#include <array>
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
namespace ham {
|
||||||
|
namespace psk {
|
||||||
|
namespace _internal {
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
class imd_calculator {
|
||||||
|
//Make object noncopyable
|
||||||
|
imd_calculator(const imd_calculator&) = delete;
|
||||||
|
imd_calculator& operator=(const imd_calculator&) = delete;
|
||||||
|
static auto constexpr NUM_FILTERS = 3;
|
||||||
|
public:
|
||||||
|
imd_calculator() {}
|
||||||
|
void reset();
|
||||||
|
bool calc_energies( std::complex<double> samp );
|
||||||
|
bool calc_value( int &imd_val );
|
||||||
|
private:
|
||||||
|
std::array<double, NUM_FILTERS> I1 {{}};
|
||||||
|
std::array<double, NUM_FILTERS> I2 {{}};
|
||||||
|
std::array<double, NUM_FILTERS> Q1 {{}};
|
||||||
|
std::array<double, NUM_FILTERS> Q2 {{}};
|
||||||
|
std::array<double, NUM_FILTERS> m_energy {{}};
|
||||||
|
int m_ncount {};
|
||||||
|
double m_snr {};
|
||||||
|
double m_imd {};
|
||||||
|
};
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
} /* namespace _internal */
|
||||||
|
} /* namespace psk */
|
||||||
|
} /* namespace ham */
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
#endif /* IMD_CALCULATOR_HPP_ */
|
||||||
|
/* ------------------------------------------------------------------------- */
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* imd_calculator.cpp
|
||||||
|
*
|
||||||
|
* Created on: 24-03-2013
|
||||||
|
* Author: lucck
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
#include "psk/imd_calculator.hpp"
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
namespace ham {
|
||||||
|
namespace psk {
|
||||||
|
namespace _internal {
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
constexpr auto PI2 = 8.0 * std::atan(1.0);
|
||||||
|
constexpr auto N = 288; //96 x 2 = Goertzel length(must be an integer value)
|
||||||
|
constexpr auto FS = 500.0; // sample frequency
|
||||||
|
constexpr auto F0 = 15.625; // bin frequencies
|
||||||
|
constexpr auto F1 = 31.25;
|
||||||
|
constexpr auto F2 = 46.875;
|
||||||
|
constexpr auto K0 = double(N)*F0/FS;
|
||||||
|
constexpr auto K1 = double(N)*F1/FS;
|
||||||
|
constexpr auto K2 = double(N)*F2/FS;
|
||||||
|
static constexpr double COEF[] =
|
||||||
|
{
|
||||||
|
2.0*std::cos(PI2*K0/double(N)),
|
||||||
|
2.0*std::cos(PI2*K1/double(N)),
|
||||||
|
2.0*std::cos(PI2*K2/double(N))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
void imd_calculator::reset()
|
||||||
|
{
|
||||||
|
I1.fill(0);
|
||||||
|
I2.fill(0);
|
||||||
|
Q1.fill(0);
|
||||||
|
Q2.fill(0);
|
||||||
|
m_ncount = 0;
|
||||||
|
}
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
bool imd_calculator::calc_energies( std::complex<double> samp )
|
||||||
|
{
|
||||||
|
std::complex<double> temp;
|
||||||
|
for(int i=0; i<NUM_FILTERS;i++)
|
||||||
|
{
|
||||||
|
temp = std::complex<double>(I1[i], Q1[i]);
|
||||||
|
I1[i] = I1[i]*COEF[i]-I2[i]+samp.real();
|
||||||
|
Q1[i] = Q1[i]*COEF[i]-Q2[i]+samp.imag();
|
||||||
|
I2[i] = temp.real(); Q2[i] = temp.imag();
|
||||||
|
}
|
||||||
|
if( ++m_ncount >= N )
|
||||||
|
{
|
||||||
|
m_ncount = 0;
|
||||||
|
for(int i=0; i<NUM_FILTERS;i++)
|
||||||
|
{
|
||||||
|
m_energy[i] = I1[i]*I1[i] + I2[i]*I2[i] - I1[i]*I2[i]*COEF[i] +
|
||||||
|
Q1[i]*Q1[i] + Q2[i]*Q2[i] - Q1[i]*Q2[i]*COEF[i];
|
||||||
|
I1[i] = I2[i] = Q1[i] = Q2[i] = 0.0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
bool imd_calculator::calc_value( int &imd_val )
|
||||||
|
{
|
||||||
|
m_snr = 10.0*std::log10(m_energy[0]/m_energy[1]);
|
||||||
|
m_imd = 10.0*std::log10(m_energy[2]/m_energy[0]);
|
||||||
|
imd_val = int(m_imd);
|
||||||
|
return m_snr > (-m_imd+6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
} /* namespace _internal */
|
||||||
|
} /* namespace psk */
|
||||||
|
} /* namespace ham */
|
||||||
|
/* ------------------------------------------------------------------------- */
|
|
@ -0,0 +1,106 @@
|
||||||
|
//http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html
|
||||||
|
//gcc --std=gnu99 -o tutorial01 psk31test.c -lavformat -lavcodec -lz -lavutil
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <functional>
|
||||||
|
#include <cstdio>
|
||||||
|
extern "C" {
|
||||||
|
#include <libavcodec/avcodec.h>
|
||||||
|
#include <libavformat/avformat.h>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <psk/decoder.hpp>
|
||||||
|
|
||||||
|
namespace _internal
|
||||||
|
{
|
||||||
|
void on_new_samples( int16_t *sample, std::size_t count );
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char * const *argv )
|
||||||
|
{
|
||||||
|
if(argc < 2)
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("INvalid argument count\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
av_register_all();
|
||||||
|
AVFormatContext *pFormatCtx = avformat_alloc_context();
|
||||||
|
// Open video file
|
||||||
|
if(avformat_open_input(&pFormatCtx, argv[1], NULL, 0)!=0)
|
||||||
|
{
|
||||||
|
printf("Couldn't open file\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(avformat_find_stream_info(pFormatCtx, NULL) <0)
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("Couldn't find stream\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
av_dump_format(pFormatCtx, 0, argv[1], 0);
|
||||||
|
int audioStream = -1;
|
||||||
|
for( int i=0; i<pFormatCtx->nb_streams; i++)
|
||||||
|
{
|
||||||
|
if( pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO )
|
||||||
|
{
|
||||||
|
audioStream = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(audioStream==-1)
|
||||||
|
{
|
||||||
|
printf("Couldn't find audio stream\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
AVCodecContext *pCodecCtx = pFormatCtx->streams[audioStream]->codec;
|
||||||
|
AVCodec *pCodec = avcodec_find_decoder( pCodecCtx->codec_id );
|
||||||
|
if(pCodec == NULL)
|
||||||
|
{
|
||||||
|
printf("Couldn't find codec\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//bitstreams where frame boundaries can fall in the middle of packets
|
||||||
|
if(pCodec->capabilities & CODEC_CAP_TRUNCATED)
|
||||||
|
pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
|
||||||
|
|
||||||
|
// Open codec
|
||||||
|
if(avcodec_open2(pCodecCtx, pCodec, NULL)<0)
|
||||||
|
{
|
||||||
|
printf("Couldn't open avcodec\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
AVFrame *decoded_frame = avcodec_alloc_frame();
|
||||||
|
AVPacket *avpkt = reinterpret_cast<AVPacket*>(malloc(sizeof(AVPacket)));
|
||||||
|
ham::psk::decoder psk_dec( 8000 );
|
||||||
|
while(av_read_frame(pFormatCtx, avpkt)>=0)
|
||||||
|
{
|
||||||
|
int got_frame = 0;
|
||||||
|
int len = 0;
|
||||||
|
{
|
||||||
|
len = avcodec_decode_audio4(pCodecCtx, decoded_frame, &got_frame, avpkt );
|
||||||
|
if(len < 0)
|
||||||
|
{
|
||||||
|
printf("Decode error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(got_frame)
|
||||||
|
{
|
||||||
|
int data_size = av_samples_get_buffer_size(NULL,pCodecCtx->channels,
|
||||||
|
decoded_frame->nb_samples, pCodecCtx->sample_fmt, 1);
|
||||||
|
psk_dec( reinterpret_cast<ham::psk::sample_type*>(decoded_frame->data[0]), data_size );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(len < 0)
|
||||||
|
{
|
||||||
|
printf("Error when decoding\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free( avpkt );
|
||||||
|
free( decoded_frame );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
# Automatic makefile for GNUARM (C/C++)
|
||||||
|
|
||||||
|
|
||||||
|
#Definicje programow
|
||||||
|
CC ?= $(CROSS_COMPILE)gcc
|
||||||
|
CXX ?= $(CROSS_COMPILE)c++
|
||||||
|
AR ?= $(CROSS_COMPILE)ar
|
||||||
|
CP ?= $(CROSS_COMPILE)objcopy
|
||||||
|
OBJDUMP ?= $(CROSS_COMPILE)objdump
|
||||||
|
SIZE ?= $(CROSS_COMPILE)size
|
||||||
|
|
||||||
|
#Current platform
|
||||||
|
PLATFORM_DEVICE ?= BFC1
|
||||||
|
|
||||||
|
#Pozostale ustawienia kompilatora
|
||||||
|
ASFLAGS +=
|
||||||
|
CFLAGS += -O$(OPT)
|
||||||
|
CXXFLAGS += -O$(OPT)
|
||||||
|
CPFLAGS = -S
|
||||||
|
ARFLAGS = rcs
|
||||||
|
|
||||||
|
ifeq ($(LISTING),y)
|
||||||
|
ASLST = -Wa,-adhlns=$(<:%.S=%.lst)
|
||||||
|
CLST = -Wa,-adhlns=$(<:%.c=%.lst)
|
||||||
|
CPPLST = -Wa,-adhlns=$(<:%.cpp=%.lst)
|
||||||
|
LSSTARGET = $(TARGET).lss
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(DEBUG),y)
|
||||||
|
CFLAGS += -g -DPDEBUG
|
||||||
|
CXXFLAGS += -g -DPDEBUG
|
||||||
|
LDFLAGS += -g -DPDEBUG
|
||||||
|
ASFLAGS += -gstabs -DPDEBUG
|
||||||
|
else
|
||||||
|
CFLAGS += -fomit-frame-pointer
|
||||||
|
CXXFLAGS += -fomit-frame-pointer
|
||||||
|
LDFLAGS += -fomit-frame-pointer
|
||||||
|
ASFLAGS += -fomit-frame-pointer
|
||||||
|
#Remove unused functions
|
||||||
|
CFLAGS += -ffunction-sections -fdata-sections
|
||||||
|
CXXFLAGS += -ffunction-sections -fdata-sections
|
||||||
|
LDFLAGS+= -Wl,--gc-sections
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(PLATFORM_DEVICE), BF210)
|
||||||
|
CFLAGS += -DPLCXML_BF210_PLATFORM
|
||||||
|
CXXFLAGS += -DPLCXML_BF210_PLATFORM
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
all: build
|
||||||
|
|
||||||
|
install: build program
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(TARGET)
|
||||||
|
rm -f $(TARGET).map
|
||||||
|
rm -f $(TARGET).lss
|
||||||
|
rm -f lib$(TARGET).a
|
||||||
|
rm -f $(OBJ) $(LST) $(DEPFILES) $(LIBS) $(LIBS_OBJS)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ifeq ($(LIBRARY),y)
|
||||||
|
build: compile
|
||||||
|
else
|
||||||
|
build: compile size-calc
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ifeq ($(LIBRARY),y)
|
||||||
|
compile: lib$(TARGET).a
|
||||||
|
else
|
||||||
|
compile: $(TARGET) $(LSSTARGET)
|
||||||
|
endif
|
||||||
|
|
||||||
|
#Calculate size
|
||||||
|
size-calc: $(TARGET)
|
||||||
|
$(SIZE) $<
|
||||||
|
|
||||||
|
|
||||||
|
#wszystkie zaleznosci
|
||||||
|
$(TARGET): $(OBJ) $(LSCRIPT)
|
||||||
|
#Tworzenie biblioteki
|
||||||
|
lib$(TARGET).a: $(OBJ)
|
||||||
|
|
||||||
|
#Depend files
|
||||||
|
DEPFILES += $(SRC:%.c=%.dep) $(CPPSRC:%.cpp=%.dep) $(ASRC:%.S=%.dep)
|
||||||
|
|
||||||
|
-include $(DEPFILES)
|
||||||
|
|
||||||
|
|
||||||
|
#Objects files
|
||||||
|
OBJ = $(SRC:%.c=%.o) $(CPPSRC:%.cpp=%.o) $(ASRC:%.S=%.o)
|
||||||
|
# Define all listing files.
|
||||||
|
LST = $(SRC:%.c=%.lst) $(CPPSRC:%.cpp=%.lst) $(ASRC:%.S=%.lst)
|
||||||
|
#Objects files
|
||||||
|
.PRECIOUS : $(OBJ)
|
||||||
|
ifeq ($(LIBRARY),y)
|
||||||
|
.SECONDARY: lib$(TARGET).a
|
||||||
|
else
|
||||||
|
.SECONDARY: $(TARGET)
|
||||||
|
endif
|
||||||
|
.DEFAULT_GOAL := all
|
||||||
|
|
||||||
|
|
||||||
|
%.dep: %.c
|
||||||
|
$(CC) -MM -MF $@ -MP -MT $(subst .dep,.o,$@) $(CFLAGS) $<
|
||||||
|
|
||||||
|
%.dep: %.cpp
|
||||||
|
$(CXX) -MM -MF $@ -MP -MT $(subst .dep,.o,$@) $(CXXFLAGS) $<
|
||||||
|
|
||||||
|
|
||||||
|
%.dep: %.S
|
||||||
|
$(CC) -MM -MF $@ -MP -MT $(subst .dep,.o,$@) $(ASFLAGS) $<
|
||||||
|
|
||||||
|
%.lss: $(TARGET)
|
||||||
|
@echo "Create extended listing..."
|
||||||
|
$(OBJDUMP) -h -S $< > $@
|
||||||
|
|
||||||
|
%.hex: %.elf
|
||||||
|
@echo "Converting to hex..."
|
||||||
|
$(CP) -O ihex $(CPFLAGS) $< $@
|
||||||
|
|
||||||
|
%.bin: %.elf
|
||||||
|
@echo "Converting to bin..."
|
||||||
|
$(CP) -O binary $(CPFLAGS) $< $@
|
||||||
|
|
||||||
|
$(TARGET): $(OBJ) $(CRT0_OBJECT) $(ADDITIONAL_DEPS) $(LIBS)
|
||||||
|
@echo "Linking..."
|
||||||
|
$(CXX) $(CXXFLAGS) $(OBJ) $(CRT0_OBJECT) $(LIBS) -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
|
%.o : %.S
|
||||||
|
@echo "Assembling..."
|
||||||
|
$(CC) -c $(ASFLAGS) $(ASLST) $< -o $@
|
||||||
|
|
||||||
|
|
||||||
|
%.o : %.c
|
||||||
|
@echo "Compiling C..."
|
||||||
|
$(CC) -c $(CFLAGS) $(CLST) $< -o $@
|
||||||
|
|
||||||
|
%.o : %.cpp
|
||||||
|
@echo "Compiling C++..."
|
||||||
|
$(CXX) -c $(CXXFLAGS) $(CPPLST) $< -o $@
|
||||||
|
|
||||||
|
lib$(TARGET).a : $(OBJ)
|
||||||
|
@echo "Creating library ..."
|
||||||
|
$(AR) $(ARFLAGS) $@ $(OBJ)
|
||||||
|
|
Ładowanie…
Reference in New Issue