示例#1
0
int usb_guitar_send(void)
{
    uint32_t wait_count=0;
    usb_packet_t *tx_packet;

    //serial_print("send");
    //serial_print("\n");
    while (1) {
        if (!usb_configuration) {
            //serial_print("error1\n");
            return -1;
        }
        if (usb_tx_packet_count(GUITAR_ENDPOINT1) < TX_PACKET_LIMIT) {
            tx_packet = usb_malloc();
            if (tx_packet) break;
        }
        if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) {
            transmit_previous_timeout = 1;
            //serial_print("error2\n");
            return -1;
        }
        yield();
    }
    transmit_previous_timeout = 0;
    memcpy(tx_packet->buf, usb_guitar_data, 7);
    tx_packet->len = 7;
    usb_tx(GUITAR_ENDPOINT1, tx_packet);
    //serial_print("ok\n");
    return 0;
}
示例#2
0
// send the contents of keyboard_keys and keyboard_modifier_keys
int usb_keyboard_send(void)
{
	if (!usb_driver_enabled)
		return 0;

	uint32_t wait_count=0;
	usb_packet_t *tx_packet;

	while (1) {
		if (!usb_configuration) {
			return -1;
		}
		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;
			return -1;
		}
		yield();
	}
	*(tx_packet->buf) = keyboard_modifier_keys;
	*(tx_packet->buf + 1) = keyboard_media_keys;
	memcpy(tx_packet->buf + 2, keyboard_keys, 6);
	tx_packet->len = 8;
	usb_tx(KEYBOARD_ENDPOINT, tx_packet);
	return 0;
}
示例#3
0
int usb_serial_write( const void *buffer, uint32_t size )
{
	uint32_t len;
	uint32_t wait_count;
	const uint8_t *src = (const uint8_t *)buffer;
	uint8_t *dest;

	tx_noautoflush = 1;
	while ( size > 0 )
	{
		if ( !tx_packet )
		{
			wait_count = 0;
			while ( 1 )
			{
				if ( !usb_configuration )
				{
					tx_noautoflush = 0;
					return -1;
				}
				if ( usb_tx_packet_count( CDC_TX_ENDPOINT ) < TX_PACKET_LIMIT )
				{
					tx_noautoflush = 1;
					tx_packet = usb_malloc();
					if ( tx_packet )
						break;
					tx_noautoflush = 0;
				}
				if ( ++wait_count > TX_TIMEOUT || transmit_previous_timeout )
				{
					transmit_previous_timeout = 1;
					return -1;
				}
				yield();
			}
		}
		transmit_previous_timeout = 0;
		len = CDC_TX_SIZE - tx_packet->index;
		if ( len > size )
			len = size;
		dest = tx_packet->buf + tx_packet->index;
		tx_packet->index += len;
		size -= len;
		while ( len-- > 0 )
			*dest++ = *src++;
		if ( tx_packet->index >= CDC_TX_SIZE )
		{
			tx_packet->len = CDC_TX_SIZE;
			usb_tx( CDC_TX_ENDPOINT, tx_packet );
			tx_packet = NULL;
		}
		usb_cdc_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
	}
	tx_noautoflush = 0;
	return 0;
}
示例#4
0
void FlightSimClass::xmit(const void *p1, uint8_t n1, const void *p2, uint8_t n2)
{
	uint16_t total;

	total = n1 + n2;
	if (total > FLIGHTSIM_TX_SIZE) {
		xmit_big_packet(p1, n1, p2,  n2);
		return;
	}
	if (!enabled || !usb_configuration) return;
	tx_noautoflush = 1;
	if (tx_packet) {
		if (total <= FLIGHTSIM_TX_SIZE - tx_packet->index) goto send;
		for (int i = tx_packet->index; i < FLIGHTSIM_TX_SIZE; i++) {
			tx_packet->buf[i] = 0;
		}
		tx_packet->len = FLIGHTSIM_TX_SIZE;
		usb_tx(FLIGHTSIM_TX_ENDPOINT, tx_packet);
		tx_packet = NULL;
	}
	while (1) {
		if (usb_tx_packet_count(FLIGHTSIM_TX_ENDPOINT) < TX_PACKET_LIMIT) {
			tx_packet = usb_malloc();
			if (tx_packet) break;
		}
		if (!enabled || !usb_configuration) {
			tx_noautoflush = 0;
			return;
		}
		tx_noautoflush = 0;
		yield();
		tx_noautoflush = 1;
	}
send:
	memcpy(tx_packet->buf + tx_packet->index, p1, n1);
	tx_packet->index += n1;
	if (n2 > 0) {
		memcpy(tx_packet->buf + tx_packet->index, p2, n2);
		tx_packet->index += n2;
	}
	if (tx_packet->index >= FLIGHTSIM_TX_SIZE) {
		tx_packet->len = FLIGHTSIM_TX_SIZE;
		usb_tx(FLIGHTSIM_TX_ENDPOINT, tx_packet);
		tx_packet = NULL;
	}
	tx_noautoflush = 0;
}
示例#5
0
int usb_rawhid_send(const void *buffer, uint32_t timeout)
{
	usb_packet_t *tx_packet;
	uint32_t begin = millis();

	while (1) {
		if (!usb_configuration) return -1;
		if (usb_tx_packet_count(RAWHID_TX_ENDPOINT) < TX_PACKET_LIMIT) {
			tx_packet = usb_malloc();
			if (tx_packet) break;
		}
		if (millis() - begin > timeout) return 0;
		yield();
	}
	memcpy(tx_packet->buf, buffer, RAWHID_TX_SIZE);
	tx_packet->len = RAWHID_TX_SIZE;
	usb_tx(RAWHID_TX_ENDPOINT, tx_packet);
	return RAWHID_TX_SIZE;
}
示例#6
0
// transmit a character.  0 returned on success, -1 on error
int usb_serial_putchar(uint8_t c)
{
#if 1
	return usb_serial_write(&c, 1);
#endif
#if 0
	uint32_t wait_count;

	tx_noautoflush = 1;
	if (!tx_packet) {
		wait_count = 0;
		while (1) {
			if (!usb_configuration) {
				tx_noautoflush = 0;
				return -1;
			}
			if (usb_tx_packet_count(CDC_TX_ENDPOINT) < TX_PACKET_LIMIT) {
				tx_noautoflush = 1;
				tx_packet = usb_malloc();
				if (tx_packet) break;
				tx_noautoflush = 0;
			}
			if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) {
				transmit_previous_timeout = 1;
				return -1;
			}
		}
	}
	transmit_previous_timeout = 0;
	tx_packet->buf[tx_packet->index++] = c;
	if (tx_packet->index < CDC_TX_SIZE) {
		usb_cdc_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
	} else {
		tx_packet->len = CDC_TX_SIZE;
		usb_cdc_transmit_flush_timer = 0;
		usb_tx(CDC_TX_ENDPOINT, tx_packet);
		tx_packet = NULL;
	}
	tx_noautoflush = 0;
	return 0;
#endif
}
// send the contents of keyboard_keys and keyboard_modifier_keys
int usb_keyboard_send(void)
{
#if 0
	serial_print("Send:");
	serial_phex(keyboard_modifier_keys);
	serial_phex(keyboard_keys[0]);
	serial_phex(keyboard_keys[1]);
	serial_phex(keyboard_keys[2]);
	serial_phex(keyboard_keys[3]);
	serial_phex(keyboard_keys[4]);
	serial_phex(keyboard_keys[5]);
	serial_print("\n");
#endif
#if 1
	uint32_t wait_count=0;
	usb_packet_t *tx_packet;

	while (1) {
		if (!usb_configuration) {
			return -1;
		}
		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;
			return -1;
		}
		yield();
	}
	*(tx_packet->buf) = keyboard_modifier_keys;
	*(tx_packet->buf + 1) = keyboard_media_keys;
	memcpy(tx_packet->buf + 2, keyboard_keys, 6);
	tx_packet->len = 8;
	usb_tx(KEYBOARD_ENDPOINT, tx_packet);
#endif
	return 0;
}
示例#8
0
int usb_serial_write_buffer_free(void)
{
	uint32_t len;

	tx_noautoflush = 1;
	if (!tx_packet) {
		if (!usb_configuration ||
		  usb_tx_packet_count(CDC_TX_ENDPOINT) >= TX_PACKET_LIMIT ||
		  (tx_packet = usb_malloc()) == NULL) {
			tx_noautoflush = 0;
			return 0;
		}
	}
	len = CDC_TX_SIZE - tx_packet->index;
	// TODO: Perhaps we need "usb_cdc_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT"
	// added here, so the SOF interrupt can't take away the available buffer
	// space we just promised the user could write without blocking?
	// But does this come with other performance downsides?  Could it lead to
	// buffer data never actually transmitting in some usage cases?  More
	// investigation is needed.
	// https://github.com/PaulStoffregen/cores/issues/10#issuecomment-61514955
	tx_noautoflush = 0;
	return len;
}
示例#9
0
void FlightSimClass::xmit_big_packet(const void *p1, uint8_t n1, const void *p2, uint8_t n2)
{
	if (!enabled || !usb_configuration) return;

	uint16_t remaining = n1 + n2;
	if (remaining > 255) return;
	
	bool part2 = false;
	uint8_t remainingPart1 = n1;
	const uint8_t *dataPtr = (const uint8_t*)p1;
	bool writeFragmentHeader = false;
	uint8_t fragmentCounter = 1;

	tx_noautoflush =1; // don't mess with my data, I'm working on it!

	if (tx_packet) {
		// If we have a current packet, fill it with whatever fits
		uint8_t partLen = FLIGHTSIM_TX_SIZE - tx_packet->index; 
		if (partLen > n1) partLen=n1;
		// copy first part, containing total packet length
		memcpy(tx_packet->buf + tx_packet->index, dataPtr, partLen);
		remainingPart1 -= partLen;
		tx_packet->index += partLen;
		if (remainingPart1) {
			// there still is data from the first part that
			// will go to the next packet. The boolean variable
			// part2 remains false
			remaining = remainingPart1+n2;
			dataPtr += partLen;
		} else {
			// maybe we have space for some data from the second part
			part2=true;
			partLen = FLIGHTSIM_TX_SIZE - tx_packet->index;
			// there is no need here to check whether partLen is
			// bigger than n2. It's not. If it were, all the data
			// would have fit in a single packet and xmit_big_packet
			// would never have been called...
			remaining = n2;
			if (partLen) {
				memcpy(tx_packet->buf + tx_packet->index, p2, partLen);
				remaining -= partLen;
				tx_packet->index += partLen;
			}
			dataPtr = (const uint8_t*)p2 + partLen;
		}
		// Packet padding should not be necessary, as xmit_big_packet 
		// will only be called for data that doesn't fit in a single
		// packet. So, the previous code should always fill up the
		// first packet. Right?
		for (int i = tx_packet->index; i < FLIGHTSIM_TX_SIZE; i++) {
			tx_packet->buf[i] = 0;
		}

		// queue first packet for sending
		tx_packet->len = FLIGHTSIM_TX_SIZE;
		usb_tx(FLIGHTSIM_TX_ENDPOINT, tx_packet);
		tx_packet = NULL;
		writeFragmentHeader = true;
	} else {
		remaining = n1+n2;
	}
	
	while (remaining >0) {
		while (1) {
			// get memory for next packet
			if (usb_tx_packet_count(FLIGHTSIM_TX_ENDPOINT) < TX_PACKET_LIMIT) {
				tx_packet = usb_malloc();
				if (tx_packet) {
					break;
				}
			}

			if (!enabled || !usb_configuration) {
				// teensy disconnected
				tx_noautoflush = 0;
				return;
			}
			tx_noautoflush = 0;  // you can pick up my data, if you like
			yield(); 			 // do other things and wait for memory to become free
			tx_noautoflush = 1;  // wait, I'm working on the packet data
		}

		if (writeFragmentHeader) {
			tx_packet->buf[0]=(remaining+3 <= FLIGHTSIM_TX_SIZE) ? (byte) remaining+3 : FLIGHTSIM_TX_SIZE;
			tx_packet->buf[1]=0xff;
			tx_packet->buf[2]=fragmentCounter++;
			tx_packet->index=3;
		}
		if (!part2) {
			// we still need to send the first part
			uint8_t partLen = FLIGHTSIM_TX_SIZE - tx_packet->index; 
			if (partLen > remainingPart1)
				partLen=remainingPart1;
			memcpy(tx_packet->buf + tx_packet->index, dataPtr, partLen);
			dataPtr += partLen;
			remainingPart1 -= partLen;
			tx_packet->index += partLen;
			remaining -= partLen;
			if (!remainingPart1) {
				part2=true;
				dataPtr = (const uint8_t*)p2;
			}
		}

		if (part2) {
			uint8_t partLen = FLIGHTSIM_TX_SIZE - tx_packet->index; 
			if (partLen) {
				if (partLen > remaining)
					partLen=remaining;
				memcpy(tx_packet->buf + tx_packet->index, dataPtr, partLen);
				remaining -= partLen;
				tx_packet->index += partLen;
				dataPtr += partLen;
			}
		} 
		writeFragmentHeader = true;
		
		if (tx_packet->index >= FLIGHTSIM_TX_SIZE) {
			// queue packet for sending
			tx_packet->len = FLIGHTSIM_TX_SIZE;
			usb_tx(FLIGHTSIM_TX_ENDPOINT, tx_packet);
			tx_packet = NULL;
		}
	}
	tx_noautoflush = 0;  // data is ready to be transmitted on start of USB token
}
示例#10
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;
}