예제 #1
0
static void
print_errinfo(const VALUE eclass, const VALUE errat, const VALUE emesg)
{
    const char *einfo = "";
    long elen = 0;
    VALUE mesg;

    if (emesg != Qundef) {
	if (NIL_P(errat) || RARRAY_LEN(errat) == 0 ||
	    NIL_P(mesg = RARRAY_AREF(errat, 0))) {
	    error_pos();
	}
	else {
	    warn_print_str(mesg);
	    warn_print(": ");
	}

	if (!NIL_P(emesg)) {
	    einfo = RSTRING_PTR(emesg);
	    elen = RSTRING_LEN(emesg);
	}
    }

    if (eclass == rb_eRuntimeError && elen == 0) {
	warn_print("unhandled exception\n");
    }
    else {
	VALUE epath;

	epath = rb_class_name(eclass);
	if (elen == 0) {
	    warn_print_str(epath);
	    warn_print("\n");
	}
	else {
	    const char *tail = 0;
	    long len = elen;

	    if (RSTRING_PTR(epath)[0] == '#')
		epath = 0;
	    if ((tail = memchr(einfo, '\n', elen)) != 0) {
		len = tail - einfo;
		tail++;		/* skip newline */
	    }
	    warn_print_str(tail ? rb_str_subseq(emesg, 0, len) : emesg);
	    if (epath) {
		warn_print(" (");
		warn_print_str(epath);
		warn_print(")\n");
	    }
	    if (tail) {
		warn_print_str(rb_str_subseq(emesg, tail - einfo, elen - len - 1));
	    }
	    if (tail ? einfo[elen-1] != '\n' : !epath) warn_print2("\n", 1);
	}
    }
}
예제 #2
0
// Sends a System Control code to the USB Output buffer
void Output_sysCtrlSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
	// Display capability name
	if ( stateType == 0xFF && state == 0xFF )
	{
		print("Output_sysCtrlSend(sysCode)");
		return;
	}

	// Not implemented in Boot Mode
	if ( USBKeys_Protocol == 0 )
	{
		warn_print("System Control is not implemented for Boot Mode");
		return;
	}

	// TODO Analog inputs
	// Only indicate USB has changed if either a press or release has occured
	if ( state == 0x01 || state == 0x03 )
		USBKeys_Changed |= USBKeyChangeState_System;

	// Only send keypresses if press or hold state
	if ( stateType == 0x00 && state == 0x03 ) // Release state
	{
		USBKeys_SysCtrl = 0;
		return;
	}

	// Set system control code
	USBKeys_SysCtrl = args[0];
}
예제 #3
0
// Setup
inline void Port_setup()
{
	// Register Scan CLI dictionary
	CLI_registerDictionary( portCLIDict, portCLIDictName );

#if Port_SwapMode_define == USBSwap
	// USB Swap
	// Start, disabled
	GPIO_Ctrl( usb_swap_pin1, GPIO_Type_DriveSetup, GPIO_Config_None );
	GPIO_Ctrl( usb_swap_pin1, GPIO_Type_DriveLow, GPIO_Config_None );
#elif Port_SwapMode_define == USBInterSwap
	// USB Swap
	// Start, disabled
	GPIO_Ctrl( usb_swap_pin1, GPIO_Type_DriveSetup, GPIO_Config_None );
	GPIO_Ctrl( usb_swap_pin1, GPIO_Type_DriveLow, GPIO_Config_None );

	// UART Tx/Rx cross-over
	// Start, disabled
	GPIO_Ctrl( uart_cross_pin1, GPIO_Type_DriveSetup, GPIO_Config_None );
	GPIO_Ctrl( uart_cross_pin1, GPIO_Type_DriveLow, GPIO_Config_None );

	// UART Swap
	// Start, disabled
	GPIO_Ctrl( uart_swap_pin1, GPIO_Type_DriveSetup, GPIO_Config_None );
	GPIO_Ctrl( uart_swap_pin1, GPIO_Type_DriveLow, GPIO_Config_None );
#else
	warn_print("Unsupported");
#endif

	// Starting point for automatic port swapping
	Port_lastcheck_ms = systick_millis_count;

	// Allocate latency measurement resource
	portLatencyResource = Latency_add_resource("PortSwap", LatencyOption_Ticks);
}
예제 #4
0
void Port_uart_swap()
{
#if Port_SwapMode_define == USBInterSwap
	info_print("Interconnect Line Swap");

	// UART Swap
	GPIO_Ctrl( uart_swap_pin1, GPIO_Type_DriveToggle, GPIO_Config_None );
#else
	warn_print("Unsupported");
#endif
}
예제 #5
0
파일: error.c 프로젝트: knugie/ruby
/* rb_warning() reports only in verbose mode */
void
rb_warning(const char *fmt, ...)
{
    va_list args;

    if (!RTEST(ruby_verbose)) return;

    va_start(args, fmt);
    warn_print(fmt, args);
    va_end(args);
}
예제 #6
0
파일: error.c 프로젝트: technohippy/oruby
/* rb_warning() reports only in verbose mode */
void
rb_warning(const char *fmt, ...)
{
    char buf[BUFSIZ];
    va_list args;

    if (!RTEST(ruby_verbose)) return;

    snprintf(buf, BUFSIZ, "warning: %s", fmt);

    va_start(args, fmt);
    warn_print(buf, args);
    va_end(args);
}
예제 #7
0
void Port_cross()
{
#if Port_SwapMode_define == USBInterSwap
	info_print("Interconnect Line Cross");

	// UART Tx/Rx cross-over
	GPIO_Ctrl( uart_cross_pin1, GPIO_Type_DriveToggle, GPIO_Config_None );

	// Reset interconnects
	Connect_reset();
#else
	warn_print("Unsupported");
#endif
}
예제 #8
0
void Port_usb_swap()
{
#if Port_SwapMode_define == USBSwap || Port_SwapMode_define == USBInterSwap
	info_print("USB Port Swap");

	// USB Swap
	GPIO_Ctrl( usb_swap_pin1, GPIO_Type_DriveToggle, GPIO_Config_None );

	// Re-initialize usb
	// Call usb_configured() to check if usb is ready
	usb_reinit();
#else
	warn_print("Unsupported");
#endif
}
예제 #9
0
파일: error.c 프로젝트: knugie/ruby
void
rb_sys_warning(const char *fmt, ...)
{
    char buf[BUFSIZ];
    va_list args;
    int errno_save;

    errno_save = errno;

    if (!RTEST(ruby_verbose)) return;

    snprintf(buf, BUFSIZ, "warning: %s", fmt);
    snprintf(buf+strlen(buf), BUFSIZ-strlen(buf), ": %s", strerror(errno_save));

    va_start(args, fmt);
    warn_print(buf, args);
    va_end(args);
    errno = errno_save;
}
예제 #10
0
void
rb_threadptr_error_print(rb_thread_t *volatile th, volatile VALUE errinfo)
{
    volatile VALUE errat = Qundef;
    volatile int raised_flag = th->raised_flag;
    volatile VALUE eclass = Qundef, emesg = Qundef;

    if (NIL_P(errinfo))
	return;
    rb_thread_raised_clear(th);

    TH_PUSH_TAG(th);
    if (TH_EXEC_TAG() == 0) {
	errat = rb_get_backtrace(errinfo);
    }
    else if (errat == Qundef) {
	errat = Qnil;
    }
    else if (eclass == Qundef || emesg != Qundef) {
	goto error;
    }
    if ((eclass = CLASS_OF(errinfo)) != Qundef) {
	VALUE e = rb_check_funcall(errinfo, rb_intern("message"), 0, 0);
	if (e != Qundef) {
	    if (!RB_TYPE_P(e, T_STRING)) e = rb_check_string_type(e);
	    emesg = e;
	}
    }
    if (rb_stderr_tty_p()) {
	if (0) warn_print("Traceback (most recent call last):\n");
	print_backtrace(eclass, errat, TRUE);
	print_errinfo(eclass, errat, emesg);
    }
    else {
	print_errinfo(eclass, errat, emesg);
	print_backtrace(eclass, errat, FALSE);
    }
  error:
    TH_POP_TAG();
    th->errinfo = errinfo;
    rb_thread_raised_set(th, raised_flag);
}
예제 #11
0
uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8_t uart_num )
{
	// Check if this is the first byte
	if ( *pending_bytes == 0xFFFF )
	{
		*pending_bytes = byte;

		if ( Connect_debug )
		{
			dbug_msg("PENDING SET -> ");
			printHex( byte );
			print(" ");
			printHex( *pending_bytes );
			print( NL );
		}
	}
	// Verify byte
	else
	{
		(*pending_bytes)--;

		// The argument bytes are always 0xD2 (11010010)
		if ( byte != 0xD2 )
		{
			warn_print("Cable Fault!");

			// Check which side of the chain
			if ( uart_num == UART_Slave )
			{
				Connect_cableFaultsSlave++;
				Connect_cableOkSlave = 0;
				print(" Slave ");
			}
			else
			{
				Connect_cableFaultsMaster++;
				Connect_cableOkMaster = 0;
				print(" Master ");
			}
			printHex( byte );
			print( NL );

			// Signal that the command should wait for a SYN again
			return 1;
		}
		else
		{
			// Check which side of the chain
			if ( uart_num == UART_Slave )
			{
				Connect_cableChecksSlave++;
			}
			else
			{
				Connect_cableChecksMaster++;
			}
		}
	}

	// If cable check was successful, set cable ok
	if ( *pending_bytes == 0 )
	{
		if ( uart_num == UART_Slave )
		{
			Connect_cableOkSlave = 1;
		}
		else
		{
			Connect_cableOkMaster = 1;
		}
	}

	if ( Connect_debug )
	{
		dbug_msg("CABLECHECK RECEIVE - ");
		printHex( byte );
		print(" ");
		printHex( *pending_bytes );
		print( NL );
	}

	// Check whether the cable check has finished
	return *pending_bytes == 0 ? 1 : 0;
}
예제 #12
0
// send the contents of keyboard_keys and keyboard_modifier_keys
void usb_keyboard_send()
{
	uint32_t wait_count = 0;
	usb_packet_t *tx_packet;

	// Wait till ready
	while ( 1 )
	{
		if ( !usb_configuration )
		{
			erro_print("USB not configured...");
			return;
		}

		if ( USBKeys_Protocol == 0 ) // Boot Mode
		{
			if ( usb_tx_packet_count( NKRO_KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT )
			{
				tx_packet = usb_malloc();
				if ( tx_packet )
					break;
			}
		}
		else if ( USBKeys_Protocol == 1 ) // NKRO Mode
		{
			if ( usb_tx_packet_count( KEYBOARD_ENDPOINT ) < TX_PACKET_LIMIT )
			{
				tx_packet = usb_malloc();
				if ( tx_packet )
					break;
			}
		}

		if ( ++wait_count > TX_TIMEOUT || transmit_previous_timeout )
		{
			transmit_previous_timeout = 1;
			warn_print("USB Transmit Timeout...");
			return;
		}
		yield();
	}

	// Pointer to USB tx packet buffer
	uint8_t *tx_buf = tx_packet->buf;

	switch ( USBKeys_Protocol )
	{
	// Send boot keyboard interrupt packet(s)
	case 0:
		// USB Boot Mode debug output
		if ( Output_DebugMode )
		{
			dbug_msg("Boot USB: ");
			printHex_op( USBKeys_Modifiers, 2 );
			print(" ");
			printHex( 0 );
			print(" ");
			printHex_op( USBKeys_Keys[0], 2 );
			printHex_op( USBKeys_Keys[1], 2 );
			printHex_op( USBKeys_Keys[2], 2 );
			printHex_op( USBKeys_Keys[3], 2 );
			printHex_op( USBKeys_Keys[4], 2 );
			printHex_op( USBKeys_Keys[5], 2 );
			print( NL );
		}

		// Boot Mode
		*tx_buf++ = USBKeys_Modifiers;
		*tx_buf++ = 0;
		memcpy( tx_buf, USBKeys_Keys, USB_BOOT_MAX_KEYS );
		tx_packet->len = 8;

		// Send USB Packet
		usb_tx( KEYBOARD_ENDPOINT, tx_packet );
		USBKeys_Changed = USBKeyChangeState_None;
		break;

	// Send NKRO keyboard interrupts packet(s)
	case 1:
		if ( Output_DebugMode )
		{
			dbug_msg("NKRO USB: ");
		}

		// Check system control keys
		if ( USBKeys_Changed & USBKeyChangeState_System )
		{
			if ( Output_DebugMode )
			{
				print("SysCtrl[");
				printHex_op( USBKeys_SysCtrl, 2 );
				print( "] " NL );
			}

			*tx_buf++ = 0x02; // ID
			*tx_buf   = USBKeys_SysCtrl;
			tx_packet->len = 2;

			// Send USB Packet
			usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet );
			USBKeys_Changed &= ~USBKeyChangeState_System; // Mark sent
		}

		// Check consumer control keys
		if ( USBKeys_Changed & USBKeyChangeState_Consumer )
		{
			if ( Output_DebugMode )
			{
				print("ConsCtrl[");
				printHex_op( USBKeys_ConsCtrl, 2 );
				print( "] " NL );
			}

			*tx_buf++ = 0x03; // ID
			*tx_buf++ = (uint8_t)(USBKeys_ConsCtrl & 0x00FF);
			*tx_buf   = (uint8_t)(USBKeys_ConsCtrl >> 8);
			tx_packet->len = 3;

			// Send USB Packet
			usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet );
			USBKeys_Changed &= ~USBKeyChangeState_Consumer; // Mark sent
		}

		// Standard HID Keyboard
		if ( USBKeys_Changed )
		{
			// USB NKRO Debug output
			if ( Output_DebugMode )
			{
				printHex_op( USBKeys_Modifiers, 2 );
				print(" ");
				for ( uint8_t c = 0; c < 6; c++ )
					printHex_op( USBKeys_Keys[ c ], 2 );
				print(" ");
				for ( uint8_t c = 6; c < 20; c++ )
					printHex_op( USBKeys_Keys[ c ], 2 );
				print(" ");
				printHex_op( USBKeys_Keys[20], 2 );
				print(" ");
				for ( uint8_t c = 21; c < 27; c++ )
					printHex_op( USBKeys_Keys[ c ], 2 );
				print( NL );
			}

			tx_packet->len = 0;

			// Modifiers
			*tx_buf++ = 0x01; // ID
			*tx_buf++ = USBKeys_Modifiers;
			tx_packet->len += 2;

			// 4-49 (first 6 bytes)
			memcpy( tx_buf, USBKeys_Keys, 6 );
			tx_buf += 6;
			tx_packet->len += 6;

			// 51-155 (Middle 14 bytes)
			memcpy( tx_buf, USBKeys_Keys + 6, 14 );
			tx_buf += 14;
			tx_packet->len += 14;

			// 157-164 (Next byte)
			memcpy( tx_buf, USBKeys_Keys + 20, 1 );
			tx_buf += 1;
			tx_packet->len += 1;

			// 176-221 (last 6 bytes)
			memcpy( tx_buf, USBKeys_Keys + 21, 6 );
			tx_packet->len += 6;

			// Send USB Packet
			usb_tx( NKRO_KEYBOARD_ENDPOINT, tx_packet );
			USBKeys_Changed = USBKeyChangeState_None; // Mark sent
		}

		break;
	}

	return;
}
예제 #13
0
파일: output_com.c 프로젝트: Olical/ergodox
// Adds a single USB Code to the USB Output buffer
// Argument #1: USB Code
void Output_usbCodeSend_capability( TriggerMacro *trigger, uint8_t state, uint8_t stateType, uint8_t *args )
{
#if enableKeyboard_define == 1
	// Display capability name
	if ( stateType == 0xFF && state == 0xFF )
	{
		print("Output_usbCodeSend(usbCode)");
		return;
	}

	// Depending on which mode the keyboard is in the USB needs Press/Hold/Release events
	uint8_t keyPress = 0; // Default to key release

	// Only send press and release events
	if ( stateType == 0x00 && state == 0x02 ) // Hold state
		return;

	// If press, send bit (NKRO) or byte (6KRO)
	if ( stateType == 0x00 && state == 0x01 ) // Press state
		keyPress = 1;

	// Get the keycode from arguments
	uint8_t key = args[0];

	// Depending on which mode the keyboard is in, USBKeys_Keys array is used differently
	// Boot mode - Maximum of 6 byte codes
	// NKRO mode - Each bit of the 26 byte corresponds to a key
	//  Bits   0 -  45 (bytes  0 -  5) correspond to USB Codes   4 -  49 (Main)
	//  Bits  48 - 161 (bytes  6 - 20) correspond to USB Codes  51 - 164 (Secondary)
	//  Bits 168 - 213 (bytes 21 - 26) correspond to USB Codes 176 - 221 (Tertiary)
	//  Bits 214 - 216                 unused
	uint8_t bytePosition = 0;
	uint8_t byteShift = 0;

	switch ( USBKeys_Protocol )
	{
	case 0: // Boot Mode
		// Set the modifier bit if this key is a modifier
		if ( (key & 0xE0) == 0xE0 ) // AND with 0xE0 (Left Ctrl, first modifier)
		{
			if ( keyPress )
			{
				USBKeys_primary.modifiers |= 1 << (key ^ 0xE0); // Left shift 1 by key XOR 0xE0
			}
			else // Release
			{
				USBKeys_primary.modifiers &= ~(1 << (key ^ 0xE0)); // Left shift 1 by key XOR 0xE0
			}

			USBKeys_primary.changed |= USBKeyChangeState_Modifiers;
		}
		// Normal USB Code
		else
		{
			// Determine if key was set
			uint8_t keyFound = 0;
			uint8_t old_sent = USBKeys_Sent;

			for ( uint8_t curkey = 0, newkey = 0; curkey < old_sent; curkey++, newkey++ )
			{
				// On press, key already present, don't re-add
				if ( keyPress && USBKeys_primary.keys[newkey] == key )
				{
					keyFound = 1;
					break;
				}

				// On release, remove if found
				if ( !keyPress && USBKeys_primary.keys[newkey] == key )
				{
					// Shift next key onto this one
					// (Doesn't matter if it overflows, buffer is large enough, and size is used)
					USBKeys_primary.keys[newkey--] = USBKeys_primary.keys[++curkey];
					USBKeys_Sent--;
					keyFound = 1;
					USBKeys_primary.changed = USBKeyChangeState_MainKeys;
					break;
				}
			}

			// USB Key limit reached
			if ( USBKeys_Sent >= USB_BOOT_MAX_KEYS )
			{
				warn_print("USB Key limit reached");
				break;
			}

			// Add key if not already found in the buffer
			if ( keyPress && !keyFound )
			{
				USBKeys_primary.keys[USBKeys_Sent++] = key;
				USBKeys_primary.changed = USBKeyChangeState_MainKeys;
			}
		}
		break;

	case 1: // NKRO Mode
		// Set the modifier bit if this key is a modifier
		if ( (key & 0xE0) == 0xE0 ) // AND with 0xE0 (Left Ctrl, first modifier)
		{
			if ( keyPress )
			{
				USBKeys_primary.modifiers |= 1 << (key ^ 0xE0); // Left shift 1 by key XOR 0xE0
			}
			else // Release
			{
				USBKeys_primary.modifiers &= ~(1 << (key ^ 0xE0)); // Left shift 1 by key XOR 0xE0
			}

			USBKeys_primary.changed |= USBKeyChangeState_Modifiers;
			break;
		}
		// First 6 bytes
		else if ( key >= 4 && key <= 49 )
		{
			// Lookup (otherwise division or multiple checks are needed to do alignment)
			// Starting at 0th position, each byte has 8 bits, starting at 4th bit
			uint8_t keyPos = key + (0 * 8 - 4); // Starting position in array, Ignoring 4 keys
			switch ( keyPos )
			{
				byteLookup( 0 );
				byteLookup( 1 );
				byteLookup( 2 );
				byteLookup( 3 );
				byteLookup( 4 );
				byteLookup( 5 );
			}

			USBKeys_primary.changed |= USBKeyChangeState_MainKeys;
		}
		// Next 14 bytes
		else if ( key >= 51 && key <= 155 )
		{
			// Lookup (otherwise division or multiple checks are needed to do alignment)
			// Starting at 6th byte position, each byte has 8 bits, starting at 51st bit
			uint8_t keyPos = key + (6 * 8 - 51); // Starting position in array
			switch ( keyPos )
			{
				byteLookup( 6 );
				byteLookup( 7 );
				byteLookup( 8 );
				byteLookup( 9 );
				byteLookup( 10 );
				byteLookup( 11 );
				byteLookup( 12 );
				byteLookup( 13 );
				byteLookup( 14 );
				byteLookup( 15 );
				byteLookup( 16 );
				byteLookup( 17 );
				byteLookup( 18 );
				byteLookup( 19 );
			}

			USBKeys_primary.changed |= USBKeyChangeState_SecondaryKeys;
		}
		// Next byte
		else if ( key >= 157 && key <= 164 )
		{
			// Lookup (otherwise division or multiple checks are needed to do alignment)
			uint8_t keyPos = key + (20 * 8 - 157); // Starting position in array, Ignoring 6 keys
			switch ( keyPos )
			{
				byteLookup( 20 );
			}

			USBKeys_primary.changed |= USBKeyChangeState_TertiaryKeys;
		}
		// Last 6 bytes
		else if ( key >= 176 && key <= 221 )
		{
			// Lookup (otherwise division or multiple checks are needed to do alignment)
			uint8_t keyPos = key + (21 * 8 - 176); // Starting position in array
			switch ( keyPos )
			{
				byteLookup( 21 );
				byteLookup( 22 );
				byteLookup( 23 );
				byteLookup( 24 );
				byteLookup( 25 );
				byteLookup( 26 );
			}

			USBKeys_primary.changed |= USBKeyChangeState_QuartiaryKeys;
		}
		// Received 0x00
		// This is a special USB Code that internally indicates a "break"
		// It is used to send "nothing" in order to break up sequences of USB Codes
		else if ( key == 0x00 )
		{
			USBKeys_primary.changed |= USBKeyChangeState_MainKeys;

			// Also flush out buffers just in case
			Output_flushBuffers();
			break;
		}
		// Invalid key
		else
		{
			warn_msg("USB Code not within 4-49 (0x4-0x31), 51-155 (0x33-0x9B), 157-164 (0x9D-0xA4), 176-221 (0xB0-0xDD) or 224-231 (0xE0-0xE7) NKRO Mode: ");
			printHex( key );
			print( NL );
			break;
		}

		// Set/Unset
		if ( keyPress )
		{
			USBKeys_primary.keys[bytePosition] |= (1 << byteShift);
			USBKeys_Sent--;
		}
		else // Release
		{
			USBKeys_primary.keys[bytePosition] &= ~(1 << byteShift);
			USBKeys_Sent++;
		}

		break;
	}
#endif
}
예제 #14
0
uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8_t uart_num )
{
	// Check if this is the first byte
	if ( *pending_bytes == BYTE_COUNT_START )
	{
		*pending_bytes = byte;

		if ( Connect_debug )
		{
			dbug_msg("PENDING SET -> ");
			printHex( byte );
			print(" ");
			printHex( *pending_bytes );
			print( NL );
		}
	}
	// Verify byte
	else
	{
		(*pending_bytes)--;

		// The argument bytes are always 0xD2 (11010010)
		if ( byte != CABLE_CHECK_ARG )
		{
			warn_print("Cable Fault!");

			// Check which side of the chain
			if ( uart_num == UART_Slave )
			{
				Connect_cableFaultsSlave++;
				Connect_cableOkSlave = 0;
				print(" Slave ");
			}
			else
			{
				// Lower current requirement during errors
				// Half of USB negotiation minimum (50 mA)
				// Only if this is not the master node
				if ( Connect_id != 0 )
				{
					Output_update_external_current( 50 );
				}

				Connect_cableFaultsMaster++;
				Connect_cableOkMaster = 0;
				print(" Master ");
			}
			printHex( byte );
			print( NL );

			// Signal that the command should wait for a SYN again
			return 1;
		}
		else
		{
			// Check which side of the chain
			if ( uart_num == UART_Slave )
			{
				Connect_cableChecksSlave++;
			}
			else
			{
				// If we already have an Id, then set max current again
				if ( Connect_id != 255 && Connect_id != 0 )
				{
					Output_update_external_current( Output_current_available() );
				}
				Connect_cableChecksMaster++;
			}
		}
	}

	// If cable check was successful, set cable ok
	if ( *pending_bytes == 0 )
	{
		if ( uart_num == UART_Slave )
		{
			Connect_cableOkSlave = 1;
		}
		else
		{
			Connect_cableOkMaster = 1;
		}
	}

	if ( Connect_debug )
	{
		dbug_msg("CABLECHECK RECEIVE - ");
		printHex( byte );
		print(" ");
		printHex( *pending_bytes );
		print( NL );
	}

	// Check whether the cable check has finished
	return *pending_bytes == 0 ? 1 : 0;
}
예제 #15
0
void i2c_isr( uint8_t ch )
{
	volatile I2C_Channel* channel = &i2c_channels[ch - ISSI_I2C_FirstBus_define];
#if defined(_kinetis_)
	volatile uint8_t *I2C_C1  = (uint8_t*)(&I2C0_C1) + i2c_offset[ch];
	volatile uint8_t *I2C_S   = (uint8_t*)(&I2C0_S) + i2c_offset[ch];
	volatile uint8_t *I2C_D   = (uint8_t*)(&I2C0_D) + i2c_offset[ch];
#elif defined(_sam_)
	Twi *twi_dev = twi_devs[ch];
#endif

	uint16_t element;
	uint8_t status;

#if defined(_kinetis_)
	status = *I2C_S;

	// Acknowledge the interrupt request
	*I2C_S |= I2C_S_IICIF;

	// Arbitration problem
	if ( status & I2C_S_ARBL )
	{
		/* XXX (HaaTa) I2C Debugging
		warn_msg("Arbitration error. Bus: ");
		printHex( ch );
		print(NL);
		*/

		*I2C_S |= I2C_S_ARBL;
		goto i2c_isr_error;
	}
#elif defined(_sam_)
	status = twi_dev->TWI_SR;

	// Arbitration problem
	if ( status & TWI_SR_ARBLST )
	{
		warn_msg("Arbitration error. Bus: ");
		printHex( ch );
		print(NL);
		goto i2c_isr_error;
	}
#endif

	if ( channel->txrx == I2C_READING )
	{
		switch( channel->reads_ahead )
		{
		// All the reads in the sequence have been processed ( but note that the final data register read still needs to
		// be done below! Now, the next thing is either a restart or the end of a sequence.
		case 0:
#if defined(_kinetis_)
		// In any case, we need to switch to TX mode, either to generate a repeated start condition, or to avoid
		// triggering another I2C read when reading the contents of the data register.
			*I2C_C1 |= I2C_C1_TX;

			// Perform the final data register read now that it's safe to do so.
			*channel->received_data++ = *I2C_D;

			// Do we have a repeated start?
			if ( ( channel->sequence < channel->sequence_end ) && ( *channel->sequence == I2C_RESTART ) )
			{

				// Generate a repeated start condition.
				*I2C_C1 |= I2C_C1_RSTA;

				// A restart is processed immediately, so we need to get a new element from our sequence. This is safe, because
				// a sequence cannot end with a RESTART: there has to be something after it. Note that the only thing that can
				// come after a restart is an address write.
				channel->txrx = I2C_WRITING;
				channel->sequence++;
				element = *channel->sequence;
				*I2C_D = element;
			}
			else
			{
				goto i2c_isr_stop;
			}
#elif defined(_sam_)

			// Perform the final data register read now that it's safe to do so.
			*channel->received_data++ = twi_dev->TWI_RHR;

			// Do we have a repeated start?
			if ( ( channel->sequence < channel->sequence_end ) && ( *channel->sequence == I2C_RESTART ) )
			{
				// Generate a repeated start condition.
				twi_dev->TWI_MMR &= ~TWI_MMR_MREAD;
				twi_dev->TWI_CR |= TWI_CR_START;

				// A restart is processed immediately, so we need to get a new element from our sequence. This is safe, because
				// a sequence cannot end with a RESTART: there has to be something after it. Note that the only thing that can
				// come after a restart is an address write.
				channel->txrx = I2C_WRITING;
				channel->sequence++;
				element = *channel->sequence;
				twi_dev->TWI_THR = element;
			}
			else
			{
				goto i2c_isr_stop;
			}
#endif
			break;

		case 1:
#if defined(_kinetis_)
			// do not ACK the final read
			*I2C_C1 |= I2C_C1_TXAK;
			*channel->received_data++ = *I2C_D;
#elif defined(_sam_)
			twi_dev->TWI_CR |= TWI_CR_STOP; //No ACK
			*channel->received_data++ = twi_dev->TWI_RHR;
#endif
			break;

		default:
#if defined(_kinetis_)
			*channel->received_data++ = *I2C_D;
#elif defined(_sam_)
			*channel->received_data++ = twi_dev->TWI_RHR;
#endif
			break;
		}

		//print("Read: ");
		//printHex( *channel->received_data );
		//print( NL );

		channel->reads_ahead--;

	}
	// channel->txrx == I2C_WRITING
	else
	{
		// First, check if we are at the end of a sequence.
		if ( channel->sequence == channel->sequence_end )
			goto i2c_isr_stop;

		// We received a NACK. Generate a STOP condition and abort.
#if defined(_kinetis_)
		if ( status & I2C_S_RXAK )
		{
			warn_print("NACK Received");
			goto i2c_isr_error;
		}
#elif defined(_sam_)
		if ( status & TWI_SR_NACK )
		{
			warn_print("NACK Received");
			goto i2c_isr_error;
		}
#endif

		// check next thing in our sequence
		element = *channel->sequence;

		// Do we have a restart? If so, generate repeated start and make sure TX is on.
		if ( element == I2C_RESTART )
		{
#if defined(_kinetis_)
			*I2C_C1 |= I2C_C1_RSTA | I2C_C1_TX;
#elif defined(_sam_)
			twi_dev->TWI_MMR &= ~TWI_MMR_MREAD;
			twi_dev->TWI_CR |= TWI_CR_START;
#endif

			// A restart is processed immediately, so we need to get a new element from our sequence.
			// This is safe, because a sequence cannot end with a RESTART: there has to be something after it.
			channel->sequence++;
			element = *channel->sequence;

			// Note that the only thing that can come after a restart is a write.
#if defined(_kinetis_)
			*I2C_D = element;
#elif defined(_sam_)
			twi_dev->TWI_THR = element;
#endif
		}
		else
		{
			if ( element == I2C_READ ) {
				channel->txrx = I2C_READING;
				// How many reads do we have ahead of us ( not including this one )?
				// For reads we need to know the segment length to correctly plan NACK transmissions.
				// We already know about one read
				channel->reads_ahead = 1;
				while (
					(  ( channel->sequence + channel->reads_ahead ) < channel->sequence_end ) &&
					( *( channel->sequence + channel->reads_ahead ) == I2C_READ )
				) {
					channel->reads_ahead++;
				}

				// Switch to RX mode.
#if defined(_kinetis_)
				*I2C_C1 &= ~I2C_C1_TX;
#elif defined(_sam_)
				twi_dev->TWI_MMR |= TWI_MMR_MREAD;
#endif

				// do not ACK the final read
				if ( channel->reads_ahead == 1 )
				{
#if defined(_kinetis_)
					*I2C_C1 |= I2C_C1_TXAK;
#elif defined(_sam_)
					twi_dev->TWI_CR |= TWI_CR_STOP;
#endif
				}
				// ACK all but the final read
				else
				{
#if defined(_kinetis_)
					*I2C_C1 &= ~( I2C_C1_TXAK );
#endif
				}

				// Dummy read comes first, note that this is not valid data!
				// This only triggers a read, actual data will come in the next interrupt call and overwrite this.
				// This is why we do not increment the received_data pointer.
#if defined(_kinetis_)
				*channel->received_data = *I2C_D;
#elif defined(_sam_)
				*channel->received_data = twi_dev->TWI_RHR;
#endif
				channel->reads_ahead--;
			}
			// Not a restart, not a read, must be a write.
			else
			{
				//print("WRITE: ");
				//printHex(element);
#if defined(_kinetis_)
				*I2C_D = element;
#elif defined(_sam_)
				// while (! (status & TWI_SR_TXRDY));
				if (!(status & TWI_SR_TXRDY)) return;
				twi_dev->TWI_THR = element;
#endif
				//print( NL );
			}
		}
	}

	channel->sequence++;
	channel->last_error = 0; // No error
	return;

i2c_isr_stop:
	// Generate STOP ( set MST=0 ), switch to RX mode, and disable further interrupts.
#if defined(_kinetis_)
	*I2C_C1 &= ~( I2C_C1_MST | I2C_C1_IICIE | I2C_C1_TXAK );
#elif defined(_sam_)
	//print("\r\n ----- STOP ----- \r\n");
	twi_dev->TWI_CR |= TWI_CR_STOP;
	twi_dev->TWI_MMR &= ~TWI_MMR_MREAD;
	twi_dev->TWI_IDR = 0xFFFFFFFF;
#endif
	channel->status = I2C_AVAILABLE;

	// Call the user-supplied callback function upon successful completion (if it exists).
	if ( channel->callback_fn )
	{
		// Delay before starting linked function
#if ISSI_Chip_31FL3731_define == 1 || ISSI_Chip_31FL3732_define == 1
		delay_us(25);
#elif ISSI_Chip_31FL3733_define == 1 || ISSI_Chip_31FL3736_define == 1
		delay_us(10);
#endif
		( *channel->callback_fn )( channel->user_data );
	}
	return;

i2c_isr_error:
	// Record error, and reset last error counter
	channel->error_count++;
	channel->last_error++;

	// Generate STOP and disable further interrupts.
	warn_print("ISR error");
#if defined(_kinetis_)
	*I2C_C1 &= ~( I2C_C1_MST | I2C_C1_IICIE );
#elif defined(_sam_)
	twi_dev->TWI_CR |= TWI_CR_STOP;
	twi_dev->TWI_IDR = 0xFFFFFFFF;
#endif
	channel->status = I2C_ERROR;
	return;
}
예제 #16
0
파일: eval_error.c 프로젝트: rhenium/ruby
static int
error_handle(int ex)
{
    int status = EXIT_FAILURE;
    rb_thread_t *th = GET_THREAD();

    if (rb_threadptr_set_raised(th))
	return EXIT_FAILURE;
    switch (ex & TAG_MASK) {
      case 0:
	status = EXIT_SUCCESS;
	break;

      case TAG_RETURN:
	error_pos();
	warn_print("unexpected return\n");
	break;
      case TAG_NEXT:
	error_pos();
	warn_print("unexpected next\n");
	break;
      case TAG_BREAK:
	error_pos();
	warn_print("unexpected break\n");
	break;
      case TAG_REDO:
	error_pos();
	warn_print("unexpected redo\n");
	break;
      case TAG_RETRY:
	error_pos();
	warn_print("retry outside of rescue clause\n");
	break;
      case TAG_THROW:
	/* TODO: fix me */
	error_pos();
	warn_print("unexpected throw\n");
	break;
      case TAG_RAISE: {
	VALUE errinfo = th->errinfo;
	if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) {
	    status = sysexit_status(errinfo);
	}
	else if (rb_obj_is_instance_of(errinfo, rb_eSignal) &&
		 rb_ivar_get(errinfo, id_signo) != INT2FIX(SIGSEGV)) {
	    /* no message when exiting by signal */
	}
	else {
	    error_print(th);
	}
	break;
      }
      case TAG_FATAL:
	error_print(th);
	break;
      default:
	unknown_longjmp_status(ex);
	break;
    }
    rb_threadptr_reset_raised(th);
    return status;
}
예제 #17
0
static void
error_print(void)
{
    volatile VALUE errat = Qnil;		/* OK */
    VALUE errinfo = GET_THREAD()->errinfo;
    volatile VALUE eclass, e;
    const char *volatile einfo;
    volatile long elen;

    if (NIL_P(errinfo))
	return;

    PUSH_TAG();
    if (EXEC_TAG() == 0) {
	errat = get_backtrace(errinfo);
    }
    else {
	errat = Qnil;
    }
    if (EXEC_TAG())
	goto error;
    if (NIL_P(errat)) {
	const char *file = rb_sourcefile();
	int line = rb_sourceline();
	if (!file)
	    warn_printf("%d", line);
	else if (!line)
	    warn_printf("%s", file);
	else
	    warn_printf("%s:%d", file, line);
    }
    else if (RARRAY_LEN(errat) == 0) {
	error_pos();
    }
    else {
	VALUE mesg = RARRAY_PTR(errat)[0];

	if (NIL_P(mesg))
	    error_pos();
	else {
	    warn_print2(RSTRING_PTR(mesg), RSTRING_LEN(mesg));
	}
    }

    eclass = CLASS_OF(errinfo);
    if (EXEC_TAG() == 0) {
	e = rb_funcall(errinfo, rb_intern("message"), 0, 0);
	StringValue(e);
	einfo = RSTRING_PTR(e);
	elen = RSTRING_LEN(e);
    }
    else {
	einfo = "";
	elen = 0;
    }
    if (EXEC_TAG())
	goto error;
    if (eclass == rb_eRuntimeError && elen == 0) {
	warn_print(": unhandled exception\n");
    }
    else {
	VALUE epath;

	epath = rb_class_name(eclass);
	if (elen == 0) {
	    warn_print(": ");
	    warn_print2(RSTRING_PTR(epath), RSTRING_LEN(epath));
	    warn_print("\n");
	}
	else {
	    char *tail = 0;
	    long len = elen;

	    if (RSTRING_PTR(epath)[0] == '#')
		epath = 0;
	    if ((tail = memchr(einfo, '\n', elen)) != 0) {
		len = tail - einfo;
		tail++;		/* skip newline */
	    }
	    warn_print(": ");
	    warn_print2(einfo, len);
	    if (epath) {
		warn_print(" (");
		warn_print2(RSTRING_PTR(epath), RSTRING_LEN(epath));
		warn_print(")\n");
	    }
	    if (tail) {
		warn_print2(tail, elen - len - 1);
		if (einfo[elen-1] != '\n') warn_print2("\n", 1);
	    }
	}
    }

    if (!NIL_P(errat)) {
	long i;
	long len = RARRAY_LEN(errat);
	VALUE *ptr = RARRAY_PTR(errat);
        int skip = eclass == rb_eSysStackError;

#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)
#define TRACE_HEAD 8
#define TRACE_TAIL 5

	for (i = 1; i < len; i++) {
	    if (TYPE(ptr[i]) == T_STRING) {
		warn_printf("\tfrom %s\n", RSTRING_PTR(ptr[i]));
	    }
	    if (skip && i == TRACE_HEAD && len > TRACE_MAX) {
		warn_printf("\t ... %ld levels...\n",
			    len - TRACE_HEAD - TRACE_TAIL);
		i = len - TRACE_TAIL;
	    }
	}
    }
  error:
    POP_TAG();
}
예제 #18
0
파일: macro.c 프로젝트: nptchang/controller
// Macro Processing Loop, called from the periodic execution thread
// Called once per USB buffer send
void Macro_periodic()
{
	// Latency measurement
	Latency_start_time( macroLatencyResource );

#if defined(ConnectEnabled_define)
	// Only compile in if a Connect node module is available
	// If this is a interconnect slave node, send all scancodes to master node
	if ( !Connect_master )
	{
		if ( macroTriggerEventBufferSize > 0 )
		{
			Connect_send_ScanCode( Connect_id, macroTriggerEventBuffer, macroTriggerEventBufferSize );
			macroTriggerEventBufferSize = 0;
		}
		return;
	}
#endif

#if defined(ConnectEnabled_define) || defined(PressReleaseCache_define)
#if defined(ConnectEnabled_define)
	// Check if there are any ScanCodes in the interconnect cache to process
	if ( Connect_master && macroInterconnectCacheSize > 0 )
#endif
	{
		// Iterate over all the cache ScanCodes
		uint8_t currentInterconnectCacheSize = macroInterconnectCacheSize;
		macroInterconnectCacheSize = 0;
		for ( uint8_t c = 0; c < currentInterconnectCacheSize; c++ )
		{
			// Add to the trigger list
			macroTriggerEventBuffer[ macroTriggerEventBufferSize++ ] = macroInterconnectCache[ c ];

			// TODO Handle other TriggerGuide types (e.g. analog)
			switch ( macroInterconnectCache[ c ].type )
			{
			// Normal (Press/Hold/Release)
			case TriggerType_Switch1:
			case TriggerType_Switch2:
			case TriggerType_Switch3:
			case TriggerType_Switch4:
			case TriggerType_LED1:
				// Decide what to do based on the current state
				switch ( macroInterconnectCache[ c ].state )
				{
				// Re-add to interconnect cache in hold state
				case ScheduleType_P: // Press
				//case ScheduleType_H: // Hold // XXX Why does this not work? -HaaTa
					macroInterconnectCache[ c ].state = ScheduleType_H;
					macroInterconnectCache[ macroInterconnectCacheSize++ ] = macroInterconnectCache[ c ];
					break;

				case ScheduleType_R: // Release
					break;

				// Otherwise, do not re-add
				default:
					break;
				}
				break;

			// Not implemented
			default:
				erro_msg("Interconnect Trigger Event Type - Not Implemented ");
				printInt8( macroInterconnectCache[ c ].type );
				print( NL );
				break;
			}
		}
	}
#endif
	// Macro incoming state debug
	switch ( macroDebugMode )
	{
	case 1:
	case 2:
		// Iterate over incoming triggers
		for ( uint16_t trigger = 0; trigger < macroTriggerEventBufferSize; trigger++ )
		{
			// Show debug info about incoming trigger
			Macro_showTriggerEvent( &macroTriggerEventBuffer[trigger] );
			print( NL );
		}

	case 3:
	default:
		break;
	}

	// Check macroTriggerEventBufferSize to make sure no overflow
	if ( macroTriggerEventBufferSize >= MaxScanCode_KLL )
	{
		// No scancodes defined
		if ( MaxScanCode_KLL == 0 )
		{
			warn_print("No scancodes defined! Check your BaseMap!");
		}
		// Bug!
		else
		{
			erro_msg("Macro Trigger Event Overflow! Serious Bug! ");
			printInt16( macroTriggerEventBufferSize );
			print( NL );
			macroTriggerEventBufferSize = 0;
		}
	}

	// If the pause flag is set, only process if the step counter is non-zero
	if ( macroPauseMode )
	{
		if ( macroStepCounter == 0 )
			return;

		// Proceed, decrementing the step counter
		macroStepCounter--;
		dbug_print("Macro Step");
	}

	// Process Trigger Macros
	Trigger_process();


	// Store events processed
	var_uint_t macroTriggerEventBufferSize_processed = macroTriggerEventBufferSize;

	// Reset TriggerList buffer
	macroTriggerEventBufferSize = 0;


	// Process result macros
	Result_process();

	// Signal buffer that we've used it
	Scan_finishedWithMacro( macroTriggerEventBufferSize_processed );

#if defined(_host_)
	// Signal host to read layer state
	Output_callback( "layerState", "" );
#endif

	// Latency measurement
	Latency_end_time( macroLatencyResource );

	// If Macro debug mode is set, clear the USB Buffer
#if defined(Output_USBEnabled_define)
	if ( macroDebugMode == 1 || macroDebugMode == 3 )
	{
		USBKeys_primary.changed = 0;
	}
#endif
}
예제 #19
0
파일: macro.c 프로젝트: nptchang/controller
void cliFunc_capSelect( char* args )
{
	// Parse code from argument
	char* curArgs;
	char* arg1Ptr;
	char* arg2Ptr = args;

	// Total number of args to scan (must do a lookup if a keyboard capability is selected)
	var_uint_t totalArgs = 2; // Always at least two args
	var_uint_t cap = 0;

	// Arguments used for keyboard capability function
	var_uint_t argSetCount = 0;
	uint8_t *argSet = (uint8_t*)args;

	// Process all args
	for ( var_uint_t c = 0; argSetCount < totalArgs; c++ )
	{
		curArgs = arg2Ptr;
		CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );

		// Stop processing args if no more are found
		// Extra arguments are ignored
		if ( *arg1Ptr == '\0' )
			break;

		// For the first argument, choose the capability
		if ( c == 0 ) switch ( arg1Ptr[0] )
		{
		// Keyboard Capability
		case 'K':
			// Determine capability index
			cap = numToInt( &arg1Ptr[1] );

			// Lookup the number of args
			totalArgs += CapabilitiesList[ cap ].argCount;
			continue;
		}

		// Because allocating memory isn't doable, and the argument count is arbitrary
		// The argument pointer is repurposed as the argument list (much smaller anyways)
		argSet[ argSetCount++ ] = (uint8_t)numToInt( arg1Ptr );

		// Once all the arguments are prepared, call the keyboard capability function
		if ( argSetCount == totalArgs )
		{
			// Indicate that the capability was called
			print( NL );
			info_msg("K");
			printInt8( cap );
			print(" - ");
			printHex( argSet[0] );
			print(" - ");
			printHex( argSet[1] );
			print(" - ");
			printHex( argSet[2] );
			print( "..." NL );

			// Make sure this isn't the reload capability
			// If it is, and the remote reflash define is not set, ignore
			if ( flashModeEnabled_define == 0 ) for ( uint32_t cap = 0; cap < CapabilitiesNum; cap++ )
			{
				if ( CapabilitiesList[ cap ].func == (const void*)Output_flashMode_capability )
				{
					print( NL );
					warn_print("flashModeEnabled not set, cancelling firmware reload...");
					info_msg("Set flashModeEnabled to 1 in your kll configuration.");
					return;
				}
			}

			void (*capability)(TriggerMacro*, uint8_t, uint8_t, uint8_t*) = \
				(void(*)(TriggerMacro*, uint8_t, uint8_t, uint8_t*))(CapabilitiesList[ cap ].func);
			capability( 0, argSet[0], argSet[1], &argSet[2] );
		}
	}
}
예제 #20
0
// Adds a single USB Code to the USB Output buffer
// Argument #1: USB Code
void Output_usbCodeSend_capability( uint8_t state, uint8_t stateType, uint8_t *args )
{
	// Display capability name
	if ( stateType == 0xFF && state == 0xFF )
	{
		print("Output_usbCodeSend(usbCode)");
		return;
	}

	// Depending on which mode the keyboard is in the USB needs Press/Hold/Release events
	uint8_t keyPress = 0; // Default to key release, only used for NKRO
	switch ( USBKeys_Protocol )
	{
	case 0: // Boot Mode
		// TODO Analog inputs
		// Only indicate USB has changed if either a press or release has occured
		if ( state == 0x01 || state == 0x03 )
			USBKeys_Changed = USBKeyChangeState_MainKeys;

		// Only send keypresses if press or hold state
		if ( stateType == 0x00 && state == 0x03 ) // Release state
			return;
		break;
	case 1: // NKRO Mode
		// Only send press and release events
		if ( stateType == 0x00 && state == 0x02 ) // Hold state
			return;

		// Determine if setting or unsetting the bitfield (press == set)
		if ( stateType == 0x00 && state == 0x01 ) // Press state
			keyPress = 1;
		break;
	}

	// Get the keycode from arguments
	uint8_t key = args[0];

	// Depending on which mode the keyboard is in, USBKeys_Keys array is used differently
	// Boot mode - Maximum of 6 byte codes
	// NKRO mode - Each bit of the 26 byte corresponds to a key
	//  Bits   0 -  45 (bytes  0 -  5) correspond to USB Codes   4 -  49 (Main)
	//  Bits  48 - 161 (bytes  6 - 20) correspond to USB Codes  51 - 164 (Secondary)
	//  Bits 168 - 213 (bytes 21 - 26) correspond to USB Codes 176 - 221 (Tertiary)
	//  Bits 214 - 216                 unused
	uint8_t bytePosition = 0;
	uint8_t byteShift = 0;
	switch ( USBKeys_Protocol )
	{
	case 0: // Boot Mode
		// Set the modifier bit if this key is a modifier
		if ( (key & 0xE0) == 0xE0 ) // AND with 0xE0 (Left Ctrl, first modifier)
		{
			USBKeys_Modifiers |= 1 << (key ^ 0xE0); // Left shift 1 by key XOR 0xE0
		}
		// Normal USB Code
		else
		{
			// USB Key limit reached
			if ( USBKeys_Sent >= USB_BOOT_MAX_KEYS )
			{
				warn_print("USB Key limit reached");
				return;
			}

			// Make sure key is within the USB HID range
			if ( key <= 104 )
			{
				USBKeys_Keys[USBKeys_Sent++] = key;
			}
			// Invalid key
			else
			{
				warn_msg("USB Code above 104/0x68 in Boot Mode: ");
				printHex( key );
				print( NL );
			}
		}
		break;

	case 1: // NKRO Mode
		// Set the modifier bit if this key is a modifier
		if ( (key & 0xE0) == 0xE0 ) // AND with 0xE0 (Left Ctrl, first modifier)
		{
			if ( keyPress )
			{
				USBKeys_Modifiers |= 1 << (key ^ 0xE0); // Left shift 1 by key XOR 0xE0
			}
			else // Release
			{
				USBKeys_Modifiers &= ~(1 << (key ^ 0xE0)); // Left shift 1 by key XOR 0xE0
			}

			USBKeys_Changed |= USBKeyChangeState_Modifiers;
			break;
		}
		// First 6 bytes
		else if ( key >= 4 && key <= 49 )
		{
			// Lookup (otherwise division or multiple checks are needed to do alignment)
			// Starting at 0th position, each byte has 8 bits, starting at 4th bit
			uint8_t keyPos = key + (0 * 8 - 4); // Starting position in array, Ignoring 4 keys
			switch ( keyPos )
			{
				byteLookup( 0 );
				byteLookup( 1 );
				byteLookup( 2 );
				byteLookup( 3 );
				byteLookup( 4 );
				byteLookup( 5 );
			}

			USBKeys_Changed |= USBKeyChangeState_MainKeys;
		}
		// Next 14 bytes
		else if ( key >= 51 && key <= 155 )
		{
			// Lookup (otherwise division or multiple checks are needed to do alignment)
			// Starting at 6th byte position, each byte has 8 bits, starting at 51st bit
			uint8_t keyPos = key + (6 * 8 - 51); // Starting position in array
			switch ( keyPos )
			{
				byteLookup( 6 );
				byteLookup( 7 );
				byteLookup( 8 );
				byteLookup( 9 );
				byteLookup( 10 );
				byteLookup( 11 );
				byteLookup( 12 );
				byteLookup( 13 );
				byteLookup( 14 );
				byteLookup( 15 );
				byteLookup( 16 );
				byteLookup( 17 );
				byteLookup( 18 );
				byteLookup( 19 );
			}

			USBKeys_Changed |= USBKeyChangeState_SecondaryKeys;
		}
		// Next byte
		else if ( key >= 157 && key <= 164 )
		{
			// Lookup (otherwise division or multiple checks are needed to do alignment)
			uint8_t keyPos = key + (20 * 8 - 157); // Starting position in array, Ignoring 6 keys
			switch ( keyPos )
			{
				byteLookup( 20 );
			}

			USBKeys_Changed |= USBKeyChangeState_TertiaryKeys;
		}
		// Last 6 bytes
		else if ( key >= 176 && key <= 221 )
		{
			// Lookup (otherwise division or multiple checks are needed to do alignment)
			uint8_t keyPos = key + (21 * 8 - 176); // Starting position in array
			switch ( keyPos )
			{
				byteLookup( 21 );
				byteLookup( 22 );
				byteLookup( 23 );
				byteLookup( 24 );
				byteLookup( 25 );
				byteLookup( 26 );
			}

			USBKeys_Changed |= USBKeyChangeState_QuartiaryKeys;
		}
		// Received 0x00
		// This is a special USB Code that internally indicates a "break"
		// It is used to send "nothing" in order to break up sequences of USB Codes
		else if ( key == 0x00 )
		{
			USBKeys_Changed |= USBKeyChangeState_MainKeys;

			// Also flush out buffers just in case
			Output_flushBuffers();
			break;
		}
		// Invalid key
		else
		{
			warn_msg("USB Code not within 4-49 (0x4-0x31), 51-155 (0x33-0x9B), 157-164 (0x9D-0xA4), 176-221 (0xB0-0xDD) or 224-231 (0xE0-0xE7) NKRO Mode: ");
			printHex( key );
			print( NL );
			break;
		}

		// Set/Unset
		if ( keyPress )
		{
			USBKeys_Keys[bytePosition] |= (1 << byteShift);
			USBKeys_Sent++;
		}
		else // Release
		{
			USBKeys_Keys[bytePosition] &= ~(1 << byteShift);
			USBKeys_Sent++;
		}

		break;
	}
}
예제 #21
0
파일: eval_error.c 프로젝트: rhenium/ruby
void
rb_threadptr_error_print(rb_thread_t *th, VALUE errinfo)
{
    volatile VALUE errat = Qundef;
    int raised_flag = th->raised_flag;
    volatile VALUE eclass = Qundef, e = Qundef;
    const char *volatile einfo;
    volatile long elen;
    VALUE mesg;

    if (NIL_P(errinfo))
	return;
    rb_thread_raised_clear(th);

    TH_PUSH_TAG(th);
    if (TH_EXEC_TAG() == 0) {
	errat = rb_get_backtrace(errinfo);
    }
    else if (errat == Qundef) {
	errat = Qnil;
    }
    else if (eclass == Qundef || e != Qundef) {
	goto error;
    }
    else {
	goto no_message;
    }
    if (NIL_P(errat) || RARRAY_LEN(errat) == 0 ||
	NIL_P(mesg = RARRAY_AREF(errat, 0))) {
	error_pos();
    }
    else {
	warn_print_str(mesg);
	warn_print(": ");
    }

    eclass = CLASS_OF(errinfo);
    if (eclass != Qundef &&
	(e = rb_check_funcall(errinfo, rb_intern("message"), 0, 0)) != Qundef &&
	(RB_TYPE_P(e, T_STRING) || !NIL_P(e = rb_check_string_type(e)))) {
	einfo = RSTRING_PTR(e);
	elen = RSTRING_LEN(e);
    }
    else {
      no_message:
	einfo = "";
	elen = 0;
    }
    if (eclass == rb_eRuntimeError && elen == 0) {
	warn_print("unhandled exception\n");
    }
    else {
	VALUE epath;

	epath = rb_class_name(eclass);
	if (elen == 0) {
	    warn_print_str(epath);
	    warn_print("\n");
	}
	else {
	    const char *tail = 0;
	    long len = elen;

	    if (RSTRING_PTR(epath)[0] == '#')
		epath = 0;
	    if ((tail = memchr(einfo, '\n', elen)) != 0) {
		len = tail - einfo;
		tail++;		/* skip newline */
	    }
	    warn_print_str(tail ? rb_str_subseq(e, 0, len) : e);
	    if (epath) {
		warn_print(" (");
		warn_print_str(epath);
		warn_print(")\n");
	    }
	    if (tail) {
		warn_print_str(rb_str_subseq(e, tail - einfo, elen - len - 1));
	    }
	    if (tail ? einfo[elen-1] != '\n' : !epath) warn_print2("\n", 1);
	}
    }

    if (!NIL_P(errat)) {
	long i;
	long len = RARRAY_LEN(errat);
        int skip = eclass == rb_eSysStackError;

#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)
#define TRACE_HEAD 8
#define TRACE_TAIL 5

	for (i = 1; i < len; i++) {
	    VALUE line = RARRAY_AREF(errat, i);
	    if (RB_TYPE_P(line, T_STRING)) {
		warn_print_str(rb_sprintf("\tfrom %"PRIsVALUE"\n", line));
	    }
	    if (skip && i == TRACE_HEAD && len > TRACE_MAX) {
		warn_print_str(rb_sprintf("\t ... %ld levels...\n",
					  len - TRACE_HEAD - TRACE_TAIL));
		i = len - TRACE_TAIL;
	    }
	}
    }
  error:
    TH_POP_TAG();
    th->errinfo = errinfo;
    rb_thread_raised_set(th, raised_flag);
}
예제 #22
0
int32_t i2c_send_sequence(
	uint8_t ch,
	uint16_t *sequence,
	uint32_t sequence_length,
	uint8_t *received_data,
	void ( *callback_fn )( void* ),
	void *user_data
) {
	int32_t result = 0;

	volatile I2C_Channel *channel = &( i2c_channels[ch - ISSI_I2C_FirstBus_define] );
	uint8_t address;

#if defined(_kinetis_)
	uint8_t status;
	volatile uint8_t *I2C_C1  = (uint8_t*)(&I2C0_C1) + i2c_offset[ch];
	volatile uint8_t *I2C_S   = (uint8_t*)(&I2C0_S) + i2c_offset[ch];
	volatile uint8_t *I2C_D   = (uint8_t*)(&I2C0_D) + i2c_offset[ch];
#elif defined(_sam_)
	Twi *twi_dev = twi_devs[ch];
#endif

	if ( channel->status == I2C_BUSY )
	{
		return -1;
	}

	// Check if there are back-to-back errors
	// in succession
	if ( channel->last_error > 5 )
	{
		warn_msg("I2C Bus Error: ");
		printInt8( ch );
		print(" errors: ");
		printInt32( channel->error_count );
		print( NL );
	}

	// Debug
	/*
	for ( uint8_t c = 0; c < sequence_length; c++ )
	{
		printHex( sequence[c] );
		print(" ");
	}
	print(NL);
	*/

	channel->sequence = sequence;
	channel->sequence_end = sequence + sequence_length;
	channel->received_data = received_data;
	channel->status = I2C_BUSY;
	channel->txrx = I2C_WRITING;
	channel->callback_fn = callback_fn;
	channel->user_data = user_data;

	// reads_ahead does not need to be initialized

#if defined(_kinetis_)
	// Acknowledge the interrupt request, just in case
	*I2C_S |= I2C_S_IICIF;
	*I2C_C1 = ( I2C_C1_IICEN | I2C_C1_IICIE );

	// Generate a start condition and prepare for transmitting.
	*I2C_C1 |= ( I2C_C1_MST | I2C_C1_TX );

	status = *I2C_S;
	if ( status & I2C_S_ARBL )
	{
		warn_print("Arbitration lost");
		result = -1;
		goto i2c_send_sequence_cleanup;
	}

	// Write the first (address) byte.
	address = *channel->sequence++;
	*I2C_D = address;

	// Everything is OK.
	return result;

i2c_send_sequence_cleanup:
	// Record error, and reset last error counter
	channel->error_count++;
	channel->last_error++;

	// Generate STOP and disable further interrupts.
	*I2C_C1 &= ~( I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TX );
	channel->status = I2C_ERROR;

#elif defined(_sam_)
	// Convert 8 bit address to 7bit + RW
	address = *channel->sequence++;
	//print("Address: ");
	//printHex( address );
	//print( NL );

	uint8_t mread = address & 1;
	address >>= 1;

	// Set slave address
	twi_dev->TWI_MMR = TWI_MMR_DADR(address) | (mread ? TWI_MMR_MREAD : 0);

	// Enable interrupts
	twi_dev->TWI_IER = TWI_IER_RXRDY | TWI_IER_TXRDY | TWI_IER_TXCOMP | TWI_IER_ARBLST;
	//twi_dev->TWI_IDR = 0xFFFFFFFF;

	// Generate a start condition
	twi_dev->TWI_CR |= TWI_CR_START;

	// Fire off the first read or write.
	// The first (address) byte is automatically trasmitted before any data
	// Arbitration errors will be handled in the isr
	i2c_isr(ch);

	// Everything is OK.
	return result;
#endif

	return result;
}