Пример #1
0
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();
}
Пример #2
0
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();
}
Пример #3
0
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();
}
Пример #4
0
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();
}
Пример #5
0
 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();          
   }
 }
Пример #6
0
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();
}
Пример #7
0
/**
   \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> */
        }
    }
Пример #9
0
// 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;
}
Пример #10
0
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

}