예제 #1
0
void idev_BeginIO(IDBase *IDBase, struct IORequest *io)
{
	UINT8 cmd = io->io_Command;
	io->io_Flags &= (~(IOF_QUEUED|IOF_CURRENT|IOF_SERVICING|IOF_DONE))&0x0ff;
	io->io_Error = 0;

	if (cmd > MD_SETTRIGGER) cmd = 0; // Invalidate the command.

	if (inputCmdQuick[cmd] >= 0)
	{
		QueueCommand((struct IOStdReq*)io, SysBase);
		// Check if we are the first in Queue, if not, just return
		if (!TEST_BITS(io->io_Flags, IOF_CURRENT))
		{
			CLEAR_BITS(io->io_Flags, IOF_QUICK);
			return;
		}
		// If Device is stopped, just return
		if (TEST_BITS(IDBase->Unit.unit_Flags, DUB_STOPPED))
		{
			CLEAR_BITS(io->io_Flags, IOF_QUICK);
			return;
		}
		// we are first in Queue, now we are Quick, otherwise we come from the IS Routine
	}
	inputCmdVector[cmd]((struct IOStdReq*) io, IDBase);
}
예제 #2
0
파일: ADC.cpp 프로젝트: Aniles/IT-Praktikum
bool ADC::init() {
    //ADC reset
    SET_BIT(* (VINTP)(ADC_MODULE + ADC_CR_OFFSET), 0);
    //ADC Clock einstellen
    prescalerRate = Configuration::ADCCLK / (Configuration::ADC_Internal_Clock * 2);
    //prescalerRate darf nicht zu gross werden
    if (prescalerRate > 255)
        return false;
    //Prescale Inhalt loeschen
    CLEAR_BITS(* (VINTP)(ADC_MODULE + ADC_MR_OFFSET), 0xFF << 8);
    //prescalerRate in das Mode Register reinschreiben
    SET_BITS(* (VINTP)(ADC_MODULE + ADC_MR_OFFSET), (prescalerRate & 0xFF) << 8);
    //Startup time einstellen
    startupTime = Configuration::ADCCLK / ((prescalerRate + 1) * 800000);
    if (startupTime > 127)
        return false;
    //startup time Inhalt loeschen
    CLEAR_BITS(* (VINTP)(ADC_MODULE + ADC_MR_OFFSET), 0x7F << 16);
    //neuen Inhalt reinschreiben
    SET_BITS(* (VINTP)(ADC_MODULE + ADC_MR_OFFSET), (startupTime & 0x7F) << 16);
    SET_BITS(* (VINTP)(ADC_MODULE + ADC_MR_OFFSET), 0xF << 24);
    //Hardware Trigger deaktivieren,
    CLEAR_BIT(* (VINTP)(ADC_MODULE + ADC_MR_OFFSET), 0);
    //10-bit Konvertierung einstellen
    CLEAR_BIT(* (VINTP)(ADC_MODULE + ADC_MR_OFFSET), 4);
    //normalen Modus waehlen, kein Sleep Mode
    CLEAR_BIT(* (VINTP)(ADC_MODULE + ADC_MR_OFFSET), 5);
    //eine Konvertierung starten
    //SET_BIT ( *( VINTP ) ( ADC_MODULE + CR_OFFSET ), 1 );
    return 1;
}
예제 #3
0
/*
 * Disable a timer.
 *
 * @param timer - A timer module (e.g. TIMER_0)
 * @param ab - Select timer A or timer B.
 */
void timer_disable(timer_module_t timer, timer_ab_t ab)
{
    timer_registers_t *p_timer = timers[timer];
    if (ab == TIMER_A)
    {
        CLEAR_BITS(p_timer->CTRL, (1 << 0));
    }
    else
    {
        CLEAR_BITS(p_timer->CTRL, (1 << 8));
    }
}
예제 #4
0
static void
usbs_at91_endpoint_set_halted (usbs_rx_endpoint * pep, cyg_bool new_value)
{
  int epn = usbs_at91_pep_to_number(pep);
  cyg_addrword_t pCSR = pCSRn(epn);
  
  cyg_drv_dsr_lock ();
  
  if (pep->halted != new_value) {       
    /* There is something is to do */
    pep->halted = new_value;
    
    if (new_value && BITS_ARE_SET (pIMR, 1 << epn)) {   
      /* Ready to transmit */
      if (pep->complete_fn) {
        (*pep->complete_fn) (pep->complete_data, -EAGAIN);
      }
      usbs_at91_endpoint_interrupt_enable (epn, false);
      SET_BITS (pCSR, AT91_UDP_CSR_FORCESTALL);
    } else {
      CLEAR_BITS (pCSR, AT91_UDP_CSR_FORCESTALL);
    }
  }
  cyg_drv_dsr_unlock ();
}
예제 #5
0
static int
WaitForConnect(
    TcpState *statePtr,		/* State of the socket. */
    int *errorCodePtr)		/* Where to store errors? */
{
    int timeOut;		/* How long to wait. */
    int state;			/* Of calling TclWaitForFile. */

    /*
     * If an asynchronous connect is in progress, attempt to wait for it to
     * complete before reading.
     */

    if (statePtr->flags & TCP_ASYNC_CONNECT) {
	if (statePtr->flags & TCP_ASYNC_SOCKET) {
	    timeOut = 0;
	} else {
	    timeOut = -1;
	}
	errno = 0;
	state = TclUnixWaitForFile(statePtr->fds.fd,
		TCL_WRITABLE | TCL_EXCEPTION, timeOut);
	if (state & TCL_EXCEPTION) {
	    return -1;
	}
	if (state & TCL_WRITABLE) {
	    CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT);
	} else if (timeOut == 0) {
	    *errorCodePtr = errno = EWOULDBLOCK;
	    return -1;
	}
    }
    return 0;
}
예제 #6
0
// Perform transmit handling on an endpoint
static bool 
usbs_at91_endpoint_isr_tx(cyg_uint8 epn)
{
  cyg_addrword_t pCSR = pCSRn(epn);
  cyg_addrword_t pFDR = pFDRn(epn);
  cyg_uint8 **ppbegin = &usbs_at91_endpoint_pbegin[epn];
  cyg_uint8 **ppend = &usbs_at91_endpoint_pend[epn];
  cyg_uint32 space = 0;
  cyg_uint16 endpoint_size = usbs_at91_endpoint_fifo_size[epn];

  CLEAR_BITS (pCSR, AT91_UDP_CSR_TXCOMP);

  if (BITS_ARE_CLEARED (pCSR, AT91_UDP_CSR_TXPKTRDY)) {       
    /* Ready to transmit ? */
    if (*ppend > *ppbegin) {  
      /* Something to send */
      
      space = (cyg_uint32) * ppend - (cyg_uint32) * ppbegin;
      if (space == endpoint_size) {
        *ppend = *ppbegin;            /* Send zero-packet */
      }
      
      *ppbegin =
        write_fifo_uint8 (pFDR, *ppbegin,
                          (cyg_uint8 *) ((cyg_uint32) * ppbegin +
                                         MIN (space, endpoint_size)));
      SET_BITS (pCSR, AT91_UDP_CSR_TXPKTRDY);
      
      if (*ppend == *ppbegin) {       /* Last packet ? */
        *ppend = *ppbegin - 1;        /* The packet isn't sent yet */
      }
    } else {
      if (*ppend + 1 == *ppbegin) {
        *ppend = *ppbegin;    /* Flag for DSR */
        return true;
      } else {
        *ppend = *ppbegin - 1;        /* Flag for zero-packet */
        SET_BITS (pCSR, AT91_UDP_CSR_TXPKTRDY);       /* Send no data */
      }
    }
  }
  
  CLEAR_BITS (pCSR,
              AT91_UDP_CSR_RX_DATA_BK0 | AT91_UDP_CSR_RX_DATA_BK1 |
              AT91_UDP_CSR_RXSETUP | AT91_UDP_CSR_ISOERROR);
  return false;
}
예제 #7
0
파일: ds3231.c 프로젝트: BenBergman/NWatch
// Switch between 1Hz output and alarm interrupt output
void ds3231_sqw(rtc_sqw_t enable)
{
	byte data;
	read(DS3231_ADDR_CTRL, &data, 1);
	CLEAR_BITS(data, DS3231_BIT_1HZ, DS3231_BIT_INTCN);
	data |= (enable == RTC_SQW_ON) ? _BV(DS3231_BIT_1HZ) : _BV(DS3231_BIT_INTCN);
	write(DS3231_ADDR_CTRL, data);
}
예제 #8
0
파일: tclUnixChan.c 프로젝트: smh377/tcl
static void
TtySetAttributes(
    int fd,			/* Open file descriptor for serial port to be
				 * modified. */
    TtyAttrs *ttyPtr)		/* Buffer containing new attributes for serial
				 * port. */
{
    struct termios iostate;
    int parity, data, flag;

    tcgetattr(fd, &iostate);
    cfsetospeed(&iostate, TtyGetSpeed(ttyPtr->baud));
    cfsetispeed(&iostate, TtyGetSpeed(ttyPtr->baud));

    flag = 0;
    parity = ttyPtr->parity;
    if (parity != 'n') {
	SET_BITS(flag, PARENB);
#ifdef PAREXT
	CLEAR_BITS(iostate.c_cflag, PAREXT);
	if ((parity == 'm') || (parity == 's')) {
	    SET_BITS(flag, PAREXT);
	}
#endif /* PAREXT */
	if ((parity == 'm') || (parity == 'o')) {
	    SET_BITS(flag, PARODD);
	}
    }
    data = ttyPtr->data;
    SET_BITS(flag,
	    (data == 5) ? CS5 :
	    (data == 6) ? CS6 :
	    (data == 7) ? CS7 : CS8);
    if (ttyPtr->stop == 2) {
	SET_BITS(flag, CSTOPB);
    }

    CLEAR_BITS(iostate.c_cflag, PARENB | PARODD | CSIZE | CSTOPB);
    SET_BITS(iostate.c_cflag, flag);

    tcsetattr(fd, TCSADRAIN, &iostate);
}
예제 #9
0
void LedDigitWiring_TurnSegmentOn(LedDigitWiring_Pin pin)
{
  uint8_t wiringPin;

  wiringPin = convertPinToWiringPin(pin);
  if (wiringPin == HWPIN_ERROR)
  {
    return;
  }
  CLEAR_BITS(HWPORT, wiringPin);
}
예제 #10
0
파일: ds3231.c 프로젝트: BenBergman/NWatch
void ds3231_init()
{
	// Set registers

	byte data;

	// Control
	// Enable oscillator
	read(DS3231_ADDR_CTRL, &data, 1);
	CLEAR_BITS(data, DS3231_BIT_EOSC, DS3231_BIT_RS1, DS3231_BIT_RS2);
	write(DS3231_ADDR_CTRL, data);

	// Status
	// Turn off 32KHz output
	// Unset alarm 1 & 2 interrupts
	read(DS3231_ADDR_STATUS, &data, 1);
	CLEAR_BITS(data, DS3231_BIT_EN32KHZ, DS3231_BIT_A2F, DS3231_BIT_A1F);
	write(DS3231_ADDR_STATUS, data);

	// Set 1Hz output
	rtc_sqw(RTC_SQW_ON);
}
예제 #11
0
파일: ds3231.c 프로젝트: BenBergman/NWatch
// Get system alarm state
bool ds3231_systemAlarmState()
{
	byte data;
	read(DS3231_ADDR_STATUS, &data, 1);
	bool state = data & _BV(DS3231_BIT_A2F);
	if(state) // Clear state if its set
	{
		CLEAR_BITS(data, DS3231_BIT_A2F);
		write(DS3231_ADDR_STATUS, data);
	}

	return state;
}
예제 #12
0
void LedNumberWiring_SetSelectPin(LedNumberWiring_Place place)
{
  uint8_t pin;

  SET_BITS(WIRINGPORT, WIRINGPIN_BITMASK);
  pin = convertPinToWiringPin(place);
  if (pin == WIRINGPIN_NONE)
  {
    return;
  }
  if (pin == WIRINGPIN_ERROR)
  {
    return;
  }
  CLEAR_BITS(WIRINGPORT, pin);
}
예제 #13
0
파일: ds3231.c 프로젝트: BenBergman/NWatch
// System wakeup uses alarm 2
// NOTE: Alarm 2 doesn't have seconds
// Will trigger when minutes match
void ds3231_setSystemAlarmWake(alarm_s* alarm)
{
	// Clear flag
	rtc_systemAlarmState();

	byte data;
	read(DS3231_ADDR_CTRL, &data, 1);
	if(alarm != NULL)
	{
		write(DS3231_ADDR_ALARM2_MINS,	dec2bcd(alarm->min));
		write(DS3231_ADDR_ALARM2_HRS,	0b10000000 | dec2bcd(alarm->hour));
		write(DS3231_ADDR_ALARM2_DAYDATE,0b10000000 | dec2bcd(alarm->days));
		SET_BITS(data, DS3231_BIT_A2IE);
	}
	else // Alarm disabled
		CLEAR_BITS(data, DS3231_BIT_A2IE);
	write(DS3231_ADDR_CTRL, data);
}
예제 #14
0
파일: ds3231.c 프로젝트: BenBergman/NWatch
// User alarm uses alarm 1
// Will trigger when day, hours, minutes, and seconds match
void ds3231_setUserAlarmWake(alarm_s* alarm)
{
	// Clear flag
	rtc_userAlarmState();

	byte data;
	read(DS3231_ADDR_CTRL, &data, 1);
	if(alarm != NULL)
	{
		write(DS3231_ADDR_ALARM1_SECS,	0);
		write(DS3231_ADDR_ALARM1_MINS,	dec2bcd(alarm->min));
		write(DS3231_ADDR_ALARM1_HRS,	dec2bcd(alarm->hour));
		write(DS3231_ADDR_ALARM1_DAYDATE, 0b01000000 | alarm->days);
		SET_BITS(data, DS3231_BIT_A1IE);
	}
	else // Alarm disabled
		CLEAR_BITS(data, DS3231_BIT_A1IE);
	write(DS3231_ADDR_CTRL, data);
}
예제 #15
0
	/* ARGSUSED */
static int
TcpBlockModeProc(
    ClientData instanceData,	/* Socket state. */
    int mode)			/* The mode to set. Can be one of
				 * TCL_MODE_BLOCKING or
				 * TCL_MODE_NONBLOCKING. */
{
    TcpState *statePtr = instanceData;

    if (mode == TCL_MODE_BLOCKING) {
	CLEAR_BITS(statePtr->flags, TCP_NONBLOCKING);
    } else {
	SET_BITS(statePtr->flags, TCP_NONBLOCKING);
    }
    if (statePtr->flags & TCP_ASYNC_CONNECT) {
        statePtr->cachedBlocking = mode;
        return 0;
    }
    if (TclUnixSetBlockingMode(statePtr->fds.fd, mode) < 0) {
	return errno;
    }
    return 0;
}
예제 #16
0
파일: tclUnixChan.c 프로젝트: smh377/tcl
static int
TtySetOptionProc(
    ClientData instanceData,	/* File state. */
    Tcl_Interp *interp,		/* For error reporting - can be NULL. */
    const char *optionName,	/* Which option to set? */
    const char *value)		/* New value for option. */
{
    FileState *fsPtr = instanceData;
    unsigned int len, vlen;
    TtyAttrs tty;
    int argc;
    const char **argv;
    struct termios iostate;

    len = strlen(optionName);
    vlen = strlen(value);

    /*
     * Option -mode baud,parity,databits,stopbits
     */

    if ((len > 2) && (strncmp(optionName, "-mode", len) == 0)) {
	if (TtyParseMode(interp, value, &tty) != TCL_OK) {
	    return TCL_ERROR;
	}

	/*
	 * system calls results should be checked there. - dl
	 */

	TtySetAttributes(fsPtr->fd, &tty);
	return TCL_OK;
    }


    /*
     * Option -handshake none|xonxoff|rtscts|dtrdsr
     */

    if ((len > 1) && (strncmp(optionName, "-handshake", len) == 0)) {
	/*
	 * Reset all handshake options. DTR and RTS are ON by default.
	 */

	tcgetattr(fsPtr->fd, &iostate);
	CLEAR_BITS(iostate.c_iflag, IXON | IXOFF | IXANY);
#ifdef CRTSCTS
	CLEAR_BITS(iostate.c_cflag, CRTSCTS);
#endif /* CRTSCTS */
	if (Tcl_UtfNcasecmp(value, "NONE", vlen) == 0) {
	    /*
	     * Leave all handshake options disabled.
	     */
	} else if (Tcl_UtfNcasecmp(value, "XONXOFF", vlen) == 0) {
	    SET_BITS(iostate.c_iflag, IXON | IXOFF | IXANY);
	} else if (Tcl_UtfNcasecmp(value, "RTSCTS", vlen) == 0) {
#ifdef CRTSCTS
	    SET_BITS(iostate.c_cflag, CRTSCTS);
#else /* !CRTSTS */
	    UNSUPPORTED_OPTION("-handshake RTSCTS");
	    return TCL_ERROR;
#endif /* CRTSCTS */
	} else if (Tcl_UtfNcasecmp(value, "DTRDSR", vlen) == 0) {
	    UNSUPPORTED_OPTION("-handshake DTRDSR");
	    return TCL_ERROR;
	} else {
	    if (interp) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"bad value for -handshake: must be one of"
			" xonxoff, rtscts, dtrdsr or none", -1));
		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FCONFIGURE",
			"VALUE", NULL);
	    }
	    return TCL_ERROR;
	}
	tcsetattr(fsPtr->fd, TCSADRAIN, &iostate);
	return TCL_OK;
    }

    /*
     * Option -xchar {\x11 \x13}
     */

    if ((len > 1) && (strncmp(optionName, "-xchar", len) == 0)) {
	Tcl_DString ds;

	if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) {
	    return TCL_ERROR;
	} else if (argc != 2) {
	    if (interp) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"bad value for -xchar: should be a list of"
			" two elements", -1));
		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FCONFIGURE",
			"VALUE", NULL);
	    }
	    ckfree(argv);
	    return TCL_ERROR;
	}

	tcgetattr(fsPtr->fd, &iostate);

	Tcl_UtfToExternalDString(NULL, argv[0], -1, &ds);
	iostate.c_cc[VSTART] = *(const cc_t *) Tcl_DStringValue(&ds);
	TclDStringClear(&ds);

	Tcl_UtfToExternalDString(NULL, argv[1], -1, &ds);
	iostate.c_cc[VSTOP] = *(const cc_t *) Tcl_DStringValue(&ds);
	Tcl_DStringFree(&ds);
	ckfree(argv);

	tcsetattr(fsPtr->fd, TCSADRAIN, &iostate);
	return TCL_OK;
    }

    /*
     * Option -timeout msec
     */

    if ((len > 2) && (strncmp(optionName, "-timeout", len) == 0)) {
	int msec;

	tcgetattr(fsPtr->fd, &iostate);
	if (Tcl_GetInt(interp, value, &msec) != TCL_OK) {
	    return TCL_ERROR;
	}
	iostate.c_cc[VMIN] = 0;
	iostate.c_cc[VTIME] = (msec==0) ? 0 : (msec<100) ? 1 : (msec+50)/100;
	tcsetattr(fsPtr->fd, TCSADRAIN, &iostate);
	return TCL_OK;
    }

    /*
     * Option -ttycontrol {DTR 1 RTS 0 BREAK 0}
     */
    if ((len > 4) && (strncmp(optionName, "-ttycontrol", len) == 0)) {
#if defined(TIOCMGET) && defined(TIOCMSET)
	int i, control, flag;

	if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) {
	    return TCL_ERROR;
	}
	if ((argc % 2) == 1) {
	    if (interp) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"bad value for -ttycontrol: should be a list of"
			" signal,value pairs", -1));
		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FCONFIGURE",
			"VALUE", NULL);
	    }
	    ckfree(argv);
	    return TCL_ERROR;
	}

	ioctl(fsPtr->fd, TIOCMGET, &control);
	for (i = 0; i < argc-1; i += 2) {
	    if (Tcl_GetBoolean(interp, argv[i+1], &flag) == TCL_ERROR) {
		ckfree(argv);
		return TCL_ERROR;
	    }
	    if (Tcl_UtfNcasecmp(argv[i], "DTR", strlen(argv[i])) == 0) {
		if (flag) {
		    SET_BITS(control, TIOCM_DTR);
		} else {
		    CLEAR_BITS(control, TIOCM_DTR);
		}
	    } else if (Tcl_UtfNcasecmp(argv[i], "RTS", strlen(argv[i])) == 0) {
		if (flag) {
		    SET_BITS(control, TIOCM_RTS);
		} else {
		    CLEAR_BITS(control, TIOCM_RTS);
		}
	    } else if (Tcl_UtfNcasecmp(argv[i], "BREAK", strlen(argv[i])) == 0) {
#if defined(TIOCSBRK) && defined(TIOCCBRK)
		if (flag) {
		    ioctl(fsPtr->fd, TIOCSBRK, NULL);
		} else {
		    ioctl(fsPtr->fd, TIOCCBRK, NULL);
		}
#else /* TIOCSBRK & TIOCCBRK */
		UNSUPPORTED_OPTION("-ttycontrol BREAK");
		ckfree(argv);
		return TCL_ERROR;
#endif /* TIOCSBRK & TIOCCBRK */
	    } else {
		if (interp) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad signal \"%s\" for -ttycontrol: must be"
			    " DTR, RTS or BREAK", argv[i]));
		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FCONFIGURE",
			"VALUE", NULL);
		}
		ckfree(argv);
		return TCL_ERROR;
	    }
	} /* -ttycontrol options loop */

	ioctl(fsPtr->fd, TIOCMSET, &control);
	ckfree(argv);
	return TCL_OK;
#else /* TIOCMGET&TIOCMSET */
	UNSUPPORTED_OPTION("-ttycontrol");
#endif /* TIOCMGET&TIOCMSET */
    }

    return Tcl_BadChannelOption(interp, optionName,
	    "mode handshake timeout ttycontrol xchar");
}
예제 #17
0
static int
TcpConnect(
    Tcl_Interp *interp,		/* For error reporting; can be NULL. */
    TcpState *statePtr)
{
    socklen_t optlen;
    int async_callback = statePtr->flags & TCP_ASYNC_PENDING;
    int ret = -1, error = errno;
    int async = statePtr->flags & TCP_ASYNC_CONNECT;

    if (async_callback) {
        goto reenter;
    }

    for (statePtr->addr = statePtr->addrlist; statePtr->addr != NULL;
            statePtr->addr = statePtr->addr->ai_next) {

        for (statePtr->myaddr = statePtr->myaddrlist; statePtr->myaddr != NULL;
                statePtr->myaddr = statePtr->myaddr->ai_next) {
            int reuseaddr = 1;

	    /*
	     * No need to try combinations of local and remote addresses of
	     * different families.
	     */

	    if (statePtr->myaddr->ai_family != statePtr->addr->ai_family) {
		continue;
	    }

            /*
             * Close the socket if it is still open from the last unsuccessful
             * iteration.
             */

            if (statePtr->fds.fd >= 0) {
		close(statePtr->fds.fd);
		statePtr->fds.fd = -1;
                errno = 0;
	    }

	    statePtr->fds.fd = socket(statePtr->addr->ai_family, SOCK_STREAM, 0);
	    if (statePtr->fds.fd < 0) {
		continue;
	    }

	    /*
	     * Set the close-on-exec flag so that the socket will not get
	     * inherited by child processes.
	     */

	    fcntl(statePtr->fds.fd, F_SETFD, FD_CLOEXEC);

	    /*
	     * Set kernel space buffering
	     */

	    TclSockMinimumBuffers(INT2PTR(statePtr->fds.fd), SOCKET_BUFSIZE);

	    if (async) {
                ret = TclUnixSetBlockingMode(statePtr->fds.fd,TCL_MODE_NONBLOCKING);
                if (ret < 0) {
                    continue;
                }
            }

            /* Gotta reset the error variable here, before we use it for the
             * first time in this iteration. */
            error = 0;

            (void) setsockopt(statePtr->fds.fd, SOL_SOCKET, SO_REUSEADDR,
                    (char *) &reuseaddr, sizeof(reuseaddr));
            ret = bind(statePtr->fds.fd, statePtr->myaddr->ai_addr,
                    statePtr->myaddr->ai_addrlen);
            if (ret < 0) {
                error = errno;
                continue;
            }

	    /*
	     * Attempt to connect. The connect may fail at present with an
	     * EINPROGRESS but at a later time it will complete. The caller
	     * will set up a file handler on the socket if she is interested
	     * in being informed when the connect completes.
	     */

	    ret = connect(statePtr->fds.fd, statePtr->addr->ai_addr,
                        statePtr->addr->ai_addrlen);
            if (ret < 0) error = errno;
	    if (ret < 0 && errno == EINPROGRESS) {
                Tcl_CreateFileHandler(statePtr->fds.fd,
                        TCL_WRITABLE|TCL_EXCEPTION, TcpAsyncCallback, statePtr);
                errno = EWOULDBLOCK;
                SET_BITS(statePtr->flags, TCP_ASYNC_PENDING);
                return TCL_OK;

            reenter:
                CLEAR_BITS(statePtr->flags, TCP_ASYNC_PENDING);
                Tcl_DeleteFileHandler(statePtr->fds.fd);

                /*
                 * Read the error state from the socket to see if the async
                 * connection has succeeded or failed. As this clears the
                 * error condition, we cache the status in the socket state
                 * struct for later retrieval by [fconfigure -error].
                 */

                optlen = sizeof(int);

                getsockopt(statePtr->fds.fd, SOL_SOCKET, SO_ERROR,
                        (char *) &error, &optlen);
                errno = error;
            }
	    if (error == 0) {
		goto out;
	    }
	}
    }

out:
    statePtr->connectError = error;
    CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT);
    if (async_callback) {
        /*
         * An asynchonous connection has finally succeeded or failed.
         */

        TcpWatchProc(statePtr, statePtr->filehandlers);
        TclUnixSetBlockingMode(statePtr->fds.fd, statePtr->cachedBlocking);

        if (error != 0) {
            SET_BITS(statePtr->flags, TCP_ASYNC_FAILED);
        }

        /*
         * We need to forward the writable event that brought us here, bcasue
         * upon reading of getsockopt(SO_ERROR), at least some OSes clear the
         * writable state from the socket, and so a subsequent select() on
         * behalf of a script level [fileevent] would not fire. It doesn't
         * hurt that this is also called in the successful case and will save
         * the event mechanism one roundtrip through select().
         */

	if (statePtr->cachedBlocking == TCL_MODE_NONBLOCKING) {
	    Tcl_NotifyChannel(statePtr->channel, TCL_WRITABLE);
	}
    }
    if (error != 0) {
        /*
         * Failure for either a synchronous connection, or an async one that
         * failed before it could enter background mode, e.g. because an
         * invalid -myaddr was given.
         */

        if (interp != NULL) {
            errno = error;
            Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                    "couldn't open socket: %s", Tcl_PosixError(interp)));
        }
        return TCL_ERROR;
    }
    return TCL_OK;
}
예제 #18
0
TEST(BitManip, ClearBits_MostSignificantBit)
{
  eightBit = 0xff;
  CLEAR_BITS(eightBit, (1<<7));
  BYTES_EQUAL(0x7f, eightBit);
}
예제 #19
0
TEST(BitManip, ClearBits_LeastSignificantBit)
{
  eightBit = 0xff;
  CLEAR_BITS(eightBit, (1<<0));
  BYTES_EQUAL(0xfe, eightBit);
}
예제 #20
0
/*
 * Enable an interrupt.
 *
 * @param timer - A timer module (e.g. TIMER_0)
 * @param ab - Select timer A or timer B.
 */
void timer_interrupt_disable(timer_module_t timer, timer_interrupt_t interrupt)
{
    timer_registers_t *p_timer = timers[timer];
    CLEAR_BITS(p_timer->IMR, interrupt);
}