stompbox_mod::stompbox_mod(QWidget *parent) : stompBox(parent) { /* MOD */ setImage(":/images/mod.png"); setLSB("07", "15"); setComboBox("07", "00", "16"); setKnob1("07", "CENTER", "17"); setSwitch("07", "00", "15"); editDetails()->patchPos(1522, 138, "07", "15"); //correct setEditPages(); }
stompbox_mfx::stompbox_mfx(QWidget *parent) : stompBox(parent) { /* MFX */ setImage(":/images/mfx.png"); setLSB("03", "04"); setComboBox("03", "00", "05"); setSwitch("03", "00", "04"); setKnob1("03", "CENTER", "06"); editDetails()->patchPos(776, 530, "03", "04"); //correct setEditPages(); }
stompbox_amp::stompbox_amp(QWidget *parent) : stompBox(parent) { /* AMP */ setImage(":/images/amp.png"); setLSB("07", "00"); setKnob1("07", "00", "02"); setKnob2("07", "00", "03"); setComboBox("07", "00", "01"); setSwitch("07", "00", "00"); editDetails()->patchPos(1480, 34, "07", "00"); //correct setEditPages(); }
stompbox_dd::stompbox_dd(QWidget *parent) : stompBox(parent) { /* DELAY */ setImage(":/images/dd.png"); setLSB("06", "05"); setKnob1("06", "00", "0B"); setKnob2("06", "00", "0A"); setComboBox("06", "00", "06"); setSwitch("06", "00", "05"); editDetails()->patchPos(1404, 14, "06", "05"); //correct setEditPages(); }
void SwitchingFunction::setSwitchType(SwitchingFunctionType sft) { if ((sft == fifth_order_poly) || (sft == cubic)) { if (haveSpline_) { delete switchSpline_; switchSpline_ = new CubicSpline(); setSwitch(rin_, rout_); } } else { sprintf( painCave.errMsg, "SwitchingFunction::setSwitchType was given unknown function type\n"); painCave.severity = OPENMD_ERROR; painCave.isFatal = 1; simError(); } }
stompbox_eq::stompbox_eq(QWidget *parent) : stompBox(parent) { /* EQ */ setImage(":/images/eq.png"); setLSB("06", "11"); setSlider1("06", "00", "13"); setSlider2("06", "00", "16"); setSlider3("06", "00", "19"); setSlider4("06", "00", "1B"); setSlider5("06", "00", "1C"); setComboBox("06", "00", "1D"); setSwitch("06", "00", "11"); editDetails()->patchPos(1428, 26, "06", "11"); //correct setEditPages(); }
/** \internal */ bool GetOpt::parse( bool untilFirstSwitchOnly ) { // qDebug( "parse(%s)", args.join( QString( "," ) ).ascii() ); // push all arguments as we got them on a stack // more pushes might following when parsing condensed arguments // like --key=value. QValueStack<QString> stack; { QStringList::const_iterator it = args.fromLast(); const QStringList::const_iterator end = args.end(); while ( it != end ) { stack.push( *it ); --it; } } const OptionConstIterator obegin = options.begin(); const OptionConstIterator oend = options.end(); enum { StartState, ExpectingState, OptionalState } state = StartState; Option currOpt; enum TokenType { LongOpt, ShortOpt, Arg, End } t, currType = End; bool extraLoop = true; // we'll do an extra round. fake an End argument while ( !stack.isEmpty() || extraLoop ) { QString a; QString origA; // identify argument type if ( !stack.isEmpty() ) { a = stack.pop(); currArg++; origA = a; // qDebug( "popped %s", a.ascii() ); if ( a.startsWith( QString::fromLatin1( "--" ) ) ) { // recognized long option a = a.mid( 2 ); if ( a.isEmpty() ) { qWarning( "'--' feature not supported, yet" ); exit( 2 ); } t = LongOpt; // split key=value style arguments int equal = a.find( '=' ); if ( equal >= 0 ) { stack.push( a.mid( equal + 1 ) ); currArg--; a = a.left( equal ); } } else if ( a.length() == 1 ) { t = Arg; } else if ( a[0] == '-' ) { #if 0 // compat mode for -long style options if ( a.length() == 2 ) { t = ShortOpt; a = a[1]; } else { a = a.mid( 1 ); t = LongOpt; // split key=value style arguments int equal = a.find( '=' ); if ( equal >= 0 ) { stack.push( a.mid( equal + 1 ) ); currArg--; a = a.left( equal ); } } #else // short option t = ShortOpt; // followed by an argument ? push it for later processing. if ( a.length() > 2 ) { stack.push( a.mid( 2 ) ); currArg--; } a = a[1]; #endif } else { t = Arg; } } else { // faked closing argument t = End; } // look up among known list of options Option opt; if ( t != End ) { OptionConstIterator oit = obegin; while ( oit != oend ) { const Option &o = *oit; if ( ( t == LongOpt && a == o.lname ) || // ### check state ( t == ShortOpt && a[0].unicode() == o.sname ) ) { opt = o; break; } ++oit; } if ( t == LongOpt && opt.type == OUnknown ) { if ( currOpt.type != OVarLen ) { qWarning( "Unknown option --%s", a.ascii() ); return false; } else { // VarLength options support arguments starting with '-' t = Arg; } } else if ( t == ShortOpt && opt.type == OUnknown ) { if ( currOpt.type != OVarLen ) { qWarning( "Unknown option -%c", a[0].unicode() ); return false; } else { // VarLength options support arguments starting with '-' t = Arg; } } } else { opt = Option( OEnd ); } // interpret result switch ( state ) { case StartState: if ( opt.type == OSwitch ) { setSwitch( opt ); setOptions.insert( opt.lname, 1 ); setOptions.insert( QString( QChar( opt.sname ) ), 1 ); } else if ( opt.type == OArg1 || opt.type == ORepeat ) { state = ExpectingState; currOpt = opt; currType = t; setOptions.insert( opt.lname, 1 ); setOptions.insert( QString( QChar( opt.sname ) ), 1 ); } else if ( opt.type == OOpt || opt.type == OVarLen ) { state = OptionalState; currOpt = opt; currType = t; setOptions.insert( opt.lname, 1 ); setOptions.insert( QString( QChar( opt.sname ) ), 1 ); } else if ( opt.type == OEnd ) { // we're done } else if ( opt.type == OUnknown && t == Arg ) { if ( numReqArgs > 0 ) { if ( reqArg.stringValue->isNull() ) { // ### *reqArg.stringValue = a; } else { qWarning( "Too many arguments" ); return false; } } else if ( numOptArgs > 0 ) { if ( optArg.stringValue->isNull() ) { // ### *optArg.stringValue = a; } else { qWarning( "Too many arguments" ); return false; } } } else { qFatal( "unhandled StartState case %d", opt.type ); } break; case ExpectingState: if ( t == Arg ) { if ( currOpt.type == OArg1 ) { *currOpt.stringValue = a; state = StartState; } else if ( currOpt.type == ORepeat ) { currOpt.listValue->append( a ); state = StartState; } else { abort(); } } else { QString n = currType == LongOpt ? currOpt.lname : QString( QChar( currOpt.sname ) ); qWarning( "Expected an argument after '%s' option", n.ascii() ); return false; } break; case OptionalState: if ( t == Arg ) { if ( currOpt.type == OOpt ) { *currOpt.stringValue = a; state = StartState; } else if ( currOpt.type == OVarLen ) { currOpt.listValue->append( origA ); // remain in this state } else { abort(); } } else { // optional argument not specified if ( currOpt.type == OOpt ) *currOpt.stringValue = currOpt.def; if ( t != End ) { // re-evaluate current argument stack.push( origA ); currArg--; } state = StartState; } break; } if ( untilFirstSwitchOnly && opt.type == OSwitch ) return true; // are we in the extra loop ? if so, flag the final end if ( t == End ) extraLoop = false; } if ( numReqArgs > 0 && reqArg.stringValue->isNull() ) { qWarning( "Lacking required argument" ); return false; } return true; }
static void parseCommand(uint8_t* line) { /* ======================== Action commands ======================== */ /** <b>Action Commands</b> */ if (line[0] == 'a') { /** <ul> <li> <b>Snm</b> Manually set Switch. Follow by battery n (1-3, 0 = none) and load m (0-1)/panel (2). Each two-bit field represents a load or panel, and the setting is the battery to be connected (no two batteries can be connected to a load/panel). */ switch (line[1]) { case 'S': { uint8_t battery = line[2]-'0'; uint8_t setting = line[3]-'0'-1; if ((battery < 4) && (setting < 4)) setSwitch(battery, setting); if (setting == 2) setPanelSwitchSetting(battery); break; } /** <li> <b>Rn</b> Reset a tripped overcurrent circuit breaker. Set a FreeRTOS timer to expire after 250ms at which time the reset line is released. The command is followed by an interface number n=0-5 being batteries 1-3, loads 1-2 and module. */ case 'R': { portTickType resetTime = 250; intf = line[2]-'0'; if (intf > NUM_IFS-1) break; xTimerHandle resetHandle = xTimerCreate("Reset",resetTime,pdFALSE,(void *)intf,resetCallback); if(resetHandle == NULL) break; if (xTimerStart(resetHandle,0) != pdPASS) break; overCurrentReset(intf); break; } /** <li> <b>W</b> Write the current configuration block to FLASH */ case 'W': { writeConfigBlock(); break; } /** <li> <b>E</b> Send an ident response */ case 'E': { char ident[35] = "Battery Management System,"; stringAppend(ident,FIRMWARE_VERSION); stringAppend(ident,","); char version[3]; intToAscii(VERSION,version); stringAppend(ident,version); sendStringLowPriority("dE",ident); break; } /** <li> <b>B</b> Set the battery SoC from the measured OCV */ case 'B': { uint8_t battery = line[2]-'1'; setBatterySoC(battery,computeSoC(getBatteryVoltage(battery), getTemperature(),getBatteryType(battery))); break; } } } /** </ul> */ /* ======================== Data request commands ================ */ /** <b>Data Request Commands</b> */ else if (line[0] == 'd') { switch (line[1]) { /** <ul> <li> <b>S</b> Ask for all switch settings to be sent as well as control settings. */ case 'S': { sendResponse("dS",(int)getSwitchControlBits()); uint8_t controlByte = getControls(); sendResponse("dD",controlByte); break; } /** <li> <b>Bn</b> Ask for battery n=1-3 parameters to be sent */ case 'B': { char id[] = "pR0"; id[2] = line[2]; uint8_t battery = line[2] - '1'; dataMessageSend(id,getBatteryResistanceAv(battery),0); id[1] = 'T'; dataMessageSend(id,(int32_t)configData.config.batteryType[battery], (int32_t)configData.config.batteryCapacity[battery]); id[1] = 'F'; dataMessageSend(id,(int32_t)configData.config. floatStageCurrentScale[battery], (int32_t)configData.config.floatVoltage[battery]); id[1] = 'A'; dataMessageSend(id,(int32_t)configData.config. bulkCurrentLimitScale[battery], (int32_t)configData.config.absorptionVoltage[battery]); break; } /** <li> <b>T</b> Ask for monitor strategy parameters to be sent. */ case 'T': { char id[] = "pts"; dataMessageSend(id,(int32_t)configData.config.monitorStrategy,0); id[2] = 'V'; dataMessageSend(id,(int32_t)configData.config.lowVoltage, (int32_t)configData.config.criticalVoltage); id[2] = 'S'; dataMessageSend(id,(int32_t)configData.config.lowSoC, (int32_t)configData.config.criticalSoC); id[2] = 'F'; dataMessageSend(id,(int32_t)configData.config.floatBulkSoC,0); break; } /** <li> <b>C</b> Ask for charger strategy parameters to be sent. */ case 'C': { char id[] = "pcs"; dataMessageSend(id,(int32_t)configData.config.chargerStrategy,0); id[2] = 'R'; dataMessageSend(id,(int32_t)configData.config.restTime, (int32_t)configData.config.absorptionTime); id[2] = 'D'; dataMessageSend(id,(int32_t)configData.config.minDutyCycle,0); id[2] = 'F'; dataMessageSend(id,(int32_t)configData.config.floatTime, (int32_t)configData.config.floatBulkSoC); break; } } } /** </ul> */ /* ================ Parameter Setting commands ================ */ /** <b>Parameter Setting Commands</b> */ else if (line[0] == 'p') { uint8_t battery = line[2]-'1'; switch (line[1]) { /** <ul> <li> <b>a-, a+</b> Turn autoTracking on or off */ case 'a': { if (line[2] == '-') configData.config.autoTrack = false; else if (line[2] == '+') configData.config.autoTrack = true; break; } /** <li> <b>c-, c+</b> Turn communications sending on or off */ case 'c': { if (line[2] == '-') configData.config.enableSend = false; else if (line[2] == '+') configData.config.enableSend = true; break; } /** <li> <b>C</b> Start a calibration sequence */ case 'C': { startCalibration(); break; } /** <li> <b>d-, d+</b> Turn on debug messages */ case 'd': { if (line[2] == '+') configData.config.debugMessageSend = true; if (line[2] == '-') configData.config.debugMessageSend = false; break; } /** <li> <b>Hxxxx</b> Set time from an ISO 8601 formatted string. */ case 'H': { setTimeFromString((char*)line+2); break; } /** <li> <b>M-, M+</b> Turn on/off data messaging (mainly for debug) */ case 'M': { if (line[2] == '-') configData.config.measurementSend = false; else if (line[2] == '+') configData.config.measurementSend = true; break; } /** <li> <b>r-, r+</b> Turn recording on or off */ case 'r': { if (line[2] == '-') configData.config.recording = false; else if ((line[2] == '+') && (writeFileHandle < 0x0FF)) configData.config.recording = true; break; } /*--------------------*/ /* BATTERY parameters */ /** <li> <b>Tntxx</b> Set battery type and capacity, n is battery, t is type, xx is capacity */ case 'T': { if (battery < 3) { uint8_t type = line[3]-'0'; if (type < 3) { configData.config.batteryType[battery] = (battery_Type)type; configData.config.batteryCapacity[battery] = asciiToInt((char*)line+4); setBatteryChargeParameters(battery); } } break; } /** <li> <b>m-, m+</b> Turn on/off battery missing */ case 'm': { if (line[3] == '-') setBatteryMissing(battery,false); else if (line[3] == '+') setBatteryMissing(battery,true); break; } /** <li> <b>Inxx</b> Set bulk current limit, n is battery, xx is limit */ case 'I': { if (battery < 3) configData.config.bulkCurrentLimitScale[battery] = asciiToInt((char*)line+3); break; } /** <li> <b>Anxx</b> Set battery gassing voltage limit, n is battery, xx is limit */ case 'A': { if (battery < 3) configData.config.absorptionVoltage[battery] = asciiToInt((char*)line+3); break; } /** <li> <b>fnxx</b> Set battery float current trigger, n is battery, xx is trigger */ case 'f': { if (battery < 3) configData.config.floatStageCurrentScale[battery] = asciiToInt((char*)line+3); break; } /** <li> <b>Fnxx</b> Set battery float voltage limit, n is battery, xx is limit */ case 'F': { if (battery < 3) configData.config.floatVoltage[battery] = asciiToInt((char*)line+3); break; } /** <li> <b>zn</b> zero current calibration by forcing current offset, n is battery */ case 'z': { if (battery < 3) setCurrentOffset(battery,getCurrent(battery)); break; } /*--------------------*/ /* MONITOR parameters */ /** <li> <b>sm</b> Set monitor strategy byte m for keeping isolation or avoiding loading the battery under charge. */ case 's': { uint8_t monitorStrategy = line[2]-'0'; if (monitorStrategy <= 3) configData.config.monitorStrategy = monitorStrategy; break; } /** <li> <b>vx</b> set low voltage threshold, x is voltage times 256. */ case 'v': { configData.config.lowVoltage = asciiToInt((char*)line+2); break; } /** <li> <b>Vx</b> set critical voltage threshold, x is voltage times 256. */ case 'V': { configData.config.criticalVoltage = asciiToInt((char*)line+2); break; } /** <li> <b>xx</b> set low SoC threshold, x is voltage times 256. */ case 'x': { configData.config.lowSoC = asciiToInt((char*)line+2); break; } /** <li> <b>Xx</b> set critical SoC threshold, x is voltage times 256. */ case 'X': { configData.config.criticalSoC = asciiToInt((char*)line+2); break; } /*--------------------*/ /* CHARGER parameters */ /** <li> <b>Sm</b> set charger strategy byte m. */ case 'S': { uint8_t chargerStrategy = line[2]-'0'; if (chargerStrategy < 2) configData.config.chargerStrategy = chargerStrategy; break; } /** <li> <b>Rx</b> set charger algorithm minimum rest time x in seconds. */ case 'R': { configData.config.restTime = asciiToInt((char*)line+2); break; } /** <li> <b>Ax</b> set charger algorithm minimum gassing phase time x in seconds. */ case 'G': { configData.config.absorptionTime = asciiToInt((char*)line+2); break; } /** <li> <b>Dx</b> set charger minimum duty cycle x in seconds. */ case 'D': { configData.config.minDutyCycle = asciiToInt((char*)line+2); break; } /** <li> <b>Fx</b> set charger time to float x in seconds. */ case 'e': { configData.config.floatTime = asciiToInt((char*)line+2); break; } /** <li> <b>Bx</b> set charger SoC x to change from float to bulk phase. */ case 'B': { configData.config.floatBulkSoC = asciiToInt((char*)line+2); break; } } } /** </ul> */ /* ======================== File commands ================ */ /* F - get free clusters Wfilename - Open file for read/write. Filename is 8.3 string style. Returns handle. Rfilename - Open file read only. Filename is 8.3 string style. Returns handle. Xfilename - Delete the file. Filename is 8.3 string style. Cxx - Close file. x is the file handle. Gxx - Read a record from read or write file. Ddirname - Get a directory listing. Directory name is 8.3 string style. d[dirname] - Get the first (if dirname present) or next entry in directory. s - Get status of open files and configData.config.recording flag M - Mount the SD card. All commands return an error status byte at the end. Only one file for writing and a second for reading is possible. Data is not written to the file externally. */ /** <b>File Commands</b> */ else if (line[0] == 'f') { switch (line[1]) { /** <ul> <li> <b>F</b> Return number of free clusters followed by the cluster size in bytes. */ case 'F': { uint8_t wordBuf; uint32_t freeClusters = 0; uint32_t sectorCluster = 0; uint8_t fileStatus = FR_INT_ERR; if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT)) { sendFileCommand('F',0,line+2); uint8_t i; for (i=0; i<4; i++) { wordBuf = 0; xQueueReceive(fileReceiveQueue,&wordBuf,portMAX_DELAY); freeClusters |= (wordBuf << 8*i); } for (i=0; i<4; i++) { wordBuf = 0; xQueueReceive(fileReceiveQueue,&wordBuf,portMAX_DELAY); sectorCluster |= (wordBuf << 8*i); } dataMessageSend("fF",freeClusters,sectorCluster); xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY); xSemaphoreGive(fileSendSemaphore); } sendResponse("fE",(uint8_t)fileStatus); break; } /** <li> <b>Wf</b> Open a file f=filename for writing */ case 'W': { if (stringLength((char*)line+2) < 12) { uint8_t fileStatus = FR_INT_ERR; if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT)) { stringCopy(writeFileName,(char*)line+2); sendFileCommand('W',13,line+2); xQueueReceive(fileReceiveQueue,&writeFileHandle,portMAX_DELAY); sendResponse("fW",writeFileHandle); xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY); xSemaphoreGive(fileSendSemaphore); } sendResponse("fE",(uint8_t)fileStatus); } break; } /** <li> <b>Rf</b> Open a file f=filename for Reading */ case 'R': { if (stringLength((char*)line+2) < 12) { uint8_t fileStatus = FR_INT_ERR; if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT)) { stringCopy(readFileName,(char*)line+2); sendFileCommand('R',13,line+2); xQueueReceive(fileReceiveQueue,&readFileHandle,portMAX_DELAY); sendResponse("fR",readFileHandle); xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY); xSemaphoreGive(fileSendSemaphore); } sendResponse("fE",(uint8_t)fileStatus); } break; } /** <li> <b>Ghh</b> hh is the file handle. Close file for write or read file. The file handle is a two character integer. */ case 'C': { uint8_t fileStatus = FR_INT_ERR; if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT)) { uint8_t fileHandle = asciiToInt((char*)line+2); sendFileCommand('C',1,&fileHandle); xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY); if (fileStatus == FR_OK) { if (writeFileHandle == fileHandle) { writeFileHandle = 0xFF; writeFileName[0] = 0; } else if (readFileHandle == fileHandle) { readFileHandle = 0xFF; readFileName[0] = 0; } } xSemaphoreGive(fileSendSemaphore); } sendResponse("fE",(uint8_t)fileStatus); break; } /** <li> <b>Ghh</b> hh is the file handle. Read a record of data from the read or write file. The data starts from the end of the previous block that was read (or the file start if just opened). The file handle is a two character integer. A block of bytes is read from the file and stored in a circular buffer. A record is taken from this block and sent, the rest remains in the buffer until the next request. */ #define GET_RECORD_SIZE 80 case 'G': { uint8_t fileStatus = FR_INT_ERR; if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT)) { int numberRecords = asciiToInt((char*)line+2); if (numberRecords < 1) numberRecords = 1; static FRESULT fileStatus = FR_OK; static uint8_t buffer[GET_RECORD_SIZE]; static uint8_t readPointer = 0; static uint8_t writePointer = 0; char sendData[GET_RECORD_SIZE]; uint8_t sendPointer = 0; uint8_t fileHandle = asciiToInt((char*)line+2); uint8_t blockLength = GET_RECORD_SIZE-1; uint8_t numRead; uint8_t parameters[2] = {fileHandle, blockLength}; while (numberRecords > 0) { /* The buffer is empty, so fill up. */ if (readPointer == writePointer) { sendFileCommand('G',2,parameters); numRead = 0; xQueueReceive(fileReceiveQueue,&numRead,portMAX_DELAY); /* As records are written in entirety, premature EOF should not happen. */ if (numRead != blockLength) { fileStatus = FR_DENIED; break; } uint8_t i; /* Read the entire block to the local buffer. */ for (i=0; i<numRead; i++) { uint8_t nextWritePointer = (writePointer+1) % GET_RECORD_SIZE; xQueueReceive(fileReceiveQueue, buffer+writePointer,portMAX_DELAY); writePointer = nextWritePointer; } /* Get status byte. */ xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY); } /* Assemble the data message until EOL encountered, or block exhausted. */ while (sendPointer < GET_RECORD_SIZE-1) { sendData[sendPointer] = buffer[readPointer]; readPointer = (readPointer+1) % GET_RECORD_SIZE; if (sendData[sendPointer] == '\n') { sendData[sendPointer+1] = 0; sendString("fG",sendData); sendPointer = 0; numberRecords--; break; } /* If the current block is exhausted, go get some more. */ if (readPointer == writePointer) break; sendPointer++; } } xSemaphoreGive(fileSendSemaphore); } /* Status sent is from the last time the file was read. */ sendResponse("fE",(uint8_t)fileStatus); break; } /** <li> <b>Dd</b> Get a directory listing d=dirname. Directory name is 8.3 string style. Gets all items in the directory and sends the type,size and name, each group preceded by a comma. The file command requests each entry in turn, terminated by a null filename when the directory listing is exhausted. */ case 'D': { if (! xSemaphoreTake(commsSendSemaphore,COMMS_SEND_TIMEOUT)) break; uint8_t fileStatus = FR_INT_ERR; if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT)) { char firstCharacter; sendFileCommand('D',13,line+2); commsPrintString("fD"); do { char type = 0; /* Single character entry type */ xQueueReceive(fileReceiveQueue,&type,portMAX_DELAY); char character; /* Four bytes of file size */ uint32_t fileSize = 0; uint8_t i; for (i=0; i<4; i++) { character = 0; xQueueReceive(fileReceiveQueue,&character,portMAX_DELAY); fileSize = (fileSize << 8) + character; } /* Filename. If the first character of name is zero then the listing is ended */ character = 0; xQueueReceive(fileReceiveQueue,&character,portMAX_DELAY); firstCharacter = character; if (firstCharacter > 0) { commsPrintString(","); commsPrintChar(&type); commsPrintHex(fileSize >> 16); commsPrintHex(fileSize & 0xFFFF); while (character > 0) { commsPrintChar(&character); character = 0; xQueueReceive(fileReceiveQueue,&character,portMAX_DELAY); } /* End of directory entry. Discard the status byte */ xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY); uint8_t eol = 0; /* Send a zero parameter to ask for the next entry */ sendFileCommand('D',1,&eol); } } while (firstCharacter > 0); commsPrintString("\r\n"); xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY); xSemaphoreGive(fileSendSemaphore); } xSemaphoreGive(commsSendSemaphore); sendResponse("fE",(uint8_t)fileStatus); break; } /** <li> <b>d[d]</b> d is the d=directory name. Get the first (if d present) or next entry in the directory. If the name has a zero in the first position, return the next entry in the directory listing. Returns the type, size and name preceded by a comma for compatibility with the full directory listing request. If there are no further entries found in the directory, then an empty string is sent back. */ case 'd': { if (! xSemaphoreTake(commsSendSemaphore,COMMS_SEND_TIMEOUT)) break; uint8_t fileStatus = FR_INT_ERR; if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT)) { sendFileCommand('D',13,line+2); commsPrintString("fd"); char type = 0; /* Single character entry type */ xQueueReceive(fileReceiveQueue,&type,portMAX_DELAY); char character; /* Four bytes of file size */ uint32_t fileSize = 0; uint8_t i; for (i=0; i<4; i++) { character = 0; xQueueReceive(fileReceiveQueue,&character,portMAX_DELAY); fileSize = (fileSize << 8) + character; } /* Filename. If the first character of name is zero then the listing is ended */ character = 0; xQueueReceive(fileReceiveQueue,&character,portMAX_DELAY); if (character > 0) /* Pull in remaining characters of name */ { commsPrintString(","); commsPrintChar(&type); commsPrintHex(fileSize >> 16); commsPrintHex(fileSize & 0xFFFF); while (character > 0) { commsPrintChar(&character); character = 0; xQueueReceive(fileReceiveQueue,&character,portMAX_DELAY); } } commsPrintString("\r\n"); xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY); xSemaphoreGive(fileSendSemaphore); } xSemaphoreGive(commsSendSemaphore); sendResponse("fE",(uint8_t)fileStatus); break; } /** <li> <b>M</b> Register (mount or remount) the SD card. */ case 'M': { uint8_t fileStatus = FR_INT_ERR; if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT)) { sendFileCommand('M',0,line+2); xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY); xSemaphoreGive(fileSendSemaphore); } sendResponse("fE",(uint8_t)fileStatus); break; } /** <li> <b>s</b> Send a status message containing: software switches (configData.config.recording), names of open files, with open write filename first followed by read filename, or blank if files are not open. */ case 's': { if (! xSemaphoreTake(commsSendSemaphore,COMMS_SEND_TIMEOUT)) break;; commsPrintString("fs,"); commsPrintInt((int)getControls()); commsPrintString(","); uint8_t writeStatus; commsPrintInt(writeFileHandle); commsPrintString(","); if (writeFileHandle < 0xFF) { commsPrintString(writeFileName); commsPrintString(","); } commsPrintInt(readFileHandle); if (readFileHandle < 0xFF) { commsPrintString(","); commsPrintString(readFileName); } commsPrintString("\r\n"); xSemaphoreGive(commsSendSemaphore); break; } /** <li> <b>Xf</b> Delete a designated file f=filename. The file must not be open at the time. A status is returned to signal a directory refresh. */ case 'X': { uint8_t fileStatus = FR_INT_ERR; if (xSemaphoreTake(fileSendSemaphore,COMMS_FILE_TIMEOUT)) { sendFileCommand('X',13,line+2); xQueueReceive(fileReceiveQueue,&fileStatus,portMAX_DELAY); xSemaphoreGive(fileSendSemaphore); } sendResponse("fE",(uint8_t)fileStatus); break; } /** </ul> */ } }
// QT3 DBus message handler: bool LapsusDaemon::handleMethodCall(const QDBusMessage& message) { if (message.interface() != LAPSUS_INTERFACE) return false; if (message.type() != QDBusMessage::MethodCallMessage) return false; if (message.member() == "listFeatures" || message.member() == "listSwitches" || message.member() == "listDisplayTypes" || message.member() == "getMaxBacklight" || message.member() == "getBacklight") { if (message.count() != 0) { return returnDBusError("org.freedesktop.DBus.Error" ".InvalidSignature", "Expected no arguments", message); } QDBusMessage reply = QDBusMessage::methodReply(message); if (message.member() == "listFeatures") { reply << QDBusData::fromList(listFeatures()); } else if (message.member() == "listSwitches") { reply << QDBusData::fromList(listSwitches()); } else if (message.member() == "listDisplayTypes") { reply << QDBusData::fromList(listDisplayTypes()); } else if (message.member() == "getMaxBacklight") { reply << QDBusData::fromUInt32(getMaxBacklight()); } else if (message.member() == "getBacklight") { reply << QDBusData::fromUInt32(getBacklight()); } else { // Should not happen... // TODO - some kind of error? to syslog? using dbus? reply << QDBusData::fromUInt32(0); } myConnection->send(reply); return true; } else if (message.member() == "getSwitch" || message.member() == "getDisplay") { if (message.count() != 1 || message[0].type() != QDBusData::String) { return returnDBusError("org.freedesktop.DBus.Error" ".InvalidSignature", "Expected one string argument", message); } QDBusMessage reply = QDBusMessage::methodReply(message); if (message.member() == "getSwitch") { reply << QDBusData::fromBool( getSwitch(message[0].toString())); } else if (message.member() == "getDisplay") { reply << QDBusData::fromBool( getDisplay(message[0].toString())); } else { // Should not happen... // TODO - some kind of error? to syslog? using dbus? reply << QDBusData::fromBool(false); } myConnection->send(reply); return true; } else if (message.member() == "setSwitch" || message.member() == "setDisplay") { if (message.count() != 2 || message[0].type() != QDBusData::String || message[1].type() != QDBusData::Bool) { return returnDBusError("org.freedesktop.DBus.Error" ".InvalidSignature", "Expected two arguments: string and bool", message); } QDBusMessage reply = QDBusMessage::methodReply(message); if (message.member() == "setSwitch") { reply << QDBusData::fromBool( setSwitch(message[0].toString(), message[1].toBool())); } else if (message.member() == "setDisplay") { reply << QDBusData::fromBool( setDisplay(message[0].toString(), message[1].toBool())); } else { // Should not happen... // TODO - some kind of error? to syslog? using dbus? reply << QDBusData::fromBool(false); } myConnection->send(reply); return true; } else if (message.member() == "setBacklight") { if (message.count() != 1 || message[0].type() != QDBusData::UInt32) { return returnDBusError("org.freedesktop.DBus.Error" ".InvalidSignature", "Expected one uint32 argument", message); } QDBusMessage reply = QDBusMessage::methodReply(message); if (message.member() == "setBacklight") { reply << QDBusData::fromBool( setBacklight(message[0].toUInt32())); } else { // Should not happen... // TODO - some kind of error? to syslog? using dbus? reply << QDBusData::fromBool(false); } myConnection->send(reply); return true; } // TODO - cpufreq return false; }
void applyTemplate(uint8_t idx) #endif { MixData *md = &g_model.mixData[0]; //CC(STK) -> vSTK //ICC(vSTK) -> STK #define ICC(x) icc[(x)-1] uint8_t icc[4] = {0}; for(uint8_t i=1; i<=4; i++) //generate inverse array for(uint8_t j=1; j<=4; j++) if(CC(i)==j) icc[j-1]=i; #ifndef NO_TEMPLATES uint8_t j = 0; //Simple 4-Ch if(idx==j++) { #endif clearMixes(); md=setDest(ICC(STK_RUD)); md->srcRaw=CM(STK_RUD); md=setDest(ICC(STK_ELE)); md->srcRaw=CM(STK_ELE); md=setDest(ICC(STK_THR)); md->srcRaw=CM(STK_THR); md=setDest(ICC(STK_AIL)); md->srcRaw=CM(STK_AIL); #ifndef NO_TEMPLATES } //T-Cut if(idx==j++) { md=setDest(ICC(STK_THR)); md->srcRaw=MIX_MAX; md->weight=-100; md->swtch=DSW_THR; md->mltpx=MLTPX_REP; } //sticky t-cut if(idx==j++) { md=setDest(ICC(STK_THR)); md->srcRaw=MIX_MAX; md->weight=-100; md->swtch=DSW_SWC; md->mltpx=MLTPX_REP; md=setDest(14); md->srcRaw=CH(14); md=setDest(14); md->srcRaw=MIX_MAX; md->weight=-100; md->swtch=DSW_SWB; md->mltpx=MLTPX_REP; md=setDest(14); md->srcRaw=MIX_MAX; md->swtch=DSW_THR; md->mltpx=MLTPX_REP; setSwitch(0xB,CS_VNEG, CM(STK_THR), -99); setSwitch(0xC,CS_VPOS, CH(14), 0); } //V-Tail if(idx==j++) { clearMixes(); md=setDest(ICC(STK_RUD)); md->srcRaw=CM(STK_RUD); md=setDest(ICC(STK_RUD)); md->srcRaw=CM(STK_ELE); md->weight=-100; md=setDest(ICC(STK_ELE)); md->srcRaw=CM(STK_RUD); md=setDest(ICC(STK_ELE)); md->srcRaw=CM(STK_ELE); } //Elevon\\Delta if(idx==j++) { clearMixes(); md=setDest(ICC(STK_ELE)); md->srcRaw=CM(STK_ELE); md=setDest(ICC(STK_ELE)); md->srcRaw=CM(STK_AIL); md=setDest(ICC(STK_AIL)); md->srcRaw=CM(STK_ELE); md=setDest(ICC(STK_AIL)); md->srcRaw=CM(STK_AIL); md->weight=-100; } //Heli Setup if(idx==j++) { clearMixes(); //This time we want a clean slate clearCurves(); //Set up Mixes //3 cyclic channels md=setDest(1); md->srcRaw=MIX_CYC1; md=setDest(2); md->srcRaw=MIX_CYC2; md=setDest(3); md->srcRaw=MIX_CYC3; //rudder md=setDest(4); md->srcRaw=CM(STK_RUD); //Throttle md=setDest(5); md->srcRaw=CM(STK_THR); md->swtch= DSW_ID0; md->curve=CV(1); md->carryTrim=TRIM_OFF; md=setDest(5); md->srcRaw=CM(STK_THR); md->swtch= DSW_ID1; md->curve=CV(2); md->carryTrim=TRIM_OFF; md=setDest(5); md->srcRaw=CM(STK_THR); md->swtch= DSW_ID2; md->curve=CV(3); md->carryTrim=TRIM_OFF; md=setDest(5); md->srcRaw=MIX_MAX; md->weight=-100; md->swtch= DSW_THR; md->mltpx=MLTPX_REP; //gyro gain md=setDest(6); md->srcRaw=MIX_FULL; md->weight=30; md->swtch=-DSW_GEA; //collective md=setDest(11); md->srcRaw=CM(STK_THR); md->weight=70; md->swtch= DSW_ID0; md->curve=CV(4); md->carryTrim=TRIM_OFF; md=setDest(11); md->srcRaw=CM(STK_THR); md->weight=70; md->swtch= DSW_ID1; md->curve=CV(5); md->carryTrim=TRIM_OFF; md=setDest(11); md->srcRaw=CM(STK_THR); md->weight=70; md->swtch= DSW_ID2; md->curve=CV(6); md->carryTrim=TRIM_OFF; g_model.swashType = SWASH_TYPE_120; g_model.swashCollectiveSource = CH(11); //Set up Curves setCurve(CURVE5(1),heli_ar1); setCurve(CURVE5(2),heli_ar2); setCurve(CURVE5(3),heli_ar3); setCurve(CURVE5(4),heli_ar4); setCurve(CURVE5(5),heli_ar5); setCurve(CURVE5(6),heli_ar5); } //Gyro Gain if(idx==j++) { md=setDest(6); md->srcRaw=STK_P2; md->weight= 50; md->swtch=-DSW_GEA; md->sOffset=100; md=setDest(6); md->srcRaw=STK_P2; md->weight=-50; md->swtch= DSW_GEA; md->sOffset=100; } //Servo Test if(idx==j++) { md=setDest(15); md->srcRaw=CH(16); md->speedUp = 8; md->speedDown = 8; md=setDest(16); md->srcRaw=MIX_FULL; md->weight= 110; md->swtch=DSW_SW1; md=setDest(16); md->srcRaw=MIX_MAX; md->weight=-110; md->swtch=DSW_SW2; md->mltpx=MLTPX_REP; md=setDest(16); md->srcRaw=MIX_MAX; md->weight= 110; md->swtch=DSW_SW3; md->mltpx=MLTPX_REP; setSwitch(1,CS_LESS,CH(15),CH(16)); setSwitch(2,CS_VPOS,CH(15), 105); setSwitch(3,CS_VNEG,CH(15), -105); } STORE_MODELVARS; eeWaitComplete() ; #endif }