예제 #1
0
파일: callback.c 프로젝트: ukaea/epics
/* This routine can be called from interrupt context */
int callbackRequest(CALLBACK *pcallback)
{
    int priority;
    int pushOK;
    cbQueueSet *mySet;

    if (!pcallback) {
        epicsInterruptContextMessage("callbackRequest: pcallback was NULL\n");
        return S_db_notInit;
    }
    priority = pcallback->priority;
    if (priority < 0 || priority >= NUM_CALLBACK_PRIORITIES) {
        epicsInterruptContextMessage("callbackRequest: Bad priority\n");
        return S_db_badChoice;
    }
    mySet = &callbackQueue[priority];
    if (mySet->queueOverflow) return S_db_bufFull;

    pushOK = epicsRingPointerPush(mySet->queue, pcallback);

    if (!pushOK) {
        char msg[48] = "callbackRequest: ";

        strcat(msg, threadNamePrefix[priority]);
        strcat(msg, " ring buffer full\n");
        epicsInterruptContextMessage(msg);
        mySet->queueOverflow = TRUE;
        return S_db_bufFull;
    }
    epicsEventSignal(mySet->semWakeUp);
    return 0;
}
예제 #2
0
파일: omsMAXv.cpp 프로젝트: Brudhu/motor
void omsMAXv::InterruptHandler( void * param )
{
    omsMAXv* pController = (omsMAXv*) param;
    volatile struct MAXv_motor *pmotor = (MAXv_motor*) pController->getCardAddress();;
    STATUS1 status1_flag;
    static char errmsg[65];

    status1_flag.All = pmotor->status1_flag.All;

    /* Motion done handling */
    if (status1_flag.Bits.done != 0) epicsEventSignal(pController->pollEventId_);

    if (status1_flag.Bits.cmndError)
    {
        strcpy(errmsg, "\nomsMAXv::InterruptHandler: command error - Port: ");
        strncat(errmsg, pController->getPortName(), sizeof(errmsg)-strlen(errmsg)-2);
        strcat(errmsg,"\n");
        epicsInterruptContextMessage(errmsg);
    }

    /* unset this bit to not clear the text_response bit */
    if (status1_flag.Bits.text_response != 0)  status1_flag.Bits.text_response = 0;

    /* Release IRQ's. Clear bits by writing a 1 */
    pmotor->status1_flag.All = status1_flag.All;

    /* do a dummy read to ensure that all previous writes, which may
     * have been queued in the VME bridge chip get processed
     */
    status1_flag.All = pmotor->status1_flag.All;

}
예제 #3
0
epicsShareFunc int errlogSevVprintf(
    const errlogSevEnum severity,const char *pFormat,va_list pvar)
{
    char *pnext;
    int nchar;
    int totalChar = 0;
    int isOkToBlock;

    if (epicsInterruptIsInterruptContext()) {
        epicsInterruptContextMessage
            ("errlogSevVprintf called from interrupt level\n");
        return 0;
    }

    errlogInit(0);
    if (pvtData.atExit)
        return 0;

    isOkToBlock = epicsThreadIsOkToBlock();
    pnext = msgbufGetFree(isOkToBlock);
    if (!pnext)
        return 0;

    nchar = sprintf(pnext, "sevr=%s ", errlogGetSevEnumString(severity));
    pnext += nchar; totalChar += nchar;
    nchar = tvsnPrint(pnext, pvtData.maxMsgSize - totalChar - 1, pFormat, pvar);
    pnext += nchar; totalChar += nchar;
    if (pnext[-1] != '\n') {
        strcpy(pnext,"\n");
        totalChar++;
    }
    msgbufSetSize(totalChar);
    return nchar;
}
예제 #4
0
static void writeRegister(niport *pniport,int offset, epicsUInt8 value)
{
    volatile epicsUInt8 *pregister = (epicsUInt8 *)
                             (((char *)pniport->registers)+offset);

    if(ni1014Debug) {
        char message[100];

        sprintf(message,"writeRegister pregister %p offset %x value %2.2x\n",
            pregister,offset,value);
        if(epicsInterruptIsInterruptContext()) {
            epicsInterruptContextMessage(message);
        } else {
            printf("%s",message);
        }
    }
    *pregister = value;

    /*
     * Must wait 5 ti9914 clock cycles between AUXMR commands
     * Documentation is confusing but experiments indicate that 6 microsecod wait
     * Is required.
     */
    if (offset == AUXMR)
	microSecondDelay(6);
}
예제 #5
0
epicsShareFunc int errlogSevPrintf(
    const errlogSevEnum severity,const char *pFormat, ...)
{
    va_list pvar;
    int nchar;
    int isOkToBlock;

    if (epicsInterruptIsInterruptContext()) {
        epicsInterruptContextMessage
            ("errlogSevPrintf called from interrupt level\n");
        return 0;
    }

    errlogInit(0);
    if (pvtData.sevToLog > severity)
        return 0;

    isOkToBlock = epicsThreadIsOkToBlock();
    if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) {
        fprintf(pvtData.console, "sevr=%s ", errlogGetSevEnumString(severity));
        va_start(pvar, pFormat);
        vfprintf(pvtData.console, pFormat, pvar);
        va_end(pvar);
        fflush(pvtData.console);
    }

    va_start(pvar, pFormat);
    nchar = errlogSevVprintf(severity, pFormat, pvar);
    va_end(pvar);
    return nchar;
}
예제 #6
0
epicsShareFunc int errlogVprintf(
    const char *pFormat,va_list pvar)
{
    int nchar;
    char *pbuffer;
    int isOkToBlock;

    if (epicsInterruptIsInterruptContext()) {
        epicsInterruptContextMessage
            ("errlogVprintf called from interrupt level\n");
        return 0;
    }

    errlogInit(0);
    if (pvtData.atExit)
        return 0;
    isOkToBlock = epicsThreadIsOkToBlock();

    pbuffer = msgbufGetFree(isOkToBlock);
    if (!pbuffer) {
        vfprintf(pvtData.console, pFormat, pvar);
        fflush(pvtData.console);
        return 0;
    }

    nchar = tvsnPrint(pbuffer, pvtData.maxMsgSize, pFormat?pFormat:"", pvar);
    if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) {
        fprintf(pvtData.console, "%s", pbuffer);
        fflush(pvtData.console);
    }
    msgbufSetSize(nchar);
    return nchar;
}
예제 #7
0
void ni1014Err(void *pvt)
{
    niport *pniport = (niport *)pvt;
    char message[50];

    sprintf(message,"%s errorInterrupt\n",pniport->portName);
    epicsInterruptContextMessage(message);
    ni1014(pvt);
}
예제 #8
0
epicsShareFunc int errlogPrintfNoConsole( const char *pFormat, ...)
{
    va_list pvar;
    int nchar;

    if (epicsInterruptIsInterruptContext()) {
        epicsInterruptContextMessage
            ("errlogPrintfNoConsole called from interrupt level\n");
        return 0;
    }

    errlogInit(0);
    va_start(pvar, pFormat);
    nchar = errlogVprintfNoConsole(pFormat, pvar);
    va_end(pvar);
    return nchar;
}
예제 #9
0
static epicsUInt8 readRegister(niport *pniport, int offset)
{
    volatile epicsUInt8 *pregister = (epicsUInt8 *)
                             (((char *)pniport->registers)+offset);
    epicsUInt8 value;
    
    value = *pregister;
    if(ni1014Debug) {
        char message[100];

        sprintf(message,"readRegister pregister %p offset %x value %2.2x\n",
            pregister,offset,value);
        if(epicsInterruptIsInterruptContext()) {
            epicsInterruptContextMessage(message);
        } else {
            printf("%s",message);
        }
    }
    return value;
}
예제 #10
0
epicsShareFunc int errlogVprintfNoConsole(
    const char *pFormat,va_list pvar)
{
    int nchar;
    char *pbuffer;

    if (epicsInterruptIsInterruptContext()) {
        epicsInterruptContextMessage
            ("errlogVprintfNoConsole called from interrupt level\n");
        return 0;
    }

    errlogInit(0);
    if (pvtData.atExit)
        return 0;

    pbuffer = msgbufGetFree(1);
    if (!pbuffer)
        return 0;

    nchar = tvsnPrint(pbuffer, pvtData.maxMsgSize, pFormat?pFormat:"", pvar);
    msgbufSetSize(nchar);
    return nchar;
}
예제 #11
0
void ni1014(void *pvt)
{
    niport          *pniport = (niport *)pvt;
    transferState_t state = pniport->transferState;
    epicsUInt8      isr1,isr2,octet;
    char            message[80];

    pniport->isr2 = isr2 = readRegister(pniport,ISR2);
    pniport->isr1 = isr1 = readRegister(pniport,ISR1);
    writeRegister(pniport,CSR1,2); /*acknowledge interrupt*/
    if(isr2&SRQI) callbackRequest(&pniport->callback);
    if(isr1&ERR) {
        if(state!=transferStateIdle) {
            sprintf(pniport->errorMessage,"\n%s interruptHandler ERR state %d\n",
                pniport->portName,state);
            pniport->status = asynError;
            epicsEventSignal(pniport->waitForInterrupt);
        }
        goto exit;
    }
    switch(state) {
    case transferStateCmd:
        if(!isr2&CO)
	    goto exit;
        if(pniport->bytesRemainingCmd == 0) {
            pniport->transferState = pniport->nextTransferState;
            if(pniport->transferState==transferStateIdle) {
                epicsEventSignal(pniport->waitForInterrupt);
            } else {
                writeRegister(pniport,AUXMR,AUXGTS);
            }
            break ;
        }
        octet = *pniport->nextByteCmd;
        writeRegister(pniport,CDOR,(epicsUInt8)octet);
        --(pniport->bytesRemainingCmd); ++(pniport->nextByteCmd);
        break;
    case transferStateWrite:
        if(!isr1&DO)
	    goto exit;
        if(pniport->bytesRemainingWrite == 0) {
            pniport->transferState = transferStateIdle;
            writeRegister(pniport,AUXMR,AUXTCA);
            epicsEventSignal(pniport->waitForInterrupt);
            break ;
        }
        if(pniport->bytesRemainingWrite==1) writeRegister(pniport,AUXMR,AUXEOI);
        octet = *pniport->nextByteWrite;
        writeRegister(pniport,CDOR,(epicsUInt8)octet);
        --(pniport->bytesRemainingWrite); ++(pniport->nextByteWrite);
        break;
    case transferStateRead:
        if(!isr1&DI) break;
        octet = readRegister(pniport,DIR);
        *pniport->nextByteRead = octet;
        --(pniport->bytesRemainingRead); ++(pniport->nextByteRead);
        if((pniport->eos != -1 ) && (octet == pniport->eos))
            pniport->eomReason |= ASYN_EOM_EOS;
        if(ENDRX&isr1) pniport->eomReason |= ASYN_EOM_END;
        if(pniport->bytesRemainingRead == 0) pniport->eomReason |= ASYN_EOM_CNT;
        if(pniport->eomReason) {
            pniport->transferState = transferStateIdle;
            writeRegister(pniport,AUXMR,AUXTCS);
            epicsEventSignal(pniport->waitForInterrupt);
            break;
        }
        writeRegister(pniport,AUXMR,AUXFH);
        break;
    case transferStateIdle:
        if(!isr1&DI)
	    goto exit;
        octet = readRegister(pniport,DIR);
        sprintf(message,"%s ni1014IH transferStateIdle received %2.2x\n",
             pniport->portName,octet);
        epicsInterruptContextMessage(message);
    }

exit:
    /* Force synchronization of VMEbus writes on PPC CPU boards. */
    readRegister(pniport,ADSR);
}
예제 #12
0
epicsShareFunc void errPrintf(long status, const char *pFileName, 
    int lineno, const char *pformat, ...)
{
    va_list pvar;
    char    *pnext;
    int     nchar;
    int     totalChar=0;
    int     isOkToBlock;
    char    name[256];

    if (epicsInterruptIsInterruptContext()) {
        epicsInterruptContextMessage("errPrintf called from interrupt level\n");
        return;
    }

    errlogInit(0);
    isOkToBlock = epicsThreadIsOkToBlock();
    if (status == 0)
        status = errno;

    if (status > 0) {
        errSymLookup(status, name, sizeof(name));
    }

    if (pvtData.atExit || (isOkToBlock && pvtData.toConsole)) {
        if (pFileName)
            fprintf(pvtData.console, "filename=\"%s\" line number=%d\n",
                pFileName, lineno);
        if (status > 0)
            fprintf(pvtData.console, "%s ", name);

        va_start(pvar, pformat);
        vfprintf(pvtData.console, pformat, pvar);
        va_end(pvar);
        fputc('\n', pvtData.console);
        fflush(pvtData.console);
    }

    if (pvtData.atExit)
        return;

    pnext = msgbufGetFree(isOkToBlock);
    if (!pnext)
        return;

    if (pFileName) {
        nchar = sprintf(pnext,"filename=\"%s\" line number=%d\n",
            pFileName, lineno);
        pnext += nchar; totalChar += nchar;
    }

    if (status > 0) {
        nchar = sprintf(pnext,"%s ",name);
        pnext += nchar; totalChar += nchar;
    }
    va_start(pvar, pformat);
    nchar = tvsnPrint(pnext, pvtData.maxMsgSize - totalChar - 1, pformat, pvar);
    va_end(pvar);
    if (nchar>0) {
        pnext += nchar;
        totalChar += nchar;
    }
    strcpy(pnext, "\n");
    totalChar++ ; /*include the \n */
    msgbufSetSize(totalChar);
}
예제 #13
0
// Called from ISR context
void SoftSequence::sync()
{
    DEBUG(3, ("Syncing %c\n", is_insync ? 'Y' : 'N') );
    if(is_insync)
        {DEBUG(3, ("Skip\n")); return;}

    assert(hw);

    if(nat_ioread32(hw->ctrlreg)&EVG_SEQ_RAM_RUNNING) {
        // we may still be _ENABLED at this point, but the trigger source is set to
        // Disabled, so this makes no difference.
        epicsInterruptContextMessage("SoftSequence::sync() while running\n");
        return;
    }

    // At this point the sequencer is not running and effectively disabled.
    // From paranoia, reset it anyway
    nat_iowrite32(hw->ctrlreg, hw->ctrlreg_hw | EVG_SEQ_RAM_RESET);

    hw->ctrlreg_user &= ~(EVG_SEQ_RAM_REPEAT_MASK|EVG_SEQ_RAM_SRC_MASK);

    switch(committed.mode) {
    case Single:
        hw->ctrlreg_user |= EVG_SEQ_RAM_SINGLE;
        break;
    case Normal:
        hw->ctrlreg_user |= EVG_SEQ_RAM_NORMAL;
        break;
    }

    epicsUInt8 src;

    // default to disabled
    switch(owner->type) {
    case SeqManager::TypeEVG:
        src = 31;
        break;
    case SeqManager::TypeEVR:
        src = 63;
        break;
    default:
        return;
    }

    // paranoia: disable any external trigger mappings
    owner->mapTriggerSrc(hw->idx, 0x02000000);

    // map trigger source codes
    // MSB governs the type of mapping
    switch(committed.src&0xff000000) {
    case 0x00000000: // raw mapping
        DEBUG(5, ("  Raw mapping %x\n", committed.src));
        // LSB is code
        src = committed.src&0xff;
        break;
    case 0x01000000: // software trigger mapping
        DEBUG(5, ("  SW mapping %x\n", committed.src));
        // ignore 0x00ffffff
        switch(owner->type) {
        case SeqManager::TypeEVG:
            src = 17+hw->idx;
            break;
        case SeqManager::TypeEVR:
            src = 61;
            break;
        }
        break;
    case 0x02000000: // external trigger
        DEBUG(5, ("  EXT mapping %x\n", committed.src));
        if(owner->type==SeqManager::TypeEVG) {
            // pass through to sub-class
            owner->mapTriggerSrc(hw->idx, committed.src);
            src = 24+hw->idx;
        }
        break;
    case 0x03000000: // disable trigger
        DEBUG(5, ("  NO mapping %x\n", committed.src));
        // use default
        break;
    default:
        DEBUG(0, ("unknown sequencer trigger code %08x\n", (unsigned)committed.src));
        break;
    }
    DEBUG(5, ("  Trig Src %x\n", src));

    hw->ctrlreg_user |= src;

    // write out the RAM
    volatile epicsUInt32 *ram = static_cast<volatile epicsUInt32 *>(hw->rambase);
    for(size_t i=0, N=committed.codes.size(); i<N; i++)
    {
        nat_iowrite32(ram++, committed.times[i]);
        nat_iowrite32(ram++, committed.codes[i]);
        if(committed.codes[i]==0x7f)
            break;
    }

    {
        epicsUInt32 ctrl = hw->ctrlreg_hw = hw->ctrlreg_user;
        if(is_enabled)
            ctrl |= EVG_SEQ_RAM_ARM;
        else
            ctrl |= EVG_SEQ_RAM_DISABLE; // paranoia

        DEBUG(3, ("  SeqCtrl %x\n", ctrl));
        nat_iowrite32(hw->ctrlreg, ctrl);
    }

    is_insync = true;
    DEBUG(3, ("In Sync\n") );
}