static void udd_ctrl_setup_received(void) { if (UDD_EPCTRL_SETUP != udd_ep_control_state) { if ((UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP == udd_ep_control_state) || (UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP == udd_ep_control_state)) { // Accept that ZLP event can be hidden by setup packet event // in case of setup packet sending quickly after a ZLP udd_ctrl_endofrequest(); } // Reinitializes control endpoint management udd_ctrl_init(); } // Fill setup request structure if (8 != udd_control_out_get_bytecnt()) return; // Error data number don't correspond to SETUP packet memcpy((uint8_t *) & udd_g_ctrlreq.req, udd_ctrl_buffer, 8); // To detect a protocol error on setup, enable nak interrupt on IN/OUT of control endpoint udd_enable_overflow_interrupt(); udd_enable_underflow_interrupt(); // Decode setup request if (udc_process_setup() == false) { // Setup request unknown then stall it udd_ctrl_stall_data(); return; } if (Udd_setup_is_in()) { udd_ctrl_prev_payload_nb_trans = 0; udd_ctrl_payload_nb_trans = 0; udd_ep_control_state = UDD_EPCTRL_DATA_IN; udd_ctrl_in_sent(); // Send first data transfer } else { if (0 == udd_g_ctrlreq.req.wLength) { // No data phase requested // Send IN ZLP to ACK setup request udd_ctrl_send_zlp_in(); return; } // OUT data phase requested udd_ctrl_prev_payload_nb_trans = 0; udd_ctrl_payload_nb_trans = 0; udd_ep_control_state = UDD_EPCTRL_DATA_OUT; // Clear packet to receive first packet udd_control_out_clear_NACK0(); udd_control_out_ack_tc(); } }
static void udd_ctrl_send_zlp_out(void) { udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP; // Valid reception of OUT packet on control endpoint udd_control_out_clear_NACK0(); }
static void udd_ctrl_out_received(void) { uint16_t nb_data; if (UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP == udd_ep_control_state) { // Valid end of setup request udd_ctrl_endofrequest(); // Reinitializes control endpoint management udd_ctrl_init(); return; } Assert(udd_ep_control_state == UDD_EPCTRL_DATA_OUT); // Read data received during OUT phase nb_data = udd_control_out_get_bytecnt(); if (udd_g_ctrlreq.payload_size < (udd_ctrl_payload_nb_trans + nb_data)) { // Payload buffer too small, ignore data remaining nb_data = udd_g_ctrlreq.payload_size - udd_ctrl_payload_nb_trans; } memcpy((uint8_t *) (udd_g_ctrlreq.payload + udd_ctrl_payload_nb_trans), udd_ctrl_buffer, nb_data); udd_ctrl_payload_nb_trans += nb_data; if ((USB_DEVICE_EP_CTRL_SIZE != nb_data) || (udd_g_ctrlreq.req.wLength <= (udd_ctrl_prev_payload_nb_trans + udd_ctrl_payload_nb_trans))) { // End of reception because it is a short packet // or all data are transfered // Before send ZLP, call intermediate callback // in case of data receive generate a stall udd_g_ctrlreq.payload_size = udd_ctrl_payload_nb_trans; if (NULL != udd_g_ctrlreq.over_under_run) { if (!udd_g_ctrlreq.over_under_run()) { // Stall ZLP udd_ctrl_stall_data(); return; } } // Send IN ZLP to ACK setup request udd_ctrl_send_zlp_in(); return; } if (udd_g_ctrlreq.payload_size == udd_ctrl_payload_nb_trans) { // Overrun then request a new payload buffer if (!udd_g_ctrlreq.over_under_run) { // No callback available to request a new payload buffer udd_ctrl_stall_data(); return; } if (!udd_g_ctrlreq.over_under_run()) { // No new payload buffer delivered udd_ctrl_stall_data(); return; } // New payload buffer available // Update number of total data received udd_ctrl_prev_payload_nb_trans += udd_ctrl_payload_nb_trans; // Reinit reception on payload buffer udd_ctrl_payload_nb_trans = 0; } // Free buffer of OUT control endpoint to authorize next reception udd_control_out_clear_NACK0(); }