correct stall & clear stall behavior for non-control pipe
fix data_residue when read10, write10 return 0 (no need for BE conversion)
This commit is contained in:
@@ -158,7 +158,7 @@ static bool read10_write10_data_xfer(mscd_interface_t* p_msc)
|
||||
|
||||
if ( 0 == xferred_block )
|
||||
{ // xferred_block is zero will cause pipe is stalled & status in CSW set to failed
|
||||
p_csw->data_residue = __n2be(p_cbw->xfer_bytes);
|
||||
p_csw->data_residue = p_cbw->xfer_bytes;
|
||||
p_csw->status = MSC_CSW_STATUS_FAILED;
|
||||
|
||||
(void) dcd_pipe_stall(edpt_hdl);
|
||||
@@ -239,6 +239,7 @@ tusb_error_t mscd_xfer_cb(endpoint_handle_t edpt_hdl, tusb_event_t event, uint32
|
||||
}
|
||||
|
||||
//------------- Status Phase -------------//
|
||||
// Either bulk in & out can be stalled in the data phase, dcd must make sure these queued transfer will be resumed after host clear stall
|
||||
if (!is_waiting_read10_write10)
|
||||
{
|
||||
ASSERT_STATUS( dcd_pipe_xfer( p_msc->edpt_in , p_csw, sizeof(msc_cmd_status_wrapper_t), true) ); // need to be true for dcd to clean up qtd !!
|
||||
|
||||
@@ -144,6 +144,7 @@ static inline uint16_t addr_offset(void const * p_buffer)
|
||||
|
||||
static void queue_xfer_to_buffer(uint8_t ep_id, uint8_t buff_idx, uint16_t buff_addr_offset, uint16_t total_bytes);
|
||||
static void pipe_queue_xfer(uint8_t ep_id, uint16_t buff_addr_offset, uint16_t total_bytes);
|
||||
static void queue_xfer_in_next_td(uint8_t ep_id);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// CONTROLLER API
|
||||
@@ -315,11 +316,7 @@ void dcd_isr(uint8_t coreid)
|
||||
//------------- Next TD is available -------------//
|
||||
if ( dcd_data.next_td[ep_id].total_bytes != 0 )
|
||||
{
|
||||
dcd_data.current_ioc |= ( dcd_data.next_ioc & BIT_(ep_id) ); // copy next IOC to current IOC
|
||||
|
||||
pipe_queue_xfer(ep_id, dcd_data.next_td[ep_id].buff_addr_offset, dcd_data.next_td[ep_id].total_bytes);
|
||||
|
||||
dcd_data.next_td[ep_id].total_bytes = 0; // clear this field as it is used to indicate next TD available
|
||||
queue_xfer_in_next_td(ep_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -370,13 +367,16 @@ static inline uint8_t edpt_phy2log(uint8_t physical_endpoint)
|
||||
//--------------------------------------------------------------------+
|
||||
tusb_error_t dcd_pipe_stall(endpoint_handle_t edpt_hdl)
|
||||
{
|
||||
// ASSERT( !dcd_pipe_is_busy(edpt_hdl), TUSB_ERROR_INTERFACE_IS_BUSY); // endpoint must not in transferring
|
||||
|
||||
dcd_data.qhd[edpt_hdl.index][0].stall = dcd_data.qhd[edpt_hdl.index][1].stall = 1;
|
||||
|
||||
return TUSB_ERROR_NONE;
|
||||
}
|
||||
|
||||
bool dcd_pipe_is_stalled(endpoint_handle_t edpt_hdl)
|
||||
{
|
||||
return dcd_data.qhd[edpt_hdl.index][0].stall || dcd_data.qhd[edpt_hdl.index][1].stall;
|
||||
}
|
||||
|
||||
tusb_error_t dcd_pipe_clear_stall(uint8_t coreid, uint8_t edpt_addr)
|
||||
{
|
||||
uint8_t ep_id = edpt_addr2phy(edpt_addr);
|
||||
@@ -387,6 +387,12 @@ tusb_error_t dcd_pipe_clear_stall(uint8_t coreid, uint8_t edpt_addr)
|
||||
dcd_data.qhd[ep_id][active_buffer].toggle_reset = 1;
|
||||
dcd_data.qhd[ep_id][active_buffer].feedback_toggle = 0;
|
||||
|
||||
//------------- clear stall must carry on any previously queued transfer -------------//
|
||||
if ( dcd_data.next_td[ep_id].total_bytes != 0 )
|
||||
{
|
||||
queue_xfer_in_next_td(ep_id);
|
||||
}
|
||||
|
||||
return TUSB_ERROR_NONE;
|
||||
}
|
||||
|
||||
@@ -460,6 +466,15 @@ static void pipe_queue_xfer(uint8_t ep_id, uint16_t buff_addr_offset, uint16_t t
|
||||
queue_xfer_to_buffer(ep_id, 0, buff_addr_offset, total_bytes);
|
||||
}
|
||||
|
||||
static void queue_xfer_in_next_td(uint8_t ep_id)
|
||||
{
|
||||
dcd_data.current_ioc |= ( dcd_data.next_ioc & BIT_(ep_id) ); // copy next IOC to current IOC
|
||||
|
||||
pipe_queue_xfer(ep_id, dcd_data.next_td[ep_id].buff_addr_offset, dcd_data.next_td[ep_id].total_bytes);
|
||||
|
||||
dcd_data.next_td[ep_id].total_bytes = 0; // clear this field as it is used to indicate whehther next TD available
|
||||
}
|
||||
|
||||
tusb_error_t dcd_pipe_queue_xfer(endpoint_handle_t edpt_hdl, void * buffer, uint16_t total_bytes)
|
||||
{
|
||||
ASSERT( !dcd_pipe_is_busy(edpt_hdl), TUSB_ERROR_INTERFACE_IS_BUSY); // endpoint must not in transferring
|
||||
@@ -473,8 +488,8 @@ tusb_error_t dcd_pipe_queue_xfer(endpoint_handle_t edpt_hdl, void * buffer, uint
|
||||
|
||||
tusb_error_t dcd_pipe_xfer(endpoint_handle_t edpt_hdl, void* buffer, uint16_t total_bytes, bool int_on_complete)
|
||||
{
|
||||
if( dcd_pipe_is_busy(edpt_hdl) )
|
||||
{ // save this transfer data to next td
|
||||
if( dcd_pipe_is_busy(edpt_hdl) || dcd_pipe_is_stalled(edpt_hdl) )
|
||||
{ // save this transfer data to next td if pipe is busy or already been stalled
|
||||
dcd_data.next_td[edpt_hdl.index].buff_addr_offset = addr_offset(buffer);
|
||||
dcd_data.next_td[edpt_hdl.index].total_bytes = total_bytes;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user