Beispiel #1
0
void _usbd_control_in(usbd_device *usbd_dev, u8 ea)
{
	(void)ea;
	struct usb_setup_data *req = &(usbd_dev->control_state.req);

	switch (usbd_dev->control_state.state) {
	case DATA_IN:
		usb_control_send_chunk(usbd_dev);
		break;
	case LAST_DATA_IN:
		usbd_dev->control_state.state = STATUS_OUT;
		break;
	case STATUS_IN:
		if (usbd_dev->control_state.complete)
			usbd_dev->control_state.complete(usbd_dev,
					&(usbd_dev->control_state.req));

		/* Exception: Handle SET ADDRESS function here... */
		if ((req->bmRequestType == 0) &&
		    (req->bRequest == USB_REQ_SET_ADDRESS))
			usbd_dev->driver->set_address(usbd_dev, req->wValue);
		usbd_dev->control_state.state = IDLE;
		break;
	default:
		usbd_ep_stall_set(usbd_dev, 0, 1);
	}
}
Beispiel #2
0
void _usbd_control_in(u8 ea)
{
	(void)ea;
	struct usb_setup_data *req = &control_state.req;

	switch (control_state.state) {
	case DATA_IN:
		usb_control_send_chunk();
		break;
	case LAST_DATA_IN:
		control_state.state = STATUS_OUT;
		break;
	case STATUS_IN:
		if (control_state.complete)
			control_state.complete(&control_state.req);

		/* Exception: Handle SET ADDRESS function here... */
		if ((req->bmRequestType == 0) &&
		    (req->bRequest == USB_REQ_SET_ADDRESS))
			_usbd_hw_set_address(req->wValue);
		control_state.state = IDLE;
		break;
	default:
		usbd_ep_stall_set(0, 1);
	}
}
Beispiel #3
0
static int usb_standard_endpoint_unstall(struct usb_setup_data *req,
					 u8 **buf, u16 *len)
{
	(void)buf;
	(void)len;

	usbd_ep_stall_set(req->wIndex, 0);

	return 1;
}
Beispiel #4
0
static int usb_standard_endpoint_stall(usbd_device *usbd_dev,
				       struct usb_setup_data *req,
				       u8 **buf, u16 *len)
{
	(void)buf;
	(void)len;

	usbd_ep_stall_set(usbd_dev, req->wIndex, 1);

	return 1;
}
Beispiel #5
0
static int usb_standard_endpoint_unstall(usbd_device *usbd_dev,
					 struct usb_setup_data *req,
					 uint8_t **buf, uint16_t *len)
{
	(void)buf;
	(void)len;

	usbd_ep_stall_set(usbd_dev, req->wIndex, 0);

	return 1;
}
Beispiel #6
0
void _usbd_control_out(usbd_device *usbd_dev, u8 ea)
{
	(void)ea;

	switch (usbd_dev->control_state.state) {
	case DATA_OUT:
		if (usb_control_recv_chunk(usbd_dev) < 0)
			break;
		if ((usbd_dev->control_state.req.wLength -
					usbd_dev->control_state.ctrl_len) <=
					usbd_dev->desc->bMaxPacketSize0)
			usbd_dev->control_state.state = LAST_DATA_OUT;
		break;
	case LAST_DATA_OUT:
		if (usb_control_recv_chunk(usbd_dev) < 0)
			break;
		/*
		 * We have now received the full data payload.
		 * Invoke callback to process.
		 */
		if (usb_control_request_dispatch(usbd_dev,
					&(usbd_dev->control_state.req))) {
			/* Got to status stage on success. */
			usbd_ep_write_packet(usbd_dev, 0, NULL, 0);
			usbd_dev->control_state.state = STATUS_IN;
		} else {
			usbd_ep_stall_set(usbd_dev, 0, 1);
		}
		break;
	case STATUS_OUT:
		usbd_ep_read_packet(usbd_dev, 0, NULL, 0);
		usbd_dev->control_state.state = IDLE;
		if (usbd_dev->control_state.complete)
			usbd_dev->control_state.complete(usbd_dev,
					&(usbd_dev->control_state.req));
		usbd_dev->control_state.complete = NULL;
		break;
	default:
		usbd_ep_stall_set(usbd_dev, 0, 1);
	}
}
Beispiel #7
0
static int usb_control_recv_chunk(void)
{
	u16 packetsize = MIN(_usbd_device.desc->bMaxPacketSize0,
			 control_state.req.wLength - control_state.ctrl_len);
	u16 size = usbd_ep_read_packet(0, control_state.ctrl_buf +
				       control_state.ctrl_len, packetsize);

	if (size != packetsize) {
		usbd_ep_stall_set(0, 1);
		return -1;
	}

	control_state.ctrl_len += size;

	return packetsize;
}
Beispiel #8
0
static void usb_control_setup_write(struct usb_setup_data *req)
{
	if (req->wLength > _usbd_device.ctrl_buf_len) {
		usbd_ep_stall_set(0, 1);
		return;
	}

	/* Buffer into which to write received data. */
	control_state.ctrl_buf = _usbd_device.ctrl_buf;
	control_state.ctrl_len = 0;
	/* Wait for DATA OUT stage. */
	if (req->wLength > _usbd_device.desc->bMaxPacketSize0)
		control_state.state = DATA_OUT;
	else
		control_state.state = LAST_DATA_OUT;
}
Beispiel #9
0
/* Handle commands and read requests. */
static void usb_control_setup_read(struct usb_setup_data *req)
{
	control_state.ctrl_buf = _usbd_device.ctrl_buf;
	control_state.ctrl_len = req->wLength;

	if (usb_control_request_dispatch(req)) {
		if (control_state.ctrl_len) {
			/* Go to data out stage if handled. */
			usb_control_send_chunk();
		} else {
			/* Go to status stage if handled. */
			usbd_ep_write_packet(0, NULL, 0);
			control_state.state = STATUS_IN;
		}
	} else {
		/* Stall endpoint on failure. */
		usbd_ep_stall_set(0, 1);
	}
}
Beispiel #10
0
static int usb_control_recv_chunk(usbd_device *usbd_dev)
{
	u16 packetsize = MIN(usbd_dev->desc->bMaxPacketSize0,
			usbd_dev->control_state.req.wLength -
			usbd_dev->control_state.ctrl_len);
	u16 size = usbd_ep_read_packet(usbd_dev, 0,
				       usbd_dev->control_state.ctrl_buf +
				       usbd_dev->control_state.ctrl_len,
				       packetsize);

	if (size != packetsize) {
		usbd_ep_stall_set(usbd_dev, 0, 1);
		return -1;
	}

	usbd_dev->control_state.ctrl_len += size;

	return packetsize;
}
Beispiel #11
0
void _usbd_control_setup(u8 ea)
{
	struct usb_setup_data *req = &control_state.req;
	(void)ea;

	control_state.complete = NULL;

	if (usbd_ep_read_packet(0, req, 8) != 8) {
		usbd_ep_stall_set(0, 1);
		return;
	}

	if (req->wLength == 0) {
		usb_control_setup_read(req);
	} else if (req->bmRequestType & 0x80) {
		usb_control_setup_read(req);
	} else {
		usb_control_setup_write(req);
	}
}
Beispiel #12
0
void traceswo_init(void)
{
	periph_clock_enable(RCC_GPIOD);
	periph_clock_enable(TRACEUART_CLK);
	__asm__("nop"); __asm__("nop"); __asm__("nop");

	gpio_mode_setup(SWO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SWO_PIN);
	gpio_set_af(SWO_PORT, 1, SWO_PIN); /* U2RX */

	uart_disable(TRACEUART);

	/* Setup UART parameters. */
	uart_clock_from_sysclk(TRACEUART);
	uart_set_baudrate(TRACEUART, 800000);
	uart_set_databits(TRACEUART, 8);
	uart_set_stopbits(TRACEUART, 1);
	uart_set_parity(TRACEUART, UART_PARITY_NONE);

	// Enable FIFO
	uart_enable_fifo(TRACEUART);

	// Set FIFO interrupt trigger levels to 4/8 full for RX buffer and
	// 7/8 empty (1/8 full) for TX buffer
	uart_set_fifo_trigger_levels(TRACEUART, UART_FIFO_RX_TRIG_1_2, UART_FIFO_TX_TRIG_7_8);

	uart_clear_interrupt_flag(TRACEUART, UART_INT_RX | UART_INT_RT);

	/* Enable interrupts */
	uart_enable_interrupts(TRACEUART, UART_INT_RX | UART_INT_RT);

	/* Finally enable the USART. */
	uart_enable(TRACEUART);

	nvic_set_priority(TRACEUART_IRQ, 0);
	nvic_enable_irq(TRACEUART_IRQ);

	/* Un-stall USB endpoint */
	usbd_ep_stall_set(usbdev, 0x85, 0);

	gpio_mode_setup(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO3);
}
Beispiel #13
0
/*
 * According to the USB 2.0 specification, section 8.5.3, when a control
 * transfer is stalled, the pipe becomes idle. We provide one utility to stall
 * a transaction to reduce boilerplate code.
 */
static void stall_transaction(usbd_device *usbd_dev)
{
	usbd_ep_stall_set(usbd_dev, 0, 1);
	usbd_dev->control_state.state = IDLE;
}