Exemple #1
0
bool WEAK CDC_Setup(Setup& setup)
{
	u8 r = setup.bRequest;
	u8 requestType = setup.bmRequestType;

	if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
	{
		if (CDC_GET_LINE_CODING == r)
		{
			USB_SendControl(0,(void*)&_usbLineInfo,7);
			return true;
		}
	}

	if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
	{
		if (CDC_SET_LINE_CODING == r)
		{
			USB_RecvControl((void*)&_usbLineInfo,7);
			return true;
		}

		if (CDC_SET_CONTROL_LINE_STATE == r)
		{
                  _usbLineInfo.lineState = setup.wValueL;
                  if(1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) {
                    // auto-reset is triggered when the port, already open at 1200 bps, is closed
                    Reboot();
                  }
                  return true;
		}
	}
	return false;
}
bool CDC_Setup(USBSetup& setup)
{
	u8 r = setup.bRequest;
	u8 requestType = setup.bmRequestType;

	if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
	{
		if (CDC_GET_LINE_CODING == r)
		{
			USB_SendControl(0,(void*)&_usbLineInfo,7);
			return true;
		}
	}

	if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
	{
		if (CDC_SET_LINE_CODING == r)
		{
			USB_RecvControl((void*)&_usbLineInfo,7);
		}

		if (CDC_SET_CONTROL_LINE_STATE == r)
		{
			_usbLineInfo.lineState = setup.wValueL;
		}

		if (CDC_SET_LINE_CODING == r || CDC_SET_CONTROL_LINE_STATE == r)
		{
			// auto-reset into the bootloader is triggered when the port, already 
			// open at 1200 bps, is closed.  this is the signal to start the watchdog
			// with a relatively long period so it can finish housekeeping tasks
			// like servicing endpoints before the sketch ends

			// We check DTR state to determine if host port is open (bit 0 of lineState).
			if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
			{
				*(uint16_t *)(RAMEND-1) = *(uint16_t *)0x0800;
				*(uint16_t *)0x0800 = 0x7777;
				wdt_enable(WDTO_120MS);
			}
			else
			{
				// Most OSs do some intermediate steps when configuring ports and DTR can
				// twiggle more than once before stabilizing.
				// To avoid spurious resets we set the watchdog to 250ms and eventually
				// cancel if DTR goes back high.

				wdt_disable();
				wdt_reset();
				*(uint16_t *)0x0800 = *(uint16_t *)(RAMEND-1);
			}
		}
		return true;
	}
	return false;
}
Exemple #3
0
bool WEAK HID_Setup(Setup& setup)
{
	u8 r = setup.bRequest;
	u8 requestType = setup.bmRequestType;
	if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
	{
		if (HID_GET_REPORT == r)
		{
			//HID_GetReport();
			return true;
		}
		if (HID_GET_PROTOCOL == r)
		{
			//Send8(_hid_protocol);	// TODO
			return true;
		}
	}

	if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
	{
		if (HID_SET_PROTOCOL == r)
		{
			_hid_protocol = setup.wValueL;
			return true;
		}

		if (HID_SET_IDLE == r)
		{
			_hid_idle = setup.wValueL;
			return true;
		}
#if defined(HID_KEYBOARD_LEDS_ENABLED)
		if (HID_SET_REPORT == r)
		{
			//TODO check correct report ID (not needed for now, no other device has an out report)
			// maybe make this a general weak implementation to use it for RAW HID later?
			if (setup.wLength == 2)
			{
				// write led out report data
				uint8_t data[2];
				if (2 == USB_RecvControl(data, 2))
					hid_keyboard_leds = data[1];
			}
			// else TODO check for other devices like RAW HID, not needed for now
		}
#endif
	}
	return false;
}
Exemple #4
0
bool WEAK HID_Setup(Setup& setup)
{
	u8 r = setup.bRequest;
	u8 requestType = setup.bmRequestType;
	if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
	{
		if (HID_GET_REPORT == r)
		{
			//HID_GetReport();
			return true;
		}
		if (HID_GET_PROTOCOL == r)
		{
			//Send8(_hid_protocol);	// TODO
			return true;
		}
	}
	
	if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
	{
		if (HID_SET_PROTOCOL == r)
		{
			_hid_protocol = setup.wValueL;
			return true;
		}

		if (HID_SET_IDLE == r)
		{
			_hid_idle = setup.wValueL;
			return true;
		}

		if (HID_SET_REPORT == r)
		{
			if (setup.wLength == 2) 
			{
				uint8_t data[2];
				if (2 == USB_RecvControl(data, 2)) 
				{
					Keyboard.setLedStatus(data[1]);
                    return true;
				}
			}
		}
	}
	return false;
}
Exemple #5
0
bool CDC_Setup(USBSetup& setup)
{
	u8 r = setup.bRequest;
	u8 requestType = setup.bmRequestType;

	if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
	{
		if (CDC_GET_LINE_CODING == r)
		{
			USB_SendControl(0,(void*)&_usbLineInfo,7);
			return true;
		}
	}

	if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
	{
		if (CDC_SEND_BREAK == r)
		{
			breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
		}

		if (CDC_SET_LINE_CODING == r)
		{
			USB_RecvControl((void*)&_usbLineInfo,7);
		}

		if (CDC_SET_CONTROL_LINE_STATE == r)
		{
			_usbLineInfo.lineState = setup.wValueL;
		}

		if (CDC_SET_LINE_CODING == r || CDC_SET_CONTROL_LINE_STATE == r)
		{
			// auto-reset into the bootloader is triggered when the port, already 
			// open at 1200 bps, is closed.  this is the signal to start the watchdog
			// with a relatively long period so it can finish housekeeping tasks
			// like servicing endpoints before the sketch ends

#ifndef MAGIC_KEY
#define MAGIC_KEY 0x7777
#endif
#ifndef MAGIC_KEY_POS
#define MAGIC_KEY_POS 0x0800
#endif

			// We check DTR state to determine if host port is open (bit 0 of lineState).
			if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
			{
#if MAGIC_KEY_POS != (RAMEND-1)
				*(uint16_t *)(RAMEND-1) = *(uint16_t *)MAGIC_KEY_POS;
				*(uint16_t *)MAGIC_KEY_POS = MAGIC_KEY;
#else
				// for future boards save the key in the inproblematic RAMEND
				// which is reserved for the main() return value (which will never return)
				*(uint16_t *)MAGIC_KEY_POS = MAGIC_KEY;
#endif
				wdt_enable(WDTO_120MS);
			}
			else
			{
				// Most OSs do some intermediate steps when configuring ports and DTR can
				// twiggle more than once before stabilizing.
				// To avoid spurious resets we set the watchdog to 250ms and eventually
				// cancel if DTR goes back high.

				wdt_disable();
				wdt_reset();
#if MAGIC_KEY_POS != (RAMEND-1)
				*(uint16_t *)MAGIC_KEY_POS = *(uint16_t *)(RAMEND-1);
#else
				*(uint16_t *)MAGIC_KEY_POS = 0x0000;
#endif
			}
		}
		return true;
	}
	return false;
}
Exemple #6
0
bool CDC_Setup(USBSetup& setup)
{
	u8 r = setup.bRequest;
	u8 requestType = setup.bmRequestType;

	if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
	{
		if (CDC_GET_LINE_CODING == r)
		{
			USB_SendControl(0,(void*)&_usbLineInfo,7);
			return true;
		}
	}

	if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
	{
		if (CDC_SEND_BREAK == r)
		{
			breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
		}

		if (CDC_SET_LINE_CODING == r)
		{
			USB_RecvControl((void*)&_usbLineInfo,7);
		}

		if (CDC_SET_CONTROL_LINE_STATE == r)
		{
			_usbLineInfo.lineState = setup.wValueL;
		}

		if (CDC_SET_LINE_CODING == r || CDC_SET_CONTROL_LINE_STATE == r)
		{
			// auto-reset into the bootloader is triggered when the port, already 
			// open at 1200 bps, is closed.  this is the signal to start the watchdog
			// with a relatively long period so it can finish housekeeping tasks
			// like servicing endpoints before the sketch ends

			uint16_t magic_key_pos = MAGIC_KEY_POS;

// If we don't use the new RAMEND directly, check manually if we have a newer bootloader.
// This is used to keep compatible with the old leonardo bootloaders.
// You are still able to set the magic key position manually to RAMEND-1 to save a few bytes for this check.
#if MAGIC_KEY_POS != (RAMEND-1)
			// For future boards save the key in the inproblematic RAMEND
			// Which is reserved for the main() return value (which will never return)
			if (_updatedLUFAbootloader) {
				// horray, we got a new bootloader!
				magic_key_pos = (RAMEND-1);
			}
#endif

			// We check DTR state to determine if host port is open (bit 0 of lineState).
			if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
			{
#if MAGIC_KEY_POS != (RAMEND-1)
				// Backup ram value if its not a newer bootloader.
				// This should avoid memory corruption at least a bit, not fully
				if (magic_key_pos != (RAMEND-1)) {
					*(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos;
				}
#endif
				// Store boot key
				*(uint16_t *)magic_key_pos = MAGIC_KEY;
				wdt_enable(WDTO_120MS);
			}
			else
			{
				// Most OSs do some intermediate steps when configuring ports and DTR can
				// twiggle more than once before stabilizing.
				// To avoid spurious resets we set the watchdog to 250ms and eventually
				// cancel if DTR goes back high.

				wdt_disable();
				wdt_reset();
#if MAGIC_KEY_POS != (RAMEND-1)
				// Restore backed up (old bootloader) magic key data
				if (magic_key_pos != (RAMEND-1)) {
					*(uint16_t *)magic_key_pos = *(uint16_t *)(RAMEND-1);
				} else
#endif
				{
				// Clean up RAMEND key
					*(uint16_t *)magic_key_pos = 0x0000;
				}
			}
		}
		return true;
	}
	return false;
}