/** Called when asyn clients call pasynFloat64->write(). * This function sends a signal to the simTask thread if the value of P_UpdateTime has changed. * For all parameters it sets the value in the parameter library and calls any registered callbacks. * \param[in] pasynUser pasynUser structure that encodes the reason and address. * \param[in] value Value to write. */ asynStatus drvQuadEM::writeFloat64(asynUser *pasynUser, epicsFloat64 value) { int function = pasynUser->reason; int status = asynSuccess; int channel; const char *paramName; const char* functionName = "writeFloat64"; getAddress(pasynUser, &channel); /* Set the parameter in the parameter library. */ status |= setDoubleParam(channel, function, value); /* Fetch the parameter string name for possible use in debugging */ getParamName(function, ¶mName); if (function == P_AveragingTime) { status |= setAveragingTime(value); epicsRingBytesFlush(ringBuffer_); ringCount_ = 0; status |= readStatus(); } else if (function == P_BiasVoltage) { status |= setBiasVoltage(value); status |= readStatus(); } else if (function == P_IntegrationTime) { status |= setIntegrationTime(value); status |= readStatus(); } else { /* All other parameters just get set in parameter list, no need to * act on them here */ } /* Do callbacks so higher layers see any changes */ status |= (asynStatus) callParamCallbacks(); if (status) epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize, "%s:%s: status=%d, function=%d, name=%s, value=%f", driverName, functionName, status, function, paramName, value); else asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, "%s:%s: function=%d, name=%s, value=%f\n", driverName, functionName, function, paramName, value); return (asynStatus)status; }
/** Downloads all of the current EPICS settings to the electrometer. * Typically used after the electrometer is power-cycled. */ asynStatus drvQuadEM::reset() { epicsInt32 iValue; epicsFloat64 dValue; getIntegerParam(P_Range, &iValue); setRange(iValue); getIntegerParam(P_ValuesPerRead, &iValue); setValuesPerRead(iValue); getDoubleParam(P_AveragingTime, &dValue); setAveragingTime(dValue); getIntegerParam(P_TriggerMode, &iValue); setTriggerMode(iValue); getIntegerParam(P_NumChannels, &iValue); setNumChannels(iValue); getIntegerParam(P_BiasState, &iValue); setBiasState(iValue); getIntegerParam(P_BiasInterlock, &iValue); setBiasInterlock(iValue); getDoubleParam(P_BiasVoltage, &dValue); setBiasVoltage(dValue); getIntegerParam(P_Resolution, &iValue); setResolution(iValue); getIntegerParam(P_ReadFormat, &iValue); setReadFormat(iValue); getDoubleParam(P_IntegrationTime, &dValue); setIntegrationTime(dValue); readStatus(); getIntegerParam(P_Acquire, &iValue); setAcquire(iValue); return asynSuccess; }
int main(void) { // init all needed services cli(); timer_init(); USART_init(); ADC_init(); sei(); // set up enable port ENA_DDR = /*(1 << ENA_LED) |*/ (1 << ENA_PIN); // ENA_PORT = (1 << ENA_LED); // init condition is receiving driverReceive(); // string, char and ascii buffers for serial comm. uint8_t read_buf = 0x00, ascii_bufh = 0x00, ascii_bufl = 0x00; char str_buf[10]; // send own address on startup HexToAscii(str_buf, 3, own_addr); sendString(str_buf); sendString(EOM); while(1) { // check if there is something to be read (non blocking...) if ( USART_dataAvaliable() ){ read_buf = 0x00; read_buf = USART_readByte(); switch(MPPC_status){ /* no start delimiter, awaits start delimiter */ case IDLE: if (read_buf == '<'){ MPPC_status = LISTENING; } else { MPPC_status = IDLE; sleep_ms(2); } break; /* received a start delimiter, awaits adress */ case LISTENING: // check wether there are characters or ASCII numbers beeing send if ( ((read_buf >= '0') && (read_buf <= '9')) || ((read_buf >= 'A') && (read_buf <= 'F')) ) { // a ASCII number has been sent, we need another digit str_buf[0] = read_buf; str_buf[1] = USART_receiveByte(); // convert both ascii numbers into a 'real' hex number read_buf = AsciiToHex(str_buf, 2); HexToAscii(str_buf, 3, read_buf); } else { // in this stage we need an address; if there are no numbers beeing sent, we are not interested anymore! MPPC_status = IDLE; break; } // We received an address, converted it to hex and now want to check, if it is our's if (read_buf == own_addr){ MPPC_status = ADDRESSED; // SEL_LED on -> module has been selected + echo sendString(str_buf); // ENA_PORT&= ~(1 << ENA_LED); // echo in ASCII } else { MPPC_status = IDLE; } break; /* received it's own address, awaits command */ case ADDRESSED: if (read_buf == '>'){ // stop delimiter MPPC_status = IDLE; // ENA_PORT |= (1 << ENA_LED); // SEL_LED off -> module has been deselected } else { command_handler(read_buf); // yet another switch/case stucture... } break; } // end switch } // end if // apply bias voltages setBiasVoltage(); } }