ctb: enable tengiga in server and moved everything to list implementation

This commit is contained in:
maliakal_d 2019-02-28 11:32:10 +01:00
parent 7f2197fc4f
commit 96584ce397
6 changed files with 191 additions and 171 deletions

View File

@ -3,7 +3,8 @@
#include "versionAPI.h" #include "versionAPI.h"
#include "logger.h" #include "logger.h"
#include "communication_funcs_UDP.h"
#include "UDPPacketHeaderGenerator.h"
#include "AD9257.h" // commonServerFunctions.h, blackfin.h, ansi.h #include "AD9257.h" // commonServerFunctions.h, blackfin.h, ansi.h
#include "AD7689.h" // slow adcs #include "AD7689.h" // slow adcs
#include "LTC2620.h" // dacs #include "LTC2620.h" // dacs
@ -22,8 +23,10 @@
// Global variable from slsDetectorServer_funcs // Global variable from slsDetectorServer_funcs
extern int debugflag; extern int debugflag;
extern int dataBytes;
extern char* ramValues; // Global variable from UDPPacketHeaderGenerator
extern uint64_t udpFrameNumber;
extern uint32_t udpPacketNumber;
int firmware_compatibility = OK; int firmware_compatibility = OK;
int firmware_check_done = 0; int firmware_check_done = 0;
@ -35,6 +38,9 @@ int virtual_status = 0;
int virtual_stop = 0; int virtual_stop = 0;
#endif #endif
int dataBytes = 0;
char* ramValues = 0;
char udpPacketData[UDP_PACKET_DATA_BYTES + sizeof(sls_detector_header)];
int32_t clkPhase[NUM_CLOCKS] = {0, 0, 0, 0}; int32_t clkPhase[NUM_CLOCKS] = {0, 0, 0, 0};
uint32_t clkDivider[NUM_CLOCKS] = {40, 20, 20, 200}; uint32_t clkDivider[NUM_CLOCKS] = {40, 20, 20, 200};
@ -540,8 +546,8 @@ void setupDetector() {
setTimer(DELAY_AFTER_TRIGGER, DEFAULT_DELAY); setTimer(DELAY_AFTER_TRIGGER, DEFAULT_DELAY);
setTiming(DEFAULT_TIMING_MODE); setTiming(DEFAULT_TIMING_MODE);
// send via tcp (moench via udp with configuremac) // 1G UDP
sendUDP(0); enableTenGigabitEthernet(0);
// clear roi // clear roi
{ {
int ret = OK, retvalsize = 0; int ret = OK, retvalsize = 0;
@ -1502,7 +1508,22 @@ int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t
return OK; return OK;
#endif #endif
FILE_LOG(logINFOBLUE, ("Configuring MAC\n")); FILE_LOG(logINFOBLUE, ("Configuring MAC\n"));
/*uint32_t sourceport = DEFAULT_TX_UDP_PORT; // 1 giga udp
if (!enableTenGigabitEthernet(-1)) {
char cDestIp[MAX_STR_LENGTH];
memset(cDestIp, 0, MAX_STR_LENGTH);
sprintf(cDestIp, "%d.%d.%d.%d", (destip>>24)&0xff,(destip>>16)&0xff,(destip>>8)&0xff,(destip)&0xff);
FILE_LOG(logINFO, ("1G UDP: Destination (IP: %s, port:%d)\n", cDestIp, udpport));
if (setUDPDestinationDetails(cDestIp, udpport) == FAIL) {
FILE_LOG(logERROR, ("could not set udp 1G destination IP and port\n"));
return FAIL;
}
return OK;
}
// 10 G
else {
uint32_t sourceport = DEFAULT_TX_UDP_PORT;
FILE_LOG(logINFO, ("\tSource IP : %d.%d.%d.%d \t\t(0x%08x)\n", FILE_LOG(logINFO, ("\tSource IP : %d.%d.%d.%d \t\t(0x%08x)\n",
(sourceip>>24)&0xff,(sourceip>>16)&0xff,(sourceip>>8)&0xff,(sourceip)&0xff, sourceip)); (sourceip>>24)&0xff,(sourceip>>16)&0xff,(sourceip>>8)&0xff,(sourceip)&0xff, sourceip));
@ -1561,27 +1582,32 @@ int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t
cleanFifos();//FIXME: resetPerpheral() for ctb? cleanFifos();//FIXME: resetPerpheral() for ctb?
resetPeripheral(); resetPeripheral();
usleep(WAIT_TIME_CONFIGURE_MAC); // todo maybe without usleep(WAIT_TIME_CONFIGURE_MAC); // todo maybe without
sendUDP(1); }
*/sendUDP(0);
return OK; return OK;
} }
int enableTenGigabitEthernet(int val) {
uint32_t addr = CONFIG_REG;
// set
if (val != -1) {
FILE_LOG(logINFO, ("Setting 10Gbe: %d\n", (val > 0) ? 1 : 0));
if (val > 0) {
bus_w(addr, bus_r(addr) | CONFIG_GB10_SND_UDP_MSK);
} else {
bus_w(addr, bus_r(addr) & (~CONFIG_GB10_SND_UDP_MSK));
}
//configuremac called from client
}
return ((bus_r(addr) & CONFIG_GB10_SND_UDP_MSK) >> CONFIG_GB10_SND_UDP_OFST);
}
/* ctb specific - pll, flashing fpga */ /* ctb specific - pll, flashing fpga */
int sendUDP(int enable) {
FILE_LOG(logINFO, ("Sending via %s\n", (enable ? "Receiver" : "CPU")));
uint32_t addr = CONFIG_REG;
if (enable > 0)
bus_w(addr, bus_r(addr) | CONFIG_GB10_SND_UDP_MSK);
else if (enable == 0)
bus_w(addr, bus_r(addr) & (~CONFIG_GB10_SND_UDP_MSK));
FILE_LOG(logDEBUG, ("\tConfig Reg: 0x%x\n", bus_r(addr)));
return ((bus_r(addr) & CONFIG_GB10_SND_UDP_MSK) >> CONFIG_GB10_SND_UDP_OFST);
}
// ind can only be ADC_CLK or DBIT_CLK // ind can only be ADC_CLK or DBIT_CLK
void configurePhase(enum CLKINDEX ind, int val) { void configurePhase(enum CLKINDEX ind, int val) {
@ -1980,8 +2006,17 @@ int startStateMachine(){
FILE_LOG(logINFOGREEN, ("Virtual Acquisition started\n")); FILE_LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
return OK; return OK;
#endif #endif
FILE_LOG(logINFOBLUE, ("Starting State Machine\n")); // 1 giga udp
if (!enableTenGigabitEthernet(-1)) {
// create udp socket
if(createUDPSocket() != OK) {
return FAIL;
}
// update header with modId, detType and version. Reset offset and fnum
createUDPPacketHeader(udpPacketData, getHardwareSerialNumber());
}
FILE_LOG(logINFOBLUE, ("Starting State Machine\n"));
cleanFifos(); cleanFifos();
unsetFifoReadStrobes(); // FIXME: unnecessary to write bus_w(dumm, 0) as it is 0 in the beginnig and the strobes are always unset if set unsetFifoReadStrobes(); // FIXME: unnecessary to write bus_w(dumm, 0) as it is 0 in the beginnig and the strobes are always unset if set
@ -2091,6 +2126,31 @@ enum runStatus getRunStatus(){
} }
void readandSendUDPFrames(int *ret, char *mess) {
FILE_LOG(logDEBUG1, ("Reading from 1G UDP\n"));
// validate udp socket
if (getUdPSocketDescriptor() <= 0) {
*ret = FAIL;
sprintf(mess,"UDP Socket not created. sockfd:%d\n", getUdPSocketDescriptor());
FILE_LOG(logERROR, (mess));
return;
}
// every frame read
while(readFrameFromFifo() == OK) {
int bytesToSend = 0, n = 0;
while((bytesToSend = fillUDPPacket(udpPacketData))) {
n += sendUDPPacket(udpPacketData, bytesToSend);
}
if (n >= dataBytes) {
FILE_LOG(logINFO, (" Frame %lld sent (%d packets, %d databytes, n:%d bytes sent)\n",
udpFrameNumber, udpPacketNumber + 1, dataBytes, n));
}
}
closeUDPSocket();
}
void readFrame(int *ret, char *mess) { void readFrame(int *ret, char *mess) {
#ifdef VIRTUAL #ifdef VIRTUAL
@ -2100,10 +2160,20 @@ void readFrame(int *ret, char *mess) {
} }
return; return;
#endif #endif
// 1G
if (!enableTenGigabitEthernet(-1)) {
readandSendUDPFrames(ret, mess);
}
// 10G
else {
// wait for acquisition to be done
while(runBusy()){ while(runBusy()){
usleep(500); // random usleep(500); // random
} }
}
// ret could be fail in 1gudp for not creating udp sockets
if (*ret != FAIL) {
// frames left to give status // frames left to give status
int64_t retval = getTimeLeft(FRAME_NUMBER) + 2; int64_t retval = getTimeLeft(FRAME_NUMBER) + 2;
if ( retval > 1) { if ( retval > 1) {
@ -2115,6 +2185,7 @@ void readFrame(int *ret, char *mess) {
FILE_LOG(logINFOGREEN, ("Acquisition successfully finished\n")); FILE_LOG(logINFOGREEN, ("Acquisition successfully finished\n"));
} }
} }
}
void unsetFifoReadStrobes() { void unsetFifoReadStrobes() {
bus_w(DUMMY_REG, bus_r(DUMMY_REG) & (~DUMMY_ANLG_FIFO_RD_STRBE_MSK) & (~DUMMY_DGTL_FIFO_RD_STRBE_MSK)); bus_w(DUMMY_REG, bus_r(DUMMY_REG) & (~DUMMY_ANLG_FIFO_RD_STRBE_MSK) & (~DUMMY_DGTL_FIFO_RD_STRBE_MSK));

View File

@ -1288,23 +1288,6 @@ int setDetectorPosition(int pos[]) {
} }
/* eiger specific - iodelay, 10g, pulse, rate, temp, activate, delay nw parameter */
int setIODelay(int val) {
if (val!=-1) {
FILE_LOG(logDEBUG1, ("Setting IO Delay: %d\n",val));
#ifndef VIRTUAL
if (Feb_Control_SetIDelays(Feb_Control_GetModuleNumber(),val))
#endif
eiger_iodelay = val;
}
return eiger_iodelay;
}
int enableTenGigabitEthernet(int val) { int enableTenGigabitEthernet(int val) {
if (val!=-1) { if (val!=-1) {
FILE_LOG(logINFO, ("Setting 10Gbe: %d\n", (val > 0) ? 1 : 0)); FILE_LOG(logINFO, ("Setting 10Gbe: %d\n", (val > 0) ? 1 : 0));
@ -1318,6 +1301,21 @@ int enableTenGigabitEthernet(int val) {
} }
/* eiger specific - iodelay, pulse, rate, temp, activate, delay nw parameter */
int setIODelay(int val) {
if (val!=-1) {
FILE_LOG(logDEBUG1, ("Setting IO Delay: %d\n",val));
#ifndef VIRTUAL
if (Feb_Control_SetIDelays(Feb_Control_GetModuleNumber(),val))
#endif
eiger_iodelay = val;
}
return eiger_iodelay;
}
int setCounterBit(int val) { int setCounterBit(int val) {
if (val!=-1) { if (val!=-1) {
FILE_LOG(logINFO, ("Setting Counter Bit: %d\n",val)); FILE_LOG(logINFO, ("Setting Counter Bit: %d\n",val));

View File

@ -158,7 +158,7 @@ void ALTERA_PLL_SetPhaseShift(int32_t phase, int clkIndex, int pos) {
((clkIndex << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK) | ((clkIndex << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK) |
(pos ? ALTERA_PLL_SHIFT_UP_DOWN_POS_VAL : ALTERA_PLL_SHIFT_UP_DOWN_NEG_VAL)); (pos ? ALTERA_PLL_SHIFT_UP_DOWN_POS_VAL : ALTERA_PLL_SHIFT_UP_DOWN_NEG_VAL));
FILE_LOG(logDEBUG1, ("\tC%d phase word:0x%08x\n", clkIndex, value)); FILE_LOG(logDEBUG1, ("C%d phase word:0x%08x\n", clkIndex, value));
// write phase shift // write phase shift
ALTERA_PLL_SetPllReconfigReg(ALTERA_PLL_PHASE_SHIFT_REG, value); ALTERA_PLL_SetPllReconfigReg(ALTERA_PLL_PHASE_SHIFT_REG, value);
@ -204,7 +204,7 @@ int ALTERA_PLL_SetOuputFrequency (int clkIndex, int pllVCOFreqMhz, int value) {
((high_count << ALTERA_PLL_C_COUNTER_HGH_CNT_OFST) & ALTERA_PLL_C_COUNTER_HGH_CNT_MSK) | ((high_count << ALTERA_PLL_C_COUNTER_HGH_CNT_OFST) & ALTERA_PLL_C_COUNTER_HGH_CNT_MSK) |
((odd_division << ALTERA_PLL_C_COUNTER_ODD_DVSN_OFST) & ALTERA_PLL_C_COUNTER_ODD_DVSN_MSK) | ((odd_division << ALTERA_PLL_C_COUNTER_ODD_DVSN_OFST) & ALTERA_PLL_C_COUNTER_ODD_DVSN_MSK) |
((clkIndex << ALTERA_PLL_C_COUNTER_SLCT_OFST) & ALTERA_PLL_C_COUNTER_SLCT_MSK)); ((clkIndex << ALTERA_PLL_C_COUNTER_SLCT_OFST) & ALTERA_PLL_C_COUNTER_SLCT_MSK));
FILE_LOG(logDEBUG1, ("\tC%d word:0x%08x\n", clkIndex, val)); FILE_LOG(logDEBUG1, ("C%d word:0x%08x\n", clkIndex, val));
// write frequency (post-scale output counter C) // write frequency (post-scale output counter C)
ALTERA_PLL_SetPllReconfigReg(ALTERA_PLL_C_COUNTER_REG, val); ALTERA_PLL_SetPllReconfigReg(ALTERA_PLL_C_COUNTER_REG, val);

View File

@ -21,6 +21,9 @@ unsigned short int udpDestinationPort = 0;
char udpDestinationIp[MAX_STR_LENGTH] = ""; char udpDestinationIp[MAX_STR_LENGTH] = "";
//DEFAULT_TX_UDP_PORT;// src port //DEFAULT_TX_UDP_PORT;// src port
int getUdPSocketDescriptor() {
return udpSockfd;
}
int setUDPDestinationDetails(const char* ip, unsigned short int port) { int setUDPDestinationDetails(const char* ip, unsigned short int port) {
udpDestinationPort = port; udpDestinationPort = port;

View File

@ -220,6 +220,9 @@ int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32
#if defined(JUNGFRAUD) || defined(EIGERD) #if defined(JUNGFRAUD) || defined(EIGERD)
int setDetectorPosition(int pos[]); int setDetectorPosition(int pos[]);
#endif #endif
#if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(EIGERD)
int enableTenGigabitEthernet(int val);
#endif
// very detector specific // very detector specific
@ -231,7 +234,6 @@ int powerChip (int on);
// chip test board specific - sendudp, pll, flashing firmware // chip test board specific - sendudp, pll, flashing firmware
#if defined(CHIPTESTBOARDD) || defined(MOENCHD) #if defined(CHIPTESTBOARDD) || defined(MOENCHD)
int sendUDP(int enable);
void configurePhase(enum CLKINDEX ind, int val); void configurePhase(enum CLKINDEX ind, int val);
int getPhase(enum CLKINDEX ind); int getPhase(enum CLKINDEX ind);
void configureFrequency(enum CLKINDEX ind, int val); void configureFrequency(enum CLKINDEX ind, int val);
@ -279,10 +281,9 @@ extern int startWritingFPGAprogram(FILE** filefp); // programfpga.h
extern void stopWritingFPGAprogram(FILE* filefp); // programfpga.h extern void stopWritingFPGAprogram(FILE* filefp); // programfpga.h
extern int writeFPGAProgram(char* fpgasrc, size_t fsize, FILE* filefp); // programfpga.h extern int writeFPGAProgram(char* fpgasrc, size_t fsize, FILE* filefp); // programfpga.h
// eiger specific - iodelay, 10g, pulse, rate, temp, activate, delay nw parameter // eiger specific - iodelay, pulse, rate, temp, activate, delay nw parameter
#elif EIGERD #elif EIGERD
int setIODelay(int val); int setIODelay(int val);
int enableTenGigabitEthernet(int val);
int setCounterBit(int val); int setCounterBit(int val);
int pulsePixel(int n, int x, int y); int pulsePixel(int n, int x, int y);
int pulsePixelNMove(int n, int x, int y); int pulsePixelNMove(int n, int x, int y);
@ -325,6 +326,7 @@ int startReadOut();
enum runStatus getRunStatus(); enum runStatus getRunStatus();
void readFrame(int *ret, char *mess); void readFrame(int *ret, char *mess);
#if defined(CHIPTESTBOARDD) || defined(MOENCHD) #if defined(CHIPTESTBOARDD) || defined(MOENCHD)
void readandSendUDPFrames(int *ret, char *mess);
void unsetFifoReadStrobes(); void unsetFifoReadStrobes();
void readSample(int ns); void readSample(int ns);
int checkDataPresent(); int checkDataPresent();

View File

@ -3,13 +3,6 @@
#include "communication_funcs.h" #include "communication_funcs.h"
#include "logger.h" #include "logger.h"
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
#include "communication_funcs_UDP.h"
#include "UDPPacketHeaderGenerator.h"
extern uint64_t udpFrameNumber;
extern uint32_t udpPacketNumber;
#endif
#include <string.h> #include <string.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <unistd.h> #include <unistd.h>
@ -42,10 +35,6 @@ extern char mess[MAX_STR_LENGTH];
// Variables that will be exported // Variables that will be exported
int sockfd = 0; int sockfd = 0;
int debugflag = 0; int debugflag = 0;
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
int dataBytes = 0;
char* ramValues = 0;
#endif
// Local variables // Local variables
int (*flist[NUM_DET_FUNCTIONS])(int); int (*flist[NUM_DET_FUNCTIONS])(int);
@ -1380,10 +1369,14 @@ int start_acquisition(int file_des) {
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
ret = startStateMachine(); ret = startStateMachine();
if (ret == FAIL) { if (ret == FAIL) {
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
sprintf(mess, "Could not start acquisition. Could not create udp socket in server. Check rx_udpip & rx_udpport.\n");
#else
sprintf(mess, "Could not start acquisition\n"); sprintf(mess, "Could not start acquisition\n");
#endif
FILE_LOG(logERROR,(mess)); FILE_LOG(logERROR,(mess));
} }
FILE_LOG(logDEBUG1, ("Starting Acquisition ret: %d\n", ret)); FILE_LOG(logDEBUG2, ("Starting Acquisition ret: %d\n", ret));
} }
return Server_SendResult(file_des, INT32, UPDATE, NULL, 0); return Server_SendResult(file_des, INT32, UPDATE, NULL, 0);
} }
@ -1464,10 +1457,14 @@ int start_and_read_all(int file_des) {
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
ret = startStateMachine(); ret = startStateMachine();
if (ret == FAIL) { if (ret == FAIL) {
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
sprintf(mess, "Could not start acquisition. Could not create udp socket in server. Check rx_udpip & rx_udpport.\n");
#else
sprintf(mess, "Could not start acquisition\n"); sprintf(mess, "Could not start acquisition\n");
#endif
FILE_LOG(logERROR,(mess)); FILE_LOG(logERROR,(mess));
} }
FILE_LOG(logDEBUG1, ("Starting Acquisition ret: %d\n", ret)); FILE_LOG(logDEBUG2, ("Starting Acquisition ret: %d\n", ret));
} }
@ -1489,59 +1486,8 @@ int read_all(int file_des) {
FILE_LOG(logDEBUG1, ("Reading all frames\n")); FILE_LOG(logDEBUG1, ("Reading all frames\n"));
// only set // only set
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
// read from fifo enabled
if (!sendUDP(-1)) {
FILE_LOG(logDEBUG1, ("Reading from 1G UDP\n"));
if (setUDPDestinationDetails("129.129.205.171", 50001) == OK) { // 10g,1 g
if (createUDPSocket() == OK) {
char buffer[UDP_PACKET_DATA_BYTES + sizeof(sls_detector_header)];
createUDPPacketHeader(buffer, getHardwareSerialNumber());
// keep reading frames
while(readFrameFromFifo() == OK) {
int bytesToSend = 0;
int n = 0;
// fill packet with pnum, nsamples per packet and data
while((bytesToSend = fillUDPPacket(buffer))) {
n += sendUDPPacket(buffer, bytesToSend);
}
if (n >= dataBytes)
FILE_LOG(logINFO, (" Frame %lld sent (%d packets, %d databytes, n:%d bytes sent)\n",
udpFrameNumber, udpPacketNumber + 1, dataBytes, n));
}
closeUDPSocket();
}
}
// finished readng frames
// frames left to give status
int64_t retval = getTimeLeft(FRAME_NUMBER) + 2;
if ( retval > 1) {
ret = FAIL;
sprintf(mess,"No data and run stopped: %lld frames left\n",(long long int)retval);
FILE_LOG(logERROR, (mess));
} else {
ret = OK; // send number of bytes (8) first to acknowledge finish of acquisition //FIXME
FILE_LOG(logINFOGREEN, ("Acquisition successfully finished\n"));
}
Server_SendResult(file_des, INT32, UPDATE, NULL, 0); // to the client
}
// read from receiver
else {
FILE_LOG(logDEBUG1, ("Reading via UDP\n"));
readFrame(&ret, mess); readFrame(&ret, mess);
} }
#else
readFrame(&ret, mess);
#endif
}
return Server_SendResult(file_des, INT32, UPDATE, NULL, 0); return Server_SendResult(file_des, INT32, UPDATE, NULL, 0);
} }
@ -2246,9 +2192,9 @@ int configure_mac(int file_des) {
{ {
int iloop = 5; int iloop = 5;
for (iloop = 5; iloop >= 0; --iloop) { for (iloop = 5; iloop >= 0; --iloop) {
FILE_LOG(logDEBUG1, ("%x", (unsigned int)(((dstMac >> (8 * iloop)) & 0xFF)))); printf ("%x", (unsigned int)(((dstMac >> (8 * iloop)) & 0xFF)));
if (iloop > 0) { if (iloop > 0) {
FILE_LOG(logDEBUG1, (":")); printf(":");
} }
} }
} }
@ -2269,9 +2215,9 @@ int configure_mac(int file_des) {
{ {
int iloop = 5; int iloop = 5;
for (iloop = 5; iloop >= 0; --iloop) { for (iloop = 5; iloop >= 0; --iloop) {
FILE_LOG(logDEBUG1, ("%x", (unsigned int)(((srcMac >> (8 * iloop)) & 0xFF)))); printf("%x", (unsigned int)(((srcMac >> (8 * iloop)) & 0xFF)));
if (iloop > 0) { if (iloop > 0) {
FILE_LOG(logDEBUG1, (":")); printf(":");
} }
} }
} }
@ -2489,7 +2435,7 @@ int enable_ten_giga(int file_des) {
return printSocketReadError(); return printSocketReadError();
FILE_LOG(logDEBUG1, ("Enable/ Disable 10GbE : %d\n", arg)); FILE_LOG(logDEBUG1, ("Enable/ Disable 10GbE : %d\n", arg));
#ifndef EIGERD #if defined(JUNGFRAUD) || defined(GOTTHARDD)
functionNotImplemented(); functionNotImplemented();
#else #else
// set & get // set & get