Esempio n. 1
0
void usb_stream_reset(struct usb_stream_config const *config)
{
	config->out_desc->flags = DOEPDMA_RXBYTES(config->tx_size) |
				  DOEPDMA_LAST | DOEPDMA_BS_HOST_RDY |
				  DOEPDMA_IOC;
	config->out_desc->addr = config->rx_ram;
	GR_USB_DOEPDMA(config->endpoint) = (uint32_t)config->out_desc;
	config->in_desc->flags = DIEPDMA_LAST | DIEPDMA_BS_HOST_BSY |
				 DIEPDMA_IOC;
	config->in_desc->addr = config->tx_ram;
	GR_USB_DIEPDMA(config->endpoint) = (uint32_t)config->in_desc;
	GR_USB_DOEPCTL(config->endpoint) = DXEPCTL_MPS(64) | DXEPCTL_USBACTEP |
					   DXEPCTL_EPTYPE_BULK |
					   DXEPCTL_CNAK | DXEPCTL_EPENA;
	GR_USB_DIEPCTL(config->endpoint) = DXEPCTL_MPS(64) | DXEPCTL_USBACTEP |
					   DXEPCTL_EPTYPE_BULK |
					   DXEPCTL_TXFNUM(config->endpoint);
	GR_USB_DAINTMSK |= DAINT_INEP(config->endpoint) |
			   DAINT_OUTEP(config->endpoint);

	*config->is_reset = 1;

	/* Flush any queued data */
	hook_call_deferred(config->deferred_tx, 0);
	hook_call_deferred(config->deferred_rx, 0);
}
Esempio n. 2
0
/* The next packet from the host should be a Setup packet. Get ready for it. */
static void expect_setup_packet(void)
{
	print_later("expect_setup_packet()", 0, 0, 0, 0, 0);

	what_am_i_doing = WAITING_FOR_SETUP_PACKET;

	next_out_desc->flags =
		DOEPDMA_RXBYTES(USB_MAX_PACKET_SIZE)
		| DOEPDMA_IOC | DOEPDMA_LAST;

	/* We don't care about IN packets right now, only OUT. */
	GR_USB_DAINTMSK |= DAINT_OUTEP(0);
	GR_USB_DAINTMSK &= ~DAINT_INEP(0);

	/* Let it run. We might need CNAK if we just got an OUT for status */
	GR_USB_DOEPCTL(0) = DXEPCTL_CNAK | DXEPCTL_EPENA;
}
Esempio n. 3
0
/* We're complaining about something by stalling both IN and OUT packets,
 * but a SETUP packet will get through anyway, so prepare for it. */
static void stall_both_fifos(void)
{
	print_later("stall_both_fifos()", 0, 0, 0, 0, 0);

	what_am_i_doing = WAITING_FOR_SETUP_PACKET;

	next_out_desc->flags =
		DOEPDMA_RXBYTES(USB_MAX_PACKET_SIZE)
		| DOEPDMA_IOC | DOEPDMA_LAST;

	/* We don't care about IN packets right now, only OUT. */
	GR_USB_DAINTMSK |= DAINT_OUTEP(0);
	GR_USB_DAINTMSK &= ~DAINT_INEP(0);

	/* Stall both IN and OUT. The hardware will reset them when the next
	 * SETUP comes along. */
	GR_USB_DOEPCTL(0) = DXEPCTL_STALL | DXEPCTL_EPENA;
	flush_in_fifo();
	GR_USB_DIEPCTL(0) = DXEPCTL_STALL | DXEPCTL_EPENA;
}
Esempio n. 4
0
/* No Data phase, just Status phase (which is IN, since Setup is OUT) */
static void expect_status_phase_in(enum table_case tc)
{
	print_later("expect_status_phase_in(%c)", "0ABCDE67"[tc], 0, 0, 0, 0);

	what_am_i_doing = NO_DATA_STAGE;

	/* Expect a zero-length IN for the Status phase */
	(void) load_in_fifo(0, 0);

	/* We apparently have to do this every time we transmit anything */
	flush_in_fifo();

	/* I don't think we have to do this every time, but the Programmer's
	 * Guide says to, so...	*/
	GR_USB_DIEPDMA(0) = (uint32_t)(cur_in_desc);

	/* Blindly following instructions here, too. */
	if (tc == TABLE_CASE_C)
		GR_USB_DIEPCTL(0) = DXEPCTL_CNAK | DXEPCTL_EPENA;
	else
		GR_USB_DIEPCTL(0) = DXEPCTL_EPENA;

	/* The Programmer's Guide instructions for the Normal Two-Stage Control
	 * Transfer leave this next bit out, so we only need it if we intend to
	 * process an Exceptional Two-Stage Control Transfer. Because obviously
	 * we always know in advance what the host is going to do. Idiots. */

	/* Be prepared to get a new Setup packet during the Status phase */
	next_out_desc->flags =
		DOEPDMA_RXBYTES(USB_MAX_PACKET_SIZE)
		| DOEPDMA_IOC | DOEPDMA_LAST;

	/* We've already set GR_USB_DOEPDMA(0), so just enable it. */
	if (tc == TABLE_CASE_C)
		GR_USB_DOEPCTL(0) = DXEPCTL_CNAK | DXEPCTL_EPENA;
	else
		GR_USB_DOEPCTL(0) = DXEPCTL_EPENA;

	/* Get an interrupt when either IN or OUT arrives */
	GR_USB_DAINTMSK |= (DAINT_OUTEP(0) | DAINT_INEP(0));
}
Esempio n. 5
0
/* The TX FIFO buffer is loaded. Start the Data phase. */
static void expect_data_phase_in(enum table_case tc)
{
	print_later("expect_data_phase_in(%c)", "0ABCDE67"[tc], 0, 0, 0, 0);

	what_am_i_doing = DATA_STAGE_IN;

	/* We apparently have to do this every time we transmit anything */
	flush_in_fifo();

	/* I don't think we have to do this every time, but the Programmer's
	 * Guide says to, so...	*/
	GR_USB_DIEPDMA(0) = (uint32_t)(cur_in_desc);

	/* Blindly following instructions here, too. */
	if (tc == TABLE_CASE_C)
		GR_USB_DIEPCTL(0) = DXEPCTL_CNAK | DXEPCTL_EPENA;
	else
		GR_USB_DIEPCTL(0) = DXEPCTL_EPENA;

	/*
	 * When the IN is done, we expect a zero-length OUT for the status
	 * phase but it could be an early SETUP instead. We'll have to deal
	 * with either one when it arrives.
	 */
	next_out_desc->flags =
		DOEPDMA_RXBYTES(USB_MAX_PACKET_SIZE)
		| DOEPDMA_IOC | DOEPDMA_LAST;

	/* And here's this jimmy rustler again... */
	if (tc == TABLE_CASE_C)
		GR_USB_DOEPCTL(0) = DXEPCTL_CNAK | DXEPCTL_EPENA;
	else
		GR_USB_DOEPCTL(0) = DXEPCTL_EPENA;

	/* Get an interrupt when either IN or OUT arrives */
	GR_USB_DAINTMSK |= (DAINT_OUTEP(0) | DAINT_INEP(0));

}
Esempio n. 6
0
static void ep_reset(void)
{
	ep_out_desc.flags = DOEPDMA_RXBYTES(USB_MAX_PACKET_SIZE) |
			    DOEPDMA_LAST | DOEPDMA_BS_HOST_RDY | DOEPDMA_IOC;
	ep_out_desc.addr = ep_buf_rx;
	GR_USB_DOEPDMA(USB_EP_BLOB) = (uint32_t)&ep_out_desc;
	ep_in_desc.flags = DIEPDMA_LAST | DIEPDMA_BS_HOST_BSY | DIEPDMA_IOC;
	ep_in_desc.addr = ep_buf_tx;
	GR_USB_DIEPDMA(USB_EP_BLOB) = (uint32_t)&ep_in_desc;
	GR_USB_DOEPCTL(USB_EP_BLOB) = DXEPCTL_MPS(64) | DXEPCTL_USBACTEP |
					 DXEPCTL_EPTYPE_BULK |
					 DXEPCTL_CNAK | DXEPCTL_EPENA;
	GR_USB_DIEPCTL(USB_EP_BLOB) = DXEPCTL_MPS(64) | DXEPCTL_USBACTEP |
					 DXEPCTL_EPTYPE_BULK |
					 DXEPCTL_TXFNUM(USB_EP_BLOB);
	GR_USB_DAINTMSK |= (1<<USB_EP_BLOB) | (1 << (USB_EP_BLOB+16));

	is_reset = 1;

	/* Flush any queued data */
	hook_call_deferred(tx_fifo_handler, 0);
	hook_call_deferred(rx_fifo_handler, 0);
}
Esempio n. 7
0
/* Let the USB HW OUT-from-host FIFO receive some bytes */
static void usb_enable_rx(struct usb_stream_config const *config, int len)
{
	config->out_desc->flags = DOEPDMA_RXBYTES(len) | DOEPDMA_LAST |
				  DOEPDMA_BS_HOST_RDY | DOEPDMA_IOC;
	GR_USB_DOEPCTL(config->endpoint) |= DXEPCTL_CNAK | DXEPCTL_EPENA;
}
Esempio n. 8
0
/* Let the USB HW OUT-from-host FIFO receive some bytes */
static void usb_enable_rx(int len)
{
	ep_out_desc.flags = DOEPDMA_RXBYTES(len) |
			    DOEPDMA_LAST | DOEPDMA_BS_HOST_RDY | DOEPDMA_IOC;
	GR_USB_DOEPCTL(USB_EP_BLOB) |= DXEPCTL_CNAK | DXEPCTL_EPENA;
}