2023-11-20 17:47:12 -05:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <iostream>
|
|
|
|
#include <thread>
|
|
|
|
#include <fstream>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <vector>
|
|
|
|
#include <bitset>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <limits.h>
|
|
|
|
#include <ctime>
|
|
|
|
#include <sys/time.h> /* struct timeval, select() */
|
|
|
|
#include <termios.h> /* tcgetattr(), tcsetattr() */
|
|
|
|
|
|
|
|
#include "../RegisterAddress.h"
|
|
|
|
#include "../ClassDigitizer.h"
|
|
|
|
|
|
|
|
static struct termios g_old_kbd_mode;
|
|
|
|
static void cooked(void); ///set keyboard behaviour as wait-for-enter
|
|
|
|
static void uncooked(void); ///set keyboard behaviour as immediate repsond
|
|
|
|
static void raw(void);
|
|
|
|
int getch(void);
|
|
|
|
bool isNumeric(const std::string& str) ;
|
|
|
|
int keyboardhit();
|
|
|
|
|
|
|
|
Digitizer * digi = nullptr;
|
|
|
|
|
|
|
|
std::vector<Reg> RegList;
|
|
|
|
|
|
|
|
bool QuitFlag = false;
|
|
|
|
|
|
|
|
void PrintCommands(){
|
|
|
|
if (QuitFlag) return;
|
|
|
|
printf("\n");
|
|
|
|
printf("\e[96m============= Command List ===================\e[0m\n");
|
|
|
|
printf("q ) Quit \n");
|
|
|
|
printf("b ) Print Board Settings\n");
|
|
|
|
printf("c ) Print Channel Settings\n");
|
|
|
|
printf("x ) Export binary to text file\n");
|
|
|
|
printf("* invalid input = back to upper level \n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void keyPressCommand(){
|
|
|
|
|
|
|
|
char c = getch();
|
|
|
|
if (c == 'q') { //========== quit
|
|
|
|
QuitFlag = true;
|
|
|
|
}
|
|
|
|
if (c == 'b') { //==========
|
|
|
|
|
2024-03-02 00:33:08 -05:00
|
|
|
if( digi->GetDPPType() == DPPTypeCode::DPP_PHA_CODE || digi->GetDPPType() == DPPTypeCode::DPP_PSD_CODE ){
|
2023-11-20 17:47:12 -05:00
|
|
|
RegList = RegisterBoardList_PHAPSD;
|
2024-03-02 00:33:08 -05:00
|
|
|
}else if(digi->GetDPPType() == DPPTypeCode::DPP_QDC_CODE) {
|
2023-11-20 17:47:12 -05:00
|
|
|
RegList = RegisterBoardList_QDC;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( int i = 0; i < (int) RegList.size(); i++){
|
|
|
|
std::string typeStr ;
|
|
|
|
if( RegList[i].GetRWType() == RW::ReadWrite ) typeStr = "R/W";
|
|
|
|
if( RegList[i].GetRWType() == RW::ReadONLY ) typeStr = "R ";
|
|
|
|
if( RegList[i].GetRWType() == RW::WriteONLY ) typeStr = " W";
|
|
|
|
|
|
|
|
|
|
|
|
printf("%2d | 0x%04X %30s %s 0x%08X = %u\n", i,
|
|
|
|
RegList[i].GetAddress(),
|
|
|
|
RegList[i].GetNameChar(),
|
|
|
|
typeStr.c_str(),
|
|
|
|
digi->GetSettingFromMemory(RegList[i], 0),
|
|
|
|
digi->GetSettingFromMemory(RegList[i], 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string input = "-1";
|
|
|
|
cooked();
|
|
|
|
do{
|
|
|
|
std::cout << "Enter Setting ID to change the setting : ";
|
|
|
|
std::getline(std::cin, input);
|
|
|
|
|
|
|
|
if( !isNumeric(input) ) break;
|
|
|
|
|
|
|
|
int ID = atoi(input.c_str());
|
|
|
|
if( 0 <= ID && ID < (int) RegList.size() ){
|
|
|
|
|
|
|
|
printf("\e[34mSelected %s = 0x%08X = %u \e[0m\n", RegList[ID].GetNameChar(),
|
|
|
|
digi->GetSettingFromMemory(RegList[ID], 0),
|
|
|
|
digi->GetSettingFromMemory(RegList[ID], 0));
|
|
|
|
|
|
|
|
if( RegList[ID].GetRWType() == RW::ReadONLY ) {
|
|
|
|
printf("This register is READ-ONLY.\n");
|
|
|
|
}else if (RegList[ID].GetRWType() == RW::WriteONLY){
|
|
|
|
printf("This register is WRITE-ONLY, which is a command. no need to set value.\n");
|
|
|
|
}else{
|
|
|
|
std::cout << "What value ? ";
|
|
|
|
std::getline(std::cin, input);
|
|
|
|
if( isNumeric(input) ){
|
|
|
|
digi->SetSettingToMemory(RegList[ID], atoi(input.c_str()), 0);
|
|
|
|
digi->SaveSettingToFile(RegList[ID], atoi(input.c_str()), 0);
|
|
|
|
printf("\e[31mNow %s = 0x%08X = %u \e[0m\n", RegList[ID].GetNameChar(),
|
|
|
|
digi->GetSettingFromMemory(RegList[ID], 0),
|
|
|
|
digi->GetSettingFromMemory(RegList[ID], 0));
|
|
|
|
}else{
|
|
|
|
printf("Entered non numerical.\n");
|
|
|
|
input = "-1";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}while( isNumeric( input) );
|
|
|
|
uncooked();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( c == 'c' ){
|
|
|
|
cooked();
|
|
|
|
std::string input = "-1";
|
|
|
|
std::cout << "Enter channel number (# of ch = " << digi->GetNumRegChannels() << ") : ";
|
|
|
|
std::getline(std::cin, input);
|
|
|
|
|
|
|
|
if( !isNumeric(input) ) {
|
|
|
|
uncooked();
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
|
|
|
|
int ch = atoi(input.c_str());
|
|
|
|
|
|
|
|
if( ch < 0 || ch >= digi->GetNumRegChannels() ){
|
|
|
|
printf("Input channel number = %d, outrange of the supported channel\n", ch);
|
|
|
|
uncooked();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-03-02 00:33:08 -05:00
|
|
|
if( digi->GetDPPType() == DPPTypeCode::DPP_PHA_CODE ) RegList = RegisterChannelList_PHA;
|
|
|
|
if( digi->GetDPPType() == DPPTypeCode::DPP_PSD_CODE ) RegList = RegisterChannelList_PSD;
|
|
|
|
if( digi->GetDPPType() == DPPTypeCode::DPP_QDC_CODE ) RegList = RegisterChannelList_QDC;
|
2023-11-20 17:47:12 -05:00
|
|
|
|
|
|
|
for( int i = 0; i < (int) RegList.size(); i++){
|
|
|
|
std::string typeStr ;
|
|
|
|
if( RegList[i].GetRWType() == RW::ReadWrite ) typeStr = "R/W";
|
|
|
|
if( RegList[i].GetRWType() == RW::ReadONLY ) typeStr = "R ";
|
|
|
|
if( RegList[i].GetRWType() == RW::WriteONLY ) typeStr = " W";
|
|
|
|
|
|
|
|
RegList[i].ActualAddress(ch);
|
|
|
|
|
|
|
|
printf("%2d | 0x%04X %30s %s 0x%08X = %u\n", i,
|
|
|
|
RegList[i].GetAddress(),
|
|
|
|
RegList[i].GetNameChar(),
|
|
|
|
typeStr.c_str(),
|
|
|
|
digi->GetSettingFromMemory(RegList[i], ch),
|
|
|
|
digi->GetSettingFromMemory(RegList[i], ch));
|
|
|
|
}
|
|
|
|
|
|
|
|
do{
|
|
|
|
std::cout << "Enter Setting ID to change the setting : ";
|
|
|
|
std::getline(std::cin, input);
|
|
|
|
|
|
|
|
if( !isNumeric(input) ) break;
|
|
|
|
|
|
|
|
int ID = atoi(input.c_str());
|
|
|
|
if( 0 <= ID && ID < (int) RegList.size() ){
|
|
|
|
|
|
|
|
printf("\e[34mID=%d | ch-%d | Selected %s = 0x%08X = %u \e[0m\n", ID, ch, RegList[ID].GetNameChar(),
|
|
|
|
digi->GetSettingFromMemory(RegList[ID], ch),
|
|
|
|
digi->GetSettingFromMemory(RegList[ID], ch));
|
|
|
|
|
|
|
|
if( RegList[ID].GetRWType() == RW::ReadONLY ) {
|
|
|
|
printf("This register is READ-ONLY.\n");
|
|
|
|
}else if (RegList[ID].GetRWType() == RW::WriteONLY){
|
|
|
|
printf("This register is WRITE-ONLY, which is a command. no need to set value.\n");
|
|
|
|
}else{
|
|
|
|
std::cout << "What value (negative will change all channels) ? ";
|
|
|
|
std::getline(std::cin, input);
|
|
|
|
if( isNumeric(input) ){
|
|
|
|
|
|
|
|
int value = atoi(input.c_str());
|
|
|
|
|
|
|
|
printf(" input : %s %d\n", input.c_str(), value);
|
|
|
|
if( value < 0 ){
|
|
|
|
value = abs(value);
|
|
|
|
for( int i = 0; i < digi->GetNumRegChannels(); i++){
|
|
|
|
digi->SetSettingToMemory(RegList[ID], value, i);
|
|
|
|
digi->SaveSettingToFile(RegList[ID], value, i);
|
|
|
|
printf("\e[31mNow ch-%2d %s = 0x%08X = %u \e[0m\n", i, RegList[ID].GetNameChar(),
|
|
|
|
digi->GetSettingFromMemory(RegList[ID], i),
|
|
|
|
digi->GetSettingFromMemory(RegList[ID], i));
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
|
|
|
|
|
|
|
|
digi->SetSettingToMemory(RegList[ID], value, ch);
|
|
|
|
digi->SaveSettingToFile(RegList[ID], value, ch);
|
|
|
|
printf("\e[31mNow ch-%2d %s = 0x%08X = %u \e[0m\n", ch, RegList[ID].GetNameChar(),
|
|
|
|
digi->GetSettingFromMemory(RegList[ID], ch),
|
|
|
|
digi->GetSettingFromMemory(RegList[ID], ch));
|
|
|
|
|
|
|
|
if( RegList[ID].IsCoupled() ){
|
|
|
|
int cpCh = (ch%2 == 0 ? ch + 1 : ch - 1);
|
|
|
|
digi->SetSettingToMemory(RegList[ID], value, cpCh);
|
|
|
|
digi->SaveSettingToFile(RegList[ID], value, cpCh);
|
|
|
|
printf("\e[31mNow ch-%2d %s = 0x%08X = %u \e[0m\n", cpCh, RegList[ID].GetNameChar(),
|
|
|
|
digi->GetSettingFromMemory(RegList[ID], cpCh),
|
|
|
|
digi->GetSettingFromMemory(RegList[ID], cpCh));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
printf("Entered non numerical.\n");
|
|
|
|
input = "-1";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}while( isNumeric( input) );
|
|
|
|
|
|
|
|
|
|
|
|
uncooked();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c == 'x') { //==========
|
|
|
|
cooked(); ///set keyboard need enter to responds
|
|
|
|
|
|
|
|
std::string input = "haha.txt";
|
|
|
|
std::cout << "Eneter file name : ";
|
|
|
|
std::getline(std::cin, input);
|
|
|
|
digi->SaveAllSettingsAsText(input);
|
|
|
|
uncooked();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//################################################
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
|
|
|
|
printf("=========================================\n");
|
|
|
|
printf("=== Setting Binary Explorer ===\n");
|
|
|
|
printf("=========================================\n");
|
|
|
|
if (argc != 2) {
|
|
|
|
printf("Incorrect number of arguments:\n");
|
|
|
|
printf("%s *bin \n", argv[0]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
digi = new Digitizer();
|
|
|
|
digi->LoadSettingBinaryToMemory(argv[1]);
|
|
|
|
|
2024-03-02 00:33:08 -05:00
|
|
|
if( !(digi->GetDPPType() == DPPTypeCode::DPP_PHA_CODE ||
|
|
|
|
digi->GetDPPType() == DPPTypeCode::DPP_PSD_CODE ||
|
|
|
|
digi->GetDPPType() == DPPTypeCode::DPP_QDC_CODE )){
|
2023-11-20 17:47:12 -05:00
|
|
|
printf("DPP-type not supported. Or Binary file is not supported.\n");
|
|
|
|
delete digi;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//digi->PrintSettingFromMemory();
|
|
|
|
|
|
|
|
PrintCommands();
|
|
|
|
|
|
|
|
do{
|
|
|
|
|
|
|
|
if(keyboardhit()) {
|
|
|
|
|
|
|
|
keyPressCommand();
|
|
|
|
|
|
|
|
PrintCommands();
|
|
|
|
}
|
|
|
|
|
|
|
|
}while(!QuitFlag);
|
|
|
|
|
|
|
|
delete digi;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//################################################
|
|
|
|
|
|
|
|
bool isNumeric(const std::string& str) {
|
|
|
|
try {
|
|
|
|
size_t pos = 0;
|
|
|
|
std::stoi(str, &pos);
|
|
|
|
return pos == str.size(); // Check if the entire string was used in conversion
|
|
|
|
} catch (...) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cooked(void){
|
|
|
|
tcsetattr(0, TCSANOW, &g_old_kbd_mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void uncooked(void){
|
|
|
|
struct termios new_kbd_mode;
|
|
|
|
/* put keyboard (stdin, actually) in raw, unbuffered mode */
|
|
|
|
tcgetattr(0, &g_old_kbd_mode);
|
|
|
|
memcpy(&new_kbd_mode, &g_old_kbd_mode, sizeof(struct termios));
|
|
|
|
new_kbd_mode.c_lflag &= ~(ICANON | ECHO);
|
|
|
|
new_kbd_mode.c_cc[VTIME] = 0;
|
|
|
|
new_kbd_mode.c_cc[VMIN] = 1;
|
|
|
|
tcsetattr(0, TCSANOW, &new_kbd_mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void raw(void){
|
|
|
|
|
|
|
|
static char init;
|
|
|
|
if(init) return;
|
|
|
|
/* put keyboard (stdin, actually) in raw, unbuffered mode */
|
|
|
|
uncooked();
|
|
|
|
/* when we exit, go back to normal, "cooked" mode */
|
|
|
|
atexit(cooked);
|
|
|
|
|
|
|
|
init = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int getch(void){
|
|
|
|
unsigned char temp;
|
|
|
|
raw();
|
|
|
|
/* stdin = fd 0 */
|
|
|
|
if(read(0, &temp, 1) != 1) return 0;
|
|
|
|
//printf("%s", &temp);
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
int keyboardhit(){
|
|
|
|
|
|
|
|
struct timeval timeout;
|
|
|
|
fd_set read_handles;
|
|
|
|
int status;
|
|
|
|
|
|
|
|
raw();
|
|
|
|
/* check stdin (fd 0) for activity */
|
|
|
|
FD_ZERO(&read_handles);
|
|
|
|
FD_SET(0, &read_handles);
|
|
|
|
timeout.tv_sec = timeout.tv_usec = 0;
|
|
|
|
status = select(0 + 1, &read_handles, NULL, NULL, &timeout);
|
|
|
|
if(status < 0){
|
|
|
|
printf("select() failed in keyboardhit()\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
return (status);
|
|
|
|
}
|