Ejemplo n.º 1
0
static void udd_ctrl_send_zlp_in(void)
{
	udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP;
	// Valid and sent empty IN packet on control endpoint
	udd_control_in_set_bytecnt(0);
	udd_control_in_clear_NACK0();
}
Ejemplo n.º 2
0
static void udd_ctrl_in_sent(void)
{
	static bool b_shortpacket = false;
	uint16_t nb_remain;

	if (UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP == udd_ep_control_state) {
		// ZLP on IN is sent, then valid end of setup request
		udd_ctrl_endofrequest();
		// Reinitializes control endpoint management
		udd_ctrl_init();
		return;
	}
	Assert(udd_ep_control_state == UDD_EPCTRL_DATA_IN);

	nb_remain = udd_g_ctrlreq.payload_size - udd_ctrl_payload_nb_trans;
	if (0 == nb_remain) {
		// Update number of total data sending by previous playload buffer
		udd_ctrl_prev_payload_nb_trans += udd_ctrl_payload_nb_trans;
		if ((udd_g_ctrlreq.req.wLength == udd_ctrl_prev_payload_nb_trans)
				|| b_shortpacket) {
			// All data requested are transfered or a short packet has been sent
			// then it is the end of data phase.
			// Generate an OUT ZLP for handshake phase.
			udd_ctrl_send_zlp_out();
			return;
		}
		// Need of new buffer because the data phase is not complete
		if ((!udd_g_ctrlreq.over_under_run)
				|| (!udd_g_ctrlreq.over_under_run())) {
			// Underrun then send zlp on IN
			// nb_remain == 0 allows to send a IN ZLP
		} else {
			// A new payload buffer is given
			udd_ctrl_payload_nb_trans = 0;
			nb_remain = udd_g_ctrlreq.payload_size;
		}
	}
	// Continue transfer an send next data
	if (nb_remain >= USB_DEVICE_EP_CTRL_SIZE) {
		nb_remain = USB_DEVICE_EP_CTRL_SIZE;
		b_shortpacket = false;
	} else {
		b_shortpacket = true;
	}
	udd_control_in_set_bytecnt(nb_remain);

	// Link payload buffer directly on USB hardware
	udd_control_in_set_buf(udd_g_ctrlreq.payload + udd_ctrl_payload_nb_trans);
	udd_ctrl_payload_nb_trans += nb_remain;

	// Valid and sent the data available in control endpoint buffer
	udd_control_in_clear_NACK0();
}
Ejemplo n.º 3
0
static void udd_ctrl_init(void)
{
	udd_disable_overflow_interrupt();
	udd_disable_underflow_interrupt();

	// Clear status flag from control endpoints
	// Mandatory for ATxmega128A1 Rev. K
	udd_control_in_set_NACK0();
	udd_control_in_set_bytecnt(0);
	udd_control_in_ack_tc();
	udd_control_ack_in_underflow();
	udd_control_ack_out_overflow();

	udd_g_ctrlreq.callback = NULL;
	udd_g_ctrlreq.over_under_run = NULL;
	udd_g_ctrlreq.payload_size = 0;
	udd_ep_control_state = UDD_EPCTRL_SETUP;
}