📄 tr_scheduler.c
字号:
/****************************************Copyright (c)**************************************************
** Guangzou ZLG-MCU Development Co.,LTD.
** graduate school
** http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: tr_scheduler.c
** Last modified Date: 2005-04-22
** Last Version: V1.0
** Description:
**
**------------------------------------------------------------------------------------------------------
** Created By: Lishan Zhou
** Created date: 2005-04-22
** Version: V1.0
** Description:
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/
/****************************************************************************/
/* includes */
/****************************************************************************/
#include "HostStack.h"
#ifndef MAX_TRANSFER_LIST
#define MAX_TRANSFER_LIST 60
#endif
/****************************************************************************/
/* constants */
/****************************************************************************/
#define PTD_HEADER_LENGTH 8
#define NUMBER_OF_TRANSFER_TYPES 3
#define ATL_STATUS__FULL 0x04
#define ATL_STATUS__DONE 0x20
#define mem_align( x ) ((unsigned char *)((((unsigned long)(x)) + 3) & ~0x3))
/****************************************************************************/
/* global vars */
/****************************************************************************/
unsigned short g_atl_access_length = 0;
transfer_instance g_transfer_list[ MAX_TRANSFER_LIST ];
unsigned char g_static_atl_buffer[ InitVal_HcATLBufferLength + 3 ];
unsigned char *g_atl_buffer;
transfer_instance *g_tr_list_ptr[3] = {NULL,NULL,NULL} ;
transfer_instance *g_insert_tr_list_ptr[3] = {NULL,NULL,NULL} ;
/****************************************************************************/
/* function prototypes */
/****************************************************************************/
unsigned char atl_buffer_state( unsigned short pattern );
void atl_read_buffer( unsigned char *bp, unsigned short length );
void atl_write_buffer( unsigned char *bp, unsigned short length );
void atl_buffer_parse( unsigned char *bp );
void atl_schedule( unsigned char *g_atl_buffer, unsigned short length, unsigned short *ap );
void PTD_image_create( PTD_header_param *php, unsigned char *data, unsigned char *atl_buffer );
void set_PTD_header( unsigned char *ph, PTD_header_param *php );
void set_LAST_PTD_flag( unsigned char *p );
void get_PTD_header( PTD_header_param *php, unsigned char *ph );
void remove_tr_list(transfer_instance **from_this_list, transfer_instance *list );
void insert_tr_to_ep_list(transfer_instance **to_this_list, transfer_instance *list );
void remove_tr_from_ep(transfer_instance *list);
/****************************************************************************/
/* function definitions */
/****************************************************************************/
void atl_initialize( void )
{
int i;
for(i=0; i < MAX_TRANSFER_LIST ; i++)
{
(g_transfer_list[i]).lock = UNLOCK;
(g_transfer_list[ i ]).readout_position = NULL;
(g_transfer_list[ i ]).data_ptr_start = NULL;
}
g_tr_list_ptr[0] = NULL ;
g_tr_list_ptr[1] = NULL ;
g_tr_list_ptr[2] = NULL ;
g_insert_tr_list_ptr[0] = NULL ;
g_insert_tr_list_ptr[1] = NULL ;
g_insert_tr_list_ptr[2] = NULL ;
g_atl_buffer = mem_align( g_static_atl_buffer );
install_ATLInt_service_routine( 0, atl_ATL_transfer_mixer );
install_SOF_service_routine( 1, atl_ATL_transfer_mixer );
}
unsigned char g_is_add = 0;
void insert_transfer_descriptor(transfer_instance *tr_instance_ptr ,
unsigned char transfer_type)
{
transfer_instance **tr_instance_type_ptr;
disable();
g_is_add =0;
switch(transfer_type & 0x03)
{
case 3:
tr_instance_type_ptr = &g_insert_tr_list_ptr[INTERRUPT_TRANSFER];
break;
case 0:
tr_instance_type_ptr = &g_insert_tr_list_ptr[CONTROL_TRANSFER];
break;
case 2:
tr_instance_type_ptr = &g_insert_tr_list_ptr[BULK_TRANSFER];
break;
}
tr_instance_ptr->tr_list_for_tr.Flink = NULL;
tr_instance_ptr->tr_list_for_tr.Blink = NULL;
if ( *tr_instance_type_ptr == NULL)
{
*tr_instance_type_ptr = tr_instance_ptr;
(*tr_instance_type_ptr)->tr_list_for_tr.Flink = tr_instance_ptr;
(*tr_instance_type_ptr)->tr_list_for_tr.Blink = NULL;
}
else
{
(*tr_instance_type_ptr)->tr_list_for_tr.Flink->tr_list_for_tr.Blink = tr_instance_ptr;
tr_instance_ptr->tr_list_for_tr.Flink = (*tr_instance_type_ptr)->tr_list_for_tr.Flink;
tr_instance_ptr->tr_list_for_tr.Blink = NULL;
(*tr_instance_type_ptr)->tr_list_for_tr.Flink = tr_instance_ptr;
}
g_is_add = 1;
enable();
}
transfer_instance *atl_open_transfer_instance( endpoint_info * epi_ptr)
{
int j;
unsigned char transfer_type = epi_ptr->transfer_type & 0x03;
OS_EVENT *os_event_ptr;
disable();
if(epi_ptr->ep_num==ENDPOINT_BE_FREE)
{
enable();
return ATL_ENDPOINT_ERR;
}
for ( j = 0; j < MAX_TRANSFER_LIST; j++ )
{
if ( (g_transfer_list[ j ]).lock == UNLOCK )
{
(g_transfer_list[ j ]).lock= LOCK;
os_event_ptr = OSMboxCreate(NULL);
if(os_event_ptr)
(g_transfer_list[ j ]).os_event_ptr = os_event_ptr;
else
{
(g_transfer_list[ j ]).lock = UNLOCK;
enable();
return NO_OPEN_ATL_TRANSFER ;
}
(g_transfer_list[ j ]).epi_ptr = epi_ptr;
(g_transfer_list[ j ]).endpoint_create_id = epi_ptr->endpoint_create_id;
insert_transfer_descriptor(&(g_transfer_list[ j ]), transfer_type);
insert_tr_to_ep_list(&epi_ptr->tr_instance_ptr, &(g_transfer_list[ j ]));
enable();
return &(g_transfer_list[ j ]) ;
}
}
enable();
return NO_OPEN_ATL_TRANSFER ;
}
void atl_close_transfer_instance( transfer_instance *tr_instance_ptr )
{
unsigned char err;
if(tr_instance_ptr->lock == UNLOCK)
return;
if(tr_instance_ptr->lock == DELETE)
return;
tr_instance_ptr->data_ptr_start = NULL;
tr_instance_ptr->lock = DELETE;
// UPDATA 2005-06-17
OSMboxDel( tr_instance_ptr->os_event_ptr,
OS_DEL_NO_PEND , &err );
if(err == OS_ERR_TASK_WAITING)
{
tr_instance_ptr->completion_code = OS_EVENT_DELETE;
OSMboxPost( tr_instance_ptr->os_event_ptr,
&tr_instance_ptr->completion_code);
return;
}
tr_instance_ptr->os_event_ptr = NULL;
}
unsigned char atl_set_transfer( transfer_instance *tr_inst_ptr,
unsigned char *buffer_ptr,
unsigned short length,
unsigned char direction,
void (*callback)( transfer_instance *tr_inst_ptr ) )
{
unsigned char schedule_rate;
if( tr_inst_ptr->lock != LOCK)
return FALSE ;
if( tr_inst_ptr->epi_ptr == NULL)
return FALSE ;
if( tr_inst_ptr->epi_ptr->ep_num == ENDPOINT_BE_FREE)
return FALSE ;
if( tr_inst_ptr->endpoint_create_id !=
tr_inst_ptr->epi_ptr->endpoint_create_id)
return FALSE;
schedule_rate = tr_inst_ptr->epi_ptr->endpoint_descriptor.bInterval;
tr_inst_ptr->data_ptr_base = buffer_ptr;
tr_inst_ptr->data_ptr_end = buffer_ptr + length;
tr_inst_ptr->direction = direction;
tr_inst_ptr->callback = callback;
tr_inst_ptr->readout_position = NULL;
tr_inst_ptr->transferred_size = 0;
tr_inst_ptr->fatal_error = 0;
tr_inst_ptr->completion_code = 0;
tr_inst_ptr->schedule_rate = schedule_rate;
tr_inst_ptr->poll_timing_timer = g_sof_counter + tr_inst_ptr->schedule_rate;
tr_inst_ptr->data_ptr_start = tr_inst_ptr->data_ptr_base;
return TRUE;
}
void re_enable_interrupt_transfer( transfer_instance *tr_inst_ptr )
{
tr_inst_ptr->data_ptr_start = tr_inst_ptr->data_ptr_base;
}
void atl_ATL_transfer_mixer( void )
{
unsigned short atl_stat;
unsigned short atl_full;
unsigned short atl_done;
unsigned short i;
transfer_instance *tr_instance_ptr;
atl_stat = atl_buffer_state( ATL_STATUS__DONE | ATL_STATUS__FULL );
atl_full = atl_stat & ATL_STATUS__FULL;
atl_done = atl_stat & ATL_STATUS__DONE;
if ( atl_full && !atl_done )
return;
if ( atl_done && g_atl_access_length )
{
atl_read_buffer( g_atl_buffer, g_atl_access_length );
atl_buffer_parse( g_atl_buffer );
}
g_atl_access_length = 0;
if(g_is_add)
for( i=0; i< NUMBER_OF_TRANSFER_TYPES;i++)
{
g_is_add = 0;
if(g_insert_tr_list_ptr[i] == NULL)
continue;
if(g_tr_list_ptr[i]==NULL)
{
g_tr_list_ptr[i] = g_insert_tr_list_ptr[i];
g_insert_tr_list_ptr[i]=NULL;
continue;
}
else
{
tr_instance_ptr = g_tr_list_ptr[i]->tr_list_for_tr.Flink;
g_tr_list_ptr[i]->tr_list_for_tr.Flink = g_insert_tr_list_ptr[i]->tr_list_for_tr.Flink;
tr_instance_ptr->tr_list_for_tr.Blink = g_insert_tr_list_ptr[i];
g_insert_tr_list_ptr[i]->tr_list_for_tr.Flink = tr_instance_ptr;
g_insert_tr_list_ptr[i] = NULL;
}
}
atl_schedule( g_atl_buffer, InitVal_HcATLBufferLength, &g_atl_access_length);
if ( g_atl_access_length )
atl_write_buffer( g_atl_buffer, g_atl_access_length );
}
void atl_read_buffer( unsigned char *bp, unsigned short length )
{
write_register16( Com16_HcTransferCounter, length );
read_register_burst_char( Com16_HcATLBufferPort, bp, length );
}
void atl_write_buffer( unsigned char *bp, unsigned short length )
{
write_register16( Com16_HcTransferCounter, length );
write_register_burst_char( Com16_HcATLBufferPort, bp, length );
}
#ifdef TRANSFER_STATUS_MONITOR
#include <conio.h>
#endif
void atl_buffer_parse( unsigned char *ptd_start )
{
transfer_instance *tr_inst_ptr;
PTD_header_param ph;
int i;
for(i=0;i<NUMBER_OF_TRANSFER_TYPES;i++)
{
for( tr_inst_ptr = g_tr_list_ptr[i];
tr_inst_ptr!=NULL;
tr_inst_ptr =tr_inst_ptr->tr_list_for_tr.Blink)
{
if ( tr_inst_ptr->data_ptr_start == NULL )
continue;
if ( tr_inst_ptr->readout_position == NULL )
continue;
ptd_start = tr_inst_ptr->readout_position;
get_PTD_header( &ph, ptd_start );
if ( i == BULK_TRANSFER)
tr_inst_ptr->readout_position = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -