static void udd_ctrl_setup_received(void) { irqflags_t flags; if (UDD_EPCTRL_SETUP != udd_ep_control_state) { // May be a hidden DATA or ZLP phase // or protocol abort udd_ctrl_endofrequest(); // Reinitializes control endpoint management udd_ctrl_init(); } // Fill setup request structure if (8 != udd_udesc_get_buf0_ctn(0)) { udd_ctrl_stall_data(); udd_ack_setup_received(0); return; // Error data number doesn't correspond to SETUP packet } memcpy((uint8_t *) & udd_g_ctrlreq.req, udd_ctrl_buffer, 8); // Manage LSB/MSB to fit with CPU usage udd_g_ctrlreq.req.wValue = le16_to_cpu(udd_g_ctrlreq.req.wValue); udd_g_ctrlreq.req.wIndex = le16_to_cpu(udd_g_ctrlreq.req.wIndex); udd_g_ctrlreq.req.wLength = le16_to_cpu(udd_g_ctrlreq.req.wLength); // Decode setup request if (udc_process_setup() == false) { // Setup request unknown then stall it udd_ctrl_stall_data(); udd_ack_setup_received(0); return; } udd_ack_setup_received(0); if (Udd_setup_is_in()) { // IN data phase requested 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; // To detect a protocol error, enable nak interrupt on data IN phase udd_ack_nak_in(0); flags = cpu_irq_save(); udd_enable_nak_in_interrupt(0); cpu_irq_restore(flags); } }
static void udd_ctrl_setup_received(void) { uint8_t i; if (UDD_EPCTRL_SETUP != udd_ep_control_state) { // May be a hidden DATA or ZLP phase // or protocol abort udd_ctrl_endofrequest(); // Reinitializes control endpoint management udd_ctrl_init(); } // Fill setup request structure if (8 != udd_byte_count(0)) { udd_ack_setup_received(0); udd_ctrl_stall_data(); return; // Error data number doesn't correspond to SETUP packet } for (i = 0; i < 8; i++) { ((uint8_t *) & udd_g_ctrlreq.req)[i] = udd_endpoint_fifo_read(0); } // Manage LSB/MSB to fit with CPU usage udd_g_ctrlreq.req.wValue = le16_to_cpu(udd_g_ctrlreq.req.wValue); udd_g_ctrlreq.req.wIndex = le16_to_cpu(udd_g_ctrlreq.req.wIndex); udd_g_ctrlreq.req.wLength = le16_to_cpu(udd_g_ctrlreq.req.wLength); // Decode setup request if (udc_process_setup() == false) { // Setup request unknown then stall it udd_ack_setup_received(0); udd_ctrl_stall_data(); return; } if (Udd_setup_is_in()) { // Set DIR udd_set_endpoint_direction_in(0); udd_ack_setup_received(0); // IN data phase requested 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 { udd_ack_setup_received(0); 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; } }
//! \brief Waits a SETUP packet and load data in main_setup_packet[] static void main_usb_wait_setup_packet(void) { while (!Is_udd_setup_received(0)); // SETUP packet received Assert(8 == udd_byte_count(0)); uint8_t *ptr = (uint8_t *) & udd_get_endpoint_fifo_access(0,8); for (uint8_t i = 0; i < 8; i++) { ((uint8_t*) &main_setup_packet)[i] = *ptr++; } udd_ack_setup_received(0); }
static void udd_ctrl_setup_received(void) { irqflags_t flags; uint8_t i; if (UDD_EPCTRL_SETUP != udd_ep_control_state) { // May be a hidden DATA or ZLP phase // or protocol abort udd_ctrl_endofrequest(); // Reinitializes control endpoint management udd_ctrl_init(); } // Fill setup request structure if (8 != udd_byte_count(0)) { udd_ctrl_stall_data(); udd_ack_setup_received(0); return; // Error data number doesn't correspond to SETUP packet } uint32_t *ptr = (uint32_t *) & udd_get_endpoint_fifo_access(0, 32); for (i = 0; i < 8 / 4; i++) { ((uint32_t *) & udd_g_ctrlreq.req)[i] = *ptr++; } // Manage LSB/MSB to fit with CPU usage udd_g_ctrlreq.req.wValue = le16_to_cpu(udd_g_ctrlreq.req.wValue); udd_g_ctrlreq.req.wIndex = le16_to_cpu(udd_g_ctrlreq.req.wIndex); udd_g_ctrlreq.req.wLength = le16_to_cpu(udd_g_ctrlreq.req.wLength); // Decode setup request if (udc_process_setup() == false) { // Setup request unknow then stall it udd_ctrl_stall_data(); udd_ack_setup_received(0); return; } udd_ack_setup_received(0); if (Udd_setup_is_in()) { // Compute if an IN ZLP must be send after IN data udd_ctrl_payload_need_in_zlp = ((udd_g_ctrlreq.payload_size % USB_DEVICE_EP_CTRL_SIZE) == 0); // IN data phase requested 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; // To detect a protocol error, enable nak interrupt on data IN phase udd_ack_nak_in(0); flags = cpu_irq_save(); udd_enable_nak_in_interrupt(0); cpu_irq_restore(flags); } }
//! \brief Enables the control endpoint STALL after a SETUP packet reception static void main_usb_stall_after_setup_packet(void) { udd_enable_stall_handshake(0); udd_ack_setup_received(0); }