diff --git a/.hgsubstate b/.hgsubstate --- a/.hgsubstate +++ b/.hgsubstate @@ -1,2 +1,2 @@ a586fe639ac179e95bdc150ebdbab0312f31dc30 LFR_basic-parameters -6d02d4b02291d2b25c387fa74037dc7929cd92b5 header/lfr_common_headers +be0dc1c1876987307ddfc0fb47044f6d41815866 header/lfr_common_headers diff --git a/FSW-qt/fsw-qt.pro b/FSW-qt/fsw-qt.pro --- a/FSW-qt/fsw-qt.pro +++ b/FSW-qt/fsw-qt.pro @@ -12,7 +12,7 @@ SWVERSION=-1-0 DEFINES += SW_VERSION_N1=2 # major DEFINES += SW_VERSION_N2=0 # minor DEFINES += SW_VERSION_N3=2 # patch -DEFINES += SW_VERSION_N4=1 # internal +DEFINES += SW_VERSION_N4=2 # internal # #QMAKE_CFLAGS_RELEASE += -fprofile-arcs -ftest-coverage diff --git a/header/GscMemoryLPP.hpp b/header/GscMemoryLPP.hpp --- a/header/GscMemoryLPP.hpp +++ b/header/GscMemoryLPP.hpp @@ -1,12 +1,11 @@ #ifndef GSCMEMORY_HPP_ #define GSCMEMORY_HPP_ -static unsigned int getCacheControlRegister(){ - #ifndef LEON3 #define LEON3 #endif +static unsigned int getCacheControlRegister(){ #ifdef LEON3 unsigned int cacheControlRegister = 0; __asm__ __volatile__("lda [%%g0] 2, %0" : "=r"(cacheControlRegister) : ); @@ -14,8 +13,8 @@ static unsigned int getCacheControlRegis #endif } -static void setCacheControlRegister(unsigned int cacheControlRegister){ - +static void setCacheControlRegister(unsigned int cacheControlRegister) +{ #ifdef LEON3 __asm__ __volatile__("sta %0, [%%g0] 2" : : "r"(cacheControlRegister)); #endif @@ -23,17 +22,16 @@ static void setCacheControlRegister(unsi /** - * Flush the data cache and the instruction cache. - * - * @return - */ +* Flush the data cache and the instruction cache. +* +* @return +*/ static inline void flushCache() { asm("flush"); } static void enableInstructionCache() { - #ifdef LEON3 unsigned int cacheControlRegister; cacheControlRegister = getCacheControlRegister(); @@ -43,7 +41,6 @@ static void enableInstructionCache() { } static void enableDataCache() { - #ifdef LEON3 unsigned int cacheControlRegister; cacheControlRegister = getCacheControlRegister(); @@ -53,7 +50,6 @@ static void enableDataCache() { } static void enableInstructionBurstFetch() { - #ifdef LEON3 unsigned int cacheControlRegister; cacheControlRegister = getCacheControlRegister(); diff --git a/header/grlib_regs.h b/header/grlib_regs.h --- a/header/grlib_regs.h +++ b/header/grlib_regs.h @@ -45,9 +45,16 @@ typedef struct { volatile int coarse_time_load; volatile int coarse_time; volatile int fine_time; - volatile int temp_scm; - volatile int temp_pcb; - volatile int temp_fpga; + // TEMPERATURES + volatile int temp_pcb; // SEL1 = 0 SEL0 = 0 + volatile int temp_fpga; // SEL1 = 0 SEL0 = 1 + volatile int temp_scm; // SEL1 = 1 SEL0 = 0 + // CALIBRATION + volatile unsigned int calDACCtrl; + volatile unsigned int calPrescaler; + volatile unsigned int calDivisor; + volatile unsigned int calDataPtr; + volatile unsigned int calData; } time_management_regs_t; // PDB >= 0.1.28 diff --git a/header/tc_handler.h b/header/tc_handler.h --- a/header/tc_handler.h +++ b/header/tc_handler.h @@ -51,6 +51,17 @@ void set_sm_irq_onError( unsigned char v void updateLFRCurrentMode(); void set_lfr_soft_reset( unsigned char value ); void reset_lfr( void ); +// CALIBRATION +void setCalibrationPrescaler( unsigned int prescaler ); +void setCalibrationDivisor( unsigned int divisionFactor ); +void setCalibrationData( void ); +void setCalibrationReload( bool state); +void setCalibrationEnable( bool state ); +void setCalibrationInterleaved( bool state ); +void startCalibration( void ); +void stopCalibration( void ); +void configureCalibration( bool interleaved ); +// void update_last_TC_exe( ccsdsTelecommandPacket_t *TC , unsigned char *time ); void update_last_TC_rej(ccsdsTelecommandPacket_t *TC , unsigned char *time ); void close_action( ccsdsTelecommandPacket_t *TC, int result, rtems_id queue_id ); diff --git a/header/wf_handler.h b/header/wf_handler.h --- a/header/wf_handler.h +++ b/header/wf_handler.h @@ -11,7 +11,7 @@ #include "fsw_misc.h" #include "fsw_params_wf_handler.h" -#define pi 3.1415 +#define pi 3.14159265359 extern int fdSPW; diff --git a/src/fsw_init.c b/src/fsw_init.c --- a/src/fsw_init.c +++ b/src/fsw_init.c @@ -145,6 +145,9 @@ rtems_task Init( rtems_task_argument ign SM_reset_current_ring_nodes(); reset_spectral_matrix_regs(); + // configure calibration + configureCalibration( false ); // true means interleaved mode, false is for normal mode + updateLFRCurrentMode(); BOOT_PRINTF1("in INIT *** lfrCurrentMode is %d\n", lfrCurrentMode) diff --git a/src/fsw_misc.c b/src/fsw_misc.c --- a/src/fsw_misc.c +++ b/src/fsw_misc.c @@ -448,6 +448,11 @@ void get_temperatures( unsigned char *te unsigned char* temp_pcb_ptr; unsigned char* temp_fpga_ptr; + // SEL1 SEL0 + // 0 0 => PCB + // 0 1 => FPGA + // 1 0 => SCM + temp_scm_ptr = (unsigned char *) &time_management_regs->temp_scm; temp_pcb_ptr = (unsigned char *) &time_management_regs->temp_pcb; temp_fpga_ptr = (unsigned char *) &time_management_regs->temp_fpga; diff --git a/src/tc_handler.c b/src/tc_handler.c --- a/src/tc_handler.c +++ b/src/tc_handler.c @@ -11,6 +11,7 @@ */ #include "tc_handler.h" +#include "math.h" //*********** // RTEMS TASK @@ -267,13 +268,12 @@ int action_enable_calibration(ccsdsTelec */ int result; - unsigned char lfrMode; result = LFR_DEFAULT; - lfrMode = (housekeeping_packet.lfr_status_word[0] & 0xf0) >> 4; - send_tm_lfr_tc_exe_not_implemented( TC, queue_id, time ); - result = LFR_DEFAULT; + startCalibration(); + + result = LFR_SUCCESSFUL; return result; } @@ -288,13 +288,12 @@ int action_disable_calibration(ccsdsTele */ int result; - unsigned char lfrMode; result = LFR_DEFAULT; - lfrMode = (housekeeping_packet.lfr_status_word[0] & 0xf0) >> 4; - send_tm_lfr_tc_exe_not_implemented( TC, queue_id, time ); - result = LFR_DEFAULT; + stopCalibration(); + + result = LFR_SUCCESSFUL; return result; } @@ -823,6 +822,153 @@ void set_sm_irq_onError( unsigned char v } } +//***************************** +// CONFIGURE CALIBRATION SIGNAL +void setCalibrationPrescaler( unsigned int prescaler ) +{ + // prescaling of the master clock (25 MHz) + // master clock is divided by 2^prescaler + time_management_regs->calPrescaler = prescaler; +} + +void setCalibrationDivisor( unsigned int divisionFactor ) +{ + // division of the prescaled clock by the division factor + time_management_regs->calDivisor = divisionFactor; +} + +void setCalibrationData( void ){ + unsigned int k; + unsigned short data; + float val; + float f0; + float f1; + float fs; + float Ts; + float scaleFactor; + + f0 = 625; + f1 = 10000; + fs = 160256.410; + Ts = 1. / fs; + scaleFactor = 0.125 / 0.000654; // 191, 500 mVpp, 2 sinus waves => 250 mVpp each, amplitude = 125 mV + + time_management_regs->calDataPtr = 0x00; + + // build the signal for the SCM calibration + for (k=0; k<256; k++) + { + val = sin( 2 * pi * f0 * k * Ts ) + + sin( 2 * pi * f1 * k * Ts ); + data = (unsigned short) ((val * scaleFactor) + 2048); + time_management_regs->calData = data & 0xfff; + } +} + +void setCalibrationDataInterleaved( void ){ + unsigned int k; + float val; + float f0; + float f1; + float fs; + float Ts; + unsigned short data[384]; + unsigned char *dataPtr; + + f0 = 625; + f1 = 10000; + fs = 240384.615; + Ts = 1. / fs; + + time_management_regs->calDataPtr = 0x00; + + // build the signal for the SCM calibration + for (k=0; k<384; k++) + { + val = sin( 2 * pi * f0 * k * Ts ) + + sin( 2 * pi * f1 * k * Ts ); + data[k] = (unsigned short) (val * 512 + 2048); + } + + // write the signal in interleaved mode + for (k=0; k<128; k++) + { + dataPtr = (unsigned char*) &data[k*3 + 2]; + time_management_regs->calData = (data[k*3] & 0xfff) + + ( (dataPtr[0] & 0x3f) << 12); + time_management_regs->calData = (data[k*3 + 1] & 0xfff) + + ( (dataPtr[1] & 0x3f) << 12); + } +} + +void setCalibrationReload( bool state) +{ + if (state == true) + { + time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000010; // [0001 0000] + } + else + { + time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffef; // [1110 1111] + } +} + +void setCalibrationEnable( bool state ) +{ + // this bit drives the multiplexer + if (state == true) + { + time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000040; // [0100 0000] + } + else + { + time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffbf; // [1011 1111] + } +} + +void setCalibrationInterleaved( bool state ) +{ + // this bit drives the multiplexer + if (state == true) + { + time_management_regs->calDACCtrl = time_management_regs->calDACCtrl | 0x00000020; // [0010 0000] + } + else + { + time_management_regs->calDACCtrl = time_management_regs->calDACCtrl & 0xffffffdf; // [1101 1111] + } +} + +void startCalibration( void ) +{ + setCalibrationEnable( true ); + setCalibrationReload( false ); +} + +void stopCalibration( void ) +{ + setCalibrationEnable( false ); + setCalibrationReload( true ); +} + +void configureCalibration( bool interleaved ) +{ + stopCalibration(); + if ( interleaved == true ) + { + setCalibrationInterleaved( true ); + setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000 + setCalibrationDivisor( 26 ); // => 240 384 + setCalibrationDataInterleaved(); + } + else + { + setCalibrationPrescaler( 0 ); // 25 MHz => 25 000 000 + setCalibrationDivisor( 38 ); // => 160 256 (39 - 1) + setCalibrationData(); + } +} + //**************** // CLOSING ACTIONS void update_last_TC_exe( ccsdsTelecommandPacket_t *TC, unsigned char * time )