Ejemplo n.º 1
0
/* Requests on the control endpoint (aka EP0) */
static void ep0_rx(void)
{
	uint16_t req = ep0_buf_rx[0]; /* bRequestType | bRequest */

	/* interface specific requests */
	if ((req & USB_RECIP_MASK) == USB_RECIP_INTERFACE) {
		uint8_t iface = ep0_buf_rx[1] & 0xff;
		if (iface < USB_IFACE_COUNT)
			usb_iface_request[iface](ep0_buf_rx, ep0_buf_tx);
		return;
	}

	/* TODO check setup bit ? */
	if (req == (USB_DIR_IN | (USB_REQ_GET_DESCRIPTOR << 8))) {
		uint8_t type = ep0_buf_rx[1] >> 8;
		uint8_t idx = ep0_buf_rx[1] & 0xff;
		const uint8_t *str_desc;

		switch (type) {
		case USB_DT_DEVICE: /* Setup : Get device descriptor */
			memcpy_usbram(ep0_buf_tx, (void *)&dev_desc,
					 sizeof(dev_desc));
			btable_ep[0].tx_count =  sizeof(dev_desc);
			STM32_TOGGLE_EP(0, EP_TX_RX_MASK, EP_TX_RX_VALID,
				  EP_STATUS_OUT /*null OUT transaction */);
			break;
		case USB_DT_CONFIGURATION: /* Setup : Get configuration desc */
			memcpy_usbram(ep0_buf_tx, __usb_desc,
					 USB_DESC_SIZE);
			/* set the real descriptor size */
			ep0_buf_tx[1] = USB_DESC_SIZE;
			btable_ep[0].tx_count = MIN(ep0_buf_rx[3],
					 USB_DESC_SIZE);
			STM32_TOGGLE_EP(0, EP_TX_RX_MASK, EP_TX_RX_VALID,
				  EP_STATUS_OUT /*null OUT transaction */);
			break;
		case USB_DT_STRING: /* Setup : Get string descriptor */
			if (idx >= USB_STR_COUNT) {
				/* The string does not exist : STALL */
				STM32_TOGGLE_EP(0, EP_TX_RX_MASK,
					  EP_RX_VALID | EP_TX_STALL, 0);
				return; /* don't remove the STALL */
			}
			str_desc = usb_strings[idx];
			memcpy_usbram(ep0_buf_tx, str_desc, str_desc[0]);
			btable_ep[0].tx_count = MIN(ep0_buf_rx[3], str_desc[0]);
			STM32_TOGGLE_EP(0, EP_TX_RX_MASK, EP_TX_RX_VALID,
				  EP_STATUS_OUT /*null OUT transaction */);
			break;
		case USB_DT_DEVICE_QUALIFIER: /* Get device qualifier desc */
			/* Not high speed : STALL next IN used as handshake */
			STM32_TOGGLE_EP(0, EP_TX_RX_MASK,
					EP_RX_VALID | EP_TX_STALL, 0);
			break;
		default: /* unhandled descriptor */
			goto unknown_req;
		}
	} else if (req == (USB_DIR_IN | (USB_REQ_GET_STATUS << 8))) {
Ejemplo n.º 2
0
void set_keyboard_report(uint64_t rpt)
{
	/* Prevent the interrupt handler from sending the data (which would use
	 * an incomplete buffer).
	 */
	hid_ep_data_ready = 0;
	hid_current_buf = hid_current_buf ? 0 : 1;
	memcpy_to_usbram((void *) usb_sram_addr(hid_ep_buf[hid_current_buf]),
			 &rpt, sizeof(rpt));

	/* Tell the interrupt handler to send the next buffer. */
	hid_ep_data_ready = 1;
	if ((STM32_USB_EP(USB_EP_HID_KEYBOARD) & EP_TX_MASK) == EP_TX_VALID) {
		/* Endpoint is busy: we sneak in an address change to give us a
		 * chance to send the most updated report. However, there is no
		 * guarantee that this buffer is the one actually sent, so we
		 * keep hid_ep_data_ready = 1, which will send a duplicated
		 * report.
		 */
		btable_ep[USB_EP_HID_KEYBOARD].tx_addr =
			usb_sram_addr(hid_ep_buf[hid_current_buf]);
		hid_ep_data_ready = 1;
	} else if (atomic_read_clear(&hid_ep_data_ready)) {
		/* Endpoint is not busy, and interrupt handler did not just
		 * send our last buffer: swap buffer, enable TX.
		 */
		btable_ep[USB_EP_HID_KEYBOARD].tx_addr =
			usb_sram_addr(hid_ep_buf[hid_current_buf]);
		STM32_TOGGLE_EP(USB_EP_HID_KEYBOARD, EP_TX_MASK,
				EP_TX_VALID, 0);
	}
}
Ejemplo n.º 3
0
static void hid_keyboard_tx(void)
{
	hid_tx(USB_EP_HID_KEYBOARD);
	if (hid_ep_data_ready) {
		/* swap buffer, enable TX */
		btable_ep[USB_EP_HID_KEYBOARD].tx_addr =
			usb_sram_addr(hid_ep_buf[hid_current_buf]);
		STM32_TOGGLE_EP(USB_EP_HID_KEYBOARD, EP_TX_MASK,
				EP_TX_VALID, 0);
	}
	hid_ep_data_ready = 0;
}
Ejemplo n.º 4
0
Archivo: usb_hid.c Proyecto: thehobn/ec
static int hid_iface_request(usb_uint *ep0_buf_rx, usb_uint *ep0_buf_tx)
{
	if ((ep0_buf_rx[0] == (USB_DIR_IN | USB_RECIP_INTERFACE |
			      (USB_REQ_GET_DESCRIPTOR << 8))) &&
			      (ep0_buf_rx[1] == (USB_HID_DT_REPORT << 8))) {
		/* Setup : HID specific : Get Report descriptor */
		memcpy_to_usbram(ep0_buf_tx, report_desc,
				 sizeof(report_desc));
		btable_ep[0].tx_count = MIN(ep0_buf_rx[3],
				   sizeof(report_desc));
		STM32_TOGGLE_EP(0, EP_TX_RX_MASK, EP_TX_RX_VALID,
			  EP_STATUS_OUT);
		CPRINTF("RPT %04x[l %04x]\n", STM32_USB_EP(0),
			ep0_buf_rx[3]);
		return 0;
	}

	return 1;
}
Ejemplo n.º 5
0
void set_keyboard_report(uint64_t rpt)
{
	memcpy_to_usbram((void *) usb_sram_addr(hid_ep_buf), &rpt, sizeof(rpt));
	/* enable TX */
	STM32_TOGGLE_EP(USB_EP_HID, EP_TX_MASK, EP_TX_VALID, 0);
}
Ejemplo n.º 6
0
static void con_ep_tx(void)
{
	/* clear IT */
	STM32_TOGGLE_EP(USB_EP_CONSOLE, 0, 0, 0);
}