📄 atl_mix.c
字号:
tip->time_of_service = 0xFFFFFFFF;
free_transfer_block( tip );
enable_INT(); // ## version1.2c
}
transfer_instance *atlmix_set_transfer( unsigned char transfer_type, unsigned char polling_rate, unsigned char index, unsigned char *buffer_ptr, unsigned short length, unsigned char direction, endpoint_info_ptr epi_ptr, void (*callback)( endpoint_info_ptr epi_ptr ) )
{
transfer_instance_ptr tip;
unsigned short intr_en;
disable_INT();
switch ( transfer_type )
{
case CONTROL_TRANSFER :
case BULK_TRANSFER :
if ( !(index < g_buffer_parameter[ CTRL_BULK_TRANSFER ].number_of_blocks) )
return ( NULL );
tip = &(g_atl_transfer_slot[ index ]);
{
if ( index == g_pp_block0 )
{
tip->paired = True;
tip->ping_pong = 0;
}
else if ( index == g_pp_block1 )
{
tip->paired = True;
tip->ping_pong = 1;
}
else
{
tip->paired = False;
tip->ping_pong = 0;
}
}
break;
case INTERRUPT_TRANSFER :
if ( !(index < g_buffer_parameter[ INTERRUPT_TRANSFER ].number_of_blocks) )
return ( NULL );
tip = &(g_intl_transfer_slot[ index ]);
break;
default :
mprintf( LIGHTRED, ABORT, "atlmix_set_transfer : Unsupported transfer type transfer_type = %d \r\n", transfer_type );
break;
}
epi_ptr->transfer_instance = tip;
tip->data_ptr_base = buffer_ptr;
tip->data_ptr_start = buffer_ptr;
tip->data_ptr_end = buffer_ptr + length;
tip->epi_ptr = epi_ptr;
tip->callback = callback;
tip->transferred_size = 0;
tip->direction = direction;
tip->completion_code = 0;
tip->fatal_error = 0;
tip->transfer_type = transfer_type;
tip->retry_count = 0;
tip->timeout = TEST_VALUE;
switch ( transfer_type )
{
case CONTROL_TRANSFER :
case BULK_TRANSFER :
atl_scheduler( index );
break;
case INTERRUPT_TRANSFER :
intl_scheduler( index, polling_rate );
break;
default :
mprintf( LIGHTRED, ABORT, "atlmix_set_transfer : Unsupported transfer type transfer_type = %d \r\n", transfer_type );
break;
}
enable_INT();
return ( tip );
}
void re_enable_atl_transfer( transfer_instance_ptr tip )
{
unsigned short intr_en;
disable_INT();
atl_scheduler( tip->index );
enable_INT();
}
void atlmix_re_enable_interrupt_transfer( transfer_instance_ptr tip )
{
unsigned short v;
tip->data_ptr_start = tip->data_ptr_base;
read_direct_access( tip->target_address, (unsigned char *)(&v), 2 );
v &= 0x0400; // Do not clear "Toggle" information
v |= 0x0800; // Set "Active" bit to activate this PTD
write_direct_access( tip->target_address, (unsigned char *)(&v), 2 ); // Needs to re-write these 2 bytes
write_register32( Com32_HcINTLPTDSkipMap, read_register32( Com32_HcINTLPTDSkipMap ) & ~(0x00000001L << (tip->index)) );
}
/***************************************
***************************************
**
** Schedulers
**
***************************************
***************************************/
void atl_scheduler( unsigned char i )
{
transfer_instance_ptr tip;
#ifdef USE_SKIPMAP
unsigned long skip_map;
#endif
tip = &(g_atl_transfer_slot[ i ]);
#if 0
if ( tip->target_block_index != 0xFF )
mprintf( YELLOW, ABORT, "atl_scheduler error (%u) : ( tip->target_block_index != 0xFF )\r\n", i );
if ( tip->data_ptr_start == NULL )
mprintf( YELLOW, ABORT, "atl_scheduler error (%u|%p) : ( tip->data_ptr_start == NULL )\r\n", i, tip );
#endif
#ifdef USE_SKIPMAP
skip_map = read_register32( Com32_HcATLPTDSkipMap );
if ( ~skip_map & (0x1 << i) )
mprintf( YELLOW, ABORT, "atl_scheduler error (%u) : ( skip_map & (0x1 << i) )\r\n", i );
#endif
tip->target_block_index = i;
g_atl_slot_number_by_block[ i ] = i;
tip->target_address = g_buffer_parameter[ CTRL_BULK_TRANSFER ].base_address + ((g_buffer_parameter[ CTRL_BULK_TRANSFER ].payload_size + PTD_HEADER_SIZE) * i);
write_a_PTD_into_1362( tip );
}
void intl_scheduler( unsigned char index, unsigned char polling_rate )
{
transfer_instance_ptr tip;
unsigned short tartget_address_1362_buffer;
unsigned char i;
tip = &(g_intl_transfer_slot[ index ]);
tip->target_block_index = index;
tartget_address_1362_buffer = g_buffer_parameter[ INTERRUPT_TRANSFER ].base_address + ((g_buffer_parameter[ INTERRUPT_TRANSFER ].payload_size + PTD_HEADER_SIZE) * index);
tip->target_address = tartget_address_1362_buffer;
tip->polling_rate = (128 < polling_rate) ? 128 : polling_rate;
write_a_PTD_into_1362( tip );
}
void write_a_PTD_into_1362( transfer_instance_ptr tip )
{
unsigned short transfer_size;
unsigned short payload_size;
unsigned char ptd_header_buffer_ptr[ PTD_HEADER_SIZE ];
PTD_header_param ph;
unsigned short skipmap_register;
unsigned short buffer_enable_mask;
unsigned char i;
payload_size = g_buffer_parameter[ CTRL_BULK_TRANSFER ].payload_size;
transfer_size = tip->data_ptr_end - tip->data_ptr_start; // remaining data size
transfer_size = (payload_size < transfer_size) ? payload_size : transfer_size;
ph.ActualBytes = 0;
ph.CompletionCode = 0xE;
ph.CompletionCode = 0;
ph.Active = 1;
ph.Toggle = (tip->epi_ptr)->toggle;
ph.MaxPacketSize = (tip->epi_ptr)->max_packet_size;
ph.EndpointNumber = (tip->epi_ptr)->ep_num;
ph.Last = 0;
ph.Speed = (tip->epi_ptr)->speed;
ph.TotalBytes = transfer_size;
ph.DirectionPID = tip->direction;
ph.Format = (tip->epi_ptr)->tr_type;
ph.FunctionAddress = (tip->epi_ptr)->dev_addr;
if ( tip->transfer_type == INTERRUPT_TRANSFER )
{
for ( i = 7; i > 0; i-- )
if ( (tip->polling_rate) & (0x01 << i) )
break;
ph.PollingRate = i;
ph.StartingFrame = tip->index;
ph.Paired = False;
ph.PingPong = 0;
skipmap_register = Com32_HcINTLPTDSkipMap;
buffer_enable_mask = 0x4;
}
else
{
ph.PollingRate = 0;
ph.StartingFrame = 0;
ph.Paired = tip->paired;
ph.PingPong = tip->ping_pong;
skipmap_register = Com32_HcATLPTDSkipMap;
buffer_enable_mask = g_pp_pause ? 0x0 : 0x8;
}
set_PTD_header( ptd_header_buffer_ptr, &ph ); // write PTD header
if ( read_register16( Com16_HcATLPTDDoneThresholdTimeOut ) )
tip->timeout = gp_sof_counter + read_register16( Com16_HcATLPTDDoneThresholdTimeOut );
else
tip->timeout = 0xFFFFFFFF;
write_direct_access( tip->target_address, ptd_header_buffer_ptr, PTD_HEADER_SIZE );
if ( tip->direction != IN )
write_direct_access( tip->target_address + PTD_HEADER_SIZE, tip->data_ptr_start, transfer_size );
write_register32( skipmap_register, read_register32( skipmap_register ) & ~(0x00000001L << tip->target_block_index) );
write_register16( Com16_HcBufferStatus, read_register16( Com16_HcBufferStatus ) | buffer_enable_mask );
}
/***************************************
***************************************
**
** IRQs
**
***************************************
***************************************/
void ATL_IRQ_service( unsigned char dummy_for_func_compatibility )
{
unsigned long done_map;
unsigned long enable_map;
unsigned long check_timeout_map;
unsigned long timeout_map = 0L;
unsigned char i;
dummy_for_func_compatibility = dummy_for_func_compatibility; // This line for erase warning
done_map = read_register32( Com32_HcATLPTDDoneMap );
enable_map = ~read_register32( Com32_HcATLPTDSkipMap );
check_timeout_map = ~done_map & enable_map;
if ( check_timeout_map && !g_pp_active )
{
for ( i = 0; i < g_buffer_parameter[ CTRL_BULK_TRANSFER ].number_of_blocks; i++ )
if ( check_timeout_map & (0x1 << i) )
if ( g_atl_transfer_slot[ g_atl_slot_number_by_block[ i ] ].timeout < gp_sof_counter )
timeout_map |= (0x1L << i);
done_map |= timeout_map;
}
if ( done_map )
{
write_register32( Com32_HcATLPTDSkipMap, ~enable_map | done_map );
if ( 0x00000000 == (enable_map & ~done_map) )
{
write_register16( Com16_HcBufferStatus, read_register16( Com16_HcBufferStatus ) & ~0x8 );
if ( !g_atl_flag_mask )
g_atl_disabled_time = gp_sof_counter;
}
for ( i = 0; i < g_buffer_parameter[ CTRL_BULK_TRANSFER ].number_of_blocks; i++ )
{
if ( done_map & (0x1 << i) )
{
if ( (timeout_map & (0x1 << i)) && (read_register16( Com16_HcBufferStatus ) & 0x8) )
{
// Wait the HC leave from ABORTED ptd-block.
//
// If it is not aborted ptd-block, software does not need to
// check this. Because HC will not touch this ptd-block
// with no-active flag in pth-header.
// Version 1.2b :
// When the "HcBufferStatus.ATL_Active (bit position 0x8)" is cleared,
// the HC stops scnanning. In this case, no need to wait the scan goes
// to other slot.
// If following loop enabled with ATL_Active==0, the program ca not exit.
while ( read_register32( Com16_HcATLCurrentActiePTD ) == i )
;
}
// handle_transfer_done( &(g_atl_transfer_slot[ g_atl_slot_number_by_block[ i ] ]) );
handle_transfer_done( &(g_atl_transfer_slot[ i ]) );
}
}
}
}
void INTL_IRQ_service( unsigned char dummy_for_func_compatibility )
{
unsigned long done_map;
unsigned char i;
dummy_for_func_compatibility = dummy_for_func_compatibility; // This line for erase warning
done_map = read_register32( Com32_HcINTLPTDDoneMap );
write_register32( Com32_HcINTLPTDSkipMap, read_register32( Com32_HcINTLPTDSkipMap ) | done_map );
for ( i = 0; i < g_buffer_parameter[ INTERRUPT_TRANSFER ].number_of_blocks; i++ )
if ( done_map& (0x1 << i) )
handle_transfer_done( &(g_intl_transfer_slot[ i ]) );
}
/***************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -