u8 process_bblerr_on_control( td_t *result_td, hc_info_t *hc_reg_data) { if(!result_td->parent_ed_p->ed_desc.is_ep_in) { return NO_ACTION; } result_td->err_cnt = 0; result_td->error_code =USB_ERR_STATUS_BBLERR; clear_ch_intr(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ALL); //Mask ack Interrupt.. mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr); result_td->parent_ed_p->ed_status.is_ping_enable =false; // we just calculate the size of the transferred data on Data Stage of Control Transfer. if(result_td->standard_dev_req_info.conrol_transfer_stage == DATA_STAGE) { result_td->transferred_szie += calc_transferred_size(false, result_td, hc_reg_data); } return DE_ALLOCATE; }
u8 process_bblerr_on_bulk(td_t *result_td, hc_info_t *hc_reg_data) { if(!result_td->parent_ed_p->ed_desc.is_ep_in) { return NO_ACTION; } result_td->err_cnt =0; result_td->error_code =USB_ERR_STATUS_BBLERR; clear_ch_intr(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ALL); //Mask ack Interrupt.. mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr); result_td->parent_ed_p->ed_status.is_ping_enable =false; result_td->transferred_szie += calc_transferred_size(false, result_td, hc_reg_data); return DE_ALLOCATE; }
u8 process_nyet_on_bulk(td_t *result_td, hc_info_t *hc_reg_data) { if(result_td->parent_ed_p->ed_desc.is_ep_in) { // Error State.... return NO_ACTION; } result_td->err_cnt = 0; mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr); clear_ch_intr(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NYET); result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data); if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG) { result_td->parent_ed_p->ed_status.is_ping_enable = true; } else { result_td->parent_ed_p->ed_status.is_ping_enable = false; } update_datatgl(hc_reg_data->hc_size.b.pid, result_td); return RE_TRANSMIT; }
u8 process_nak_on_control( td_t *result_td, hc_info_t *hc_reg_data) { result_td->err_cnt = 0; mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr); clear_ch_intr(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK); //at OUT Transfer, we must re-transmit. if(result_td->parent_ed_p->ed_desc.is_ep_in==false) { result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data); update_datatgl(hc_reg_data->hc_size.b.pid, result_td); } if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG) { if(result_td->standard_dev_req_info.conrol_transfer_stage == DATA_STAGE) { if(result_td->parent_ed_p->ed_desc.is_ep_in==false) { result_td->parent_ed_p->ed_status.is_ping_enable = true; } } else if(result_td->standard_dev_req_info.conrol_transfer_stage == STATUS_STAGE) { if(result_td->parent_ed_p->ed_desc.is_ep_in==true) { result_td->parent_ed_p->ed_status.is_ping_enable = true; } } else { result_td->parent_ed_p->ed_status.is_ping_enable = false; } } return RE_SCHEDULE; }
u8 process_xacterr_on_bulk( td_t *result_td, hc_info_t *hc_reg_data) { u8 ret_val = 0; if(result_td->err_cnt<RETRANSMIT_THRESHOLD) { result_td->cur_stransfer.hc_reg.hc_int_msk.d32 |= (CH_STATUS_ACK+CH_STATUS_NAK+CH_STATUS_DataTglErr); ret_val = RE_TRANSMIT; result_td->err_cnt++ ; } else { mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr); ret_val = DE_ALLOCATE; result_td->err_cnt = 0 ; result_td->error_code = USB_ERR_STATUS_XACTERR; } clear_ch_intr(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr); result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data); if(result_td->parent_ed_p->ed_desc.is_ep_in==false) { if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG) { result_td->parent_ed_p->ed_status.is_ping_enable = true; } else { result_td->parent_ed_p->ed_status.is_ping_enable = false; } } update_datatgl(hc_reg_data->hc_size.b.pid, result_td); return ret_val; }
u8 process_ahb_on_bulk(td_t *result_td, hc_info_t *hc_reg_data) { result_td->err_cnt =0; result_td->error_code =USB_ERR_STATUS_AHBERR; clear_ch_intr(result_td->cur_stransfer.alloc_chnum, CH_STATUS_AHBErr); //Mask ack Interrupt.. mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr); // we just calculate the size of the transferred data on Data Stage of Bulk Transfer. result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data); result_td->parent_ed_p->ed_status.is_ping_enable = false; return DE_ALLOCATE; }
u8 process_ahb_on_control( td_t *result_td, hc_info_t *hc_reg_data) { result_td->err_cnt =0; result_td->error_code =USB_ERR_STATUS_AHBERR; clear_ch_intr(result_td->cur_stransfer.alloc_chnum, CH_STATUS_AHBErr); //Mask ack Interrupt.. mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr); // we just calculate the size of the transferred data on Data Stage of Control Transfer. if(result_td->standard_dev_req_info.conrol_transfer_stage == DATA_STAGE) { result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data); } return DE_ALLOCATE; }
u8 process_stall_on_bulk( td_t * result_td, hc_info_t * hc_reg_data) { result_td->err_cnt =0; result_td->error_code =USB_ERR_STATUS_STALL; //this channel is stalled, So we don't process another interrupts. clear_ch_intr(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ALL); //Mask ack Interrupt.. mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr); result_td->parent_ed_p->ed_status.is_ping_enable = false; result_td->transferred_szie += calc_transferred_size(false,result_td, hc_reg_data); update_datatgl(DATA0, result_td); return DE_ALLOCATE; }
u8 process_xfercompl_on_control(td_t *result_td, hc_info_t *hc_reg_data) { u8 ret_val = 0; result_td->err_cnt = 0; clear_ch_intr(result_td->cur_stransfer.alloc_chnum,CH_STATUS_ALL); //Mask ack Interrupt.. mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr); result_td->parent_ed_p->ed_status.is_ping_enable =false; switch(result_td->standard_dev_req_info.conrol_transfer_stage) { case SETUP_STAGE: if(result_td->standard_dev_req_info.is_data_stage) { result_td->standard_dev_req_info.conrol_transfer_stage = DATA_STAGE; } else { result_td->standard_dev_req_info.conrol_transfer_stage = STATUS_STAGE; } ret_val = RE_TRANSMIT; break; case DATA_STAGE: result_td->transferred_szie += calc_transferred_size(true,result_td, hc_reg_data); if(result_td->transferred_szie==result_td->buf_size) { //at IN Transfer, short transfer is accepted. result_td->standard_dev_req_info.conrol_transfer_stage =STATUS_STAGE; result_td->error_code = USB_ERR_STATUS_COMPLETE; } else { if(result_td->parent_ed_p->ed_desc.is_ep_in&& hc_reg_data->hc_size.b.xfersize) { if(result_td->transfer_flag&USB_TRANS_FLAG_NOT_SHORT) { result_td->error_code =USB_ERR_STATUS_SHORTREAD; result_td->standard_dev_req_info.conrol_transfer_stage=STATUS_STAGE; } else { result_td->error_code =USB_ERR_STATUS_COMPLETE; result_td->standard_dev_req_info.conrol_transfer_stage =STATUS_STAGE; } } else { // the Data Stage is not completed. So we need to continue Data Stage. result_td->standard_dev_req_info.conrol_transfer_stage = DATA_STAGE; update_datatgl(hc_reg_data->hc_size.b.pid, result_td); } } if(hc_reg_data->hc_int.b.nyet) { //at OUT Transfer, we must re-transmit. if(result_td->parent_ed_p->ed_desc.is_ep_in==false) { if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG) { result_td->parent_ed_p->ed_status.is_ping_enable = true; } else { result_td->parent_ed_p->ed_status.is_ping_enable = false; } } } ret_val = RE_TRANSMIT; break; case STATUS_STAGE: result_td->standard_dev_req_info.conrol_transfer_stage = COMPLETE_STAGE; if(hc_reg_data->hc_int.b.nyet) { //at OUT Transfer, we must re-transmit. if(result_td->parent_ed_p->ed_desc.is_ep_in==false) { if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG) { result_td->parent_ed_p->ed_status.is_ping_enable = true; } else { result_td->parent_ed_p->ed_status.is_ping_enable = false; } } } ret_val = DE_ALLOCATE; break; default: break; } return ret_val; }
u8 process_xfercompl_on_bulk(td_t *result_td, hc_info_t *hc_reg_data) { u8 ret_val=0; result_td->err_cnt = 0; clear_ch_intr(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ALL); //Mask ack Interrupt.. mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_ACK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_NAK); mask_channel_interrupt(result_td->cur_stransfer.alloc_chnum, CH_STATUS_DataTglErr); result_td->parent_ed_p->ed_status.is_ping_enable =false; result_td->transferred_szie += calc_transferred_size(true,result_td, hc_reg_data); if(result_td->transferred_szie==result_td->buf_size) {//at IN Transfer, short transfer is accepted. result_td->error_code = USB_ERR_STATUS_COMPLETE; ret_val = DE_ALLOCATE; } else { if(result_td->parent_ed_p->ed_desc.is_ep_in&& hc_reg_data->hc_size.b.xfersize) { if(result_td->transfer_flag&USB_TRANS_FLAG_NOT_SHORT) { result_td->error_code =USB_ERR_STATUS_SHORTREAD; } else { result_td->error_code =USB_ERR_STATUS_COMPLETE; } ret_val = DE_ALLOCATE; } else { ret_val = RE_SCHEDULE; } } update_datatgl(hc_reg_data->hc_size.b.pid, result_td); if(hc_reg_data->hc_int.b.nyet) { //at OUT Transfer, we must re-transmit. if(result_td->parent_ed_p->ed_desc.is_ep_in==false) { if(result_td->parent_ed_p->ed_desc.dev_speed == HIGH_SPEED_OTG) { result_td->parent_ed_p->ed_status.is_ping_enable = true; } else { result_td->parent_ed_p->ed_status.is_ping_enable = false; } } } return ret_val; }